If you prepare a language learning environment on your private PC, you can create a lot of garbage files after the learning environment is no longer needed, so it was difficult to prepare it, but it is possible to easily prepare a development environment with WSL2 + Docker + VS Code environment. Since I knew, I prepared a Python development environment with reference to books.
I actually tried to build a Django environment, but I had a hard time because the cooperation between NGINX and UWSGI did not go well, so I will leave it as a memorandum.
Django https://docs.djangoproject.com/ja/3.1/intro/install/
NGINX https://docs.nginx.com/nginx/admin-guide/web-server/app-gateway-uwsgi-django/
uWSGI documentation https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html https://github.com/nginx/nginx/blob/master/conf/uwsgi_params
Reference book
We will build a development environment with the following folders and file structures.
Django_Dev
│
│ docker-compose.yml
│
├─db
│
├─django
│ │ Dockerfile
│ │ requirements.txt
│ │
│ └─uwsgi
│ uwsgi.ini
│
├─src
│ └─static
│
└─web
│ uwsgi_params
│
└─conf
nginx.conf
Create a docker-compose.yml file with the following content.
docker-compose.yml
version: '3.8'
services:
db:
image: postgres:13.1
container_name: postgres
volumes:
- ./db/dbdata:/var/lib/postgresql/data
expose:
- '5432'
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=myappdb
django:
build: ./django
image: django
container_name: django
expose:
- '8080'
volumes:
- ./src:/code
- ./django/uwsgi:/etc/uwsgi/
depends_on:
- db
web:
image: nginx:1.18.0
container_name: nginx
volumes:
- ./web/conf:/etc/nginx/conf.d
- ./web/uwsgi_params:/etc/nginx/uwsgi_params
- ./src/static:/static
ports:
- '80:80'
depends_on:
- django
Build a Django and uWSGI environment with Dockerfile based on the Python image.
Dockerfile
FROM python:3.9.1-buster
RUN apt-get update && apt-get install -y tzdata && rm -rf /var/lib/apt/lists/*
RUN mkdir /etc/uwsgi
RUN mkdir /code
WORKDIR /code
COPY requirements.txt ${PWD}
RUN pip install -r requirements.txt
ENV PYTHONUNBUFFERED 1
ENV TZ=Asia/Tokyo
CMD ["uwsgi","--ini","/etc/uwsgi/uwsgi.ini"]
requirements.txt
Django==3.1.4
psycopg2==2.8.6
uwsgi==2.0.19.1
uwsgi.ini
[uwsgi]
module = myapp.wsgi
socket = :8080
uid = www-data
gid = www-data
chmod-socket = 755
vacuum = true
Create nginx.conf and uwsgi_params files with the following contents.
nginx.conf
upstream django {
server django:8080;
}
server {
listen 80;
server_name dockerhost;
charset utf-8;
location /static {
alias /static;
}
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params;
}
}
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;
Run the following command in the directory where the docker-compose.yml file is located to build the Docker image with Django and uWSGI installed.
docker-compose build
Execution result
db uses an image, skipping
web uses an image, skipping
Building django
Step 1/10 : FROM python:3.9.1-buster
3.9.1-buster: Pulling from library/python
(snip)
Successfully built a65b92412516
Successfully tagged django:latest
Run the following command to verify that the django image has been created.
docker images
Execution result
REPOSITORY TAG IMAGE ID CREATED SIZE
django latest a65b92412516 6 minutes ago 936MB ★
python 3.9.1-buster d1eef6fb8dbe 2 weeks ago 885MB
Execute the following command to start the container.
docker-compose up -d
Execution result
Creating network "django_dev_default" with the default driver
Pulling db (postgres:13.1)...
13.1: Pulling from library/postgres
(snip)
Status: Downloaded newer image for nginx:1.18.0
Creating postgres ... done
Creating django ... done
Creating nginx ... done
Execute the following command and confirm that the container is started.
docker ps -a
Execution result
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff1bf925d1fe nginx:1.18.0 "/docker-entrypoint.…" 19 seconds ago Up 16 seconds 0.0.0.0:80->80/tcp nginx
9a4e0631ed5d django "uwsgi --ini /etc/uw…" 20 seconds ago Up 17 seconds 8080/tcp django
b3e6d1bd4d77 postgres:13.1 "docker-entrypoint.s…" 20 seconds ago Up 17 seconds 5432/tcp postgres
Check if the image file specified in docker-compose.yml has been downloaded.
docker images
Execution result
REPOSITORY TAG IMAGE ID CREATED SIZE
django latest a65b92412516 10 minutes ago 936MB
postgres 13.1 1f1bd4302537 4 days ago 314MB
python 3.9.1-buster d1eef6fb8dbe 2 weeks ago 885MB
nginx 1.18.0 05f64a802c26 3 weeks ago 133MB
Execute the following command to connect to the django container and create a project with myapp name.
docker-compose exec django /bin/bash
django-admin startproject myapp .
Execute the following command and confirm that the new file has been created.
ls -lR
.:
total 4
-rwxr-xr-x 1 root root 661 Jan 4 11:41 manage.py
drwxr-xr-x 1 root root 4096 Jan 4 11:41 myapp
drwxrwxrwx 1 root root 4096 Jan 3 22:44 static
./myapp:
total 8
-rw-r--r-- 1 root root 0 Jan 4 11:41 __init__.py
-rw-r--r-- 1 root root 387 Jan 4 11:41 asgi.py
-rw-r--r-- 1 root root 3059 Jan 4 11:41 settings.py
-rw-r--r-- 1 root root 747 Jan 4 11:41 urls.py
-rw-r--r-- 1 root root 387 Jan 4 11:41 wsgi.py
./static:
total 0
Make the minimum initial setup to get Django working.
settings.py
import os
(snip)
ALLOWED_HOSTS = ["*"]
(snip)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'myappdb',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': 'db',
'PORT': 5432,
}
}
(snip)
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Execute the following command to aggregate the static files into the static folder.
docker-compose exec django /bin/bash
./manage.py collectstatic
Execution result
132 static files copied to '/code/static'.
Restart the service with the following command for the settings to take effect.
docker-compose restart
Restarting nginx ... done
Restarting django ... done
Restarting postgres ... done
Confirm that the service is started with the following command.
docker-compose ps -a
Name Command State Ports
----------------------------------------------------------------------
django uwsgi --ini /etc/uwsgi/uws ... Up 8080/tcp
nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:80->80/tcp
postgres docker-entrypoint.sh postgres Up 5432/tcp
Enter the local loopback address in your browser and verify that the following screen is displayed.
If it doesn't work, use the following command to check the log and troubleshoot. Since the current setting is not set to save the log on the Windows side, it is necessary to additionally save it on the Windows side.
docker-compose logs or docker-compose logs container name
Now that you have a Django environment, I want to create a web application. I will upload it to GitHUB when it is completed.