Simplify Dockerfile and GitHub Actions workflow for single-stage Docker build

This commit is contained in:
wood chen 2025-02-08 17:36:33 +08:00
parent 7487aaadda
commit 85f21a3105
3 changed files with 138 additions and 37 deletions

View File

@ -19,6 +19,65 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
# 设置 Go 环境
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
# 构建后端
- name: Build backend
run: |
cd backend
go build -o main .
# 设置 Node.js 环境
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
# 构建前端
- name: Build frontend
run: |
cd frontend
npm ci
npm run build
# 创建 nginx 配置
- name: Create nginx config
run: |
mkdir -p backend/config
cat > backend/config/nginx.conf << 'EOL'
worker_processes auto;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name localhost;
location / {
root /app/frontend;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
EOL
# 设置 QEMU 以支持多架构构建 # 设置 QEMU 以支持多架构构建
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3

View File

@ -1,34 +1,4 @@
# 第一阶段:构建后端 # 使用 Alpine 作为基础镜像
FROM golang:1.21-alpine AS backend-builder
WORKDIR /app/backend
# 安装依赖
COPY backend/go.mod backend/go.sum ./
RUN go mod download
# 复制后端源代码
COPY backend/ .
# 编译后端
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
# 第二阶段:构建前端
FROM node:18-alpine AS frontend-builder
WORKDIR /app/frontend
# 安装依赖
COPY frontend/package.json frontend/package-lock.json ./
RUN npm ci
# 复制前端源代码
COPY frontend/ .
# 构建前端
RUN npm run build
# 第三阶段:最终镜像
FROM alpine:3.18 FROM alpine:3.18
WORKDIR /app WORKDIR /app
@ -36,17 +6,17 @@ WORKDIR /app
# 安装 nginx # 安装 nginx
RUN apk add --no-cache nginx RUN apk add --no-cache nginx
# 创建数据目录 # 创建必要的目录
RUN mkdir -p /app/data RUN mkdir -p /app/data /app/frontend
# 复制后端二进制文件 # 复制后端二进制文件
COPY --from=backend-builder /app/backend/main ./ COPY backend/main ./
# 复制 nginx 配置
COPY backend/config/nginx.conf /etc/nginx/nginx.conf COPY backend/config/nginx.conf /etc/nginx/nginx.conf
# 复制前端构建产物 # 复制前端构建产物
COPY --from=frontend-builder /app/frontend/.next/static /app/frontend/static COPY frontend/dist /app/frontend
COPY --from=frontend-builder /app/frontend/public /app/frontend/public
COPY --from=frontend-builder /app/frontend/.next/standalone /app/frontend
# 复制启动脚本 # 复制启动脚本
COPY scripts/start.sh ./ COPY scripts/start.sh ./

72
backend/config/nginx.conf Normal file
View File

@ -0,0 +1,72 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
gzip_vary on;
server {
listen 80;
server_name localhost;
root /app/frontend;
index index.html;
# 前端文件缓存设置
location /assets {
expires 7d;
add_header Cache-Control "public, no-transform";
}
# API 反向代理
location /api {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_buffering off;
proxy_read_timeout 300s;
}
# SPA 路由支持
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}