Portainer 升級文把 Docker 更新變清單
我把 Portainer 的 Docker Standalone 升級流程拆成可直接複製的檢查清單,讓你不用邊升級邊猜。

我把 Portainer 的 Docker Standalone 升級流程拆成可直接複製的檢查清單,讓你不用邊升級邊猜。
我用 Portainer 跑 Docker 一陣子了。老實說,它最煩的地方不是升級指令難,而是你每次一要動手,腦袋就同時開三個分頁:資料會不會不見、容器砍掉會不會把別的 stack 一起帶走、agent 版本有沒有跟上。這種東西最容易把人卡住。命令本身很短,心理負擔卻很重。我以前也會在 docker rm 那一步停住,開始懷疑自己是不是要先備份到天荒地老。
後來我去看 Portainer 的 Docker Standalone upgrade doc,才發現它其實是在教一個很樸素的套路:把 runtime 換掉,資料留著,版本對齊,然後不要自作聰明。它沒有把升級寫成儀式感滿滿的大工程,反而像一張操作單。這種寫法我很買單,因為我不想在維運工具上玩猜謎。
Portainer 的核心思路其實很無聊,但很對
訂閱 AI 趨勢週報
每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。
不會寄垃圾信,隨時可取消。
To update to the latest version of Portainer Server, use the following commands to stop then remove the old version. Your other applications/containers will not be removed.
翻譯一下就是:Portainer 容器可以丟,資料不要丟。這句話看起來普通,但它其實是在劃清楚一件事:容器是可替換的執行層,真正重要的是外掛出去的 volume。這種設計才讓升級變成「換容器」而不是「重裝系統」。

我之前帶一個小環境時,最怕的就是工具本身跟資料綁死。只要一升級就像在拆房子。Portainer 這份文件的好處,就是它一直提醒你:不要把 container filesystem 當成家。家要放在 named volume 裡,container 只是臨時住客。
實操上我會這樣做:
- 先確認 Portainer 的資料真的在 named volume,例如
portainer_data。 - 只停掉 Portainer 自己,不要碰你管理中的其他 containers 或 stacks。
- 就算文件說安全,我還是會先備份 volume,這不是不信任,是避免自己手滑。
這也是我喜歡 Portainer 文件的地方。它沒有把升級包裝成什麼神秘流程,反而把最重要的界線講清楚:runtime 可換,state 要留。
版本對齊不是潔癖,是少走冤枉路
Portainer 文件很直接地說,server 跟 agent 要用同一版。這件事很多人會想偷懶,覺得「差一點點應該沒差吧」。我以前也這樣想,結果通常不是當場炸,而是開始出現那種很難描述的怪問題:連線怪怪的、環境看不到、UI 沒報錯但行為就是不對。
也就是說,Portainer 不太吃「大概相容」這套。server 和 agent 不是各升各的就好,它們是配對關係。你如果 server 升了、agent 還卡在舊版,問題不一定馬上爆,但你會開始浪費時間猜到底是 Docker、網路、權限,還是版本不合。通常最後答案都很無聊,就是沒對齊。
我自己遇過最煩的一次,是 lab 環境裡 server 先升,agent 晚了一拍。沒有大事故,但就是開始 flaky。那種感覺最差,因為你沒辦法很快證明是誰壞掉。文件把這件事講死,反而是幫你省時間。
實操寫法我會抓三件事:
- 升級前先記下目前 server 版本,別只看 UI 右上角一眼帶過。
- 能同步升 agent 就同步升,不要 server 先跑太遠。
- 如果你還卡在 Portainer 1.x,先走到 2.0.0,再談最新版本,別想一步跳過去。
這裡我也順手補一個連結:Portainer 官方文件站是 docs.portainer.io,它把不同平台的升級路徑拆開,這比把所有情況揉成一鍋好太多。
9443 和 HTTPS 這件事,別用舊習慣硬撐
文件裡有個很容易被忽略的點:從 Portainer CE 2.9、BE 2.10 開始,HTTPS 預設是開在 9443。這代表你不能再只盯著以前那個 HTTP 習慣,因為升級後的預設世界已經變了。

翻譯一下就是,Portainer 沒有故意刁難你,它只是把安全預設往前推了一格。問題在於,很多人升級完還在用舊書籤,直接打 http://server:9000,然後開始懷疑服務掛了。其實不是掛,是你還在用舊入口。
我很常看到這種錯法,尤其是平常太依賴 bookmark 的人。升級本身沒出錯,錯的是你沒跟著改連線方式。這種 bug 最討厭,因為它看起來像故障,實際上是習慣。
實操上我會這樣處理:
- 先確認 agent 和 edge agent 已經能用 HTTPS 溝通,再升 server。
- 升完之後,主要入口改用
https://your-server:9443。 - 只有真的需要過渡期時,才暫時保留 9000,不要把舊 HTTP 當永久方案。
如果你有自管憑證,Portainer 也有對應的 SSL 參數,這點我反而覺得很實用。至少你不用把內網管理介面交給預設憑證亂跑,還得回頭查半天到底是哪個路徑沒掛上。
升級不是遷移,是替換 runtime
Portainer server 的更新流程其實很短:停掉舊容器、刪掉舊容器、拉新 image、用同一個 volume 跑新容器。文件還特別寫了,其他 applications/containers 不會被移除。這句話很重要,因為它把升級的邏輯講得很乾淨。
也就是說,你不是在「搬家」,你是在「換一台新的 Portainer 執行個體」,然後把原本的資料庫接回去。這個心智模型一旦建立,很多恐懼會直接少一半。因為你知道真正要保護的是資料,不是那個舊 container id。
我現在看 admin 工具都會用這個角度判斷:它是不是把 state 外掛出去?如果是,那升級就應該像換電池,不該像拆主機板。Portainer 這份文件就是在教你用這種方式思考。
實操寫法可以很直接:
- 先
docker stop再docker rm,但只動 Portainer 自己。 - 拉對 edition 的
ltsimage,不要亂挑 tag。 - 重跑 container 時,volume、port、restart policy 都維持原樣。
我也建議你把 Portainer 當成基礎設施的一部分,而不是一般 app。管理工具如果每次升級都像賭博,那你整個維運節奏都會被它拖慢。
agent 那段才是真正容易翻車的地方
很多人升 Portainer 只看 server,結果真正出事的是 agent。文件把 agent 更新獨立出來,我覺得這很誠實。它不是附錄,而是另一條流程:停 agent、刪 agent、拉 portainer/agent:lts、再跑起來。
翻譯一下就是,agent 不是什麼可有可無的小配件。它有自己的身份,還可能帶著 AGENT_SECRET。你如果 server 有設 secret,agent 升級時沒帶同一組環境變數,連線就會卡住。那種錯很煩,因為看起來像網路問題,實際上只是少打一個參數。
我自己最怕的就是晚上臨時 refresh agent,覺得應該很快,結果卡在 secret 或 port 9001。這種時候你會很想怪 Docker,但通常是自己少看了一行文件。Portainer 把這件事寫出來,等於先幫你把坑標好。
實操方式我會這樣做:
- server 和 agent 版本盡量同步,不要 server 先升、agent 放著不管。
- 如果你有用
AGENT_SECRET,升級時原封不動帶回去。 - 確認
9001在你的網路環境裡是可達的,別等升完才發現防火牆擋掉。
另外,Portainer 的 GitHub 在 github.com/portainer/portainer,真遇到奇怪案例時,我會去那邊看 issue 和實際討論,比自己在腦內推理快很多。
備份那句話不是裝飾,是保命線
文件有提醒你在任何更新前先備份目前的 Portainer 設定。這句話很容易被滑過去,因為前面的 commands 看起來太乾淨了。但老實說,越是看起來乾淨的流程,越要先備份。人類最常犯的錯就是把「步驟很少」誤認成「風險很低」。
翻譯一下就是,Portainer 本身不是脆弱,而是你對環境的記憶通常很脆弱。你會忘記自訂憑證路徑,忘記某個額外 port,忘記當初為什麼多加一個 flag。等你真的出事,最值錢的不是勇氣,是備份。
我對這件事的立場很硬:任何會管理容器、stack、registry、environment 的工具,升版本前都該先備份。不是因為官方不可信,是因為你自己不可能記得所有細節。
實操上我會做這幾件事:
- 先備份 Portainer 的 data volume,再開始任何升級動作。
- 把原本 run command 的 custom flags 記下來,別只靠記憶。
- 順手記住目前 image tag 和版本,萬一要 rollback 才有路走。
如果你把這整個流程看成一句話,那就是:保留資料、替換 runtime、確認入口、再核對版本。真的不用搞得很戲劇化。
可抄的模板
# Portainer Docker Standalone 升級清單
## 升級前
- [ ] 確認目前 Portainer 版本
- [ ] 確認是 CE 還是 BE
- [ ] 備份 Portainer data volume
- [ ] 確認 agent 版本和 server 對齊
- [ ] 如果還在 1.x,先規劃到 2.0.0 的中繼升級
- [ ] 確認 agent / edge agent 已經能用 HTTPS 溝通
- [ ] 記下原本 container 的 custom flags、port、憑證路徑
## 升級 Portainer Server
# 停止舊容器
docker stop portainer
# 移除舊容器
docker rm portainer
# 拉對應版本的 image
# Community Edition
docker pull portainer/portainer-ce:lts
# Business Edition
# docker pull portainer/portainer-ee:lts
# 重新啟動新容器
# Community Edition
docker run -d --name=portainer --restart=always \
-p 8000:8000 -p 9443:9443 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:lts
# Business Edition
# docker run -d --name=portainer --restart=always \
# -p 8000:8000 -p 9443:9443 \
# -v /var/run/docker.sock:/var/run/docker.sock \
# -v portainer_data:/data \
# portainer/portainer-ee:lts
## 過渡期選項
# 如果你真的還需要舊 HTTP 入口,暫時加上:
# -p 9000:9000
# 如果你有自訂 TLS 憑證
# --sslcert /path/to/cert/portainer.crt \
# --sslkey /path/to/cert/portainer.key
## 升級 Portainer Agent
# 停止舊 agent
# docker stop portainer_agent
# docker rm portainer_agent
# 拉 agent image
# docker pull portainer/agent:lts
# 重新啟動 agent
# docker run -d --name portainer_agent --restart=always \
# -p 9001:9001 \
# -v /var/run/docker.sock:/var/run/docker.sock \
# -v /var/lib/docker/volumes:/var/lib/docker/volumes \
# portainer/agent:lts
# 如果 server 有設定 AGENT_SECRET,這裡也要帶回來
# -e AGENT_SECRET=yoursecret
## 升級後
- [ ] 打開 https://your-server-address:9443
- [ ] 確認版本號已更新
- [ ] 確認 environments 和 agents 都連上了
- [ ] 確認自訂憑證仍然正常
- [ ] 如果有臨時開 9000,升完後記得關掉
- [ ] 確認 update notification 已消失這份模板是我把 Portainer 官方 Docker Standalone upgrade doc 拆成可直接照抄的版本。原始步驟和版本規則來自官方文件,我加的是檢查順序、風險提示,還有比較適合台灣開發者直接拿去用的操作語氣。
如果你要我給一句最短的結論:Portainer 的升級不是在拼技術,是在拼你有沒有把資料和 runtime 分開想。這個想通了,整份文件就不再像說明書,而像一張可以直接執行的清單。