快速导航

引言

一个简单的网页应用(Python 写的)
用户可以提交留言,数据存到 MySQL 数据库里,
即使删除容器,留言也不会丢失(靠 volume 持久化)。

准备工作

用到两个容器,一个是mysql容器,用于存储留言数据,需要用volume持久化数据(避免删容器丢数据)
一个是python容器(自己编写dockerfile)运行网页程序,需要连接MySQL容器,读取/写入留言

步骤1:创建 MySQL 容器(搭建数据库)

#创建一个专门存MySQL数据的卷
docker volume create mysql-data


启动MySQL容器
docker run -d \
--name mymysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=message_board \
-v mysql-data:/var/lib/mysql \
-p 3306:3306 \
mysql:5.7

#数据库持久化:用 docker volume create 创建命名卷,
#挂载到 MySQL 的/var/lib/mysql(这是 MySQL 存储数据的默认目录),
#确保容器删除后数据不丢。


验证 MySQL 是否启动成功
docker logs mymysql


步骤2:准备 Python 留言板应用(简单的python代码,基于flask框架)

在本地创建应用目录并写代码
# 创建存放应用代码的目录
mkdir -p /root/message-board
cd /root/message-board


创建一个 Python 文件(app.py),功能是:显示留言表单→提交后存到 MySQL→展示所有留言


cat > app.py << 'EOF'
from flask import Flask, request, render_template_string, redirect, url_for
import pymysql
import os

app = Flask(__name__)

# 从环境变量获取MySQL连接信息
db_host = os.getenv('DB_HOST', 'mymysql')
db_user = os.getenv('DB_USER', 'root')
db_password = os.getenv('DB_PASSWORD', '123456')
db_name = os.getenv('DB_NAME', 'message_board')

# 初始化数据库,创建留言表(如果不存在)
def init_db():
    conn = pymysql.connect(host=db_host, user=db_user, password=db_password, db=db_name)
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS messages (
            id INT AUTO_INCREMENT PRIMARY KEY,
            content TEXT NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')
    conn.commit()
    conn.close()

# 首页:处理留言提交和展示
@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        # 获取表单提交的留言内容
        content = request.form.get('content')
        if content:  # 确保内容不为空
            # 连接数据库并插入留言
            conn = pymysql.connect(host=db_host, user=db_user, password=db_password, db=db_name)
            cursor = conn.cursor()
            cursor.execute('INSERT INTO messages (content) VALUES (%s)', (content,))
            conn.commit()
            conn.close()
        # 提交后重定向到首页(避免刷新重复提交)
        return redirect(url_for('index'))
    
    # 读取所有历史留言
    conn = pymysql.connect(host=db_host, user=db_user, password=db_password, db=db_name)
    cursor = conn.cursor()
    cursor.execute('SELECT content, created_at FROM messages ORDER BY created_at DESC')
    messages = cursor.fetchall()
    conn.close()
    
    # 渲染网页
    return render_template_string('''
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title>留言板</title>
        </head>
        <body>
            <h1>留言板</h1>
            <form method="POST">
                <textarea name="content" rows="3" cols="50" placeholder="请输入留言..."></textarea><br>
                <button type="submit">提交</button>
            </form>
            <hr>
            <h3>历史留言</h3>
            {% for msg in messages %}
                <p>{{ msg[1] }}:{{ msg[0] }}</p>
            {% endfor %}
        </body>
        </html>
    ''', messages=messages)

if __name__ == '__main__':
    init_db()  # 启动时初始化数据库
    app.run(host='0.0.0.0', port=5000)  # 允许外部访问
EOF






创建依赖文件(告诉 Python 需要安装哪些库)
cat > requirements.txt << 'EOF'
flask==2.0.1
werkzeug==2.0.3  # 新增这行,指定兼容版本
pymysql==1.0.2
EOF

步骤3:构建 Python 应用镜像

自定义镜像:用 Dockerfile 把应用代码和依赖打包成镜像,实现 “一次构建,到处运行”。

cat > Dockerfile << 'EOF'
# 基础镜像:Python 3.9
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY app.py .
# 暴露应用端口(Flask默认5000)
EXPOSE 5000
# 启动命令
CMD ["python", "app.py"]
EOF




构建镜像
# 在/root/message-board目录下执行,构建一个叫message-app的镜像
docker build -t message-app:v1 .

步骤4:启动 Python 应用容器(连接 MySQL)

docker run -d \
--name myapp \
-p 5000:5000 \
-e DB_HOST=mymysql \
-e DB_PASSWORD=123456 \
-e DB_NAME=message_board \
--link mymysql:mymysql \
message-app:v1

说明:
docker run -d \
--name myapp \  # 容器名
 -p 5000:5000 \  # 端口映射(主机5000→容器5000)
 # 环境变量:告诉应用如何连接MySQL(和前面MySQL的配置对应)
 -e DB_HOST=mymysql \  # 数据库主机名=MySQL容器名(Docker内部可直接用容器名通信)
 -e DB_PASSWORD=123456 \
-e DB_NAME=message_board \
 --link mymysql:mymysql \  # 链接到MySQL容器(让两个容器在同一网络)
  message-app:v1  # 用刚才构建的镜像

步骤5:验证应用功能与数据持久化

访问 服务器IP:5000,会看到一个留言板页面,输入一条留言hello提交:
在这里插入图片描述

测试数据持久化:

# 删掉应用容器再重建(模拟容器故障)
docker rm -f myapp
# 重新启动应用容器(新容器,但数据还是旧数据,验证数据一致性)
docker run -d --name myapp -p 5000:5000 -e DB_HOST=mymysql -e DB_PASSWORD=123456 -e DB_NAME=message_board --link mymysql:mymysql message-app:v1

再次刷新页面,发现数据还在:

在这里插入图片描述
因为数据存在 MySQL 的 volume 里,没丢
说明数据确实通过 MySQL 的命名卷持久化了

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐