文档

Docker 部署指南

📌 开始之前

我需要使用 Docker 吗?

推荐新手使用更简单的部署方案:

如果你是新手或希望快速部署,我们强烈推荐使用以下平台,无需配置 Docker

| 平台 | 特点 | 推荐指数 | 适用场景 | |------|------|---------|---------| | Vercel | 零配置、自动构建、全球 CDN | ⭐⭐⭐⭐⭐ | 首选方案,适合个人项目和小团队 | | Netlify | 简单易用、免费额度充足 | ⭐⭐⭐⭐ | 个人项目、静态站点 | | Railway | 支持数据库、简单配置 | ⭐⭐⭐⭐ | 需要数据库的全栈应用 | | Render | 免费层、自动部署 | ⭐⭐⭐⭐ | 中小型应用 |

Vercel 部署只需 3 步:

  1. 将代码推送到 GitHub
  2. 在 Vercel 导入项目
  3. 配置环境变量,点击部署

无需学习 Docker、Nginx、服务器配置自动 HTTPS、CDN 加速、零停机部署适合 90% 的使用场景


什么时候需要使用 Docker?

只有在以下情况下才推荐使用 Docker:

✅ 适合使用 Docker 的场景

  1. 自有服务器部署

    • 你有自己的 VPS 或云服务器(阿里云、腾讯云、AWS)
    • 需要完全控制服务器环境和配置
    • 成本考虑:长期运行可能比 Vercel 更便宜
  2. 复杂的微服务架构

    • 需要运行多个服务(应用、数据库、Redis、消息队列等)
    • 需要本地完整的开发环境镜像
    • 团队协作需要统一的开发环境
  3. 特殊的运行环境要求

    • 需要特定的系统依赖或二进制文件
    • 需要在国内服务器上部署(避免国际网络问题)
    • 企业内网部署或私有化部署
  4. CI/CD 流程需求

    • 需要自定义的构建和部署流程
    • 需要集成到现有的 DevOps 工具链
    • 需要多环境部署(开发、测试、生产)

❌ 不推荐使用 Docker 的场景

  • 你是新手,刚开始学习 Web 开发
  • 只是想快速上线一个项目
  • 不想花时间学习 Docker、Linux、Nginx 等运维知识
  • 团队没有专门的运维人员

Docker vs Vercel 对比

| 对比项 | Docker 部署 | Vercel 部署 | |--------|------------|------------| | 难度 | ⭐⭐⭐⭐ 需要学习 Docker、Linux 命令 | ⭐ 几乎零配置 | | 部署时间 | 30-60 分钟(首次配置) | 5-10 分钟 | | 维护成本 | 需要管理服务器、更新系统、监控服务 | 完全托管,无需维护 | | 成本 | 服务器费用:$5-50/月起 | 免费额度充足,超出后按量计费 | | 扩展性 | 需要手动扩容 | 自动扩容 | | HTTPS | 需要配置 SSL 证书 | 自动配置 | | CDN | 需要单独配置 | 全球 CDN 自动启用 | | 适用人群 | 有运维经验的开发者、企业项目 | 新手、个人项目、小团队 |


决策建议

使用 Vercel(推荐 ⭐⭐⭐⭐⭐):

# 1. 安装 Vercel CLI
npm i -g vercel

# 2. 部署(自动配置所有内容)
vercel

使用 Docker(高级用户): 如果你确定需要 Docker,请继续阅读下面的完整指南。


🚀 快速开始

使用自动化脚本(推荐)

# 1. 使用 Docker Hub (默认)
DOCKERHUB_USERNAME=myusername ./docker-build.sh v1.0.0

# 2. 使用腾讯云镜像仓库(快捷参数)
./docker-build.sh v1.0.0 tencent

# 3. 同时推送到多个镜像仓库
DOCKERHUB_USERNAME=myusername ./docker-push-all.sh v1.0.0

快捷参数说明:

  • tencent - 使用腾讯云镜像仓库(国内访问更快)
  • dockerhub - 使用 Docker Hub(默认,需设置 DOCKERHUB_USERNAME
  • 也可以直接指定自定义仓库地址

基础 Docker 构建

本地构建和测试:

# 1. 构建 Docker 镜像
docker build -t community:latest .

# 2. 运行容器(使用环境变量文件)
docker run -d \
  --name community \
  -p 3000:3000 \
  --env-file .env.local \
  community:latest

# 3. 查看日志
docker logs -f community

生产环境镜像(腾讯云):

# 标记为腾讯云镜像
docker tag community:latest \
  ccr.ccs.tencentyun.com/hackathonweekly/community:latest

# 推送到腾讯云
docker push ccr.ccs.tencentyun.com/hackathonweekly/community:latest

跨平台构建(Mac → Ubuntu/Linux)

如果你在 Mac 上开发,需要部署到 Ubuntu 服务器,必须使用 --platform linux/amd64 参数构建兼容的镜像。

为什么需要指定平台?

  • Mac M1/M2/M3 芯片是 ARM 架构(linux/arm64
  • Ubuntu 服务器通常是 x86 架构(linux/amd64
  • 不指定平台会导致镜像在服务器上无法运行

构建方法:

# 方式 1: 使用自动化脚本(已内置 --platform 参数)
./docker-build.sh v1.0.0 tencent

# 方式 2: 手动构建
docker build --platform linux/amd64 \
  -t community:latest \
  .

# 验证镜像平台
docker inspect community:latest | grep Architecture
# 应该显示: "Architecture": "amd64"

注意事项:

  1. ✅ 脚本已自动添加 --platform linux/amd64 参数
  2. ✅ 构建的镜像可以在 Ubuntu/CentOS/Debian 等 Linux 服务器运行
  3. ⚠️ 跨平台构建可能比原生构建稍慢(需要模拟)
  4. ⚠️ 本地测试时,Mac 也可以运行 linux/amd64 镜像(通过 QEMU 模拟)

📦 使用 Docker Compose

1. 准备配置文件

# 复制示例配置
cp docker-compose.yml.example docker-compose.yml

# 创建环境变量文件
cp .env.local.example .env.local
# 编辑 .env.local 填入实际的环境变量

2. 启动服务

# 构建并启动(后台运行)
docker-compose up -d --build

# 查看日志
docker-compose logs -f

# 查看运行状态
docker-compose ps

# 停止服务
docker-compose down

3. 环境变量配置

⚠️ 重要: 环境变量不应写在镜像中,而应该在运行时通过以下方式传入:

方式一:使用 .env 文件

# docker-compose.yml
services:
  app:
    env_file:
      - .env.local

方式二:直接在 docker-compose.yml 中配置

services:
  app:
    environment:
      - DATABASE_URL=postgresql://user:pass@host:5432/db
      - BETTER_AUTH_SECRET=your-secret-key
      - BETTER_AUTH_URL=https://yourdomain.com

方式三:docker run 命令传入

docker run -d \
  -e DATABASE_URL="postgresql://..." \
  -e BETTER_AUTH_SECRET="..." \
  --env-file .env.local \
  community:latest

🏗️ 镜像仓库配置

Docker Hub(国际,默认)

1. 创建 Docker Hub 账号

访问 Docker Hub 注册账号。

2. 创建镜像仓库

  1. 登录 Docker Hub
  2. 点击 "Create Repository"
  3. 填写仓库名称:community
  4. 选择可见性:Public(公开)或 Private(私有)
  5. 点击 "Create"

3. 本地登录 Docker Hub

# 登录 Docker Hub
docker login

# 输入用户名和密码
Username: your-username
Password: your-password

4. 推送镜像到 Docker Hub

# 方式 1: 使用自动化脚本
DOCKERHUB_USERNAME=your-username ./docker-build.sh v1.0.0

# 方式 2: 手动操作
# 标记镜像
docker tag community:latest your-username/community:latest
docker tag community:latest your-username/community:v1.0.0

# 推送镜像
docker push your-username/community:latest
docker push your-username/community:v1.0.0

5. 在服务器上拉取镜像

# 公开仓库无需登录,直接拉取
docker pull your-username/community:latest

# 私有仓库需要先登录
docker login
docker pull your-username/community:latest

# 运行容器
docker run -d \
  --name community \
  -p 3000:3000 \
  --env-file .env.production \
  --restart unless-stopped \
  your-username/community:latest

腾讯云容器镜像服务(国内加速,推荐国内用户)

腾讯云容器镜像服务 (TCR) 提供国内高速访问,适合国内部署环境。

1. 创建镜像仓库

  1. 访问 腾讯云容器镜像服务
  2. 选择 个人版(免费)或 企业版(付费,更快)
  3. 创建命名空间,如 hackathonweekly
  4. 在命名空间下创建镜像仓库,如 community

2. 获取访问凭证

个人版(推荐新手):

  1. 进入 容器镜像服务 - 个人版
  2. 点击"获取访问凭证"
  3. 记录你的账号 ID(如:100015625279
  4. 设置固定密码或使用临时密码

企业版(推荐生产环境):

  1. 进入 访问凭证
  2. 创建访问凭证,获取用户名和密码

3. 本地登录腾讯云

# 个人版登录
docker login ccr.ccs.tencentyun.com --username=100015625279
# 输入密码(在腾讯云控制台获取)

# 企业版登录(替换为你的实例名)
docker login your-instance.tencentcloudcr.com --username=your-username

4. 推送镜像到腾讯云

# 方式 1: 使用自动化脚本(推荐)
./docker-build.sh v1.0.0 tencent

# 方式 2: 手动操作
# 标记镜像
docker tag community:latest \
  ccr.ccs.tencentyun.com/hackathonweekly/community:latest
docker tag community:latest \
  ccr.ccs.tencentyun.com/hackathonweekly/community:v1.0.0

# 推送镜像
docker push ccr.ccs.tencentyun.com/hackathonweekly/community:latest
docker push ccr.ccs.tencentyun.com/hackathonweekly/community:v1.0.0

5. 在服务器上拉取镜像

# 登录腾讯云镜像仓库
docker login ccr.ccs.tencentyun.com --username=100015625279
# 输入密码

# 拉取镜像
docker pull ccr.ccs.tencentyun.com/hackathonweekly/community:latest

# 运行容器
docker run -d \
  --name community \
  -p 3000:3000 \
  --env-file .env.production \
  --restart unless-stopped \
  ccr.ccs.tencentyun.com/hackathonweekly/community:latest

6. 配置 Docker 镜像加速(可选)

如果需要加速 Docker Hub 镜像拉取,可以配置镜像加速器。由于国内访问 Docker Hub 不稳定,建议配置国内镜像源。

当前可用的镜像加速器(2025年更新):

| 镜像源 | 地址 | 说明 | |--------|------|------| | 1Panel | https://docker.1panel.live/ | 限制只能中国地区访问 | | 毫秒镜像 | https://docker.1ms.run | 高速镜像 | | 轩辕镜像 | https://docker.xuanyuan.me | 会员版 | | Unsee Tech | https://docker-0.unsee.tech | Docker Hub 镜像加速 | | Docker Proxy | https://dockerproxy.net | 镜像代理加速 | | DaoCloud | https://docker.m.daocloud.io | DaoCloud 镜像站 | | Hub Rat | https://hub.rat.dev | 镜像加速 |

配置 daemon.json(推荐):

# Linux/Ubuntu 系统
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.1panel.live",
    "https://docker.1ms.run",
    "https://dockerproxy.net",
    "https://docker.m.daocloud.io",
    "https://hub.rat.dev"
  ]
}
EOF

# 重启 Docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker

# 验证配置
docker info | grep -A 10 "Registry Mirrors"

Mac Docker Desktop 配置:

  1. 打开 Docker Desktop → Settings ⚙️
  2. 选择 Docker Engine
  3. 编辑 JSON 配置,添加镜像源:
{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "registry-mirrors": [
    "https://docker.1panel.live",
    "https://docker.1ms.run",
    "https://dockerproxy.net",
    "https://docker.m.daocloud.io",
    "https://hub.rat.dev"
  ],
  "experimental": false
}
  1. 点击 "Apply & Restart"

Windows Docker Desktop 配置:

  1. 打开 Docker Desktop → Settings ⚙️
  2. 选择 Docker Engine
  3. 在 JSON 配置中添加上述镜像源
  4. 点击 "Apply & Restart"

测试镜像加速是否生效:

# 拉取一个测试镜像
docker pull hello-world

# 查看配置的镜像源
docker info | grep -i mirror

注意事项:

  • 镜像源可能会失效,建议配置多个作为备选
  • 如遇到某个镜像源无法访问,Docker 会自动尝试下一个
  • 更多最新镜像源请查看:Docker 镜像加速器列表
  • 企业用户建议使用私有镜像仓库(如腾讯云、阿里云)

镜像仓库对比

| 特性 | Docker Hub | 腾讯云个人版 | 腾讯云企业版 | |------|-----------|------------|------------| | 费用 | 免费(限速) | 免费 | 付费 | | 国内访问速度 | 较慢 | 快 | 非常快 | | 存储空间 | 无限(公开仓库) | 10GB | 可扩展 | | 私有仓库数量 | 1个(免费版) | 无限 | 无限 | | 适用场景 | 国际访问、开源项目 | 国内个人项目 | 生产环境 | | 登录命令 | docker login | docker login ccr.ccs.tencentyun.com --username=100015625279 | 企业实例登录 |

🚀 完整部署流程(开发到生产)

本地开发环境

# 1. 使用开发 Dockerfile
docker-compose -f docker-compose.dev.yml up

生产环境部署

步骤 1: 本地构建镜像

# 在 Mac 上构建 linux/amd64 镜像
docker build --platform linux/amd64 \
  -t community:v1.0.0 \
  .

# 标记为腾讯云镜像
docker tag community:v1.0.0 \
  ccr.ccs.tencentyun.com/hackathonweekly/community:v1.0.0

docker tag community:v1.0.0 \
  ccr.ccs.tencentyun.com/hackathonweekly/community:latest

步骤 2: 推送到镜像仓库

# 登录腾讯云
docker login ccr.ccs.tencentyun.com --username=<账号ID>

# 推送镜像
docker push ccr.ccs.tencentyun.com/hackathonweekly/community:v1.0.0
docker push ccr.ccs.tencentyun.com/hackathonweekly/community:latest

步骤 3: 在服务器上部署

# SSH 登录到服务器
ssh user@your-server

# 登录镜像仓库
docker login ccr.ccs.tencentyun.com --username=<账号ID>

# 拉取最新镜像
docker pull ccr.ccs.tencentyun.com/hackathonweekly/community:latest

# 停止旧容器
docker stop community || true
docker rm community || true

# 启动新容器
docker run -d \
  --name community \
  -p 3000:3000 \
  --env-file /path/to/.env.production \
  --restart unless-stopped \
  ccr.ccs.tencentyun.com/hackathonweekly/community:latest

# 查看日志
docker logs -f community

步骤 4: 使用 docker-compose(推荐)

在服务器上创建 docker-compose.yml:

version: '3.8'

services:
  app:
    image: ccr.ccs.tencentyun.com/hackathonweekly/community:latest
    container_name: community
    ports:
      - "3000:3000"
    env_file:
      - .env.production
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
      interval: 30s
      timeout: 3s
      retries: 3

部署命令:

# 拉取最新镜像并重启
docker-compose pull
docker-compose up -d

# 查看日志
docker-compose logs -f

📝 环境变量清单

必需的环境变量(复制到 .env.local.env.production):

# 数据库
DATABASE_URL="postgresql://user:password@host:5432/database"

# 认证
BETTER_AUTH_SECRET="your-secret-key-min-32-chars"
BETTER_AUTH_URL="https://yourdomain.com"

# OAuth(可选)
AUTH_GOOGLE_ID="your-google-client-id"
AUTH_GOOGLE_SECRET="your-google-client-secret"
AUTH_GITHUB_ID="your-github-client-id"
AUTH_GITHUB_SECRET="your-github-client-secret"

# 邮件(可选)
EMAIL_FROM="noreply@yourdomain.com"
EMAIL_SERVER="smtp://user:pass@smtp.example.com:587"

# 其他配置
NODE_ENV="production"
PORT="3000"

🔍 故障排查

Docker Hub 网络问题(常见)

问题现象:

ERROR: failed to solve: failed to fetch anonymous token: Get "https://auth.docker.io/token?...": EOF
ERROR: ... timeout
ERROR: ... connection refused

原因: 国内访问 Docker Hub 不稳定

解决方案:

方案 1: 使用腾讯云镜像仓库(推荐)

# 避免访问 Docker Hub
./docker-build.sh v1.0.0 tencent

方案 2: 配置 Docker 镜像加速(推荐使用多个镜像源)

Linux/Ubuntu:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.1panel.live",
    "https://docker.1ms.run",
    "https://dockerproxy.net",
    "https://docker.m.daocloud.io",
    "https://hub.rat.dev"
  ]
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

Mac Docker Desktop:

  1. 打开 Docker Desktop → Settings ⚙️
  2. 选择 Docker Engine
  3. 在现有配置中添加 registry-mirrors(与其他配置项平级):
{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "registry-mirrors": [
    "https://docker.1panel.live",
    "https://docker.1ms.run",
    "https://dockerproxy.net",
    "https://docker.m.daocloud.io",
    "https://hub.rat.dev"
  ],
  "experimental": false
}
  1. 点击 "Apply & Restart"

验证配置:

docker info | grep -A 10 "Registry Mirrors"

更多镜像源和详细配置请查看:

容器无法启动

# 查看容器日志
docker logs community

# 进入容器调试
docker exec -it community sh

# 查看容器详细信息
docker inspect community

环境变量未生效

# 检查容器中的环境变量
docker exec community env

# 确认 .env 文件是否正确挂载
docker inspect community | grep -A 10 Env

数据库连接失败

# 检查数据库 URL 格式
# 格式: postgresql://user:password@host:port/database

# 如果数据库在另一个容器中,使用容器名作为 host
# 例如: postgresql://user:password@postgres:5432/database

# 测试数据库连接
docker exec community node -e "require('node:child_process').execSync('bunx prisma db push --skip-generate')"

跨平台兼容性问题

问题: 在 Mac 上构建的镜像在 Ubuntu 服务器上无法运行

原因: 架构不匹配(ARM vs x86)

解决: 使用 --platform linux/amd64 参数

# 使用脚本(已自动处理)
./docker-build.sh v1.0.0 tencent

# 或手动指定平台
docker build --platform linux/amd64 -t myimage .

# 验证镜像架构
docker inspect myimage | grep Architecture
# 应该显示: "Architecture": "amd64"
# 检查健康检查状态
docker inspect --format='{{json .State.Health}}' community

# 手动测试健康检查端点
curl http://localhost:3000/api/health

🎯 最佳实践

  1. 版本管理: 使用语义化版本标记镜像(如 v1.0.0
  2. 环境分离: 开发、测试、生产使用不同的环境变量文件
  3. 资源限制: 在 docker-compose.yml 中配置 CPU 和内存限制
  4. 日志管理: 配置日志驱动,避免日志文件过大
  5. 定期更新: 定期更新基础镜像和依赖,修复安全漏洞
  6. 监控告警: 配合 Prometheus + Grafana 监控容器状态

🔐 安全建议

  1. 不要在镜像中包含敏感信息(密钥、密码等)
  2. 使用 .dockerignore 排除不必要的文件
  3. 定期扫描镜像安全漏洞:
    docker scan community:latest
    
  4. 使用非 root 用户运行(已在 Dockerfile 中配置)
  5. 限制容器资源使用,防止资源耗尽

📚 参考资源

On this page

No Headings