Appearance
部署 Python
Flask 应用示例
python
# app.py
from flask import Flask, jsonify
import os
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello from Python Flask in Docker!'
@app.route('/health')
def health():
return jsonify(status='ok')
if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)Dockerfile(Flask)
dockerfile
FROM python:3.12-slim
# 环境变量
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PORT=5000
# 创建非 root 用户
RUN groupadd --system appgroup && \
useradd --system --group appgroup appuser
WORKDIR /app
# 安装依赖(先复制 requirements.txt 利用缓存)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY --chown=appuser:appgroup . .
USER appuser
EXPOSE 5000
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:5000/health')"
CMD ["python", "app.py"]生产环境用 Gunicorn
dockerfile
FROM python:3.12-slim AS runtime
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
RUN groupadd --system app && useradd --system --group app appuser
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt gunicorn
COPY --chown=appuser:app . .
USER appuser
EXPOSE 8000
CMD ["gunicorn", \
"--bind", "0.0.0.0:8000", \
"--workers", "4", \
"--worker-class", "sync", \
"--timeout", "60", \
"--access-logfile", "-", \
"app:app"]Django 应用 Dockerfile
dockerfile
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
DJANGO_SETTINGS_MODULE=myproject.settings.production
WORKDIR /app
RUN apt-get update && apt-get install -y \
libpq-dev gcc \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN python manage.py collectstatic --noinput
EXPOSE 8000
CMD ["gunicorn", "myproject.wsgi:application", \
"--bind", "0.0.0.0:8000", "--workers", "4"]Docker Compose(Django + PostgreSQL)
yaml
services:
web:
build: .
restart: unless-stopped
command: >
sh -c "python manage.py migrate &&
gunicorn myproject.wsgi:application --bind 0.0.0.0:8000"
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://postgres:secret@db:5432/mydb
SECRET_KEY: ${DJANGO_SECRET_KEY}
DEBUG: "False"
volumes:
- static-files:/app/staticfiles
- media-files:/app/media
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: mydb
POSTGRES_USER: postgres
POSTGRES_PASSWORD: secret
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
retries: 5
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- static-files:/static:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- web
volumes:
postgres-data:
static-files:
media-files:多阶段构建优化
dockerfile
# 阶段一:安装依赖
FROM python:3.12-slim AS builder
WORKDIR /build
RUN apt-get update && apt-get install -y gcc libpq-dev \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# 阶段二:运行时
FROM python:3.12-slim AS runtime
RUN apt-get update && apt-get install -y libpq5 \
&& rm -rf /var/lib/apt/lists/*
RUN groupadd --system app && useradd --system --group app appuser
WORKDIR /app
# 从 builder 阶段复制已安装的包
COPY --from=builder --chown=appuser:app /root/.local /home/appuser/.local
COPY --chown=appuser:app . .
USER appuser
ENV PATH=/home/appuser/.local/bin:$PATH \
PYTHONUNBUFFERED=1
EXPOSE 8000
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]常见问题
pip 安装慢
使用国内镜像:
dockerfile
RUN pip install --no-cache-dir \
-i https://pypi.tuna.tsinghua.edu.cn/simple \
-r requirements.txt时区问题
dockerfile
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone