Softhub软件下载站实战开发(二十):Docker部署全攻略
🐳 Softhub软件下载站实战开发(二十):Docker部署全攻略
随着本系列步入尾声,本篇文章将分享Softhub项目的Docker部署方案,这是一个包含前后端的完整Web应用。我们将深入探讨Dockerfile的编写技巧、Supervisor进程管理以及Nginx配置优化等关键内容。打包完成之后将实现一个docker镜像包含后台管理、后台管理、前台页面,非常适合个人部署使用。🚀
📦 多阶段构建的Dockerfile
我们的Dockerfile采用了多阶段构建技术,这是现代Docker实践中的重要优化手段:
# 阶段1:构建后端
FROM golang:1.23-alpine AS backend-builder
# ...构建步骤...# 阶段2:最终镜像
FROM alpine:latest
# ...复制构建产物...
这种设计带来了几个显著优势:
- 减小最终镜像体积 - 构建工具不会出现在最终镜像中
- 提高安全性 - 最终镜像只包含运行时必要的组件
- 优化构建缓存 - 可以更细粒度地控制缓存失效
🔧 关键构建技巧
-
Go构建优化:
RUN go build -a -installsuffix cgo -ldflags="-s -w" -o main .
-a
:强制重新构建所有包-ldflags="-s -w"
:移除调试信息减小体积
-
依赖缓存:
RUN --mount=type=cache,target=/go/pkg/mod \go mod download
使用BuildKit缓存特性加速后续构建
-
时区配置:
RUN apk --no-cache add tzdata ENV TZ=Asia/Shanghai
确保容器内使用正确的时间
🎛 Supervisor进程管理
我们使用Supervisor来管理多个进程:
Supervisor的优势
- 进程守护:自动重启崩溃的进程
- 统一日志:集中管理所有子进程日志
- 简单配置:一个配置文件管理所有服务
- 启动顺序控制:可以定义依赖关系
🌐 Nginx高级配置
nginx配置一些细节
1. 前后端分离路由
# 后台管理
location /admin {try_files $uri $uri/ /admin/index.html;
}# 前台页面
location / {try_files $uri $uri/ /index.html;
}
2. 静态资源优化
location /assets {expires 1y;add_header Cache-Control "public, immutable";
}
设置长期缓存并添加immutable标记,避免不必要的验证请求
3. API代理配置
location /api {proxy_pass http://localhost:8808;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";# 大文件上传超时设置proxy_read_timeout 300s;
}
🏗 目录结构设计
容器内的目录结构经过精心设计:
/app
├── main # 后端可执行文件
├── manifest/config/ # 配置文件
└── resource/ # 资源文件├── casbin/├── data/└── log//usr/share/nginx/html
├── admin/ # 后台前端
└── client/ # 用户前端
🚨 错误处理机制
添加错误页面处理:
error_page 500 502 503 504 /50x.html;
location = /50x.html {root /usr/share/nginx/html/client;internal;
}
提供友好的用户体验。
🔍 健康检查
Docker健康检查确保服务可用性:
HEALTHCHECK --interval=30s --timeout=10s \CMD wget --spider http://localhost:8808/api/v1/client/health && \wget --spider http://localhost/ || exit 1
💡 最佳实践总结
- 最小化镜像:使用alpine基础镜像,移除不必要的文件
- 构建分离:多阶段构建减少最终镜像体积
- 缓存优化:利用BuildKit缓存加速构建
- 进程管理:Supervisor管理多个进程
- 静态资源优化:长期缓存+immutable标记
- 健康检查:确保服务可用性
- 日志集中:统一收集所有服务日志
通过这套部署方案,Softhub应用实现了:
- 单容器部署前后端
- 高效的资源利用
- 稳定的服务运行
- 便捷的运维管理
附录
服务器错误页面
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>服务器错误</title><style>body {font-family: Arial, sans-serif;text-align: center;padding: 50px;background-color: #f5f5f5;}.error-container {max-width: 600px;margin: 0 auto;background: white;padding: 40px;border-radius: 10px;box-shadow: 0 2px 10px rgba(0,0,0,0.1);}h1 {color: #e74c3c;font-size: 2.5em;margin-bottom: 20px;}p {color: #666;font-size: 1.2em;line-height: 1.6;}.back-btn {display: inline-block;margin-top: 20px;padding: 10px 20px;background: #3498db;color: white;text-decoration: none;border-radius: 5px;transition: background 0.3s;}.back-btn:hover {background: #2980b9;}</style>
</head>
<body><div class="error-container"><h1>服务器错误</h1><p>抱歉,服务器遇到了一些问题。请稍后再试。</p><a href="/" class="back-btn">返回首页</a></div>
</body>
</html>
mime.types
types {text/html html htm shtml;text/css css;text/xml xml;image/gif gif;image/jpeg jpeg jpg;application/javascript js;application/atom+xml atom;application/rss+xml rss;text/mathml mml;text/plain txt;text/vnd.sun.j2me.app-descriptor jad;text/vnd.wap.wml wml;text/x-component htc;image/png png;image/svg+xml svg svgz;image/tiff tif tiff;image/vnd.wap.wbmp wbmp;image/webp webp;image/x-icon ico;image/x-jng jng;image/x-ms-bmp bmp;font/woff woff;font/woff2 woff2;application/java-archive jar war ear;application/json json;application/mac-binhex40 hqx;application/msword doc;application/pdf pdf;application/postscript ps eps ai;application/rtf rtf;application/vnd.apple.mpegurl m3u8;application/vnd.google-earth.kml+xml kml;application/vnd.google-earth.kmz kmz;application/vnd.ms-excel xls;application/vnd.ms-fontobject eot;application/vnd.ms-powerpoint ppt;application/vnd.oasis.opendocument.graphics odg;application/vnd.oasis.opendocument.presentation odp;application/vnd.oasis.opendocument.spreadsheet ods;application/vnd.oasis.opendocument.text odt;application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;application/vnd.wap.wmlc wmlc;application/x-7z-compressed 7z;application/x-cocoa cco;application/x-java-archive-diff jardiff;application/x-java-jnlp-file jnlp;application/x-makeself run;application/x-perl pl pm;application/x-pilot prc pdb;application/x-rar-compressed rar;application/x-redhat-package-manager rpm;application/x-sea sea;application/x-shockwave-flash swf;application/x-stuffit sit;application/x-tcl tcl tk;application/x-x509-ca-cert der pem crt;application/x-xpinstall xpi;application/xhtml+xml xhtml;application/xspf+xml xspf;application/zip zip;application/octet-stream bin exe dll;application/octet-stream deb;application/octet-stream dmg;application/octet-stream iso img;application/octet-stream msi msp msm;audio/midi mid midi kar;audio/mpeg mp3;audio/ogg ogg;audio/x-m4a m4a;audio/x-realaudio ra;video/3gpp 3gpp 3gp;video/mp2t ts;video/mp4 mp4;video/mpeg mpeg mpg;video/quicktime mov;video/webm webm;video/x-flv flv;video/x-m4v m4v;video/x-mng mng;video/x-ms-asf asx asf;video/x-ms-wmv wmv;video/x-msvideo avi;
}
nginx.conf
server {listen 80;server_name _;# 包含 MIME 类型include /etc/nginx/mime.types;# 设置最大上传文件大小client_max_body_size 4G;# 大文件上传超时设置client_body_timeout 300s;client_header_timeout 300s;send_timeout 300s;# 禁用自动重定向absolute_redirect off;# 后台管理页面的 /sys 资源路径(映射到 admin 目录)location /sys {alias /usr/share/nginx/html/admin;expires 1y;add_header Cache-Control "public, immutable";try_files $uri =404;}# 后台管理页面路由(精确匹配)location = /admin {root /usr/share/nginx/html;try_files /admin/index.html =404;add_header Content-Type "text/html; charset=utf-8";}# 后台管理页面路由(带路径)location /admin/ {root /usr/share/nginx/html;try_files $uri $uri/ /admin/index.html;# 对 HTML 文件设置正确的 Content-Typelocation ~ \.html$ {add_header Content-Type "text/html; charset=utf-8";}}# 前台页面的静态资源(assets目录)location /assets {root /usr/share/nginx/html/client;expires 1y;add_header Cache-Control "public, immutable";try_files $uri =404;}# CDN资源路径location ~ ^/(at\.alicdn\.com|netdna\.bootstrapcdn\.com)/ {root /usr/share/nginx/html/client;try_files $uri =404;expires 1y;add_header Cache-Control "public, immutable";}# 前台页面路由(默认路由)location / {root /usr/share/nginx/html/client;index index.html;try_files $uri $uri/ /index.html;}# API代理到后端服务location /api {proxy_pass http://localhost:8808;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_connect_timeout 300s;proxy_send_timeout 300s;proxy_read_timeout 300s;# 支持WebSocketproxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";}# Swagger文档路由location /swagger {proxy_pass http://localhost:8808;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;}# 错误页面(避免重定向循环)error_page 500 502 503 504 /50x.html;# 创建 50x.html 错误页面location = /50x.html {root /usr/share/nginx/html/client;internal;}# 日志配置access_log /var/log/nginx/access.log;error_log /var/log/nginx/error.log;
}
supervisord.conf
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid[program:backend]
command=/app/main
directory=/app
autorestart=true
stdout_logfile=/var/log/supervisor/backend.log
stderr_logfile=/var/log/supervisor/backend.log[program:nginx]
command=nginx -g "daemon off;"
autorestart=true
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.log
dockerfile
# 统一的 Dockerfile - 包含后端+两个前端
# 使用 BuildKit 语法
# syntax=docker/dockerfile:1.4# 阶段1:构建后端
FROM golang:1.23-alpine AS backend-builder# 安装必要的工具
RUN apk add --no-cache git# 设置Go代理环境变量
ENV GOPROXY=https://goproxy.cn,direct
ENV GOSUMDB=sum.golang.google.cn
ENV GOPRIVATE=*.gitlab.com,*.gitee.com
ENV CGO_ENABLED=0
ENV GOOS=linux# 设置工作目录
WORKDIR /app# 复制 go mod 文件
COPY go.mod go.sum ./# 下载依赖(使用缓存)
RUN --mount=type=cache,target=/go/pkg/mod \go mod download# 复制后端源码
COPY . .# 构建后端(使用更激进的优化)
RUN go build -a -installsuffix cgo -ldflags="-s -w" -o main .# 阶段2:最终镜像
FROM alpine:latest# 安装必要的运行时依赖
RUN apk --no-cache add ca-certificates tzdata wget nginx supervisor ffmpeg curl# 设置时区
ENV TZ=Asia/Shanghai# 设置工作目录
WORKDIR /app# 从构建阶段复制后端二进制文件
COPY --from=backend-builder /app/main .# 复制后端配置文件
COPY manifest/config/config.yaml ./manifest/config/# 复制后端资源文件(只复制必要的)
COPY resource/casbin/ ./resource/casbin/
COPY resource/data/ ./resource/data/# 创建必要的目录结构
RUN mkdir -p resource/log/run \resource/log/server \resource/log/sql \resource/log/public \/var/log/nginx \/var/log/supervisor# 创建前端目录结构
RUN mkdir -p /usr/share/nginx/html/admin /usr/share/nginx/html/client# 复制前端dist目录(需要预先构建好)
COPY web/admin/dist /usr/share/nginx/html/admin
COPY web/client/dist /usr/share/nginx/html/client# 复制nginx配置文件
COPY nginx.conf /etc/nginx/http.d/default.conf# 复制MIME类型文件
COPY mime.types /etc/nginx/mime.types# 复制错误页面
COPY 50x.html /usr/share/nginx/html/client/50x.html# 复制supervisor配置文件
COPY supervisord.conf /etc/supervisord.conf# 暴露端口
EXPOSE 8808 80# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \CMD wget --no-verbose --tries=1 --spider http://localhost:8808/api/v1/client/health && \wget --no-verbose --tries=1 --spider http://localhost/ || exit 1# 启动命令
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
softhub系列往期文章
- Softhub软件下载站实战开发(一):项目总览
- Softhub软件下载站实战开发(二):项目基础框架搭建
- Softhub软件下载站实战开发(三):平台管理模块实战
- Softhub软件下载站实战开发(四):代码生成器设计与实现
- Softhub软件下载站实战开发(五):分类模块实现
- Softhub软件下载站实战开发(六):软件配置面板实现
- Softhub软件下载站实战开发(七):集成MinIO实现文件存储功能
- Softhub软件下载站实战开发(八):编写软件后台管理
- Softhub软件下载站实战开发(九):编写软件配置管理界面
- Softhub软件下载站实战开发(十):实现图片视频上传下载接口
- Softhub软件下载站实战开发(十一):软件分片上传接口实现
- Softhub软件下载站实战开发(十二):软件管理编辑页面实现
- Softhub软件下载站实战开发(十三):软件管理前端分片上传实现
- Softhub软件下载站实战开发(十四):软件收藏集设计
- Softhub软件下载站实战开发(十五):仪表盘API设计
- Softhub软件下载站实战开发(十六):仪表盘前端设计与实现
- Softhub软件下载站实战开发(十七):用户端API设计
- Softhub软件下载站实战开发(十八):软件分类展示
- Softhub软件下载站实战开发(十九):软件信息展示