使用Docker配置Django2环境

首先

我开始尝试新的Laravel环境搭建,以满足我的兴趣。

由于对Docker构建已经熟悉,我再次尝试使用Docker来创建Django2环境的开发环境。

环境

    • Windows10 Pro

 

    • docker for windows (docker desctop community) (ver.2.1.0.2)

 

    VSCode

Django2的配置环境

Docker的配置如下所示。

nginx-python-postgres.png
    • django2_nginx:1.17.3 (based nginx:1.17.3)

 

    • django2_python:3.7.4 (based python:3.7.4)

 

    django2_postgres:9.6.15 (based postgres:9.6.15)

Docker的定义

我已经制定了本地目录结构。

├─ laravel/
   ├─ postgres/
   │  └─ Dockerfile       # postgres用Dockerfile
   ├─ nginx/
   │  ├─ etc/
   │  │  ├─ conf.d/
   │  │  │  └─ default.conf    # nginxサイト定義
   │  │  └─ nginx.conf          # nginx基本定義
   │  └─ Dockerfile               # nginx用Dockerfile
   ├─ python/
   │  ├─ apps/
   │  │  │ :
   │  │  └─ setup.sh    # migrate,createsuperuser用スクリプト
   │  └─ Dockerfile      # php-fpm用Dockerfile
   ├─ .gitignore           # pythonのキャッシュ除外用gitignore
   ├─ docker-compose.yaml  # 全てのdocker定義

docker-compose.yaml的翻译如下:

所有的要求,docker-compose.yaml现在变成了这样。
端口略微有点怪异是因为我想与之前的Laravel共存(笑)。

    • nginxはポート8088でlistenしています。

 

    • nginxはdjango2プロジェクトのapps/staticを/opt/apps/staticに腹持ちさせました。

 

    • postgresは5432番でlistenしています。

 

    • postgresはデータ永続化のためdbvolumeコンテナを作成しました。

 

    • pythonは/opt/appsにdjango2プロジェクトをあらかじめ生成したものを腹持ちさせています。

 

    Django2はgunicornによりnginxからの通信を3031番で待ち受けします。
version: '3.3'
services:
  postgres:
    container_name: django2_postgres
    build: ./postgresql/
    image: django2_postgres:9.6.15
    restart: always
    ports:
      - 5432:5432
    volumes:
      - dbvolume:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=sample_db
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres@1234
      - PGDATA=/var/lib/postgresql/data

  python:
    container_name: django2_python
    build: ./python/
    image: django2_python:3.7.4
    links:
      - postgres
    volumes:
      - ./python/apps:/opt/apps
      - ./python/app/static:/opt/apps/static
    expose:
      - 3031
    environment:
      - DJANGO_ADMIN_USER=admin
      - DJANGO_ADMIN_EMAIL=admin@localhost.localdomain
      - DJANGO_ADMIN_PASSWORD=django2@1234
    command: >
      /bin/bash -c
      "./setup.sh && 
       gunicorn wsgi -b 0.0.0.0:3031"
    depends_on:
      - postgres

  nginx:
    container_name: django2_nginx
    build: ./nginx/
    image: django2_nginx:1.17.3
    ports:
      - 8088:80
    links:
      - python
    depends_on:
      - python
    volumes:
      - ./python/app/static:/opt/apps/static

volumes:
  dbvolume:

让我们来看一下各个Docker的定义吧!

以Docker方式定义了PostgreSQL 9.6.15。

我正在使用仅包含TZ更改的Dockerfile。

FROM postgres:9.6.15

RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

用Docker定义了nginx的版本为1.17.3。

我正在使用一个Dockerfile进行TZ更改以及将日志文件的stdout、strerr链接和配置文件进行COPY。

FROM nginx:1.17.3

RUN ln -sf /usr/share/zoneinfo/Japan /etc/localtime

RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
    ln -sf /dev/stderr /var/log/nginx/error.log && \
    ln -sf /dev/stdout /var/log/nginx/host.access.log

COPY ./etc/nginx.conf /etc/nginx/nginx.conf
COPY ./etc/conf.d /etc/nginx/conf.d

nginx.conf 文件进行了gzip和上游服务器的配置。


user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    server_tokens off;

    include       /etc/nginx/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  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;
    gzip_types image/png image/gif image/jpeg text/javascript text/css;
    gzip_min_length 1000;
    gzip_proxied any;
    gzip_comp_level 9;

    upstream django2_server  {
        server python:3031 fail_timeout=0;
    }

    include /etc/nginx/conf.d/*.conf;
}

default.conf的设置相当简单。

server {
    listen       80;
    server_name  _;

    root /opt/apps;
    index index.php;

    #charset koi8-r;
    access_log  /var/log/nginx/host.access.log  main;

    location /static/ {
        root /opt/apps/static;
    }

    location / {
        try_files $uri @proxy_to_django2;
    }

    location @proxy_to_django2 {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_redirect off;
        proxy_pass http://django2_server;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\. {
        deny  all;
    }
}

使用Docker来定义Python版本为3.7.4。

改变时区与其他服务器的Dockerfile相同,但是通过requirements.txt文件来指定安装python模块。

WORKDIR将Django2项目设置为apps文件夹。

FROM python:3.7.4

ENV APP_PATH /opt/apps

RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

WORKDIR $APP_PATH

COPY ./apps/requirements.txt $APP_PATH/

RUN pip install --no-cache-dir -r $APP_PATH/requirements.txt

请根据您创建的项目添加以下要安装的模块。

django==2.2.5
djangorestframework
django-filter
psycopg2
gunicorn

这个setup.sh文件用于进行数据库迁移和创建超级用户。
用户名称、电子邮件地址和密码在docker-compose.yaml文件的环境变量中指定。

#!/bin/bash

echo "##### setup django2 app #####"
echo "-> migrate database"
python manage.py makemigrations --noinput
python manage.py migrate --noinput

echo "-> create super user"
python manage.py shell <<EOF
from django.contrib.auth.models import User
if not User.objects.filter(username='$DJANGO_ADMIN_USER'):
    User.objects.create_superuser('$DJANGO_ADMIN_USER', '$DJANGO_ADMIN_EMAIL', '$DJANGO_ADMIN_PASSWORD')
    print('    create super user: $DJANGO_ADMIN_USER')
else:
    print('    user: $DJANGO_ADMIN_USER already exists, nothing to do')

防止Python运行时生成的缓存文件被提交到Git中的魔法咒语(^^♪)

__pycache__/
*.py[cod]

启动Docker

当准备工作完成后,启动Docker。

C:\Users\tak>cd C:\Git\docker\django2
C:\Git\docker\django2>docker-compose build
C:\Git\docker\django2>docker-compose up

不,使用Docker来构建开发环境非常方便,可以轻松地创建和销毁,非常实用!