描述
私人服务器部署方案以及维护期间的一些心得
访问加速
- 图片格式:图片尽量选用 JPG 格式,PNG 格式的图片普遍要比 JPG 格式的图片大很多。
- 图片压缩:过大的资源加载会非常耗时,影响网站渲染的速度,用 tinypng 或者 compress 压缩,清晰度损失很小。
- CDN 加速:七牛云的收费性价比很高,可以使用七牛云的对象存储配合 CDN 加速。
网站部署
结论先行:我的方案是本地先用 Hugo 生成好静态文件,将静态文件打包到镜像内,然后用 Go 写一个简单的阻塞,编译成二进制文件作为容器启动命令,然后打包成镜像推送到阿里云镜像仓库,然后在服务器用 docker compose 启动一个 Nginx ,通过共享卷的方式访问博客静态页面。
为什么这么做?
为什么本地生成静态文件?
- 国内网络问题镜像下载缓慢
- 容器内生成,需要 Go 和 Hugo ,Go 依赖下载缓慢
- 带 Go 和 Hugo 的镜像太大
为什么不把博客打包成 Nginx?
- 本身希望服务器上的 Nginx 只是作为 Gateway,不要跟博客打包在一起,也正是这个原因用到了共享卷,为了让 Nginx 容器能访问到博客静态文件,共享卷有缓存问题,记得每次启动的时候清下卷。
- 希望服务器上只有一个 Nginx,其他的 Pod 只做基础服务。
为什么需要构建 Go 的二进制执行文件?
- Docker 规定 Pod 容器要能提供服务,纯静态文件没有命令是无法启动的,所以我用了个小技巧,写了个 Go 的阻塞当做启动命令。
部署文件
dockerfile
# 使用 scratch 镜像最小化
FROM scratch
# 复制本机生成的静态文件
COPY public /var/www/hugo
# 复制一个最小 Go 程序,保持容器运行
COPY sleep /sleep
# 启动 sleep,容器持续运行
CMD ["/sleep"]
docker-compose.yml
services:
hugo-static:
image: <<your mirror repositories>>
container_name: hugo-static
command: ["/sleep"]
volumes:
- hugo-static:/var/www/hugo
nginx:
image: docker.m.daocloud.io/library/nginx:1.25
container_name: gateway_nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- hugo-static:/var/www/hugo:ro
- /root/nginx:/etc/nginx/conf.d
- /root/.acme.sh:/root/.acme.sh:ro
volumes:
hugo-static:
- 用 Makefile 方便点
.PHONY: deployment build clean run
registry=example.registry
version=$(shell date +%Y%m%d%H%M%S)
image_name=hugo
# 本机生成 Hugo 静态文件
hugo_build:
@echo "Generating Hugo static files..." \
&& hugo --minify
# 构建 Docker 镜像并推送
build: hugo_build
@echo "Building Docker image..." \
&& docker buildx build --platform=linux/amd64 -t $(image_name) . \
&& docker tag $(image_name) $(registry)/allens-blog/$(image_name):$(version) \
&& docker tag $(image_name) $(registry)/allens-blog/$(image_name):latest \
&& docker push $(registry)/allens-blog/$(image_name):$(version) \
&& docker push $(registry)/allens-blog/$(image_name):latest
# 部署(也是先生成静态文件再打包推送)
deployment: hugo_build
@echo "Deploying Docker image..." \
&& docker buildx build --platform=linux/amd64 -t $(image_name) . \
&& docker tag $(image_name) $(registry)/allens-blog/$(image_name):$(version) \
&& docker tag $(image_name) $(registry)/allens-blog/$(image_name):latest \
&& docker push $(registry)/allens-blog/$(image_name):$(version) \
&& docker push $(registry)/allens-blog/$(image_name):latest \
&& echo "Deployed version: $(version)"
# 清理悬挂镜像
clean:
@echo "Cleaning dangling images..." \
&& docker images --filter dangling=true -q | xargs -r docker rmi
# 本机本地启动 Hugo 服务器
run:
@hugo server
证书自动化
- 上面配置 docker-compose.yml 已经把 ACME 的目录挂在到 Nginx 容器里了,
- 使用 ACME 实现证书自动化续期。
- 使用 Crontab 定时重载下 Nginx 容器。
创建定时任务
crontab -e
添加一行
0 4 * * 2 docker exec gateway_nginx nginx -s reload > /tmp/nginx_reload.log 2>&1
查看是否创建成功
crontab -l
清除冗余镜像
- 网站运行的久了,总会多出很多 tag 为 none 的镜像,占用磁盘容量,可以使用如下命令进行批量删除,你也可以把它能加到 Crontab 里。
docker rmi -f $(docker images -f dangling=true -q)
