Remix Docker部署 #

一、Docker概述 #

Docker 提供了一致的部署环境,适合在各种平台上部署 Remix 应用。

二、创建Dockerfile #

2.1 基础Dockerfile #

dockerfile
FROM node:20-alpine AS base

WORKDIR /app

COPY package.json package-lock.json ./

RUN npm ci

COPY . .

RUN npm run build

FROM node:20-alpine AS runner

WORKDIR /app

ENV NODE_ENV=production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 remix

COPY --from=base --chown=remix:nodejs /app/build ./build
COPY --from=base --chown=remix:nodejs /app/public ./public
COPY --from=base --chown=remix:nodejs /app/package.json ./
COPY --from=base --chown=remix:nodejs /app/node_modules ./node_modules

USER remix

EXPOSE 3000

CMD ["npm", "start"]

2.2 多阶段构建 #

dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 remix

COPY --from=builder /app/build ./build
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./

RUN npm install --production

USER remix

EXPOSE 3000

CMD ["npm", "start"]

三、Docker Compose #

3.1 docker-compose.yml #

yaml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
      - SESSION_SECRET=your-secret-key
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  postgres_data:

3.2 启动服务 #

bash
docker-compose up -d

3.3 查看日志 #

bash
docker-compose logs -f app

四、环境变量 #

4.1 使用.env文件 #

yaml
services:
  app:
    env_file:
      - .env.production

4.2 使用secrets #

yaml
services:
  app:
    secrets:
      - session_secret

secrets:
  session_secret:
    file: ./secrets/session_secret.txt

五、健康检查 #

5.1 Dockerfile健康检查 #

dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

5.2 Docker Compose健康检查 #

yaml
services:
  app:
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 5s

5.3 健康检查路由 #

tsx
export async function loader() {
  return json({ status: "ok" });
}

六、Nginx反向代理 #

6.1 Nginx配置 #

nginx
upstream remix {
    server app:3000;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://remix;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    location /assets {
        proxy_pass http://remix;
        proxy_cache static_cache;
        proxy_cache_valid 200 365d;
        add_header Cache-Control "public, max-age=31536000, immutable";
    }
}

6.2 Docker Compose with Nginx #

yaml
services:
  app:
    build: .
    expose:
      - "3000"
    environment:
      - NODE_ENV=production

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app

七、CI/CD集成 #

7.1 GitHub Actions #

yaml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Build Docker image
        run: docker build -t myapp:${{ github.sha }} .
      
      - name: Push to registry
        run: |
          docker tag myapp:${{ github.sha }} registry.example.com/myapp:latest
          docker push registry.example.com/myapp:latest
      
      - name: Deploy
        run: |
          ssh user@server 'docker pull registry.example.com/myapp:latest'
          ssh user@server 'docker-compose up -d'

八、生产优化 #

8.1 镜像优化 #

  • 使用 alpine 基础镜像
  • 多阶段构建减小体积
  • 缓存依赖层

8.2 安全配置 #

dockerfile
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 remix
USER remix

8.3 资源限制 #

yaml
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

九、常见问题 #

9.1 构建缓存 #

dockerfile
COPY package.json package-lock.json ./
RUN npm ci
COPY . .

9.2 时区设置 #

dockerfile
ENV TZ=Asia/Shanghai
RUN apk add --no-cache tzdata

9.3 日志管理 #

yaml
services:
  app:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

十、总结 #

本章我们学习了:

  1. Dockerfile:创建和优化
  2. Docker Compose:服务编排
  3. 环境变量:配置管理
  4. Nginx:反向代理配置
  5. CI/CD:自动化部署

核心要点:

  • 使用多阶段构建优化镜像
  • 使用Docker Compose编排服务
  • 配置健康检查
  • 设置资源限制
最后更新:2026-03-28