第一篇: 使用Docker部署flask项目(Flask + DB 容器化)

python-flask项目开发:

  1. flask开发完整过程总结:https://blog.csdn.net/qq_38444844/article/details/151928286?spm=1011.2415.3001.5331
  2. 项目源码:https://gitee.com/loveTianWen/Forum-platform/tree/master
  3. 第二篇: 部署 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
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(可选)

  1. 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
  1. 运行部署脚本 (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、密码:固定密码

  1. 在终端登录 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
  1. 删除弃用容器和镜像
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镜像加速器以及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 文件读取配置。

相关推荐
Q_Q19632884756 小时前
python大学生爱心校园互助代购网站_nyvlx_django Flask vue pycharm项目
python·django·flask
Deng9452013146 小时前
Vue + Flask 前后端分离项目实战:从零搭建一个完整博客系统
前端·vue.js·flask
码农阿豪6 小时前
Python Flask应用中文件处理与异常处理的实践指南
开发语言·python·flask
xcLeigh6 小时前
Python 项目实战:用 Flask 实现 MySQL 数据库增删改查 API
数据库·python·mysql·flask·教程·python3
威迪斯特6 小时前
Flask:轻量级Web框架的技术本质与工程实践
前端·数据库·后端·python·flask·开发框架·核心架构
xu_yule6 小时前
Redis存储(15)Redis的应用_分布式锁_Lua脚本/Redlock算法
数据库·redis·分布式
一灰灰blog6 小时前
Spring AI中的多轮对话艺术:让大模型主动提问获取明确需求
数据库·人工智能·spring
Nandeska7 小时前
15、基于MySQL的组复制
数据库·mysql
AllData公司负责人7 小时前
AllData数据中台-数据同步平台【Seatunnel-Web】整库同步MySQL同步Doris能力演示
大数据·数据库·mysql·开源