Django项目容器化实战

目录

项目地址

Django博客

项目结构

├─blog
│  ├─migrations
│  └─templates
├─log
├─myblog
├─resources
│  ├─myblog
│  └─mysql
└─static
    └─admin
        ├─css
        │  └─vendor
        │      └─select2
        ├─fonts
        ├─img
        │  └─gis
        └─js
            ├─admin
            └─vendor
                ├─jquery
                ├─select2
                │  └─i18n
                └─xregexp

Dockerfile

通常把Dockerfile放在业务的根目录下:这

# Base Image基础镜像 centos:centos7.5.1804;:之后的centos7.5.1804表示标签
FROM centos:centos7.5.1804

# ENV设置环境变量,这里设置了两个环境变量; LANG:语言;LC_ALL:所有区域
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8

# RUN执行命令,这里是在容器中curl下载了Centos-7.repo文件,然后安装了nginx, -s表示静默模式,不显示进度条,-o表示输出到指定文件; rpm -Uvh:安装rpm包,-U:升级已经安装的包,-v:显示详细信息,-h:显示进度条; RPM包是Red Hat Package Manager的缩写,是Red Hat Linux发行版的软件安装包格式,类似于Windows中的exe安装包
RUN curl -so /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo && rpm -Uvh https://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
RUN yum install -y python3.6 python3-devel gcc pcre-devel zlib-devel make net-tools nginx

# 设置工作目录
WORKDIR /opt/myblog

# 将当前目录下的所有文件拷贝到容器中的/opt/myblog目录下;
COPY ./* /opt/myblog

# 拷贝nginx配置文件
COPY myblog.conf /etc/nginx
# 安装依赖的插件
RUN pip3 install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r requirements.txt

RUN chmod +x run.sh && rm -rf ~/.cache/pip

# 映射端口
EXPOSE 8002

# 容器启动时执行命令
CMD ["./run.sh"]

nginx配置文件

在根目录的myblog.conf是nginx配置文件信息:

worker_process表示


#user  nobody;
worker_processes  4;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;


    server {
        listen 8002;
        server_name 127.0.0.1;
        charset     utf-8;
        access_log      /opt/myblog/log/nginx_access.log;
        error_log       /opt/myblog/log/nginx_error.log;
        client_max_body_size 75M;


        location /static {
            alias /opt/myblog/static;
        }
        location /media {
            alias /opt/myblog/media;
        }
        location / {
            root        /opt/myblog;
            include     /etc/nginx/uwsgi_params;
            uwsgi_pass  127.0.0.1:8000;
        }
    }


}

run.sh和requirements.txt

#!/bin/bash
uwsgi --ini ./uwsgi.ini
nginx -c /etc/nginx/myblog.conf -g 'daemon off;'
PyMySQL==0.9.3
Django==2.1.8
uwsgi==2.0.18

删除镜像和容器

有的时候我们需要删除镜像或者容器,可以使用如下命令:

docker ps -a
docker rm -f 容器id
docker images
docker rmi 镜像id

执行构建

这一步是根据Dockerfile构建镜像,-t表示指定镜像名称,-f表示指定Dockerfile文件;

docker build . -t myblog:v1 -f Dockerfile

运行mysql

mysql也是中间件,需要单独运行容器: -v表示挂载目录,-e表示环境变量,-d表示后台运行;

这一步骤可能存在问题,没有权限无法挂载目录,可以使用–privileged=true参数,表示给容器赋予所有的权限;

docker run --privileged=true -p 3306:3306 --name mysql -v /opt/mysql:/var/lib/mysql -e MYSQL_DATABASE=myblog -e MYSQL_PASSWORD=123456 mysql:5.7

# 进入容器,查看数据库
docker exec -it mysql bash
#/ mysql -p123456
#/ show databases;

还是没有启动容器,报错如下:

2023-07-26 06:04:42+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
    You need to specify one of the following as an environment variable:
    - MYSQL_ROOT_PASSWORD
    - MYSQL_ALLOW_EMPTY_PASSWORD
    - MYSQL_RANDOM_ROOT_PASSWORD

修改如下:

docker run --privileged=true -p 3306:3306 --name mysql -v /opt/mysql:/var/lib/mysql -e MYSQL_DATABASE=myblog -e MYSQL_PASSWORD=123456 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7

这个项目中,database的设置在myblog/settings.py中:

os.environ.get(‘MYSQL_DATABASE’, ‘root’)表示获取环境变量中的MYSQL_DATABASE,如果没有就使用root;

下面的其他三个语句都是一样的,说明启动这个数据库只需要设置四个环境变量,分别是:”MYSQL_DATABASE”、”MYSQL_PASSWD”、”MYSQL_HOST”和”MYSQL_PORT”。

20230726134806

容器启动成功,但是无法访问:

docker exec -ti mysql bash
bash-4.2# mysql -p123456 
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
bash-4.2# mysql -uroot  
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
bash-4.2# mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
bash-4.2# mysql -u root -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

解决办法:修改my.in/my.cnf配置文件

进入mysql安装目录(linux环境:/etc/my.cnf,也可以通过mysql –help查看)

编辑my.ini,这里要注意,如果你没有my.ini文件,就在Mysql安装目录下新建一个

在[mysqld]下添加skip-grant-tables,保存即可!(意思是跳过验证)

然后重启服务即可

docker restart mysql对应的容器id

查看mysql:

docker exec -ti mysql bash
bash-4.2 # mysql -uroot
mysql> use myblog;
mysql> show tables;

显示结果如下:

#/ mysql -p123456
#/ show databases;

20230726145355

其他可能错误原因

参考链接

还是不行:

如果确认自己的明文密码是正确的,原因有可能是mysql8.0使用的默认加密插件是 caching_sha2_password 而非5.6的 mysql_native_password,当你在控制台使用明文密码登录的时候走的是mysql_native_password加密,而数据库记录的是caching_sha2_password加密后的密码,匹配自然不正确。这个概论很小

启动Django应用

# 启动容器
docker run -d -p 8002:8002 --name myblog -e MYSQL_HOST=172.21.56.67 -e MYSQL_USER=root -e MYSQL_PASSWD=123456 myblog:v1

启动之后,可以通过docker ps查看容器是否启动成功,如果启动成功,可以通过浏览器访问:172.21.56.67:8002,发现无法访问,查看报错信息:

如果docker ps没有显示容器,且使用docker ps -a发现容器已经exit,可以使用如下命令查看容器日志:

docker logs 容器id

错误原因如下:

exec ./run.sh: no such file or directory

说明并没有进入需要的工作目录!!!

原因是因为是个空表,需要先创建表格!!

docker exec -it myblog bash # 进入myblog容器

在容器中执行如下命令:

pwd # 确定单前目录为/opt/myblog
python3 manage.py makemigrations # 生成迁移文件,这一步会在migrations目录下生成0001_initial.py文件
python3 manage.py migrate # 执行迁移文件,这一步会在数据库中生成表格
python3 manage.py createsuperuser # 创建超级用户

这个时候,就可以愉快的访问172.51.67:8080/admin了!

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦