python-flask项目开发:
- flask开发完整过程总结:https://blog.csdn.net/qq_38444844/article/details/151928286?spm=1011.2415.3001.5331
- 项目源码:https://gitee.com/loveTianWen/Forum-platform/tree/master
- 第二篇: 部署 Kubernetes 集群(Ubuntu 24.04.3)https://blog.csdn.net/qq_38444844/article/details/156615128?sharetype=blogdetail\&sharerId=156615128\&sharerefer=PC\&sharesource=qq_38444844\&spm=1011.2480.3001.8118
目的:Docker部署flask项目
环境准备:
Ubuntu下载地址:https://ubuntu.com/download
安装教程:https://blog.csdn.net/xl196908/article/details/137222758

华为云镜像站,下载 ISO 安装系统:(登录下载)
https://repo.huaweicloud.com/ubuntu-releases/24.04.3/

VirtualBox安装Ubuntu 24.04(附安装包)超详细小白图文教程:
https://blog.csdn.net/2508_92702046/article/details/150558467

机器必配项:静态 IP、SSH、主机名、APT 源
- Your name: ubuntu
- Server name: db(对应角色,如 app, k8s-master)
- Username: ubuntu
- Password: your_password(5 台可相同)
bash
/etc/hosts
192.168.56.109 db
192.168.56.110 app
192.168.56.111 k8s-master
192.168.56.112 k8s-worker1
192.168.56.113 k8s-worker2
1、xshell远程登录Ubuntu 24.04.3
注意:Ubuntu 24.04 默认 禁用 root 远程登录,所以请用普通用户(如 ubuntu)登录,再用 sudo 提权。
- 网卡1:连接方式 = NAT网络
- 网卡2:连接方式 = 仅主机(Host-Only)网络


a. 远程配置
bash
# 1、检查是否已安装 OpenSSH Serve
systemctl status ssh
# 2、如果没安装,先安装
sudo apt update
sudo apt install openssh-server -y
# 3、 启动并设置开机自启:
sudo systemctl enable --now ssh
# 4、查看 IP 地址(通常是 enp0s3)
ip a
# 或
hostname -I
# 5、确保防火墙允许 SSH(默认通常允许)
sudo ufw status
# 6、如果启用且没放行 22 端口,执行:
sudo ufw allow OpenSSH
# 或
sudo ufw allow 22/tcp
# 7、设置/重置密码(如果不确定):
sudo passwd ubuntu
-
修改网卡配置:/etc/netplan/50-cloud-init.yaml
-
默认只有enp0s3配置
yaml
ubuntu@db:~$ sudo cat /etc/netplan/50-cloud-init.yaml
cat > /etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
enp0s3:
dhcp4: true
- 修改后的网卡enp0s3 + enp0s8配置:00-config.yaml
yaml
# 切换到 root 再操作
sudo -i
# 或者直接用tee
cat <<EOF | sudo tee /etc/netplan/00-installer-config.yaml
network:
version: 2
ethernets:
enp0s3:
dhcp4: true
enp0s8:
dhcp4: false
addresses: [192.168.56.110/24]
optional: true
EOF
exit
bash
# 应用配置
sudo netplan apply
# 验证配置生效
ip a
ping -c 3 8.8.8.8
# 立即禁Ubuntu云服务器上cloud-init自动网络配置(防止下次重启被覆盖)
echo 'network: {config: disabled}' | sudo tee /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
- 各机器 IP 规划:
bash
# 切换到 root 再操作
sudo -i
或者直接用tee
# cat >> /etc/hosts <<EOF
cat <<EOF | sudo tee /etc/hosts
192.168.56.109 db
192.168.56.110 app
192.168.56.111 k8s-master
192.168.56.112 k8s-worker1
192.168.56.113 k8s-worker2
EOF
- 允许 root 密码登录(方便后续自动化)
bash
# 1、设置 root 密码
passwd root
# 先删除已有的 PermitRootLogin 行(如果存在),匹配以 PermitRootLogin 开头的行,进行delete
# sudo sed -i '/^PermitRootLogin/d' /etc/ssh/sshd_config
# 2、允许 root 密码登录 SSH,把PermitRootLogin yes 追加到ssh配置里
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
# 3、修改后必须重启 SSH 服务
systemctl restart sshd
b. 克隆四台机器(为集群做准备)

bash
# 1、切换到 root
sudo -i
# 2、修改ip,主机名
vi /etc/netplan/00-config.yaml
vi /etc/hostname
# 3、应用配置
sudo netplan apply
# 4、验证配置生效
ip a
ping -c 3 8.8.8.8
c. ssh免密登录
前提:所有机器使用 同一个普通用户(如 ubuntu)
目标:任意机器之间可通过 主机名 + 公钥认证 免密 SSH 登录
不使用 root,符合安全最佳实践
- 选一台机器执行下面操作,如:app 192.168.56.110
bash
# 检查当前用户
# whoami # 应返回 ubuntu
# 1、切换到 ubuntu 用户(如果不是)
su - ubuntu
# 2、生成 RSA 密钥对(一路回车,不设密码 passphrase)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
私钥:~/.ssh/id_rsa(绝不外传!)
公钥:~/.ssh/id_rsa.pub(可分发)
-
将公钥复制到 所有机器(包括自己)
-
方法 A:手动逐台复制(适合少量机器)
bash
# 格式:ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@host,避免每次输入yes:-o StrictHostKeyChecking=no,密码第一次必输
ssh-copy-id -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa.pub ubuntu@db
ssh-copy-id -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa.pub ubuntu@app
ssh-copy-id -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa.pub ubuntu@k8s-master
ssh-copy-id -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa.pub ubuntu@k8s-worker1
ssh-copy-id -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa.pub ubuntu@k8s-worker2
- 方法 B:用脚本批量复制(推荐)
bash
#!/bin/bash
HOSTS=("db" "app" "k8s-master" "k8s-worker1" "k8s-worker2")
for host in "${HOSTS[@]}"; do
echo "Copying key to $host..."
ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@$host
done
- 保存为 setup-ssh.sh,运行
bash
chmod +x setup-ssh.sh
./setup-ssh.sh
- 验证免密登录
bash
# 测试从 app 登录 db
ssh ubuntu@db 'hostname'
# 测试从 db 登录 k8s-master
ssh ubuntu@k8s-master 'uptime'
总结:关键配置点
双网卡配置主机网络 实现外部上网和 VM 间互通,模拟真实服务器环境
静态 IP enps08中固定IP(如 DB_HOST=192.168.56.104)
SSH 开启并免密登录 后续 Ansible / kubeadm join 需要
华为云 APT 源 加速软件安装,避免超时失败
root 密码登录 简化初期操作(生产环境应禁用)
d. 环境准备已完成
所有机器已安装 Ubuntu 24.04.3 Server,并配置好 SSH、静态 IP、主机名解析(或直接用 IP) 所有机器已配置SSH 免密、静态 IP、网络互通。
**
192.168.56.109 db MariaDB 数据库服务器
192.168.56.110 app Flask 应用服务器(用于构建 + 测试)
192.168.56.111 k8s-master Kubernetes 控制平面
192.168.56.112 k8s-worker1 Kubernetes 工作节点
192.168.56.113 k8s-worker2 Kubernetes 工作节点
替换为阿里云镜像
- 原镜像配置:
bash
cat /etc/apt/sources.list.d$/ubuntu.sources
yaml
Types: deb
URIs: http://archive.ubuntu.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: http://security.ubuntu.com/ubuntu/
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
- 备份原配置
bash
1、备份原配置
sudo cp /etc/apt/sources.list.d/ubuntu.sources{,.bak}
2、阿里云镜像,仅将 http://archive.ubuntu.com/ubuntu/ 和 http://security.ubuntu.com/ubuntu/ 替换为 https://mirrors.aliyun.com/ubuntu/
cat << EOF | sudo tee /etc/apt/sources.list.d/ubuntu.sources
Types: deb
URIs: https://mirrors.aliyun.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: https://mirrors.aliyun.com/ubuntu/
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF
3、清理并更新 APT 缓存
sudo apt clean
sudo apt update
4、验证是否生效
# 查看是否从阿里云拉取
apt policy ubuntu-minimal
2、在 app 机器(192.168.56.110)构建镜像
-
下面操作也在另一台阿里云ecs服务器上进行,可忽略!!! (Alibaba Cloud Linux 3)
-
Alibaba Cloud Linux 3,兼容 CentOS/RHEL 8,可以使用 yum/dnf 命令
a. 安装 Docker CLI + Buildx
- 安装 Docker CLI + Buildx,不安装 dockerd(避免与 Containerd 冲突)
bash
1 登录 app 机器
ssh ubuntu@192.168.56.110
2. 安装 Docker CLI(仅客户端,不装 dockerd)
sudo apt update
3 添加阿里云 Docker GPG 密钥
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
4 添加阿里云 Docker APT 源(noble = Ubuntu 24.04)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu noble stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
5 安装 docker-cli 和 buildx(用于构建镜像)
sudo apt update
sudo apt install -y docker-buildx-plugin docker-cli
6 验证(应只有 Client,无 Server)
docker version

b. 克隆项目并构建镜像
bash
# 克隆你的 Flask loveTianWen论坛项目
git clone https://gitee.com/yourname/Forum-platform.git
cd Forum-platform
# 确保包含 PyMySQL(Ubuntu 24.04 推荐)
echo "PyMySQL" >> requirements.txt
c. 创建 Dockerfile (ubuntu)
yaml
cd /Forum-platform
cat << 'EOF' | sudo tee Dockerfile > /dev/null
# 使用国内加速的 Python 3.10 + Debian 12 (bookworm)
FROM docker.m.daocloud.io/library/python:3.10-slim-bookworm
WORKDIR /app
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 使用Python的PyMySQL,不需要系统MySQL库
COPY requirements.txt .
RUN pip install --no-cache-dir \
-i http://mirrors.aliyun.com/pypi/simple/ \
--trusted-host mirrors.aliyun.com \
--timeout=300 \
--retries=3 \
-r requirements.txt && \
pip check # 检查依赖冲突
# 完全跳过系统依赖安装
# 如果你的应用使用PyMySQL,它不需要系统MySQL库
COPY . .
# 创建非root用户(安全最佳实践)
RUN groupadd -r appuser && useradd -r -g appuser -u 1001 appuser && \
chown -R appuser:appuser /app
USER appuser
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "app:app"]
EOF
创建 Dockerfile (Alibaba Cloud Linux 3,可选)
- Alibaba Cloud Linux 3,兼容 CentOS/RHEL 8,可以使用 yum/dnf 命令
bash
# 使用国内加速的 Python 3.10 + Debian 12 (bookworm)
FROM docker.m.daocloud.io/library/python:3.10-slim-bookworm
WORKDIR /app
# 【关键修复】手动写入阿里云 APT 源(因为 slim 镜像没有 sources.list)
RUN echo "deb https://mirrors.aliyun.com/debian/ bookworm main" > /etc/apt/sources.list && \
echo "deb https://mirrors.aliyun.com/debian-security/ bookworm-security main" >> /etc/apt/sources.list && \
echo "deb https://mirrors.aliyun.com/debian/ bookworm-updates main" >> /etc/apt/sources.list && \
apt-get update && \
apt-get install -y --no-install-recommends \
gcc \
default-libmysqlclient-dev \
curl \
&& rm -rf /var/lib/apt/lists/*
# 安装 Python 依赖(清华源)
COPY requirements.txt .
RUN pip install --no-cache-dir \
-i https://pypi.tuna.tsinghua.edu.cn/simple \
--trusted-host pypi.tuna.tsinghua.edu.cn \
-r requirements.txt
# 复制代码
COPY . .
EXPOSE 5000
# 启动 Gunicorn(确保 app.py 中有 app = Flask(__name__))
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "app:app"]
d. 构建docker镜像
docker compose 命令构建
- 第一次构建
bash
方案1:最简方式(推荐)
docker compose up -d --build
方案2:分步执行
docker compose build # 构建应用镜像 + 拉取数据库镜像
docker compose up -d # 创建并启动所有容器
查看本地所有镜像,过滤包含 "forum" 的行
docker images | grep forum
- 第一次没构建好时,再次构建流程
bash
1 开发环境完整重建流程
docker compose down # 停止并清理所有容器
docker compose build # 重新构建镜像
docker compose up -d # 后台启动所有服务
2 仅重建特定服务(不停止其他服务)
docker compose build forum-app # 只构建app镜像
docker compose up -d --no-deps forum-app # 重启app服务
3. 查看本地所有镜像,过滤包含 "forum" 的行
docker images | grep forum
错误1: permission denied while trying to connect to the Docker daemon
socket 当前用户 ubuntu 不在 docker 用户组,无法直接使用 Docker。
bash
# 1、将用户 ubuntu 加入 docker 组
sudo usermod -aG docker ubuntu
# 2、然后 重新登录终端(或执行)
newgrp docker
第一次构建成功后,验证报错
问题:构建成功后,验证报错 报错:500 Internal Server Error
原因:
应用尝试连接 MySQL 数据库,地址是localhost,但在 Docker 容器内,localhost 指的是 容器自己,而MySQL 实际运行在宿主机(ECS)上,所以连接被拒绝(Connection refused)。
方法:
使用docker-compose.yml 实现MySQL 数据库容器化
- 应用容器(forum-app)在docker, 数据库(MariaDB)跑在宿主机, 这种架构叫 "混合部署" ------ 不是纯容器化,是 容器 +宿主机服务依赖。 所以把数据库也容器化,并用 Docker 网络互联

e 方法 docker-compose.yml 实现全容器化
- 使用 docker-compose.yml 实现全容器化
修改架构

bash
优势:
不依赖宿主机任何服务
别人 git clone + docker-compose up 就能跑
本地开发、测试、生产环境一致
可轻松迁移到任何支持 Docker 的机器
最终方案:
使用 docker-compose.yml 实现全容器化
1 把 MySQL/MariaDB 也放进容器
2 使用 docker-compose 管理两个服务
3 所有配置通过 .env 文件或命令行传入
4 提供一键部署脚本(自动创建文件)
Step 1:创建 .env 文件(所有配置都在这里)
bash
cd /home/Forum-platform
sudo tee .env > /dev/null <<'EOF'
# ==== MariaDB 容器专用环境变量 ====
# 数据库服务主机名(在 Docker 网络中,其他容器通过此名访问)
DB_HOST=forum-db
# 数据库端口(容器内部默认 3306)
DB_PORT=3306
# 数据库用户名(root 是默认超级用户)
DB_USER=root
# root 密码留空(配合下一行允许空密码)
DB_PASSWORD=
# 应用使用的数据库名
DB_NAME=zhiliaooa
# 【关键】允许 root 用户无密码登录(仅限开发/测试!)
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=yes
# 容器启动时自动创建的数据库名(与 DB_NAME 一致)
MARIADB_DATABASE=zhiliaooa
EOF
Step 2:创建 docker-compose.yml(核心部署文件)
- cd /home/Forum-platform/docker-compose.yml
1 /dev/null 的作用是:屏蔽 tee 命令的输出
2 注释掉端口ports: - "3306:3306" , 不需要从外部访问数据库,直接在 docker-compose.yml 中移除端口映射,避免端口冲突问题。
bash
sudo tee docker-compose.yml > /dev/null <<'EOF'
version: '3.8'
services:
# ===== 数据库服务:MariaDB =====
forum-db:
image: mariadb:10.6 # 使用 MariaDB 10.6 官方镜像
container_name: forum-db # 容器命名为 forum-db(方便调试)
environment:
- MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=yes # 允许 root 用户无密码(仅限开发!)
- MARIADB_DATABASE=zhiliaooa # 启动时自动创建名为 zhiliaooa 的数据库
#ports:
#- "3306:3306" # 将容器 3306 端口映射到宿主机(方便本地连接)
volumes:
- mysql_data:/var/lib/mysql # 持久化数据库数据,避免重启丢失
restart: always # 容器随 Docker 自启
command: --default-authentication-plugin=mysql_native_password # 兼容旧版 MySQL 客户端
# ===== 应用服务:Flask + Gunicorn =====
forum-app:
build: . # 从当前目录的 Dockerfile 构建镜像
image: flask-forum:1.0 # 新增显式指定镜像名,之前是默认名
container_name: forum-app # 容器命名为 forum-app
ports:
- "${APP_PORT:-5000}:5000" # 映射端口:默认 5000,可通过 .env 中 APP_PORT 覆盖
env_file:
- .env # 加载 .env 文件作为环境变量(供 Flask 读取)
depends_on:
- forum-db # 启动前等待 forum-db 就绪(注意:不保证 DB 已初始化完成)
restart: always # 容器崩溃或系统重启后自动恢复
# ===== 数据卷声明 =====
volumes:
mysql_data: # 声明一个命名卷,用于持久化 MariaDB 数据
EOF
Step 3:运行脚本 (ubuntu版)
bash
1. 安装 docker-compose(Ubuntu 推荐方式)
sudo apt update
sudo apt install -y docker-compose-plugin
2. 启动服务
sudo docker compose down
sudo docker compose up -d --build
3. 查看日志
sudo docker logs forum-app
sudo docker logs forum-db
4. 测试
curl http://localhost:8000
阿里云ecs中可用另一种方式,先创建一键部署脚本 deploy.sh(可选)
- Alibaba Cloud Linux 3:兼容CentOS/RHEL 8,可以使用 yum/dnf 命令
bash
sudo tee deploy.sh > /dev/null <<'EOF'
#!/bin/bash
set -e
echo "开始部署 Forum 平台(纯容器化,无需宿主机数据库)"
# === 检查是否安装 Docker ===
if ! command -v docker &> /dev/null; then
echo " Docker 未安装,请先安装:"
echo " sudo yum install -y docker"
exit 1
fi
# === 启动 Docker 服务 ===
if ! sudo systemctl is-active --quiet docker; then
echo "启动 Docker 服务..."
sudo systemctl start docker
fi
# === 检查是否支持 docker compose ===
if ! docker compose version &> /dev/null; then
echo "安装 docker compose 插件..."
sudo mkdir -p ~/.docker/cli-plugins/
sudo curl -L https://get.daocloud.io/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \
-o ~/.docker/cli-plugins/docker-compose
sudo chmod +x ~/.docker/cli-plugins/docker-compose
fi
# === 构建并启动应用 ===
echo "构建镜像并启动服务..."
sudo docker compose down 2>/dev/null || true
sudo docker compose up -d --build
echo ""
echo "部署成功!访问 http://localhost:${APP_PORT:-5000}"
echo "提示:修改配置请编辑 .env 文件"
echo "再次运行此脚本将重启服务"
EOF
- 运行部署脚本 (Alibaba Cloud Linux 3)
bash
1 赋予执行权限
sudo chmod +x deploy.sh
2 运行部署脚本
sudo ./deploy.sh
f. 验证docker镜像构建是否成功
- 快速测试
bash
1 启动容器,映射 8000 端口,--rm退出后自动清理容器
docker run --rm -p 8000:8000 flask-forum:1.0
- 后台运行 + 自动化验证
bash
#!/bin/bash
1 启动容器(后台模式,命名为 forum-test)
sudo docker run -d --name forum-test -p 5000:5000 flask-forum:1.0
2 等待 2 秒,让 Gunicorn 完成启动
sleep 2
3 查看日志,没有ImportError、DB 连接失败等
sudo docker logs forum-test
4 查看容器是否正在运行
sudo docker ps
5 本地访问测试(应返回 HTML 页面)
curl -v http://localhost:5000
6 清理测试容器(停止并删除)
sudo docker stop forum-test && sudo docker rm forum-test
- 部署到正式环境后,再次确认服务健康
bash
1. 查看容器是否正在运行
sudo docker ps
2. 在服务器本地测试访问
curl http://localhost:5000
3. 从外部浏览器访问(替换为你的公网 IP)
http://47.96.22.96:5000
g. 推送镜像到阿里云 ACR 镜像仓库
前提条件:
登录阿里云 ACR 镜像仓库:https://www.alibabacloud.com 开通 容器镜像服务 ACR(个人版免费)
获得账密,地址:
1、Registry 地址:crpi-ua3er91ww0y2dq1i.cn-shenzhen.personal.cr.aliyuncs.com
2、用户名:username
3、密码:固定密码

- 在终端登录 ACR
bash
替换为自己的yourname,Registry
docker login --username=yourname crpi-ua3er91ww0y2dq1i.cn-shenzhen.personal.cr.aliyuncs.com
2 重命名(Tag)本地镜像为 ACR 格式
- 在 ACR 控制台 → 个人实例 → 命名空间 → 创建命名空间(如:mirrors-yuan)
bash
原始镜像名:flask-forum:1.0
目标镜像名:crpi-ua3er91ww0y2dq1i.cn-shenzhen.personal.cr.aliyuncs.com/mirrors-yuan/flask-forum:1.0
1. 将 admin 加入 docker 组
sudo usermod -aG docker admin
2. 退出当前 SSH,重新登录修改才生效
3. 查看当前镜像
docker ps
docker images
4. 打标签
docker tag flask-forum:1.0 crpi-ua3er91ww0y2dq1i.cn-shenzhen.personal.cr.aliyuncs.com/mirrors-yuan/flask-forum:1.0
5. 推送到个人acr
docker push crpi-ua3er91ww0y2dq1i.cn-shenzhen.personal.cr.aliyuncs.com/mirrors-yuan/flask-forum:1.0
- 删除弃用容器和镜像
bash
# 1. 查看当前所有容器
docker ps -a
# 2. 删除所有已停止的容器(释放对旧镜像的引用)
docker container prune -f
# 2.1:手动删除指定容器
docker rm 56a516e777c6 21013466a0b0
# 3. 删除不需要的旧镜像(按名称指定,避免误删)
docker rmi forum-app:latest my-flask-forum:latest 2>/dev/null || echo "部分镜像不存在,已跳过"
# 4. 清理悬空镜像(<none> 标签的中间层或未引用镜像)
docker image prune -f
# 5.查看剩余镜像
docker images
h. 从阿里云 ACR 仓库拉取flask-forum:1.0镜像到本地
flask-forum:1.0私有镜像地址:
crpi-ua3er91ww0y2dq1i.cn-shenzhen.personal.cr.aliyuncs.com/mirrors-yuan/flask-forum:1.0
- 登录阿里云 ACR
bash
1 登录 ACR 公网地址(替换 YOUR_USERNAME 为你的阿里云账号全名)
sudo docker login --username=YOUR_USERNAME crpi-ua3er91ww0y2dq1i.cn-shenzhen.personal.cr.aliyuncs.com
2 拉取镜像
sudo docker pull crpi-ua3er91ww0y2dq1i.cn-shenzhen.personal.cr.aliyuncs.com/mirrors-yuan/flask-forum:1.0
3 (可选)给镜像打一个简洁标签(方便后续使用)比如 flask-forum:latest
sudo docker tag crpi-ua3er91ww0y2dq1i-vpc.cn-shenzhen.personal.cr.aliyuncs.com/mirrors-yuan/flask-forum:1.0 flask-forum:latest
4 测试运行(验证是否成功)
sudo docker run -d --name test-app -p 5000:5000 flask-forum:latest
5 查看是否运行
sudo docker ps | grep test-app
6 测试访问(如果本机有 curl)
curl http://localhost:5000
问题汇总
问题1:admin用户没有权限操作问题
WARNING! Your password will be stored unencrypted in
/home/admin/.docker/config.json. Configure a credential helper to
remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Error saving credentials: open
/home/admin/.docker/config.json4100422755: permission denied
已经成功登录了 ACR,但 Docker 在保存凭证时因权限问题失败;
执行 docker login 时,Docker 尝试写入 /home/admin/.docker/config.json
然而该目录或文件 权限不足(admin用户没有权限操作)
方法:
bash
1 创建目录(如果不存在)
mkdir -p /home/admin/.docker
2 修复权限:确保 admin 用户拥有该目录
sudo chown -R admin:admin /home/admin/.docker
sudo chmod 700 /home/admin/.docker
3 重新登录 ACR
cd /home/Forum-platform
docker login --username="yourname" \
crpi-ua3er91ww0y2dq1i.cn-shenzhen.personal.cr.aliyuncs.com
4 验证是否成功
cat /home/admin/.docker/config.json
问题2:设置修复 DNS
加 sudo 后执行命令
lookup registry-1.docker.io on [::1]:53: read udp [::1]:44570->[::1]:53: read: connection refused DNS 解析失败!系统试图用 IPv6的 localhost([::1]),查 DNS,但本地没有 DNS 服务(如 systemd-resolved 没运行或配置错误)。
Ubuntu 24.04 使用 systemd-resolved,但可能未启用。启用并配置:
bash
1、启用并启动 resolved
sudo systemctl enable --now systemd-resolved
2、设置修复 DNS
sudo resolvectl dns enp0s3 8.8.8.8 114.114.114.114
sudo resolvectl dns enp0s8 8.8.8.8 114.114.114.114
3、允许 fallback 到传统 /etc/resolv.conf
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
问题3:拉取镜像超时
Docker在尝试从Docker Hub拉取镜像时遇到了超时问题。
具体错误是: context deadline exceeded 和 Client.Timeout exceeded while awaiting headers。Docker遇到了网络连接问题,无法访问 Docker Hub
配置 Docker 镜像加速器,更换新镜像源
- 方法:使用阿里云镜像加速器,替换docker默认的官方镜像站https://registry-1.docker.io

- 配置Docker镜像加速器以及DaoCloud镜像,轩辕镜像:
bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://xxx.mirror.aliyuncs.com",
"https://docker.m.daocloud.io",
"https://docker.xuanyuan.me",
"https://docker.imgdb.de",
"https://docker-0.unsee.tech"
]
}
EOF
# 重新加载配置并重启 Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证配置
sudo systemctl status docker
docker info | grep -i mirror
Docker镜像源配置指南:https://blog.csdn.net/sinat_42699064/article/details/149903610

问题4:docker-compose: command not found
原因:系统已安装 Docker( Docker version 26.1.3),但 未安装 docker-compose 工具。
从 Docker v20.10 起,官方推荐使用 docker compose(空格) 作为插件形式,而非独立的 docker-compose(横杠)二进制。
- 方法:启用 docker compose 插件(国内加速)
bash
1. 下载 docker-compose 插件(使用 DaoCloud 国内镜像加速)
sudo mkdir -p ~/.docker/cli-plugins/
sudo curl -L https://get.daocloud.io/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \
-o ~/.docker/cli-plugins/docker-compose
2. 赋予执行权限
sudo chmod +x ~/.docker/cli-plugins/docker-compose
3. 验证安装
docker compose version
输出示例:Docker Compose version v2.27.0
问题5:5000 端口已经被占用了。
Error response from daemon: driver failed programming external connectivity on endpoint forum-app (...):
Bind for 0.0.0.0:5000 failed: port is already allocated
表面原因:5000 端口被占用,Bind for 0.0.0.0:5000 failed: port is already allocated
深层原因: Docker 的 docker-proxy 进程未完全退出; Docker 内部仍保留端口映射状态;即使容器已删除,iptables 规则或虚拟网络未清理干净;
手动 pkill docker-proxy 无效 ------ 因为 Dockerdaemon 会认为端口仍在使用中。

方法:
bash
sudo ss -tulnp | grep :5000

- 彻底停止并清理所有相关容器
重启 Docker 服务(强制释放所有端口和网络)
bash
1 Docker 重启后会清空所有 docker-proxy、iptables 规则、虚拟网卡等。
sudo systemctl restart docker
2 检查是否还有进程占用 5000
sudo ss -tulnp | grep :5000
3 重新部署
sudo ./deploy.sh
问题6:MySQL 官方镜像禁止通过 MYSQL_USER=root
部署后访问应用返回 500 错误 docker ps: 容器不断重启 → 无法解析 forum-db → Flask 连不上数据库。
forum-db 启动失败!
bash
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'forum-db' ([Errno -2] Name or service not known)")
18b01af6f2d8 mysql:8.0 ... Restarting (1) ...
查看日志
sudo docker logs forum-db
[ERROR] [Entrypoint]: MYSQL_USER="root", MYSQL_USER and MYSQL_PASSWORD are for configuring a regular user and cannot be used for the root user
- 原因:MySQL 官方镜像禁止通过 MYSQL_USER=root 设置 root 用户!
- 方法:切换到 MariaDB + 无密码
bash
#!/bin/bash
cd /home/Forum-platform
1. 备份配置
sudo cp docker-compose.yml docker-compose.yml.bak.$(date +%s)
2. 替换镜像为 mariadb:10.6
sudo sed -i 's|image: mysql:8.0|image: mariadb:10.6|g' docker-compose.yml
3. 写入正确的 .env(无密码)
cat > .env << 'EOF'
DB_HOST=forum-db
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_NAME=zhiliaooa
# MariaDB 初始化参数
MYSQL_ALLOW_EMPTY_PASSWORD=yes
MYSQL_DATABASE=zhiliaooa
EOF
4. 清理旧数据(避免残留配置冲突)
sudo docker compose down
sudo docker volume rm -f forum-platform_mysql_data 2>/dev/null || true
5. 重新部署
sudo ./deploy.sh
问题7:数据库连上了,但表不存在!
bash
pymysql.err.ProgrammingError: (1146, "Table 'zhiliaooa.question' doesn't exist")
原因:数据库 zhiliaooa 已创建; 但 Flask 应用未执行数据库迁移,表结构为空。
方案:手动执行数据库迁移
- 进入应用容器,运行迁移命令
bash
1 进入 Flask 容器
sudo docker exec -it forum-app bash
2 执行数据库升级
flask db upgrade
3 执行后,question 等表将被自动创建,应用恢复正常。
4. 在服务器本地测试访问
curl http://localhost:5000
5. 从外部浏览器访问(公网 IP)
http://47.96.22.96:5000
or
http://192.168.56.100:5000
问题 8:docker-compose.yml 中 environment 重复定义
bash
forum-db:
environment:
- MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=yes
- MARIADB_DATABASE=zhiliaooa
# ... 其他配置
environment: # 重复定义!
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
问题:YAML 不允许同名键重复,后一个 environment 会覆盖前一个,导致 MARIADB_* 变量失效。
原因:MariaDB 官方镜像要求使用 MARIADB_* 环境变量初始化数据库;而 MYSQL_* 是 MySQL 镜像的变量,在
MariaDB 中部分兼容但不保证生效。
方法:合并所有环境变量,统一使用 MARIADB_* 前缀,并从 .env 文件读取配置。