Skip to content

Docker 安裝

官方映像自帶 nginx、PHP 8.2、MariaDB、Redis,不需要你配置任何東西。跑起來開啟瀏覽器就能開始安裝。

  • 映像地址:ghcr.io/lizhipay/acg-faka:latest
  • 支援架構:amd64arm64(ARM 伺服器、Apple 晶片的 Mac 都能跑)
  • 體積:約 265 MB

先裝 Docker

已經裝好的跳過這一節。不知道 Docker 是什麼也沒關係 —— 你可以把它理解成一個「打包好的整機」:程式、PHP、資料庫、Redis 全都封在裡面,你不用一個個去裝、去配版本,拉下來跑起來就是一臺配好的伺服器。

Linux 伺服器

SSH 連上伺服器,一條命令裝完(Debian / Ubuntu / CentOS 都適用):

bash
curl -fsSL https://get.docker.com | sh

國內伺服器訪問不暢的話,用阿里雲的映像源:

bash
curl -fsSL https://get.docker.com | sh -s -- --mirror Aliyun

裝完啟動,並設成開機自啟:

bash
systemctl start docker && systemctl enable docker

驗證一下,能列印出版本號就成了:

bash
docker -v

Windows / macOS

Docker Desktop,圖形介面操作,見 Windows 安裝

Windows 需要 64 位 Windows 10 2004 版以上或 Windows 11,安裝時會自動裝 WSL 2。

裝不上怎麼辦

現象處理
指令碼卡住或超時換阿里雲映像源那條命令
docker: command not found裝完沒生效,重新連一次 SSH
Cannot connect to the Docker daemon服務沒起,執行 systemctl start docker
CentOS 7 裝完起不來系統核心太老,建議換 Debian 12 或 Ubuntu 22.04

一條命令跑起來

bash
docker run -d --name faka -p 80:80 -v acg_data:/data --restart unless-stopped ghcr.io/lizhipay/acg-faka:latest

等大約 20 秒,瀏覽器開啟 http://伺服器IP 就會看到安裝嚮導。

資料庫那一步什麼都不用填,直接下一步 —— 映像裡的資料庫已經建好了,嚮導會自己填上。

這條命令每一段是什麼意思

片段作用
-d後臺執行
--name faka給容器起個名字,以後 docker logs faka 之類的命令要用
-p 80:80連接埠對映,最容易出錯的一段,見下方
-v acg_data:/data資料放在卷裡,不加這段升級會丟資料
--restart unless-stopped伺服器重啟後自動把容器拉起來

連接埠對映:-p 80:80

連接埠對映示意連接埠對映示意

冒號左邊是宿主機連接埠(你在瀏覽器裡輸的那個),右邊是容器內部連接埠

容器內部固定是 80,永遠不要改右邊那個 80。

如果伺服器的 80 連接埠已經被別的網站佔用了,就改左邊:

bash
docker run -d --name faka -p 8080:80 -v acg_data:/data --restart unless-stopped ghcr.io/lizhipay/acg-faka:latest

這時候訪問地址就是 http://伺服器IP:8080

打不開網頁,九成是這裡寫反了或者宿主機連接埠被佔用。用 -p 8080:80 換個連接埠再試。雲伺服器還要去控制檯的安全組裡放行這個連接埠。

資料卷:-v acg_data:/data

資料卷示意資料卷示意

容器本身是一次性的,刪掉就沒了。但資料庫、配置檔案、上傳的圖片都放在 /data 裡,只要這個卷還在,刪容器、換映像、升級版本,資料都還在。

不寫這一段,容器一刪資料全沒。

升級到新版本

程式本身支援在後臺點版本號線上升級,一般不需要動容器。要換映像時:

bash
docker pull ghcr.io/lizhipay/acg-faka:latest
docker stop faka && docker rm faka
docker run -d --name faka -p 80:80 -v acg_data:/data --restart unless-stopped ghcr.io/lizhipay/acg-faka:latest

只要 -v acg_data:/data 沒變,資料一條都不會少。

常用命令

bash
docker logs -f faka          # 看日誌,出問題先看這個
docker restart faka          # 重啟
docker exec -it faka bash    # 進容器內部
docker stop faka             # 停止

配置 HTTPS(一條命令)

映像裡已經帶了 nginx 和 certbot,證書直接在容器裡簽,不用裝面板、也不用另外起反向代理

前提

要滿足什麼怎麼做
域名已解析到這臺伺服器到域名商那裡加一條 A 記錄,指向伺服器 IP
80 和 443 都能從外網訪問雲伺服器要在安全組裡放行這兩個連接埠
容器對映了 80 和 443見下一步

第 1 步:讓容器同時監聽 80 和 443

當初只寫了 -p 80:80 的話,443 是不通的。刪掉容器重建一個(資料在卷裡,不會丟):

bash
docker stop faka && docker rm faka
docker run -d --name faka -p 80:80 -p 443:443 -v acg_data:/data --restart unless-stopped ghcr.io/lizhipay/acg-faka:latest

第 2 步:簽證書

shop.abc.com 換成你的域名,[email protected] 換成你的郵箱:

bash
docker exec faka acg-ssl shop.abc.com [email protected]

跑完顯示 ✔ 配好了:https://shop.abc.com 就成了,瀏覽器開啟就是小鎖頭。

這條命令做了三件事:向 Let's Encrypt 申請證書 → 生成 nginx 的 HTTPS 配置 → 重新載入 nginx。全程不用你改任何配置檔案。

郵箱是給 Let's Encrypt 發到期提醒用的,填個你能收到的。

第 3 步:設定自動續期

Let's Encrypt 的證書只有 90 天。在宿主機上加一條定時任務,每天檢查一次:

bash
(crontab -l 2>/dev/null; echo "0 3 * * * docker exec faka acg-ssl-renew") | crontab -

證書剩餘不足 30 天時才會真的續期並重新載入 nginx,天天跑也不會觸發頻率限制。

多個域名

域名往後排著寫,最後跟郵箱,它們會簽進同一張證書

bash
docker exec faka acg-ssl abc.com www.abc.com shop.abc.com [email protected]

主域名 + www 一起簽是最常見的寫法,這樣兩個地址都能開啟且都不報證書錯誤。

要加域名時,把所有域名一起重新跑一遍,別只跑新增的那個 —— 這條命令會整個覆蓋舊配置,漏掉的域名會掉出證書。

只要有一個域名沒解析過來,整張證書就簽不下來。 先把所有域名的 A 記錄都指到這臺伺服器再跑。

子站點用的泛域名 *.abc.com 這條命令簽不了,Let's Encrypt 只允許用 DNS 驗證簽泛域名,見泛域名證書

強制 HTTPS

預設就是開的。 簽完證書後 http:// 會自動 301 跳到 https://,不用再設定什麼。

不想強制跳轉(比如前面掛了 CDN、回源走的是 http,強制跳會變成無限重定向):

bash
docker exec faka acg-ssl abc.com www.abc.com [email protected] --no-redirect

想更徹底,加上 HSTS —— 瀏覽器會記住這個域名一年內只准走 https,連第一次的 301 都省掉:

bash
docker exec faka acg-ssl abc.com www.abc.com [email protected] --hsts

HSTS 一旦開啟,這一年內你改不回 http,瀏覽器會直接拒絕訪問。確定長期用 HTTPS 再開。

已經有證書了(Cloudflare 源站證書 / 買的商業證書)

不用去申請 Let's Encrypt,直接把手上的證書裝進去。先在宿主機上把兩個檔案拷進容器:

bash
docker cp cert.pem faka:/tmp/
docker cp key.pem faka:/tmp/

再裝上:

bash
docker exec faka acg-ssl-import --cert /tmp/cert.pem --key /tmp/key.pem

域名不用寫,命令會自己從證書裡讀,泛域名 *.abc.com 也能正確識別。要手動指定就跟在後面(泛域名記得加引號):

bash
docker exec faka acg-ssl-import --cert /tmp/cert.pem --key /tmp/key.pem abc.com '*.abc.com'

--no-redirect--hsts 兩個開關跟 acg-ssl 一樣。

子站點終於有解了。 acg-ssl 走的是 Let's Encrypt 的 HTTP 驗證,簽不了泛域名;而 Cloudflare 的源站證書預設就帶 *.abc.com,導進來一次覆蓋所有子站點域名。

裝之前命令會替你擋掉三個最常見的錯誤:證書和私鑰不是一對(裝上去 nginx 直接起不來)、證書已經過期、只有證書沒帶中間證書(漏了的話桌面瀏覽器看著正常,安卓和老客戶端報錯)。

這張證書不會自動續期。 acg-ssl-renew 只管 Let's Encrypt 簽的那些。商業證書到期前重新跑一次上面的命令換上新檔案即可;Cloudflare 源站證書預設 15 年,基本不用管。

掛了 CDN(Cloudflare 等)

三件事,缺一個都會出問題。

1. 回源協議要對上。 Cloudflare 的 SSL 模式選 完全(嚴格)/ Full (strict),配合上面裝好的源站證書。如果選了「靈活 / Flexible」(CDN 到源站走 http),而站點這邊又開著強制跳轉,就會無限重定向 —— 這種情況加 --no-redirect 重跑一次。

2. Cloudflare 源站證書只有走 CDN 時才有效。 它不是公共信任的證書,DNS 那條記錄必須是橙色小云(代理已開啟)。哪天改成灰色(僅 DNS 解析),瀏覽器立刻報證書錯誤。

3. 不配真實 IP,訂單 IP 會全變成 CDN 的地址。 到後臺 網站設定 → 安全

  • IP 獲取方式CF-Connecting-IP(其他 CDN 一般是 X-Forwarded-For
  • 受信代理 IP 填 CDN 的回源 IP 段,Cloudflare 的清單在 cloudflare.com/ips

只改「IP 獲取方式」、不填受信代理是不生效的。 受信代理為空時,程式對任何轉發頭都不信任,仍然退回連線過來的那個 IP(也就是 CDN 的)。這是防止別人直接偽造請求頭來偽裝 IP,不是 BUG。詳見網站設定

配置會不會在升級後丟

不會。證書和 nginx 配置都寫在資料卷的 /data/ssl/data/nginx 裡,換映像、重建容器都還在,不用重新簽。

簽不下來怎麼辦

失敗時命令會直接告訴你原因。最常見的三種:

提示原因
驗證失敗 / 連線超時域名沒解析到這臺伺服器,或解析還沒生效(等幾分鐘再試)
同上80 連接埠沒開 —— 雲伺服器要去安全組放行
同上容器沒對映 80(要有 -p 80:80

詳細日誌在容器裡:

bash
docker exec faka tail -30 /data/ssl/logs/letsencrypt.log

換域名

重新跑一次第 2 步就行,新配置會覆蓋舊的(有多個域名就全部列上,別只寫新的那個):

bash
docker exec faka acg-ssl 新域名 你的郵箱

前面已經有反向代理的情況

如果你的伺服器上已經跑著別的網站、80 連接埠被佔用,那就讓已有的那層做證書,容器只對映一個內網連接埠(例如 -p 8080:80),反代過去即可。這種情況下不要acg-ssl

反代必須帶上這三個頭,否則訂單 IP 會全變成反代地址:

nginx
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

接自己的 MySQL / Redis

不想用映像自帶的資料庫,就把連線資訊用環境變數傳進去,映像會自動跳過內建資料庫:

bash
docker run -d --name faka -p 80:80 -v acg_data:/data \
  -e ACG_DB_HOST=192.168.1.10 \
  -e ACG_DB_PORT=3306 \
  -e ACG_DB_DATABASE=faka \
  -e ACG_DB_USERNAME=faka \
  -e ACG_DB_PASSWORD=你的密碼 \
  -e ACG_REDIS_HOST=192.168.1.11 \
  --restart unless-stopped ghcr.io/lizhipay/acg-faka:latest
變數說明
ACG_DB_HOST資料庫地址,填了就不用內建資料庫
ACG_DB_PORT連接埠,預設 3306
ACG_DB_DATABASE庫名
ACG_DB_USERNAME / ACG_DB_PASSWORD賬號密碼
ACG_DB_PASSWORD_FILE從檔案讀密碼,配合 Docker secrets 用
ACG_DB_PREFIX表字首,預設 acg_
ACG_REDIS_HOST填了就用 Redis 存會話,不填用檔案
ACG_REDIS_PORT / ACG_REDIS_DB預設 6379 / 0

資料庫賬號請授權成 'faka'@'%' 而不是 'faka'@'localhost' —— MySQL 裡的 localhost 只匹配 Unix socket,從容器過去是 TCP 連線,配 localhost 會連不上。

docker compose

倉庫裡帶了 docker-compose.yml,會起三個容器(程式 + MySQL 5.7 + Redis 7.2),資料庫密碼隨機生成:

bash
docker compose up -d

健康檢查

映像內建了健康檢查,docker ps 的 STATUS 列會顯示 healthy。它同時驗證 nginx 和 PHP 都活著:

bash
docker inspect --format='{{.State.Health.Status}}' faka

遇到問題

現象原因
瀏覽器打不開連接埠對映寫反了,或雲伺服器安全組沒放行
剛起來就開啟顯示 502資料庫還在初始化,等 20 秒重新整理
升級後資料沒了當初沒加 -v acg_data:/data
容器一直重啟docker logs faka 看日誌

更多見 常見問題

基於 MIT 協議開源