云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验

项目部署总结

  • 相关配置版本
  • 安装Docker
  • Docker修改权限
    • 1. 确定存在 docker 用户组
    • 2. 将当前用户添加到 docker 用户组
    • 3. 重启服务
    • 4. 切换当前会话到新 group 或者重启 XShell 会话
  • Docker 部署
    • 1. 基于镜像(images)制作容器(containers)
      • a. 整体项目目录结构
      • b. 整体容器配置文件——docker-compose.yml
      • c. 制作Nginx容器,使用Doockerfile(基于Nginx)
      • d. 制作 Web 容器,使用 Doockerfile(基于 Python 3.7)
    • 2. 整体制作容器成功后启动
    • 3. Docker 遇到问题时救火的操作命令
  • Web 容器访问宿主机数据库
  • Django 项目中的 settings.py 部分重要配置
  • 使用 Gunicorn 启动 Web 服务
  • Nginx 代理后,网页没有样式

相关配置版本

宿主机 Python包
操作系统 MySQL Docker django docker-compose docker
ubuntu 18.0.4 5.7 19.03.8 3.0.8 1.26.2 4.3.1

安装Docker

卸载旧版本,没有安装过 Docker 可以略过此步骤。

$ sudo apt-get remove docker docker-engine docker.io containerd runc

建立仓库,依次执行即可。

$ sudo apt-get update

$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88

会出现如是提示

pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <[email protected]>
sub   rsa4096 2017-02-22 [S]

添加下载链接到 apt 仓库中,其中网址部分为获取的源链接(xue微有些慢),我感觉可以改为镜像源链接(但并未尝试)。

$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

开始安装,详细介绍请看官网教程,下方的参考链接。

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

参考链接0 - Install Docker Engine on Ubuntu

Docker修改权限

1. 确定存在 docker 用户组

$ sudo groupadd docker # 一般都初始化,已经存在

2. 将当前用户添加到 docker 用户组

$ USER=user_name
$ sudo gpasswd -a ${USER} docker

3. 重启服务

$ sudo service docker restart

4. 切换当前会话到新 group 或者重启 XShell 会话

$ newgrp - docker

参考链接1 - Ubuntu:添加docker权限给当前用户(可以使docker命令免sudo)
参考链接2 - Ubuntu下docker使用非root权限运行docker

# 一般/etc/docker默认存在,可不执行下面的命令
$ sudo mkdir -p /etc/docker
$ sudo tee /etc/docker/daemon.json <<-'EOF'
 {
   "registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
 }
 EOF
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

https://xxxxxxxx.mirror.aliyuncs.com 是通过阿里云容器加速服务进行获取,每个服务器有不同的加速地址。

参考链接3 - docker怎么修改拉取源从指定的国内仓库拉取镜像

Docker 部署

1. 基于镜像(images)制作容器(containers)

a. 整体项目目录结构

云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验_第1张图片
MySQL 服务放在宿主机上,不放入 DockerNginx 一个 Docker 容器,Django+Gunicorn 一个 Docker 容器,只用 Docker 开启两个容器服务。

服务 位置
MySQL 宿主机
Nginx Docker容器
Web Docker容器

b. 整体容器配置文件——docker-compose.yml

云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验_第2张图片

c. 制作Nginx容器,使用Doockerfile(基于Nginx)

Dockerfile 内容

云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验_第3张图片

注意:nginx 容器的端口(在 docker-compose.yml 文件中设置)暴露给宿主机的为80,暴露给其它容器的为8000,因为其要反向代理 Web 服务,以上端口的设置都可以不在 Dockerfile 中进行,只需要在 docker-compose.yml 配置即可。其中 nginx.conf 文件的配置内容如下:

云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验_第4张图片
注意:nginx.conf 文件中设置 server 属性中的 proxy_pass 为带与 gunicorn 端口一致的端口号的地址即 proxy_pass http://qsud:8000;

d. 制作 Web 容器,使用 Doockerfile(基于 Python 3.7)

Dockerfile 内容

云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验_第5张图片
还有一个是容器运行起来后需要运行的命令,也就是 docker-compose.yml 文件中 Web 容器配置的 command 字段,其中 djangoProject 是我的项目名,命令一次的含义为,制作数据库迁移,迁移数据库,收集静态文件,使用 gunicorn 启动项目。

云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验_第6张图片

2. 整体制作容器成功后启动

# 激活虚拟环境,其实完全可以不用虚拟环境了,但之前在本地开发时用到了,就直接搬过来了
$ cd papi
$ source venv/bin/activate
# 切换到docker-compose.yml文件的目录下
(venv)$ cd hms1
# 按照docker-compose.yml进行创建镜像,需要在虚拟环境下
(venv)$ docker-compose build
# 以后台模式运行容器,需要在虚拟环境下
(venv)$ docker-compose up -d
# 使用docker-compose命令查看正在运行的容器,需要在虚拟环境下
(venv)$ docker-compose ps
# 使用docker-compose命令移除正在运行的容器,需要在虚拟环境下
(venv)$ docker-compose down
# 使用docker命令查看正在运行的容器可显示id,无论是否虚拟环境
$ docker ps -a

参考链接4 - Docker部署Web应用(Django)
参考链接5 - 使用docker-compose部署Django项目
参考链接6 - docker部署Django项目(前后端分离项目)

3. Docker 遇到问题时救火的操作命令

  • 通过查看 Docker 的容器运行日志寻找错误原因
$ sudo docker logs container_id
# 或者查看docker-compose的全部容器输出,-f 跟踪日志输出
(venv)$ docker-compose logs
  • 访问正在运行的容器 Shell 进入容器内部操作
$ sudo docker exec -it container_id /bin/bash
  • 在本地创建一个镜像,PUSH 上去,在远程服务器 PULL 下来

Web 容器访问宿主机数据库

1. 首先设置宿主机 MySQL 的绑定地址,直接找到 MySQL 的配置文件。

# 你的配置文件位置可能不为此,但默认一般是这里
$ cd /etc/mysql/mysql.conf.d

其中的 bind-address 字段默认值为 127.0.0.1,直接把这一行用 # 注释掉(已尝试可行),或者改成 0.0.0.0 (未尝试)。

参考链接7 - 在docker容器内访问宿主机的mysql服务

2. 其次查看网卡

# 主要是得到Docker的虚拟网卡
$ ifconfig

云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验_第7张图片
下面 setting.py 文件中的数据库配置部分的主机名设置成 172.17.0.1
在腾讯云服务器中,发现使用 172.17.0.1 连接数据库时,日志却报出错误的访问地址为 172.28.0.2

在这里插入图片描述
而且每次停止容器,然后再运行容器后发现,都会是 172.28.0.228 位置的数字改变,猜测原因可能是动态分配地址,而且如果考虑可能多个应用访问该段地址的话,那么最终需要在 MySql 中设置该网段的 IP 地址可以访问数据库。第一个 % 代表可能动态分配的数字,第二个 % 代表可能有多个应用连接。

# 新建规则
GRANT ALL PRIVILEGES ON db_qsud.* TO 'root'@'172.%.0.%' IDENTIFIED BY '123456';
# 最后要进行刷新权限
flush privileges;

注1: 以上仅适用于我的腾讯云服务器,可能对其它人的腾讯云服务器或其它品牌的云服务器不适用。
注2: 以上是不使用SSL模式访问的情况(通俗理解 http://,监听80端口,不需要证书)下,如果是SSL访问情况(通俗理解 https://,监听443端口,需要有证书)下 IP 地址还会不一样,需要在MySql 中新增允许网段,具体设置为何网段的 IP 地址看日志即可。

参考链接8 - Docker容器内连接宿主机的Mysql服务器

Django 项目中的 settings.py 部分重要配置

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

# 允许访问此项目的地址
ALLOWED_HOSTS = ['*']  # 其实只添加你的IP地址或域名即可

# Application definition
INSTALLED_APPS = [
    ...
    'gunicorn',
]

# Database
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db_qc',
        'HOST': '172.17.0.1',
        'PORT': '3306',
        'USER': 'root',
        'PASSWORD': '123456',
        'CHARSET': 'utf8',
    }
}

# Static files (CSS, JavaScript, Images)
# # 对外提供WEB访问时的URL地址
STATIC_URL = '/s/'
# # 然后会将项目中的静态文件(包括STATICFILES_DIRS、自带admin的静态文件)收集到该目录下面来(所以不应该在该目录下面放置自己的一些静态文件,因为会覆盖掉)
STATIC_ROOT = os.path.join(BASE_DIR, "static")

# Upload source
# # 对外提供WEB访问时的URL地址
MEDIA_URL = '/m/'
# # 放置项目接收的上传文件
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

使用 Gunicorn 启动 Web 服务

gunicorn 的配置文件中如果设置成 gevent 模式

# gunicorn.conf文件
bind='0.0.0.0:8000'
proc_name='qsud'
pidfile='/tmp/qsud.pid'
workers=4
worker_class='gevent'
max_requests=6666
timeout = 30

注意1: 使用此模式需要安装 gevent,安装 gevent 的前提需要更新 pip ,更新 pip 命令已在制作 Web 容器时配置过了,只需要在 requirements.txt 中添加 gevent 包信息,或者直接使用下面命令,制作第三方库依赖文件。
注意2:gunicorn 绑定端口(在 gunicorn.conf 文件中设置)跟 Web 容器暴露给其它容器的端口一致(在 docker-compose.yml 文件中设置)。

# 在虚拟环境中
(venv)$ pip freeze > requirements.txt

Nginx 代理后,网页没有样式

肯定是没有正确获取到设置的收集静态文件的目录(在 Djangosetting.py 中设置 STATIC_ROOT )才会这样,之前网页没有样式的问题,原因就是因为我的 nginx.conf 文件中的 location 的静态文件配置中没有最后的 “ / ” ,导致以为是个 static 文件,而非 static 文件夹。

云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验_第8张图片
注意 locationalias 的使用,注意最后的 “ / ” 字符不能丢,代表在此目录下,是个文件夹。

云服务器部署Django+Gunicorn+Nginx+MySql——Docker完整体验_第9张图片
具体的 locationalias 使用请参照官网的说明。

参考文献9 - Nginx官网中 alias 和 location 字段的使用说明

你可能感兴趣的:(docker,linux,django,nginx)