Docker 部署博客详细步骤(小白版)
本文面向零基础用户,手把手教你用 Docker 把博客部署到云服务器。每一步都会说明「在做什么」「为什么这样做」「代码是什么意思」。
一、部署前需要准备什么
1.1 硬件与账号
| 准备项 | 说明 | 示例 |
|---|---|---|
| 云服务器 | 1 台可公网访问的 Linux 服务器 | 腾讯云、阿里云等 |
| root 密码 | 用于 SSH 登录 | 购买时设置 |
| 项目代码 | 已推送到 GitHub 的完整项目 | 含 blog-springboot、blog-vue、deploy 等 |
1.2 需要的文件(都在项目里)
项目根目录大致结构:
项目根目录/
├── blog-springboot/ # 后端 Java 代码
├── blog-vue/ # 前端 Vue 代码
│ ├── shoka-blog/ # 博客前台
│ └── shoka-admin/ # 后台管理
├── deploy/ # 部署相关(核心)
│ ├── .env.example # 环境变量模板
│ ├── blog.sql # 数据库初始化脚本
│ ├── deploy.sh # 一键部署脚本
│ ├── docker-compose.yml
│ ├── Dockerfile # 后端镜像构建
│ ├── Dockerfile.nginx # 前端镜像构建
│ └── nginx.conf # Nginx 配置
└── emoji/ # 表情包(可选)
必要有 :deploy/ 目录下的所有文件,以及 blog.sql。
1.3 安全组(必做)
云服务器安全组必须开放 80 端口,否则外网无法访问网站。
- 登录云控制台 → 云服务器 → 实例
- 安全组 → 编辑规则 → 添加入站规则
- 端口:80,协议:TCP,来源:0.0.0.0/0
二、部署流程(5 步)
第一步:连接服务器
在本地命令行执行(把 IP 换成你的):
bash
ssh root@你的服务器IP
输入 root 密码,看到类似 [root@xxx ~]# 即表示连接成功。
第二步:把项目传到服务器
用 Git 克隆(推荐):
bash
# 安装 git(若未安装)
dnf install -y git
# 进入工作目录
cd /opt
# 克隆项目(替换成你的仓库地址)
git clone https://github.com/你的用户名/仓库名.git aricOnline
# 进入 deploy 目录
cd /opt/aricOnline/deploy
可选:如果 clone 太慢,可用 MobaXterm 等工具把项目 zip 上传到 /opt/,再解压。
第三步:配置环境变量
环境变量用来告诉程序:数据库密码、Redis 密码、博客地址等。
bash
# 在 deploy 目录下
cd /opt/aricOnline/deploy
# 从模板复制一份
cp .env.example .env
# 编辑配置
vim .env
vim 基本操作:
- 按
i进入编辑 - 改完后按
Esc退出编辑 - 输入
:wq回车保存并退出
必改项 (在 .env 里):
bash
MYSQL_PASSWORD=你的MySQL密码 # 例如: MyBlog@2026
REDIS_PASSWORD=你的Redis密码 # 例如: redis123
BLOG_URL=http://你的服务器IP/ # 例如:
UPLOAD_STRATEGY=local # 无 OSS 用 local
第四步:一键部署
bash
cd /opt/aricOnline/deploy
# 给脚本执行权限
chmod +x deploy.sh
# 执行部署
./deploy.sh
首次部署大约 15--30 分钟,脚本会自动完成:
- 安装 Docker 和 Docker Compose
- 拉取镜像(MySQL、Redis、Nginx 等)
- 构建后端和前端镜像
- 启动 4 个容器
第五步:验证
bash
# 查看容器状态
docker compose ps
4 个容器都是 Up 即正常。
浏览器访问:
- 博客前台:
http://你的IP/ - 后台管理:
http://你的IP/admin/
三、核心文件说明(看懂代码含义)
3.1 .env.example 与 .env
.env.example 是模板,.env 是实际配置,不要 把 .env 提交到 Git。
bash
# .env 示例(摘录)
MYSQL_HOST=mysql # 容器内用服务名,不是 localhost
MYSQL_PORT=3306 # 容器内端口,不是宿主机 4000
MYSQL_PASSWORD=xxx # 必改
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=xxx # 必改
BLOG_URL=http://你的IP/ # 必改,博客访问地址
含义:
MYSQL_HOST=mysql:容器间用服务名mysql通信MYSQL_PORT=3306:MySQL 容器内部端口BLOG_URL:邮件、链接等会用到
3.2 docker-compose.yml
定义 4 个服务及它们的关系。
yaml
version: "3.8" # 使用的 compose 版本
services:
mysql: # 服务名,也是容器间访问的 host
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD} # 从 .env 读取
ports:
- "4000:3306" # 宿主机 4000 → 容器 3306
volumes:
- mysql-data:/var/lib/mysql # 数据持久化
- ./blog.sql:/docker-entrypoint-initdb.d/init.sql:ro # 首次启动导入
含义:
ports: "4000:3306":宿主机 4000 映射到容器 3306volumes:数据持久化、挂载初始化脚本environment:容器内环境变量
yaml
blog-server:
depends_on:
mysql:
condition: service_healthy # 等 MySQL 健康后再启动
environment:
MYSQL_HOST: mysql # 用服务名连接
MYSQL_PORT: 3306 # 容器内端口
含义:
depends_on:启动顺序condition: service_healthy:等 MySQL 健康检查通过MYSQL_HOST=mysql:后端通过名称访问 MySQL
3.3 Dockerfile(后端)
多阶段构建:先编译,再运行。
dockerfile
# 阶段 1:构建
FROM maven:3.8-openjdk-11 AS builder
WORKDIR /build
COPY blog-springboot/pom.xml .
RUN mvn dependency:go-offline -B # 先下载依赖
COPY blog-springboot/src ./src
RUN mvn package -DskipTests -B # 打包,跳过测试
# 阶段 2:运行
FROM eclipse-temurin:11-jre
COPY --from=builder /build/target/blog-springboot-*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
含义:
FROM ... AS builder:第一阶段,只用于构建COPY --from=builder:从构建阶段复制 jarENTRYPOINT:容器启动时执行的命令
3.4 Dockerfile.nginx(前端)
先构建前台和后台,再交给 Nginx 托管。
dockerfile
# 构建前台
FROM node:18-alpine AS blog-builder
WORKDIR /build/blog
COPY blog-vue/shoka-blog/ .
RUN npm install --registry=https://registry.npmmirror.com
RUN npm run build
# 构建后台
FROM node:18-alpine AS admin-builder
WORKDIR /build/admin
COPY blog-vue/shoka-admin/ .
RUN npm install --registry=https://registry.npmmirror.com
RUN npm run build:prod
# Nginx 阶段
FROM nginx:1.25-alpine
COPY --from=blog-builder /build/blog/blog /usr/share/nginx/blog
COPY --from=admin-builder /build/admin/dist /usr/share/nginx/admin
COPY --from=admin-builder /build/admin/static /usr/share/nginx/static
COPY deploy/nginx.conf /etc/nginx/nginx.conf
含义:
AS blog-builder:前台构建阶段AS admin-builder:后台构建阶段registry.npmmirror.com:国内 npm 镜像static:表情包等静态资源
3.5 nginx.conf
Nginx 负责把请求分发到不同路径。
nginx
location / { # 访问 / 时
root /usr/share/nginx/blog;
try_files $uri $uri/ /index.html; # SPA 路由回退到 index.html
}
location /admin/ { # 访问 /admin/ 时
alias /usr/share/nginx/admin/;
try_files $uri $uri/ /admin/index.html;
}
location ^~ /api/ { # 访问 /api/ 时
proxy_pass http://blog-server:8000/; # 转发到后端
}
含义:
root:静态文件根目录alias:路径映射try_files:找不到文件时回退到 index.html(SPA)proxy_pass:把/api/转发到后端 8000 端口
3.6 deploy.sh(一键部署脚本)
脚本主要流程:
bash
# 1. 检查 root
if [ "$EUID" -ne 0 ]; then
error "请使用 root 用户运行"
exit 1
fi
# 2. 若未安装 Docker,用 dnf 安装
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 3. 若未安装 Compose 插件,用 dnf 安装
dnf install -y docker-compose-plugin
# 4. 检查 .env 是否存在
if [ ! -f ".env" ]; then
cp .env.example .env
exit 1 # 提示用户先编辑 .env
fi
# 5. 拉取基础镜像
docker pull mysql:8.0
docker pull redis:7-alpine
# ...
# 6. 构建并启动
docker compose up -d --build
含义:
set -e:出错立即退出$EUID:当前用户 ID,0 表示 rootdocker compose up -d --build:后台构建并启动
四、常用命令速查
bash
# 查看状态
docker compose ps
# 查看日志
docker compose logs -f
docker compose logs -f blog-server
# 重启
docker compose restart
# 停止
docker compose down
# 更新代码后重新部署
cd /opt/aricOnline
git pull
cd deploy
docker compose up -d --build
五、常见问题
1. 网站打不开
- 检查安全组是否开放 80 端口
- 检查
docker compose ps是否全部 Up
2. 后台管理打不开或白屏
- 访问
http://你的IP/admin/(带末尾斜杠) - 检查
shoka-admin的vite.config.ts是否有base: '/admin/'
3. 表情包不显示
- 检查
Dockerfile.nginx是否复制了static - 检查
nginx.conf是否有location /static/
4. 后端一直重启
- 查看日志:
docker compose logs blog-server - 检查
.env中MYSQL_PASSWORD、REDIS_PASSWORD是否正确
5. 镜像拉取失败
- 配置
/etc/docker/daemon.json的registry-mirrors - 执行
systemctl restart docker后重试./deploy.sh
六、部署检查清单
部署前:
- 有云服务器和 root 密码
- 安全组开放 80 端口
- 项目已克隆/上传到服务器
- 已配置
.env(MYSQL_PASSWORD、REDIS_PASSWORD、BLOG_URL)
部署后:
-
docker compose ps四个容器 Up - 能访问
http://你的IP/ - 能访问
http://你的IP/admin/ - 能登录后台
七、总结
部署三步:准备环境 → 配置 .env → 执行 deploy.sh 。
核心是理解:Docker 用容器运行服务,docker-compose 统一管理,Nginx 负责把请求分到前台、后台和 API。
遇到问题可先看 docker compose logs 和 deploy/README.md 的排查部分。