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 协议开源