目标

把现有 flask_blog(run.py + uwsgi + MySQL)装进一个容器先跑起来,MySQL 仍用宿主机,验证后再做 Compose 全栈。

1. 写 Dockerfile

项目 Python 3.13,依赖含 uwsgi / Pillow / pymysql,视频处理还调用 ffmpeg/ffprobe,所以基础镜像要装 ffmpeg。

FROM python:3.13-slim
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg build-essential \
 && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENV FLASK_CONFIG=production
EXPOSE 5000
CMD ["uwsgi", "--http", "0.0.0.0:5000", "--module", "run:app", "--processes", "2", "--threads", "2"]

注意:生产容器用 --http 而不是你现在 uwsgi.ini 里的 socket,socket 是给同一宿主机 Nginx 用的,进容器后改 http 最省事。

2. 环境变量

SECRET_KEY=xxx
DATABASE_URL=mysql+pymysql://strli:xxx@host.docker.internal/flask_blog
ADMIN_API_KEY=xxx

容器连宿主机 MySQL 用 host.docker.internal(Linux 需 --add-host=host.docker.internal:host-gateway),并确认 MySQL 允许远程用户。

3. 构建运行

docker build -t flask-blog:single .
docker run -d --name blog \
  --add-host=host.docker.internal:host-gateway \
  --env-file .env.docker -p 5000:5000 \
  -v $(pwd)/app/static/uploads:/app/app/static/uploads \
  -v $(pwd)/app/static/thumbnails:/app/app/static/thumbnails \
  flask-blog:single
docker logs -f blog

4. 验证

打开 http://服务器IP:5000/ 看列表,/admin/login 进后台发一篇测试文章,检查封面缩略图是否生成。注意 uploads/thumbnails 已挂 volume,删容器不丢图。

踩坑

  • Pillow 在 slim 镜像需 build-essential,或直接用 wheels,一般可装上,失败再加 libjpeg-dev zlib1g-dev。
  • 视频上传 1GB:保持 MAX_CONTENT_LENGTH 和 uwsgi limit-post/http-timeout 一致。
  • 首次启动先 flask db upgrade && flask create-admin,可做成 entrypoint。

下一篇:Compose 一键起 web + mysql,数据卷、初始化、备份。