<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Portainer on 魔都水滴</title>
    <link>https://blog.margrop.net/tag/portainer/</link>
    <description>Recent content in Portainer on 魔都水滴</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh-CN</language>
    <lastBuildDate>Fri, 10 Jul 2026 15:30:00 +0800</lastBuildDate>
    <atom:link href="https://blog.margrop.net/tag/portainer/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>我把 Docker 命令行装进了“驾驶舱”：Portainer 2.39.4 从部署到避坑，一篇就够</title>
      <link>https://blog.margrop.net/post/portainer-ce-docker-deployment-guide/</link>
      <pubDate>Fri, 10 Jul 2026 15:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/portainer-ce-docker-deployment-guide/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Portainer 不是 Docker 的替代品，它更像 Docker 主机的“驾驶舱”：底层发动机仍然是 Docker Engine，Portainer 只是把容器、镜像、网络、卷和 Compose Stack 整理成网页按钮、表格与状态卡片。&lt;/p&gt;&#xA;&lt;p&gt;我用 &lt;code&gt;portainer/portainer-ce:2.39.4&lt;/code&gt; 做了一次隔离部署，完成初始化、接入本机 Docker、查看仪表盘、筛选容器、创建演示 Stack，并记录了真实截图。部署本身只要一条 &lt;code&gt;docker run&lt;/code&gt;，真正需要认真理解的却是三件事：&lt;code&gt;/data&lt;/code&gt; 必须持久化、&lt;code&gt;/var/run/docker.sock&lt;/code&gt; 权限非常高、生产环境不要把管理页面毫无遮挡地暴露到公网。&lt;/p&gt;&#xA;&lt;p&gt;本文没有展示完整 IP 地址、真实主机名、内网域名、管理员密码、Token、Cookie、私有镜像地址或生产容器名称。截图里的实验资源使用专门的演示名称，容器地址已遮盖。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>别再让 Agent 吞掉你的 Token：我把 Headroom 接到 NewAPI、OpenClaw 和 HermesAgent 的完整实战</title>
      <link>https://blog.margrop.net/post/headroom-newapi-openclaw-hermesagent-token-compression-guide/</link>
      <pubDate>Sat, 20 Jun 2026 12:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/headroom-newapi-openclaw-hermesagent-token-compression-guide/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这次我没有替换原来的 NewAPI，也没有让 OpenClaw / HermesAgent 直接改用一个不确定的新网关。真正做法是：在 NewAPI 前面加一层 Headroom 代理，把所有已经使用 OpenAI-compatible 协议的调用改到 &lt;code&gt;http://&amp;lt;headroom-host&amp;gt;:8787/v1&lt;/code&gt;，而原来的 NewAPI 入口继续保留。这样 Agent 发来的长上下文先经过 Headroom 压缩，再转发给 NewAPI，最后仍由 NewAPI 统一路由到后端模型。&lt;/p&gt;&#xA;&lt;p&gt;最关键的原则只有一句：&lt;strong&gt;先测试，后修改；只迁移测试通过的 OpenAI-compatible 项；非 OpenAI 协议的 fallback 不碰。&lt;/strong&gt; 这篇文章既是复盘，也是一份可以直接交给 Agent 或人工照着执行的操作指南。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>我把 AnythingLLM 装进 Docker 之后，容器像一只上紧发条的小松鼠——反复重启直到我把那个 1000:1000 给它</title>
      <link>https://blog.margrop.net/post/anythingllm-docker-deploy/</link>
      <pubDate>Wed, 17 Jun 2026 20:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/anythingllm-docker-deploy/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR（先说结论）&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;AnythingLLM 这只&amp;quot;啥都能塞进去的 LLM 口袋书&amp;quot;官方就有 Docker 镜像，正常情况下 &lt;code&gt;docker run&lt;/code&gt; 一行就能起；但它里面那位 &lt;code&gt;anythingllm&lt;/code&gt; 用户很挑剔——挂给它的宿主机目录必须属于 &lt;code&gt;1000:1000&lt;/code&gt;，否则它写不动自己的 SQLite 数据库，Prisma 启动迁移会直接挂掉，容器就会进入&amp;quot;重启—挂掉—再重启&amp;quot;的死循环。修起来不到一分钟：&lt;code&gt;chown -R 1000:1000 /你的数据目录&lt;/code&gt;，再 &lt;code&gt;docker compose up -d&lt;/code&gt; 一次，它就乖乖听 &lt;code&gt;3001&lt;/code&gt; 了。&lt;/p&gt;&#xA;&lt;p&gt;本文顺道把&amp;quot;Prisma 那个 &lt;code&gt;file:../storage/anythingllm.db&lt;/code&gt; 相对路径为什么能坑死人&amp;quot;讲清楚，最后附上 Portainer stack 写法、几条常见坑、以及中英两个 demo 地址。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Portainer 改个 stack 一直 500？我花了一晚上才明白，是 Docker 引擎里多了一个「重影」网络</title>
      <link>https://blog.margrop.net/post/portainer-500-duplicate-compose-network-enigma/</link>
      <pubDate>Sat, 13 Jun 2026 08:00:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/portainer-500-duplicate-compose-network-enigma/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Portainer 改一个 stack，浏览器上弹出 &lt;code&gt;500 Internal Server Error&lt;/code&gt;。你以为又是 YAML 写错了，回去检查 compose 语法、缩进、引号、镜像 tag，全部都对。但每次重试都是同一个 500。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;真正的问题藏在 HTTP response body 的 &lt;code&gt;message&lt;/code&gt; 字段最深处：&lt;code&gt;network librespeed_default is ambiguous (2 matches found on name)&lt;/code&gt;。&lt;/strong&gt; 也就是说，Docker 引擎里同时存在两个 &lt;code&gt;librespeed_default&lt;/code&gt; 网络——两个 ID、两个 &lt;code&gt;Created&lt;/code&gt; 时间、两个 &lt;code&gt;com.docker.compose.config-hash&lt;/code&gt;，但名字一模一样。Compose 启动时让引擎去 lookup 名字，引擎说「我选不出来」，compose up 失败，Portainer 把这条错误原样包成 500 退给浏览器。&lt;/p&gt;&#xA;&lt;p&gt;修复办法朴素到尴尬：在引擎上&lt;strong&gt;删掉其中一个孤儿网络&lt;/strong&gt;（&lt;code&gt;docker network rm &amp;lt;id&amp;gt;&lt;/code&gt; 或在 Portainer 的 Networks 里点 Remove），再原样点一次 Update the stack，就过了。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;这篇文章源于一次真实的 stack 改挂载路径的过程。全程我已经把所有内网地址、镜像仓库地址、卷挂载路径、容器名、用户名密码用 &lt;code&gt;&amp;lt;PLACEHOLDER&amp;gt;&lt;/code&gt; 替换，只保留公开信息、官方源码、错误文本这些可分享的内容。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Docker 容器太多导致网段冲突：把自动分配网络统一迁回 172 私有段的完整记录</title>
      <link>https://blog.margrop.net/post/docker-network-subnet-conflict-migration-record/</link>
      <pubDate>Mon, 13 Apr 2026 08:00:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/docker-network-subnet-conflict-migration-record/</guid>
      <description>&lt;p&gt;这篇文章记录的是一次很典型、也很容易被忽略的 Docker 网络故障：容器越来越多，Docker 自动分配出来的 user-defined bridge 网段，最后落进了 &lt;code&gt;192.168.x.x&lt;/code&gt;，并且和家里的真实局域网发生了冲突。问题本身不算复杂，但它有一个很讨厌的特点：它不是那种“容器起不来”或者“端口没映射”的显性错误，而是把整个家庭网络拖进一个很别扭的半瘫痪状态。&lt;/p&gt;&#xA;&lt;p&gt;当时在我的 NAS 上，家里部分设备开始出现访问异常。表面上看，像是某个设备离线，或者某个交换机、AP、路由器出了毛病；但我沿着 Docker 的网络一路排查下去后，最终确认，真正的根因不是单个容器坏了，而是 Docker 网络池的自动分配策略，已经把局域网挤到了一个危险的位置。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
