We have released a repository to easily build an environment of "Django + nginx + uwsgi + mysql" using docker-compose.
You can easily build it just by git clone and launching the container.
If you want to change the project name, change each configuration file and restart the container.
At the stage of cloning, the initial migration to the DB has been completed.
It was troublesome to write docker-compose.yml every time, so I tried to publish it in the repository because I thought I should publish it.
The basic structure is the following file, so if you want to build it yourself, please refer to it.
(I'm waiting for a comment that there is a better way)
Basically it works by copy and paste, but if you want to change the file name etc., please change it as appropriate.
django-docker
 ├django
(├django files)
 ├mysql
  ├sql
   ├init.sql
(├mysql files)
 ├nginx
  ├conf
   ├app_nginx.conf
  ├uwsgi_params
 ├python
  ├Dockerfile
  ├requirements.txt
 ├docker-compose.yml
You don't have to worry about the files in parentheses.
docker-compose.yml First, let's look at the contents
version: '3'
services:
  nginx:
      image: nginx:1.13
      ports:
        - "8000:8000"
      volumes:
        - ./nginx/conf:/etc/nginx/conf.d
        - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
        - ./static:/static
      depends_on:
        - python
  db:
      image: mysql:5.7
      command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
      ports:
        - "3306:3306"
      environment:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_DATABASE: django_docker
        MYSQL_USER: user
        MYSQL_PASSWORD: password
        TZ: 'Asia/Tokyo'
      volumes:
        - ./mysql:/var/lib/mysql
        - ./mysql/sql:/docker-entrypoint-initdb.d
  python:
      build: ./python
      command: uwsgi --socket :8001 --module django_docker.wsgi --py-autoreload 1 --logto /tmp/mylog.log
      volumes:
        - ./django:/code
        - ./static:/static
      expose:
        - "8001"
      depends_on:
        - db
Build Websever, DB, and application in separate containers.
nginx
In the "nginx" folder, prepare the uwsgi parameter file "uwsgi_params" and the nginx config file "conf/app_nginx.conf".
uwsgi_params
uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;
uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;
uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
conf/app_nginx.conf
upstream django {
    ip_hash;
    server python:8001;
}
server {
    listen      8000;
    server_name 127.0.0.1;
    charset     utf-8;
    location /static {
        alias /static;
    }
    location / {
        uwsgi_pass  django;
        include     /etc/nginx/uwsgi_params;
    }
}
server_tokens off;
mysql In the "mysql" folder, only the SQL that gives permissions to the DB user is run first.
sql/init.sql
GRANT ALL PRIVILEGES ON django_docker.* TO 'user'@'%';
FLUSH PRIVILEGES;
It doesn't matter if you don't understand the meaning of SQL, but if you are interested, please try google.
python In the "python" folder, write a script to run when building a python container and a script to install the necessary python library.
Dockerfile You can change the python version to your liking.
Is it 3.9 if it is the latest? (I'm sorry if I made a mistake)
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
requirements.txt Describe the library you want to install in the python container.
There is no problem even if you do not specify the version of the library, but it is also a good point of Docker that you can specify the version of each library in the development environment, so I think that you should specify it.
Django==3.1
uwsgi==2.0.18
mysqlclient==2.0.3
Let's start the container when the file is ready
docker-compose up
I think this will launch the container itself, but since there is no django project yet, let's create one.
docker-compose exec python django-admin startproject project name
Let's also migrate including checking if django and DB are communicating
docker-compose exec python python manage.py migrate
Please note that there are many parts that are not fully explained because it has been scribbled.
It's annoying because the web application framework does the same work first.
I think that it is easier to build a development environment that suits you by automating the parts that can be automated!
I hope it helps someone even a little.
Recommended Posts