Skip to content

Docker 部署

Docker 将代码与运行环境打包为容器镜像,确保在任意机器上行为一致。生成的项目已内置 Docker 配置,无需额外编写即可一键启动。

生成的 Docker 文件

project/
├── backend/
│   └── Dockerfile          # 后端打包配置
├── frontend/
│   └── Dockerfile          # 前端打包配置
└── docker-compose.yml      # 一键启动配置
  • Dockerfile:定义如何构建单个服务的镜像(安装依赖、编译产物、设置启动命令)。
  • docker-compose.yml:声明多个服务及其依赖关系,一条命令同时启动前端、后端和数据库。

快速启动

进入项目目录,执行:

bash
# 构建并启动所有服务(后台运行)
docker compose up -d --build

启动成功后:

  • 前端:http://localhost:80
  • 后端:http://localhost:3000
  • 数据库:在容器内自动运行

常用命令:

操作命令
查看服务状态docker compose ps
查看日志docker compose logs -f
停止所有服务docker compose down
重新构建并启动docker compose up -d --build
查看后端日志(最近 100 行)docker compose logs backend --tail 100
进入容器调试docker compose exec backend sh

docker-compose.yml 详解

以下是一个典型的配置,每行附有注释:

yaml
services:
  # 后端服务
  backend:
    build: ./backend          # 使用 backend/Dockerfile 构建
    ports:
      - "3000:3000"           # 宿主机 3000 -> 容器 3000
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/app
    depends_on:
      - db                    # 等数据库就绪后再启动

  # 前端服务
  frontend:
    build: ./frontend
    ports:
      - "80:80"               # 宿主机 80 -> 容器 80

  # 数据库
  db:
    image: postgres:15        # 使用官方 PostgreSQL 15 镜像
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data  # 数据持久化,容器删除后数据不丢失

volumes:
  pgdata:                     # 声明命名卷

容器间通信

容器内访问其他容器时,使用服务名作为主机名(如 db),而非 localhost

yaml
# 正确
DATABASE_URL=postgresql://postgres:password@db:5432/app

# 错误
DATABASE_URL=postgresql://postgres:password@localhost:5432/app

部署到云服务器

安装 Docker

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

上传代码

bash
# 方式一:Git
git clone https://github.com/你的用户名/你的项目.git

# 方式二:scp
scp -r ./你的项目 root@服务器IP:/home/app

启动

bash
cd /home/app && docker compose up -d --build

常见问题

镜像拉取缓慢

国内访问 Docker Hub 较慢,可配置镜像加速:

bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
EOF

sudo systemctl restart docker

端口被占用

修改 docker-compose.yml 中宿主机端口号:

yaml
ports:
  - "3001:3000"   # 将宿主机端口改为 3001

敏感信息管理

不要将密码写死在 docker-compose.yml 中,使用 .env 文件:

bash
# .env
POSTGRES_PASSWORD=your_secure_password
DATABASE_URL=postgresql://postgres:your_secure_password@db:5432/app

docker-compose.yml 中引用:

yaml
environment:
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

CI/CD 自动部署

CI/CD(持续集成 / 持续部署)在代码推送到仓库后自动完成构建和部署,无需手动操作服务器。

如果使用 Vercel、Zeabur 等平台,CI/CD 已内置,推送代码即可自动更新。

GitHub Actions 部署示例

在项目根目录创建 .github/workflows/deploy.yml

yaml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install pnpm
        run: npm install -g pnpm

      - name: Install dependencies
        run: pnpm install

      - name: Build
        run: pnpm build

      - name: Deploy to server
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            cd /home/app/your-project
            git pull origin main
            docker compose up -d --build

然后在 GitHub 仓库 Settings → Secrets and variables → Actions 中添加以下密钥:

Secret 名称说明
HOST服务器 IP 地址
USERNAMESSH 用户名(如 root
SSH_KEYSSH 私钥内容

配置完成后,每次向 main 分支推送代码,GitHub Actions 会自动构建并通过 SSH 登录服务器执行部署。

Webhook 方式(宝塔面板)

如果服务器使用宝塔面板,可以安装 Webhook 插件实现自动部署:

bash
#!/bin/bash
cd /home/app/your-project
git pull origin main
docker compose down
docker compose up -d --build

在宝塔面板创建 Webhook 后,将回调地址填入 GitHub 仓库的 Settings → Webhooks 中即可。

域名与公网访问

域名注册

域名后缀首年价格适用场景
.com50-70 元通用,首选
.cn20-40 元国内项目,需备案
.io300+ 元科技类项目

学习阶段可以使用平台提供的免费子域名(如 your-app.vercel.app),正式上线时再购买独立域名。

DNS 解析配置

购买域名后,在域名服务商的 DNS 管理面板添加解析记录,将域名指向服务器 IP:

主机记录类型记录值效果
@A203.0.113.50example.com → 服务器
wwwA203.0.113.50www.example.com → 服务器
apiA203.0.113.50api.example.com → 服务器

HTTPS 证书

现代网站必须使用 HTTPS,浏览器会对 HTTP 站点显示不安全警告。免费方案:

方式说明
Let's Encrypt免费证书,可用 Certbot 自动续期
Cloudflare接入后自动提供 HTTPS
云厂商免费证书阿里云、腾讯云均提供免费单域名证书

使用 Certbot 申请证书的示例:

bash
# 安装 Certbot
sudo apt install certbot

# 申请证书(需要域名已解析到服务器)
sudo certbot certonly --standalone -d example.com -d www.example.com

# 证书路径
# /etc/letsencrypt/live/example.com/fullchain.pem
# /etc/letsencrypt/live/example.com/privkey.pem

国内 ICP 备案

如果服务器位于中国大陆,域名必须完成 ICP 备案后才能正常访问。备案流程:

  1. 在云服务商控制台提交备案申请
  2. 填写个人/企业信息,上传身份证
  3. 等待审核(7-20 个工作日)
  4. 审核通过后在网站底部展示备案号

服务器在海外或港澳台则无需备案。

Released under the MIT License.