文章目录
- 本文概述
- 部署django项目
- 相关配置文件
- docker-compose.yml中的相关配置
- django镜像的dockerfile文件内容
- start.sh启动脚本的内容
- 启动结果
- 失败原因分析
- 改动start.sh
本文概述
使用docker-compose部署django项目,通常做法是:
- 构建docker镜像
- 运行容器
- 进入容器里面启动django项目
但是这样不够自动化。
尝试通过配置脚本的方式,让容器启动的时候就启动django项目,但这样往往使得容器一直处于重启状态,容器无法运行,本文主要解决这个问题
部署django项目
相关配置文件
docker-compose.yml中的相关配置
仅关注django部分配置即可
# /icwp_docker_compose/project/
version: '1'
services:
mysql:
build: ./mysql_env
image: mysql-5.7:compose
container_name: mysql-icwp-compose
environment:
- MYSQL_ROOT_PASSWORD=123456
- TZ=Asia/Shanghai
volumes:
- /mysql_env/conf:/etc/mysql/conf.d # 挂载配置文件
- ./mysql_env/init:/docker-entrypoint-initdb.d/ # 挂载初始化文件
- ../data/mysql:/var/lib/mysql # 挂载数据库数据
- ../log/mysql:/var/log/mysql # 挂载日志
ports:
- "3306:3306"
restart: always
networks:
- net-icwp
django:
build: ./python_env
image: django-icwp:compose
container_name: django-icwp-compose
ports:
- "8000:8000"
volumes:
- ../log/icwp:/icwp/Log # 挂载项目生成的log文件
stdin_open: true
tty: true
restart: always
networks:
- net-icwp
depends_on:
- mysql
nginx:
build: ./nginx_env
image: nginx-icwp:compose
container_name: nginx-icwp-compose
ports:
- "80:80"
- "8081:8081"
- "9000:9000"
volumes:
- ./nginx_env/conf/nginx.conf:/etc/nginx/nginx.conf # 挂载默认配置文件
- ./nginx_env/conf/conf.d:/etc/nginx/conf.d # 挂载自定义配置文件
- ./nginx_env/html:/usr/share/nginx/html # 挂载静态文件
- ../log/nginx:/var/log/nginx # 挂载日志
restart: always
networks:
- net-icwp
depends_on:
- django
networks:
net-icwp:
name: net-icwp-compose
django镜像的dockerfile文件内容
# 指定操作的镜像
FROM django-fixed:centos
# 指定语言,防止中文日志乱码
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# 创建文件夹
# 项目存放路径
RUN mkdir -p /icwp/code/Django_ICWP_v3
# 存放mysqlclient的安装包
RUN mkdir -p /icwp/code/mysqlclient
# 拷贝Django项目到指定地址
# 注意:只拷贝内容,不拷贝Django_ICWP_v3这个文件夹本身
COPY Django_ICWP_v3 /icwp/code/Django_ICWP_v3
# 传入mysqlclient的whl包,这玩意命令行安装简直折磨
COPY mysqlclient-2.2.1-cp38-cp38-linux_x86_64.whl /icwp/code/mysqlclient
# 更新pip:注意这里的python3.8,以及后续的pip3.8
# 这样写是因为创建这个镜像的时候python3:centos,通过软连接加入系统变量的是python3.8
# 更新pip操作视情况给出,若安装顺利,则无需更新pip
# RUN python3.8 -m pip install --upgrade pip
WORKDIR /icwp/code/mysqlclient
RUN pip3.8 install mysqlclient-2.2.1-cp38-cp38-linux_x86_64.whl
#这句指令相当与:cd django项目
WORKDIR /icwp/code/Django_ICWP_v3
# 这句话意思是排除掉requirements.txt文件中关于Django和mysqlclient的安装信息,并将剩余内容存入到requirements_new.txt
# 虽然可以在txt文件中注释掉Django和mysqlclient的,但是为了体现自动化的思想,多了这样一行命令
RUN grep -v '^ *#\|^Django\|^mysqlclient' requirements.txt | grep . > requirements_new.txt
# 安装依赖包
RUN pip3.8 --default-timeout=100 install -r requirements_new.txt -i http:///simple/ --trusted-host
# 配置uwsgi的系统变量
RUN ln -s /usr/local/python38/bin/uwsgi /usr/bin/uwsgi
# 解决启动脚本的换行问题
RUN sed -i 's/\r//' start.sh
# 赋予脚本执行权限
RUN chmod +x start.sh
EXPOSE 8000
ENTRYPOINT ["/bin/bash","start.sh"]
start.sh启动脚本的内容
python3.8 manage.py collectstatic --noinput&&
python3.8 manage.py makemigrations&&
python3.8 manage.py migrate&&
uwsgi --http :8000 --ini uwsgi.ini
启动结果
- 启动
[root@localhost project]# docker compose up -d
- 查看状态
[root@localhost project]# docker compose ps -a
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
django-icwp-compose django-icwp:compose "/bin/bash start.sh" django 21 seconds ago Restarting (0) 1 second ago
mysql-icwp-compose mysql-5.7:compose "docker-entrypoint.sh mysqld" mysql 21 seconds ago Up 20 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp
nginx-icwp-compose nginx-icwp:compose "/docker-entrypoint.sh nginx -g 'daemon off;'" nginx 21 seconds ago Up 20
seconds
可以发现django-icwp-compose这个容器,一直在重启,并没有成功启动
失败原因分析
django容器启动失败的原因是,执行完django项目的启动脚本之后,没有前台进程了,容器就自动关闭了,然后在compose中又设置了自动重启,就一直保持尝试启动的状态
要想解决这个问题,只需要在执行完启动脚本后,留一个交互式的命令,来阻塞进程,避免容器自动关闭即可
改动start.sh
以下任意一个改动,都可以使得docker-compose启动容器后,自动运行django
- 进入python3.8的交互式命令行
python3.8 manage.py collectstatic --noinput&&
python3.8 manage.py makemigrations&&
python3.8 manage.py migrate&&
uwsgi --http :8000 --ini uwsgi.ini&&
python3.8
- 进行/bin/bash
python3.8 manage.py collectstatic --noinput&&
python3.8 manage.py makemigrations&&
python3.8 manage.py migrate&&
uwsgi --http :8000 --ini uwsgi.ini&&
/bin/bash