麒麟 ARM64 Docker 离线部署手册
两台机器、两个阶段:自有电脑有网(装 Docker、拉镜像、导出镜像、下依赖包、下 Docker 离线安装包);部署服务器离线(离线装 Docker → 导入镜像 → 启动服务)。
目录
一、整体流程
| 项目 | 阶段一:自有电脑 | 阶段二:部署服务器 |
|---|---|---|
| 系统 | 银河麒麟 V10 ARM64 (aarch64) | 银河麒麟 V10 ARM64 (aarch64) |
| 网络 | 有网 | 离线 |
| Docker | 未安装(需先安装) | 未安装(需离线安装) |
| 要做什么 | 装 Docker → 配加速 → 拉镜像 → 准备依赖 → 导出 tar → 下 Docker 离线包 | 离线装 Docker → 装 Compose → 导入镜像 → 启动服务 → 验证 |
最终部署的 5 个服务: MySQL 8.0 + Redis 7 + Nginx 1.24 + JDK 8 + Python 3.8.9
端口映射(避免与宿主机已有服务冲突):
| 服务 | 容器内端口 | 宿主机映射端口 | 密码 |
|---|---|---|---|
| MySQL 8.0 | 3306 | 3307 | 123456 |
| Redis 7 | 6379 | 6380 | 123456 |
| Nginx 1.24 | 80 / 443 | 8080 / 8443 | - |
| JDK 8 | 8020 | 8020 | - |
| Python 3.8.9 | 5004 | 5004 | - |
二、阶段一:在自有电脑上准备镜像(有网)
银河麒麟 V10 ARM64 · 未安装 Docker · 需要先安装 Docker
步骤 1:确认系统架构
打开终端,确认电脑是 ARM64 架构:
# 查看 CPU 架构,应输出 aarch64
uname -m
# 确认是麒麟系统
cat /etc/kylin-release
预期输出:
aarch64
Kylin Linux Advanced Server release V10 (Lance)
步骤 2:安装 Docker 并下载离线安装包
麒麟 V10 软件源里没有 Docker,需手动添加 Docker CE 仓库。注意:不要用 yum-utils,麒麟源里没有这个包,直接写 repo 文件即可。
# 切换到 root 用户
su -
# 第 1 步:创建 Docker CE 仓库文件
cat > /etc/yum.repos.d/docker-ce.repo << 'EOF'
[docker-ce-stable]
name=Docker CE Stable
baseurl=https://mirrors.huaweicloud.com/docker-ce/linux/centos/8/aarch64/stable
enabled=1
gpgcheck=0
EOF
# 第 2 步:刷新缓存
yum makecache
# 第 3 步:卸载麒麟自带的旧版容器组件(避免与 containerd.io 冲突)
yum remove -y docker-runc podman
# 第 4 步:清理后重新刷新缓存
yum clean all
yum makecache
下载 Docker 离线安装包(供部署服务器离线安装用):
# 下载 Docker CE 及其所有依赖的 RPM 包到指定目录(仅下载不安装)
mkdir -p /opt/offline-images/docker-rpms
yum install -y --downloadonly --downloaddir=/opt/offline-images/docker-rpms \
docker-ce docker-ce-cli containerd.io
下载的 RPM 包会存放在
/opt/offline-images/docker-rpms/目录,稍后随镜像文件一起拷到离线服务器。
安装本机 Docker:
# 安装 Docker
yum install -y docker-ce docker-ce-cli containerd.io
安装过程中会下载约 73MB 的包,耐心等它跑完,不要按 Ctrl+C。看到
Complete!说明装好了。
安装完成后,启动 Docker 并设置开机自启:
# 启动 Docker 服务
systemctl start docker
# 设置开机自启
systemctl enable docker
# 验证安装成功
docker --version
# 应输出: Docker version 26.1.x 或更高
步骤 3:配置镜像加速器(必做)
国内拉 Docker Hub 镜像非常慢,必须配加速器。很多老加速器已停服(中科大、网易、Docker 中国官方等均已失效),以下为当前可用的加速源。
# 创建 Docker 配置目录
mkdir -p /etc/docker
# 写入多个镜像加速源(Docker 会按顺序尝试,哪个快用哪个)
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me",
"https://hub.rat.dev",
"https://docker.m.daocloud.io",
"https://docker.1panel.live",
"https://hub.amingg.com",
"https://docker.kejilion.pro",
"https://docker.sunzishaokao.com"
]
}
EOF
# 重新加载配置并重启 Docker
systemctl daemon-reload
systemctl restart docker
# 验证加速器是否生效
docker info | grep -A 10 "Registry Mirrors"
拉取还是慢? 可手动指定加速器前缀拉取,拉完再重命名:
docker pull docker.1ms.run/library/mysql:8.0 docker tag docker.1ms.run/library/mysql:8.0 mysql:8.0
步骤 4:下载(拉取)Docker 镜像
ARM64 架构下直接 docker pull 即可拉到 arm64 版本的镜像。逐个拉取以下 5 个镜像:
# 拉取 MySQL 8.0(约 650MB,最慢的一个,耐心等)
docker pull mysql:8.0
# 拉取 Redis 7(约 40MB,很快)
docker pull redis:7-alpine
# 拉取 Nginx 1.24(约 50MB,很快)
docker pull nginx:1.24-alpine
# 拉取 JDK 8(约 350MB,Eclipse Temurin 版,官方支持 arm64)
docker pull eclipse-temurin:8-jdk
# 拉取 Python 3.8.9(约 120MB)
docker pull python:3.8.9-slim
各镜像大小和速度参考:
| 镜像 | 大小 | 预计耗时 |
|---|---|---|
| mysql:8.0 | ~650MB | 3-5 分钟 |
| redis:7-alpine | ~40MB | 10 秒 |
| nginx:1.24-alpine | ~50MB | 10 秒 |
| eclipse-temurin:8-jdk | ~350MB | 1-3 分钟 |
| python:3.8.9-slim | ~120MB | 30 秒 |
拉完后确认全部到位:
docker images
应能看到 5 个镜像,总大小约 1.2GB。
步骤 5:准备 Python 离线依赖包
部署服务器是离线的,Python 第三方依赖包需先在有网电脑上下载好。整个过程分 3 步:装包 → 生成依赖清单 → 导出离线包。
第 1 步:把代码拷到挂载目录
# 把 Python 项目代码拷到 Docker 挂载目录
cp -r /opt/need/code_0807/* /opt/docker-deploy/app/python/
# 确认拷进去了
ls /opt/docker-deploy/app/python/
第 2 步:启动临时容器,装包并跑通程序
# 启动临时 Python 容器(用于安装依赖和生成离线包)
docker run -d --name python-temp -v /opt/docker-deploy/app/python:/app -w /app python:3.8.9-slim tail -f /dev/null
# 进入容器
docker exec -it python-temp bash
# ---- 以下在容器内执行 ----
cd /app
# 先试着运行你的程序
python http_server.py
# 如果报 ModuleNotFoundError: No module named 'xxx'
# 就根据报错安装缺少的包:
pip install scipy numpy pandas flask requests -i https://pypi.tuna.tsinghua.edu.cn/simple
# 装完后再次运行,直到不报错为止
python http_server.py
# 如果还报缺包,继续装:
# pip install 缺少的包名 -i https://pypi.tuna.tsinghua.edu.cn/simple
说明:
python:3.8.9-slim是精简镜像,里面只有 Python 标准库,没有任何第三方包。所以pip freeze输出为空是正常的,必须先手动装好所有依赖、跑通程序后,再生成 requirements.txt。
第 3 步:生成依赖清单并导出离线包
程序跑通后,所有依赖已安装在容器中。用 pip freeze 生成清单,再用 pip download 导出 wheel 文件(不加 -i,pip 会优先使用本地缓存,之前 pip install 下过的包直接从缓存取,不重复走网络):
# 生成完整的依赖清单
pip freeze > requirements.txt
# 查看内容,确认不为空
cat requirements.txt
# 导出所有依赖的 wheel 文件到 packages 目录(走本地缓存,不重复下载)
mkdir -p packages
pip download -r requirements.txt -d packages/
# 下载完成后退出容器
exit
退出容器后,停止并删除临时容器:
# 停止并删除临时容器
docker stop python-temp && docker rm python-temp
验证离线包下载成功(在宿主机上查看):
ls -lh /opt/docker-deploy/app/python/packages/
应能看到一堆 .whl 和 .tar.gz 文件。
为什么必须在容器里下载? 容器是 ARM64 架构 + Python 3.8.9,在这里下载的 wheel 包架构天然匹配。如果在 x86 电脑上下载,装到 ARM64 服务器上会报架构不匹配。
步骤 6:下载 Docker Compose
部署服务器上没有 Compose,需下载 ARM64 版本一起拷过去:
cd /opt/offline-images
# 下载 Docker Compose v2(ARM64 版本)
curl -L -o docker-compose \
https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-aarch64
# 赋予执行权限
chmod +x docker-compose
GitHub 下载慢? 用加速链接:
curl -L -o docker-compose \ https://ghproxy.com/https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-aarch64或者用浏览器打开链接下载后放到
/opt/offline-images/目录。
步骤 7:导出全部 5 个镜像
将 5 个原始镜像全部导出成 .tar 文件。docker save 是纯磁盘操作不走网络,通常几十秒完成。
# 进入导出目录
cd /opt/offline-images
# 导出 5 个原始镜像
docker save -o mysql.tar mysql:8.0
docker save -o redis.tar redis:7-alpine
docker save -o nginx.tar nginx:1.24-alpine
docker save -o jdk8.tar eclipse-temurin:8-jdk
docker save -o python.tar python:3.8.9-slim
# 查看所有导出的文件(应共 5 个 tar 文件)
ls -lh
注意:
docker save执行过程中不显示进度条,光标会停住,这是正常的,不要按 Ctrl+C,等它跑完就会出现提示符。说明: 导出的是原始基础镜像。JDK 和 Python 的时区、依赖安装、启动命令都在
docker-compose.yml的command中配置,启动容器时直接使用镜像,不需要构建。
步骤 8:拷贝文件到部署服务器
把镜像文件、Docker 离线安装包和部署配置文件(含离线依赖包)一起拷到部署服务器:
# 方法 1:用 scp 拷贝(把 192.168.x.x 换成部署服务器 IP)
# 拷贝镜像文件和 Docker 离线安装包
scp -r /opt/offline-images root@192.168.x.x:/opt/
# 拷贝部署配置文件(含 Python 代码和离线依赖包)
scp -r /opt/docker-deploy root@192.168.x.x:/opt/
也可以用 U 盘拷贝。拷完后,部署服务器上应有以下目录结构:
/opt/
├── offline-images/ # 镜像文件 + 离线安装包
│ ├── docker-rpms/ # Docker 离线 RPM 安装包
│ │ ├── docker-ce-*.rpm # Docker 引擎
│ │ ├── docker-ce-cli-*.rpm # Docker CLI
│ │ ├── containerd.io-*.rpm # 容器运行时
│ │ └── ... # 其他依赖 RPM 包
│ ├── mysql.tar # ~650MB
│ ├── redis.tar # ~40MB
│ ├── nginx.tar # ~50MB
│ ├── jdk8.tar # eclipse-temurin:8-jdk ~350MB
│ ├── python.tar # python:3.8.9-slim ~120MB
│ └── docker-compose # Compose 可执行文件 ~60MB
│
└── docker-deploy/ # 部署配置
├── docker-compose.yml # 编排文件
├── .env # 密码等环境变量
├── mysql/ # MySQL 配置
│ ├── conf/
│ │ └── app.cnf
│ ├── data/
│ └── init/
│ └── init.sql
├── nginx/ # Nginx 配置
│ ├── nginx.conf
│ ├── conf.d/
│ │ └── default.conf
│ └── html/
├── redis/ # Redis 配置
│ ├── redis.conf # Redis 配置文件
│ └── data/ # Redis 数据(自动生成)
└── app/
├── java/ # Java 项目
│ ├── Dockerfile # 可选,当前方案用 command 启动,不需要
│ └── your-app.jar
└── python/ # Python 项目
├── Dockerfile # 可选,当前方案用 command 装依赖,不需要
├── http_server.py
├── *.py
├── requirements.txt
└── packages/ # 离线依赖包(.whl 文件)
三、阶段二:在部署服务器上部署服务(离线)
银河麒麟 V10 ARM64 · 未安装 Docker · 离线环境
步骤 1:离线安装 Docker
部署服务器没有 Docker,用阶段一下载的 RPM 包离线安装:
# 切换到 root
su -
# 卸载麒麟自带的旧版容器组件(避免冲突)
yum remove -y docker-runc podman
# 从本地 RPM 包离线安装 Docker(不需要联网)
yum localinstall -y /opt/offline-images/docker-rpms/*.rpm
# 启动 Docker 并设置开机自启
systemctl start docker
systemctl enable docker
# 验证安装成功
docker --version
# 应输出: Docker version 26.1.x 或更高
# 确认 Docker 在运行
docker info
如果
yum localinstall报缺少依赖: 说明部分系统依赖包未包含在下载的 RPM 中。需回到有网电脑,用yum install -y --downloadonly --downloaddir=/opt/offline-images/docker-rpms 缺少的包名补下缺失的依赖,重新拷过来再安装。
步骤 2:安装 Docker Compose
把阶段一拷过来的 docker-compose 文件安装为系统命令:
# 把 docker-compose 安装为 Docker CLI 插件
mkdir -p /usr/local/lib/docker/cli-plugins
cp /opt/offline-images/docker-compose \
/usr/local/lib/docker/cli-plugins/docker-compose
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
# 同时放一份到 bin 目录,这样 docker-compose 命令也能用
cp /opt/offline-images/docker-compose /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# 验证安装
docker compose version
# 应输出: Docker Compose version v2.27.0
步骤 3:导入 Docker 镜像
把 tar 文件逐个导入到 Docker 中(docker load 是纯磁盘操作,比下载快得多):
# 逐个导入
docker load -i /opt/offline-images/mysql.tar
docker load -i /opt/offline-images/redis.tar
docker load -i /opt/offline-images/nginx.tar
docker load -i /opt/offline-images/jdk8.tar
docker load -i /opt/offline-images/python.tar
导入完成后,确认 5 个镜像都在:
docker images
应能看到 mysql:8.0、redis:7-alpine、nginx:1.24-alpine、eclipse-temurin:8-jdk、python:3.8.9-slim 这 5 个基础镜像。
步骤 4:启动全部服务
进入部署配置目录,一键启动:
# 进入部署目录
cd /opt/docker-deploy
# (可选)先看一眼配置文件,确认密码和端口
cat .env
# 一键启动 5 个服务(-d 表示后台运行)
docker compose up -d
这会按照 docker-compose.yml 里的配置,依次启动 MySQL、Redis、Nginx、JDK8、Python 五个容器。所有镜像已通过 docker load 导入,直接启动即可,无需联网。JDK 容器启动时等待 15 秒后自动运行 jar 包;Python 容器启动时先从本地 packages/ 目录离线安装依赖,再运行 http_server.py。
如果看到
WARN: 'version' is obsolete,这是 Docker Compose v2 的正常提示,不影响使用,忽略即可。
步骤 5:查看运行状态
# 查看所有容器状态
docker compose ps
# 查看某个服务的日志(比如 MySQL)
docker compose logs -f mysql
# 查看 Python 容器的启动日志(确认依赖安装和服务启动是否成功)
docker compose logs -f python
正常状态下,5 个容器全部显示 Up 即说明启动成功:
NAME STATUS PORTS
mysql Up 0.0.0.0:3307->3306/tcp
redis Up 0.0.0.0:6380->6379/tcp
nginx Up 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp
jdk8 Up 0.0.0.0:8020->8020/tcp
python389 Up 0.0.0.0:5004->5004/tcp
步骤 6:逐个验证服务
分别验证每个服务是否正常工作:
# 验证 MySQL 8.0(外部端口 3307,密码 123456)
docker exec mysql mysql -uroot -p123456 -e "SELECT VERSION();"
# 应输出: 8.0.xx
# 验证 Redis(外部端口 6380,密码 123456)
docker exec redis redis-cli -a 123456 ping
# 应输出: PONG
# 验证 Nginx(外部端口 8080)
curl http://localhost:8080
# 应输出: HTML 页面内容
# 验证 JDK 8
docker exec jdk8 java -version
# 应输出: openjdk version "1.8.0_xxx"
# 验证 Python
docker exec python389 python --version
# 应输出: Python 3.8.9
步骤 7:运行你的应用
导入 MySQL 数据库
如果项目有 SQL 文件(建表语句、初始数据等),需导入到 MySQL 容器中:
# 方法 1:从宿主机直接导入 SQL 文件到 MySQL 容器
# 把 your-data.sql 换成你的 SQL 文件名
docker exec -i mysql mysql -uroot -p123456 < /opt/your-data.sql
# 方法 2:进入 MySQL 容器手动导入
# 先把 SQL 文件拷到容器里
docker cp /opt/your-data.sql mysql:/tmp/
# 进入 MySQL 容器
docker exec -it mysql bash
# 登录 MySQL
mysql -uroot -p123456
# 创建数据库(如果还没创建)
CREATE DATABASE your_db_name DEFAULT CHARACTER SET utf8mb4;
# 切换到数据库
USE your_db_name;
# 导入 SQL 文件
source /tmp/your-data.sql;
# 查看表是否导入成功
SHOW TABLES;
# 退出 MySQL 和容器
exit
exit
注意事项:
- SQL 文件编码建议用
utf8mb4,避免中文乱码 - 如果 SQL 文件里已包含
CREATE DATABASE语句,就不需要手动创建数据库 - 导入大文件可能较慢,耐心等它跑完
验证导入结果:
# 登录 MySQL 查看数据库列表
docker exec -it mysql mysql -uroot -p123456 -e "SHOW DATABASES;"
# 查看某个数据库的表
docker exec -it mysql mysql -uroot -p123456 -e "USE your_db_name; SHOW TABLES;"
# 查看表数据(举例)
docker exec -it mysql mysql -uroot -p123456 -e "USE your_db_name; SELECT * FROM your_table LIMIT 10;"
运行 Python 程序
Python 容器启动时会先从本地 packages/ 目录离线安装依赖,然后自动运行 http_server.py。如需查看日志或调试:
# 查看程序启动日志
docker compose logs -f python
# 如需进入容器调试
docker exec -it python389 bash
cd /app
# 如需重启程序:先 kill 旧进程再启动
# ps aux | grep python
# kill <PID>
# python http_server.py
启动 Java 后台
JDK 容器启动时会自动运行 app/java/ 目录下的 jar 包,无需手动操作。把 jar 包放到挂载目录后重启容器即可:
# 把 jar 包拷到挂载目录(确保目录下只有一个 jar 文件)
cp your-app.jar /opt/docker-deploy/app/java/
# 重启 JDK 容器(自动加载并运行新 jar 包)
docker compose restart jdk8
# 查看启动日志,确认正常运行
docker compose logs -f jdk8
如需手动调试,可进入容器:
docker exec -it jdk8 bash
cd /app
# 手动运行 jar 包
java -jar your-app.jar
Java 后台端口说明: Java 程序监听
8020端口(容器内),Nginx 已配好反向代理:/api/→http://jdk8:8020/。请确保 Java 应用配置的监听端口为 8020。
部署 Vue 前端
Vue 前端不需要单独容器,打包成静态文件后放到 Nginx 目录即可:
# 1. 在开发电脑上打包 Vue 项目
npm run build
# 2. 打包后会生成 dist 目录,把里面的所有文件拷到服务器:
# 目标目录:/opt/docker-deploy/nginx/html/
# (把里面的 index.html 等文件替换掉)
# 3. 如果 Nginx 已经在运行,不用重启,直接刷新浏览器就生效
# 如果修改了 nginx 配置文件,重载一下:
docker exec -it nginx nginx -s reload
前端文件目录结构:
/opt/docker-deploy/nginx/html/
├── index.html # Vue 入口文件
├── css/ # 样式文件
├── js/ # 脚本文件
└── ... # 其他静态资源
访问方式
| 访问内容 | 地址 | 说明 |
|---|---|---|
| Vue 前端页面 | http://服务器IP:8080 | Nginx 托管静态文件 |
| Java API | http://服务器IP:8080/api/xxx | Nginx 反向代理到 JDK 容器 8020 |
| Python API | http://服务器IP:8080/pyapi/xxx | Nginx 反向代理到 Python 容器 5004 |
前端请求后端的路径配置: Vue 项目打包前,确保 API 请求地址用的是相对路径(如
/api/xxx),而不是绝对路径(如http://localhost:8080/api/xxx),这样 Nginx 才能正确代理。
四、端口与密码速查
| 服务 | 宿主机访问端口 | 容器内端口 | 用户名 | 密码 |
|---|---|---|---|---|
| MySQL | 3307 | 3306 | root | 123456 |
| MySQL(业务用户) | 3307 | 3306 | appuser | 123456 |
| Redis | 6380 | 6379 | - | 123456 |
| Nginx(HTTP) | 8080 | 80 | - | - |
| Nginx(HTTPS) | 8443 | 443 | - | - |
| JDK 8 | 8020 | 8020 | - | - |
| Python 3.8.9 | 5004 | 5004 | - | - |
外部连接示例:
# 从外部连接 MySQL(注意端口是 3307)
mysql -h 服务器IP -P 3307 -uroot -p123456
# 从外部连接 Redis(注意端口是 6380)
redis-cli -h 服务器IP -p 6380 -a 123456
# 浏览器访问 Nginx(注意端口是 8080)
http://服务器IP:8080
容器之间互相访问: 容器之间走 Docker 内部网络,用的是容器名 + 容器内端口,不受宿主机端口映射影响:
# 在 Python 代码里连接 MySQL(用容器名和容器内端口) mysql -h mysql -P 3306 -uroot -p123456 # 在 Python 代码里连接 Redis redis -h redis -p 6379 -a 123456
五、日常运维命令速查
| 操作 | 命令 |
|---|---|
| 启动全部 | docker compose up -d |
| 停止全部 | docker compose down |
| 重启某个 | docker compose restart mysql |
| 查看状态 | docker compose ps |
| 查看日志 | docker compose logs -f mysql |
| 进入 MySQL | docker exec -it mysql mysql -uroot -p123456 |
| 进入 Redis | docker exec -it redis redis-cli -a 123456 |
| 进入 JDK 容器 | docker exec -it jdk8 bash |
| 进入 Python 容器 | docker exec -it python389 bash |
| 重载 Nginx 配置 | docker exec -it nginx nginx -s reload |
| 停止并清数据(慎用) | docker compose down -v |
六、如何更新 Python 依赖
在有网电脑上(下载离线包)
如果后续需要新增 Python 依赖包,先在有网电脑上下载好离线包:
# 1. 启动临时容器
docker run -d --name python-temp -v /opt/docker-deploy/app/python:/app -w /app python:3.8.9-slim tail -f /dev/null
docker exec -it python-temp bash
# 2. 在容器内安装新包(验证能否正常使用)
pip install 新包名 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 3. 重新生成 requirements.txt
pip freeze > requirements.txt
# 4. 导出所有离线包到 packages 目录(走本地缓存,不重复下载)
pip download -r requirements.txt -d packages/
# 5. 退出并清理临时容器
exit
docker stop python-temp && docker rm python-temp
在离线服务器上(重启容器自动安装)
把更新后的 requirements.txt 和 packages/ 目录拷到离线服务器的 /opt/docker-deploy/app/python/ 目录,然后重启 Python 容器即可。容器启动时会自动执行 pip install --no-index --find-links=/app/packages -r requirements.txt 安装新依赖:
# 进入部署目录
cd /opt/docker-deploy
# 重启 Python 容器(启动时自动安装更新后的依赖)
docker compose restart python
# 查看启动日志(确认依赖安装和服务启动是否成功)
docker compose logs -f python
说明: Python 容器的
command配置为pip install --no-index --find-links=/app/packages -r requirements.txt && python http_server.py,每次启动都会从本地packages/目录安装依赖,因此更新依赖只需替换文件后重启容器,无需重新构建镜像。
七、部署配置文件参考
以下文件放在
docker-deploy/目录下,按目录结构组织。拷到部署服务器后直接docker compose up -d即可启动。
目录结构总览
docker-deploy/
├── docker-compose.yml # 编排文件(核心)
├── .env # 环境变量(密码等)
├── mysql/
│ ├── conf/ # MySQL 配置文件目录
│ │ └── app.cnf # 字符集等配置
│ ├── data/ # MySQL 数据(自动生成,别手动改)
│ └── init/ # 初始化 SQL 脚本(首次启动自动执行)
│ └── init.sql # 建库建表脚本(按需放入)
├── nginx/
│ ├── nginx.conf # Nginx 主配置文件
│ ├── conf.d/ # 站点配置目录
│ │ └── default.conf # 反向代理配置
│ └── html/ # Vue 静态文件目录
│ ├── index.html
│ ├── css/
│ └── js/
├── redis/
│ ├── redis.conf # Redis 配置文件(持久化、内存等)
│ └── data/ # Redis 数据(自动生成)
└── app/
├── java/ # Java 项目
│ ├── Dockerfile # 可选,当前方案用 command 启动,不需要
│ └── your-app.jar
└── python/ # Python 项目
├── Dockerfile # 可选,当前方案用 command 装依赖,不需要
├── http_server.py
├── *.py
├── requirements.txt
└── packages/ # 离线依赖包(.whl 文件)
docker-compose.yml
services:
# ========== MySQL 8.0 ==========
mysql:
image: mysql:8.0
container_name: mysql
restart: always
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf:/etc/mysql/conf.d
- ./mysql/init:/docker-entrypoint-initdb.d
networks:
- app-network
# ========== Redis 7 ==========
redis:
image: redis:7-alpine
container_name: redis
restart: always
ports:
- "6380:6379"
environment:
- TZ=Asia/Shanghai
# 密码通过 .env 传入,其余配置走 redis.conf
command: redis-server /etc/redis/redis.conf --requirepass ${REDIS_PASSWORD}
volumes:
- ./redis/data:/data
- ./redis/redis.conf:/etc/redis/redis.conf
networks:
- app-network
# ========== Nginx 1.24 ==========
nginx:
image: nginx:1.24-alpine
container_name: nginx
restart: always
ports:
- "8080:80"
- "8443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/html:/usr/share/nginx/html
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- jdk8
- python
networks:
- app-network
# ========== JDK 8 ==========
jdk8:
image: eclipse-temurin:8-jdk
container_name: jdk8
restart: always
ports:
- "8020:8020"
environment:
- TZ=Asia/Shanghai
working_dir: /app
command: ["bash", "-c", "sleep 15 && java -jar *.jar"]
volumes:
- ./app/java:/app
depends_on:
- mysql
- redis
networks:
- app-network
# ========== Python 3.8.9 ==========
python:
image: python:3.8.9-slim
container_name: python389
restart: always
ports:
- "5004:5004"
environment:
- TZ=Asia/Shanghai
working_dir: /app
command: ["bash", "-c", "pip install --no-index --find-links=/app/packages -r requirements.txt && python http_server.py"]
volumes:
- ./app/python:/app
depends_on:
- mysql
- redis
networks:
- app-network
networks:
app-network:
driver: bridge
.env
# ===== MySQL 配置 =====
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=appdb
MYSQL_USER=appuser
MYSQL_PASSWORD=123456
# ===== Redis 配置 =====
REDIS_PASSWORD=123456
app/java/Dockerfile(可选,当前方案未使用)
当前方案中 docker-compose.yml 直接使用
image: eclipse-temurin:8-jdk基础镜像,通过command和environment配置启动,不需要 Dockerfile。以下 Dockerfile 仅供参考,如果你想改用build:方式构建自定义镜像,可以使用它。
FROM eclipse-temurin:8-jdk
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 设置工作目录
WORKDIR /app
# 暴露 Java 服务端口
EXPOSE 8020
# jar 包通过 volume 挂载到 /app 目录,启动时等待 MySQL 就绪
CMD ["bash", "-c", "sleep 15 && java -jar *.jar"]
jar 包不打进镜像,通过 volume 挂载方便更新。
app/java/目录下只放一个 jar 文件即可。请确保 Java 应用配置的监听端口为 8020。
app/python/Dockerfile(可选,当前方案未使用)
当前方案中 docker-compose.yml 直接使用
image: python:3.8.9-slim基础镜像,通过command在容器启动时安装依赖并运行程序,不需要 Dockerfile。以下 Dockerfile 仅供参考,如果你想改用build:方式将依赖内置到镜像中,可以使用它。
FROM python:3.8.9-slim
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 设置工作目录
WORKDIR /app
# 构建时离线安装依赖(requirements.txt 和 packages/ 在构建上下文中)
# --no-index 表示不从 PyPI 下载,只使用本地 packages/ 目录中的 wheel 文件
COPY requirements.txt .
COPY packages/ ./packages/
RUN pip install --no-index --find-links=/app/packages -r requirements.txt
# 暴露 Python 服务端口
EXPOSE 5004
# 代码通过 volume 挂载到 /app,依赖已内置到镜像中
CMD ["python", "http_server.py"]
关键设计: 依赖在构建时安装到镜像的 site-packages 中,不随 volume 挂载覆盖。运行时代码通过 volume 挂载,更新代码只需替换文件、重启容器,不用重新构建镜像。把
http_server.py换成你的实际启动文件名。请确保 Python 程序监听端口为 5004。离线构建说明: Dockerfile 中没有
apt-get install等需要联网的命令,pip install --no-index只使用本地packages/目录中的 wheel 文件,因此可以在离线服务器上直接docker compose up -d自动构建。如果个别包安装报错提示缺少编译器,说明该包没有预编译 wheel,需回到有网电脑用带 gcc 的镜像构建后导出。
nginx/conf.d/default.conf
# 网页访问的端口号 # server_name 看自己自定义
server {
listen 80;
server_name localhost
charset utf-8;
# root dist所存放的位置
location / {
root /home/dist;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
# windows dist存放在nginx的位置
location / {
root html/dist;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
# 访问地图资源
location /biying/ {
alias html/biying/;
try_files $uri $uri/ /index.html;
index index.html index.htm;
# 启用CORS,防止跨域
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
# 配置反向代理 proxy_pass 需要改成自己后端的ip端口
location /dev-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://容器名:8020/;
proxy_read_timeout 3600; # 单位为秒
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
mysql/conf/app.cnf
# ============================================================
# MySQL 8.0 配置文件
# 针对 ARM64 环境优化
# ============================================================
[mysqld]
# 基本配置
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
# 字符集 - 使用 utf8mb4 支持完整 Unicode(含 emoji)
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 存储引擎
default-storage-engine = InnoDB
# MySQL 8.0 认证方式 - 使用 mysql_native_password 兼容旧客户端
# 也可以在 docker-compose.yml 的 command 中指定
default-authentication-plugin = mysql_native_password
# SQL 模式
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
# 连接配置
max_connections = 500
wait_timeout = 28800
interactive_timeout = 28800
# InnoDB 配置 (针对 ARM64 虚拟机环境调优)
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
# 日志配置
log_error = /var/lib/mysql/error.log
slow_query_log = 0
long_query_time = 2
# 时区
default-time-zone = '+08:00'
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
mysql/init/init.sql(可选,按需创建)
-- 首次启动 MySQL 时自动执行(仅首次,已有数据后不会重复执行)
-- 如果你的业务需要额外的初始化,写在这里
-- 示例:创建业务数据库(如果 docker-compose.yml 里已通过 MYSQL_DATABASE 创建,这里可省略)
-- CREATE DATABASE IF NOT EXISTS appdb DEFAULT CHARACTER SET utf8mb4;
-- 示例:给业务用户授权
-- GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'%';
-- FLUSH PRIVILEGES;
redis/redis.conf
# ============================================
# Redis 配置文件
# ============================================
# 绑定地址,容器内允许所有来源访问(端口映射由 Docker 控制)
bind 0.0.0.0
# 保护模式关闭(已通过 requirepass 设置密码)
protected-mode no
# 端口(容器内端口,与 docker-compose.yml 映射无关)
port 6379
# ----- 持久化配置 -----
# 开启 AOF 持久化(每次写操作追加到 appendonly.aof)
appendonly yes
# AOF 文件名
appendfilename "appendonly.aof"
# AOF 刷盘策略:每秒刷盘(兼顾性能和安全)
appendfsync everysec
# 同时保留 RDB 快照(双保险)
save 900 1
save 300 10
save 60 10000
# RDB 文件名
dbfilename dump.rdb
# 数据目录(与 docker-compose.yml 中 volume 挂载一致)
dir /data
# ----- 内存管理 -----
# 最大内存限制 256MB(根据服务器内存调整)
maxmemory 256mb
# 内存满时的淘汰策略:LRU 淘汰最少使用的 key
maxmemory-policy allkeys-lru
# ----- 日志 -----
# 日志级别(debug / verbose / notice / warning)
loglevel notice
# 日志输出到标准输出(docker logs 可查看)
logfile ""
# ----- 其他 -----
# 数据库数量(默认 16 个库)
databases 16
# 超时时间(秒),客户端空闲超过此值则断开(0 表示永不超时)
timeout 0
# TCP keepalive 探测间隔(秒)
tcp-keepalive 300
说明: 密码不在 redis.conf 中设置,而是通过 docker-compose.yml 的
command参数--requirepass ${REDIS_PASSWORD}传入,这样修改密码只需改.env文件,不用动 redis.conf。上面配置主要管持久化(AOF + RDB 双保险)和内存管理(256MB 上限 + LRU 淘汰)。
nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
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;
types_hash_max_size 2048;
# 文件上传大小限制
client_max_body_size 100m;
# Gzip 压缩
gzip on;
gzip_min_length 1k;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 包含站点配置
include /etc/nginx/conf.d/*.conf;
}
说明: 官方
nginx:alpine镜像自带默认nginx.conf,但不包含文件上传大小限制(client_max_body_size 100m)和 Gzip 压缩。上面的配置补充了这两项,最后通过include /etc/nginx/conf.d/*.conf;加载default.conf里的反向代理规则。
各文件说明
| 文件 | 作用 | 需要手动创建 |
|---|---|---|
docker-compose.yml | 核心编排文件,定义 5 个服务的镜像、端口、挂载、网络 | 是 |
.env | 环境变量,存放 MySQL 和 Redis 的密码 | 是 |
nginx/nginx.conf | Nginx 主配置,文件上传大小限制、Gzip 压缩等 | 是 |
nginx/conf.d/default.conf | Nginx 站点配置,前端静态文件和 API 反向代理规则 | 是 |
mysql/conf/app.cnf | MySQL 自定义配置,字符集、连接数等 | 是 |
mysql/init/init.sql | MySQL 首次启动初始化脚本,建库建表(可选) | 按需 |
redis/redis.conf | Redis 配置文件,持久化、内存管理等 | 是 |
app/java/Dockerfile | JDK 自定义镜像构建文件(可选,当前方案用 command 启动,不需要) | 否(可选) |
app/python/Dockerfile | Python 自定义镜像构建文件(可选,当前方案用 command 装依赖,不需要) | 否(可选) |
mysql/data/ | MySQL 数据目录,容器启动后自动生成 | 否(自动生成) |
redis/data/ | Redis 数据目录,容器启动后自动生成 | 否(自动生成) |
nginx/html/ | Vue 打包后的静态文件,npm run build 产出的 dist 内容 | 是(放入前端文件) |
app/java/ | Java jar 包存放目录(只放一个 jar 文件,容器自动启动) | 是(放入 jar 包) |
app/python/ | Python 代码、requirements.txt、packages/ 离线依赖包 | 是 |

212

被折叠的 条评论
为什么被折叠?



