<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Containers on Margrop Blog</title>
    <link>https://blog.margrop.net/en/tag/containers/</link>
    <description>Recent content in Containers on Margrop Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-US</language>
    <lastBuildDate>Fri, 10 Jul 2026 15:30:00 +0800</lastBuildDate>
    <atom:link href="https://blog.margrop.net/en/tag/containers/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>I Put Docker in a Control Room: Portainer CE 2.39.4 Deployment, Daily Use, and Real Traps</title>
      <link>https://blog.margrop.net/en/post/portainer-ce-docker-deployment-guide/</link>
      <pubDate>Fri, 10 Jul 2026 15:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/portainer-ce-docker-deployment-guide/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Bottom line first&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Portainer does not replace Docker. It is a control room for a Docker host. Docker Engine remains the machinery; Portainer organizes containers, images, networks, volumes, and Compose stacks into a web dashboard.&lt;/p&gt;&#xA;&lt;p&gt;I ran an isolated deployment of &lt;code&gt;portainer/portainer-ce:2.39.4&lt;/code&gt;, initialized it, connected the local Docker environment, inspected the dashboard, filtered a disposable container, and created a demonstration stack. The installation is one &lt;code&gt;docker run&lt;/code&gt; command. The important lessons are broader: persist &lt;code&gt;/data&lt;/code&gt;, understand that &lt;code&gt;/var/run/docker.sock&lt;/code&gt; is highly privileged, and never expose the management interface to an untrusted network without protection.&lt;/p&gt;&#xA;&lt;p&gt;This article contains no complete IP address, real host name, private domain, administrator password, token, cookie, private registry address, or production container name. The screenshots use disposable names, and the container address is redacted.&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>The Portainer 500 Error That Wasn&#39;t the YAML — A Two-librespeed_default-Network Story</title>
      <link>https://blog.margrop.net/en/post/portainer-500-duplicate-compose-network-enigma/</link>
      <pubDate>Sat, 13 Jun 2026 08:00:00 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/portainer-500-duplicate-compose-network-enigma/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;The short version&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;You update a stack in Portainer. The browser slaps you with a red &lt;code&gt;500 Internal Server Error&lt;/code&gt;. You assume the YAML is wrong, fix the indentation, swap the quotes, drop the image tag. You hit Update again. Same 500. And again. And again.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;The real culprit is buried at the deepest level of the HTTP response body: &lt;code&gt;network librespeed_default is ambiguous (2 matches found on name)&lt;/code&gt;.&lt;/strong&gt; Two networks with the same name exist in the same Docker engine—two IDs, two &lt;code&gt;Created&lt;/code&gt; timestamps, two &lt;code&gt;com.docker.compose.config-hash&lt;/code&gt; labels, but a single shared name. Compose asks the engine to look up that name; the engine refuses to pick between them; &lt;code&gt;compose up&lt;/code&gt; fails; Portainer wraps the error as a 500 and returns it to your browser.&lt;/p&gt;&#xA;&lt;p&gt;The fix is embarrassingly simple: &lt;strong&gt;delete one of the two orphan networks&lt;/strong&gt; (&lt;code&gt;docker network rm &amp;lt;id&amp;gt;&lt;/code&gt; or click Remove in Portainer&amp;rsquo;s Networks page), then re-run Update the stack with the exact same content. It just works.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This post is a real debugging session: a stack update that was supposed to be a 30-second mount-path change turned into a 1-hour investigation. All private details (internal addresses, registry URLs, volume paths, container names, credentials) have been replaced with &lt;code&gt;&amp;lt;PLACEHOLDER&amp;gt;&lt;/code&gt;. Only public source code, official docs, and the error text itself are preserved.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
