Dockerfile 常见编写方法
- 基础镜像选择:选择一个合适的基础镜像作为起点。
- 工作目录设置 :使用
WORKDIR
指令设置工作目录。 - 依赖安装 :使用
RUN
指令安装必要的依赖。 - 文件复制 :使用
COPY
或ADD
指令将本地文件复制到镜像中。 - 环境变量设置 :使用
ENV
指令设置环境变量。 - 暴露端口 :使用
EXPOSE
指令声明容器运行时需要监听的端口。 - 启动命令 :使用
CMD
或ENTRYPOINT
指令指定容器启动时要运行的命令。
常用指令
-
FROM:
- 用途:指定基础镜像。
- 示例:
FROM python:3.9-slim
-
WORKDIR:
- 用途:设置工作目录。
- 示例:
WORKDIR /app
-
RUN:
- 用途:执行命令并创建新的镜像层。
- 示例:
RUN pip install -r requirements.txt
-
COPY:
- 用途:将文件或目录从主机复制到镜像中的指定位置。
- 示例:
COPY . /app
-
ADD:
- 用途:类似于
COPY
,但支持自动解压压缩文件。 - 示例:
ADD myapp.tar.gz /app
- 用途:类似于
-
ENV:
- 用途:设置环境变量。
- 示例:
ENV MY_ENV_VAR=my_value
-
EXPOSE:
- 用途:声明容器运行时需要监听的端口。
- 示例:
EXPOSE 8000
-
CMD:
- 用途:指定容器启动时要运行的默认命令。
- 示例:
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
-
ENTRYPOINT:
- 用途:指定容器启动时要运行的命令,通常与
CMD
结合使用。 - 示例:
ENTRYPOINT ["uwsgi", "--ini", "uwsgi.ini"]
- 用途:指定容器启动时要运行的命令,通常与
-
VOLUME:
- 用途:创建挂载点,用于数据持久化。
- 示例:
VOLUME /data
Django + uWSGI 的最佳实践
假设你的项目结构如下:
my-django-app/
├── docker-compose.yml
├── Dockerfile
├── requirements.txt
├── uwsgi.ini
└── src/
└── manage.py
└── my_django_app/
└── settings.py
└── wsgi.py
Dockerfile
文件
Dockerfile
# 使用官方Python基础镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制项目代码
COPY . .
# 安装uWSGI
RUN pip install uwsgi
# 创建日志目录
RUN mkdir -p /var/log/uwsgi
# 设置环境变量
ENV DJANGO_SETTINGS_MODULE=my_django_app.settings
# 暴露端口
EXPOSE 8000
# 默认命令
CMD ["uwsgi", "--ini", "uwsgi.ini"]
requirements.txt
文件
确保你的 requirements.txt
文件包含所有必要的依赖项,例如:
Django==3.2.12
uwsgi==2.0.20
mysqlclient==2.0.3
redis==3.5.3
uwsgi.ini
文件
以下是一个简单的 uWSGI 配置文件示例:
ini
[uwsgi]
module = my_django_app.wsgi:application
master = true
processes = 4
socket = :8000
chmod-socket = 660
vacuum = true
die-on-term = true
logto = /var/log/uwsgi/uwsgi.log
docker-compose.yml
文件
为了方便管理和部署,可以使用 docker-compose.yml
文件来定义服务:
yaml
version: '3.8'
services:
db:
image: mysql:5.7
container_name: django_db
environment:
MYSQL_ROOT_PASSWORD: example_root_password
MYSQL_DATABASE: django_db
MYSQL_USER: django_user
MYSQL_PASSWORD: example_django_password
volumes:
- db_data:/var/lib/mysql
networks:
- django-net
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 3
start_period: 10s
restart: unless-stopped
redis:
image: redis:alpine
container_name: django_redis
networks:
- django-net
restart: unless-stopped
web:
build: .
container_name: django_web
ports:
- "8000:8000"
environment:
DJANGO_DB_HOST: db
DJANGO_DB_NAME: django_db
DJANGO_DB_USER: django_user
DJANGO_DB_PASSWORD: example_django_password
REDIS_HOST: redis
depends_on:
- db
- redis
networks:
- django-net
restart: unless-stopped
networks:
django-net:
driver: bridge
volumes:
db_data:
具体部署命令
-
构建和启动服务:
bashdocker-compose up -d
-
查看服务状态:
bashdocker-compose ps
-
停止服务:
bashdocker-compose down
-
重启服务:
bashdocker-compose restart <service_name>
例如,重启
web
服务:bashdocker-compose restart web
-
重新构建并启动服务 (如果修改了
docker-compose.yml
或Dockerfile
):bashdocker-compose up -d --build