麒麟ARM架构Docker离线部署

麒麟 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.033063307123456
Redis 763796380123456
Nginx 1.2480 / 4438080 / 8443-
JDK 880208020-
Python 3.8.950045004-

二、阶段一:在自有电脑上准备镜像(有网)

银河麒麟 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~650MB3-5 分钟
redis:7-alpine~40MB10 秒
nginx:1.24-alpine~50MB10 秒
eclipse-temurin:8-jdk~350MB1-3 分钟
python:3.8.9-slim~120MB30 秒

拉完后确认全部到位:

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.ymlcommand 中配置,启动容器时直接使用镜像,不需要构建。

步骤 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.0redis:7-alpinenginx:1.24-alpineeclipse-temurin:8-jdkpython: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:8080Nginx 托管静态文件
Java APIhttp://服务器IP:8080/api/xxxNginx 反向代理到 JDK 容器 8020
Python APIhttp://服务器IP:8080/pyapi/xxxNginx 反向代理到 Python 容器 5004

前端请求后端的路径配置: Vue 项目打包前,确保 API 请求地址用的是相对路径(如 /api/xxx),而不是绝对路径(如 http://localhost:8080/api/xxx),这样 Nginx 才能正确代理。


四、端口与密码速查

服务宿主机访问端口容器内端口用户名密码
MySQL33073306root123456
MySQL(业务用户)33073306appuser123456
Redis63806379-123456
Nginx(HTTP)808080--
Nginx(HTTPS)8443443--
JDK 880208020--
Python 3.8.950045004--

外部连接示例:

# 从外部连接 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
进入 MySQLdocker exec -it mysql mysql -uroot -p123456
进入 Redisdocker 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.txtpackages/ 目录拷到离线服务器的 /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 基础镜像,通过 commandenvironment 配置启动,不需要 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.confNginx 主配置,文件上传大小限制、Gzip 压缩等
nginx/conf.d/default.confNginx 站点配置,前端静态文件和 API 反向代理规则
mysql/conf/app.cnfMySQL 自定义配置,字符集、连接数等
mysql/init/init.sqlMySQL 首次启动初始化脚本,建库建表(可选)按需
redis/redis.confRedis 配置文件,持久化、内存管理等
app/java/DockerfileJDK 自定义镜像构建文件(可选,当前方案用 command 启动,不需要)否(可选)
app/python/DockerfilePython 自定义镜像构建文件(可选,当前方案用 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/ 离线依赖包
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值