姜十三论坛 Docker 部署教程

约 10 分钟 读完

姜十三论坛 Docker 部署教程

姜十三
Lv.2站长
548 浏览 0 评论 约 10 分钟 读完

发布于

# Docker# 教程

项目架构:Next.js 前端(web)+ Go 后端(api)+ PostgreSQL 17,三者为独立容器。


一、镜像说明

服务镜像来源
apihangzhang714128/jiang13-api个人仓库
webhangzhang714128/jiang13-web个人仓库
postgrespostgres:17-alpineDocker Hub 官方公共镜像,直接拉取

安全说明:api / web 镜像为多阶段构建产物,最终镜像不含源码,密钥运行时注入,不烤进镜像。


二、1Panel 部署

1.. 用编排一键部署

容器 → 「编排」标签 → 创建编排,名称 jiang13,粘贴以下内容:

yaml
name: jiang13
 
services:
  postgres:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: jiang13
      POSTGRES_PASSWORD: 改成你的强密码
      POSTGRES_DB: jiang13
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U jiang13 -d jiang13"]
      interval: 5s
      timeout: 5s
      retries: 10
 
  api:
    image: <你的用户名>/jiang13-api:0.1.0
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      HTTP_PORT: "3001"
      DEV_MODE: "false"
      JIANG13_WORK_PATH: /var/lib/jiang13
      DATA_DIR: /var/lib/jiang13/data
      DB_DSN: postgres://jiang13:改成上面同一个密码@postgres:5432/jiang13?sslmode=disable
      JWT_SECRET: ""
      SITE_URL: https://改成你的域名
      SETTINGS_MASTER_KEY: ""
    volumes:
      - appdata:/var/lib/jiang13/data
 
  web:
    image: <你的用户名>/jiang13-web:0.1.0
    restart: unless-stopped
    depends_on:
      api:
        condition: service_healthy
    environment:
      BACKEND_URL: http://api:3001
      SITE_URL: https://改成你的域名
      NODE_ENV: production
      DEV_MODE: "false"
      PORT: "3000"
      HOSTNAME: 0.0.0.0
    ports:
      - "13000:3000"
 
volumes:
  pgdata:
  appdata:

只需改 3 处:

  1. POSTGRES_PASSWORD 的值
  2. DB_DSN 里的密码(必须与第 1 处完全一致)
  3. 两处 SITE_URL 的域名

保存后,编排会自动:拉镜像 → 起 postgres → 健康后起 api → 健康后起 web。

容器名固定为 postgres / api,因为服务间通过容器名互访(@postgres:5432、http://api:3001)。

2. 验证启动

「容器」标签确认三个容器状态:

  • postgres Up (healthy)
  • api Up (healthy) ← 健康才说明连库成功
  • web Up

接口检查:

plaintext
curl http://127.0.0.1:13000/healthz     # web,返回 ok
docker exec jiang13-api-1 wget -qO- http://127.0.0.1:3001/health   # api

三、Nginx 反向代理 + HTTPS

DEV_MODE=false 启用了 __Host- 前缀 cookie,必须 HTTPS。

1Panel 网站 → 创建网站 → 反向代理:

  • 目标地址:http://127.0.0.1:13000
  • 申请并开启 SSL(1Panel 可一键 Let's Encrypt)
  • 域名 DNS 解析到服务器

访问 https://你的域名,空库下第一个注册的账号自动成为站长(管理员)。


四、配置说明

环境变量

变量说明建议
POSTGRES_PASSWORD数据库密码强密码,与 DB_DSN 一致
DB_DSN后端连库串密码须与上者一致
JWT_SECRET登录 token 签名密钥留空,自动生成并持久化到 data/.jwt_secret;自填须 ≥32 字符强随机
SETTINGS_MASTER_KEY加密邮件/S3 凭据(32字节Base64)留空=禁用保存凭据功能;需要时用 openssl rand -base64 32 生成
SITE_URL对外公开 origin前后端一致,与浏览器地址栏完全相同(含 https、无尾斜杠)。运行时读取,可后改重启生效

JWT_SECRET 与 SETTINGS_MASTER_KEY 不要填同一个值(密钥复用是安全大忌,且两者格式/生命周期不同)。

端口被占用怎么办

  • 容器内端口(3000/3001)写死不能改;只改映射的宿主机端口(冒号左边),如 "13000:3000"。
  • 用 Nginx 反代时 api 无需暴露端口(web 通过容器名内部访问)。
  • 查占用:ss -tlnp | grep -E ':3000|:3001'

数据卷

  • pgdata:数据库数据
  • appdata:上传文件 / .jwt_secret

删除编排时不要勾选删除数据卷,否则数据丢失。若换过数据库密码,需先删除旧 pgdata 卷重建(Postgres 只在空数据目录初始化密码)。


五、更新与运维

更新版本

修改编排中镜像的 tag(如 :0.1.0 → :0.2.0),或使用 :latest 标签后点「重新拉取镜像」再重启容器:

plaintext
docker compose pull
docker compose up -d

常用命令

plaintext
docker compose ps                 # 查看状态
docker compose logs -f            # 看日志
docker compose logs api --tail 50
docker compose down               # 停止(保留数据)
docker compose down -v            # 停止并清空数据(慎用)

六、排障速查

现象原因解决
api 反复 restart,日志 password authentication failed密码不一致 / pgdata 残留旧密码统一两处密码;删 pgdata 卷重建
api 日志 JWT_SECRET 过弱填了 change-me 或过短留空自动生成,或换 ≥32 字符强随机值
拉私有镜像 denied未配置仓库认证1Panel 仓库里添加 Docker Hub 凭证
web 不启动等不到 api healthy先把 api 弄健康(解决上面问题)
能打开页面但登录异常HTTP 下 __Host- cookie 不生效必须走 HTTPS 反代

登录后查看评论

本站评论仅对登录用户开放。

去登录