昨天折腾了一下用Docker部署Django+redis+MySQL的项目,顺便压缩了一下之前不使用数据库的Django的项目的镜像大小。
配置文件 推荐使用alang/django
,一个是因为官方几年前就停止更新了,另一个是如果通过python的镜像进行构建,构建出来的镜像会比较大,大概1G多,而由于这个镜像是基于alpine
构建的,大概在300M左右(用python的alpine
构建也可以,但如果需要用gunicorn
启动的话得自己配置,比较麻烦。)
Dockerfile FROM alang/django:4.1 WORKDIR /usr/django/app COPY requirements.txt . USER rootRUN apk add --update --no-cache curl jq py3-configobj py3-pip py3-setuptools python3-dev mariadb-connector-c-dev \ && apk add --no-cache gcc g++ jpeg-dev zlib-dev libc-dev musl-dev libffi-dev mariadb-dev \ && pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple \ && apk del gcc g++ musl-dev libffi-dev python3-dev \ && apk del curl jq py3-configobj py3-pip py3-setuptools \ && rm -rf /var/cache/apk/* WORKDIR /usr/django
如果需要修改python版本,可以参考下面这个Dockerfile
FROM python:3.9 -alpineENV PORT=8000 ENV GUNICORN_CONFIG_ROOT=/etc/gunicornRUN mkdir -p $GUNICORN_CONFIG_ROOT COPY gunicorn.conf.py $GUNICORN_CONFIG_ROOT ENV WORKDIR =/usr/django RUN mkdir -p $WORKDIR WORKDIR $WORKDIR RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories RUN python3 -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple RUN apk add --no-cache tini gettext bash COPY start.sh $WORKDIR RUN chmod +x ./start.sh ENTRYPOINT ["/sbin/tini" , "--" ] CMD ["./start.sh" ] ENV STATIC_ROOT=/var/www/staticENV MEDIA_ROOT=/var/www/mediaENV SOURCE_ROOT=$WORKDIR /app RUN mkdir -p $STATIC_ROOT $MEDIA_ROOT $SOURCE_ROOT ENV GUNICORN_VERSION=21.2 .0 RUN pip install \ gunicorn==$GUNICORN_VERSION \ -i https://pypi.tuna.tsinghua.edu.cn/simple WORKDIR /usr/django/app COPY requirements.txt . RUN apk add --update --no-cache curl jq py3-configobj py3-pip py3-setuptools python3-dev mariadb-connector-c-dev \ && apk add --no-cache gcc g++ jpeg-dev zlib-dev libc-dev musl-dev libffi-dev mariadb-dev \ && pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple \ && apk del gcc g++ musl-dev libffi-dev python3-dev \ && apk del curl jq py3-configobj py3-pip py3-setuptools \ && rm -rf /var/cache/apk/* WORKDIR /usr/django
环境变量说明 alang/django
镜像的环境变量说明,官方没有表格,只有一个文本描述,不太直观
说明
默认值
变量名
Django项目名,必填,不然无法启动
无
DJANGO_APP
端口
8000
PORT
如果true,会在代码更新后自动重启项目
false
GUNICORN_RELOAD
Django项目启动前执行的manage.py命令,例如
无
DJANGO_MANAGEMENT_ON_START
设置后,会依次执行其中的命令,并且执行后,不会使用
无
DJANGO_MANAGEMENT_JOB
docker-compose.yaml version: '3' services: web: build: . ports: - "8000:8000" volumes: - .:/usr/django/app environment: - DJANGO_APP=Django项目名称 - GUNICORN_RELOAD=true - DJANGO_MANAGEMENT_ON_START=makemigrations --noinput;migrate --noinput;collectstatic --noinput depends_on: - redis - db links: - redis - db restart: always db: image: mysql:8.0.3 environment: MYSQL_ROOT_PASSWORD: 数据库ROOT密码 MYSQL_DATABASE: 数据库名 MYSQL_USER: 数据库用户名 MYSQL_PASSWORD: 数据库密码 redis: image: redis:alpine
然后将Django
项目中数据库的地址使用db
替代,redis
地址使用redis
替代,使用docker-compose
启动即可。
MySQL数据持久化 如果将数据放在容器上显然是不太安全的,如果哪天容器无法启动或者其他不可抗力因素那么数据就永远丢失了。
我们首先使用docker-compose build
构建,然后使用docker-compose up
进行启动,启动之后,使用cp命令拷贝数据库文件夹到本地。
docker cp db容器名:/var/lib/mysql ./db_data
之后再在compose文件中添加目录映射。
db: image: mysql:8.0.3 volumes: - ./db_data/mysql:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: 数据库ROOT密码 MYSQL_DATABASE: 数据库名 MYSQL_USER: 数据库用户名 MYSQL_PASSWORD: 数据库密码
这样记得备份./db_data
目录就可以了。
遇到的一点问题 之前在Dockerfile
中加入了migrate
,发现怎么都运行不起来,而且尝试在Django
容器中ping
数据库和redis
,都ping不同,最后发现自己理解错误。Docker得先构建出镜像才能运行,在构建镜像的过程中是不涉及启动任何相关的内容,所以应该将migrate
放入docker-compose
的command
中。
附录 如果alpine
的apk安装太慢,可以换apk的源,建议使用中科大的。
sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories