J'ai écrit cet article avant. Créez un environnement de développement Django avec Docker! (Docker-compose / Django / postgreSQL / nginx)
L'article original a été écrit il y a longtemps (environ un an?), Mais maintenant que j'ai accumulé quelques connaissances, j'ai pensé que je pouvais l'améliorer un peu, alors j'ai décidé de relever le défi!
Je ne parlerai pas des détails tels que l'installation de Docker, donc si vous êtes intéressé, veuillez consulter l'article original! (Ici Je pense que quelque chose sera utile.)
De plus, comme une différence claire avec l'article précédent, Django est considéré comme un serveur de distribution d'API, et Vue.js et React sont supposés pour l'implémentation frontale, donc la distribution de fichiers statiques et les paramètres de modèle sont effectués. Veuillez noter que nous ne faisons rien comme la création de docker-compose.yml
et docker-compose.yml.prod
pour séparer l'environnement de production de l'environnement de développement.
En fin de compte, la structure des répertoires ressemble à ceci!
backend
└── containers
├── django
│ ├── Dockerfile
│ ├── Pipfile
│ ├── Pipfile.lock
│ ├── config
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── entrypoint.sh
│ ├── manage.py
├── docker-compose.yml
├── nginx
│ ├── Dockerfile
│ └── nginx.conf
└── postgres
├── Dockerfile
└── sql
└── init.sql
Chaque conteneur est placé dans le répertoire conteneurs sous le répertoire backend.
Le répertoire postgres a été ajouté par rapport à l'article précédent.
Commençons maintenant par le répertoire django supérieur!
Tout d'abord, créons trois répertoires: backend, containers et django! Puis passez au répertoire django.
$mkdir -p backend/containers/django
$cd backend/containers/django
Commençons par créer un Pipfile dans le répertoire django. La version de chaque package est la dernière version au moment de la rédaction de cet article, et il n'y a pas de préférence particulière. N'hésitez pas à le changer. (Le fonctionnement n'est pas garanti)
De plus, si le paquet à installer est arbitraire et que le but est uniquement de construire l'environnement, il n'y a pas de problème si seuls django
, gunicorn
et django-environ
sont inclus.
backend/containers/django/Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
django = "==3.0.6"
djangorestframework = "==3.11.0"
djangorestframework-simplejwt = "==4.4.0"
djangorestframework-gis = "==0.15"
django-cors-headers = "==3.2.1"
django-environ = "==0.4.5"
djoser = "==2.0.3"
gunicorn = "==20.0.4"
psycopg2-binary = "==2.8.5"
[requires]
python_version = "3.8.2"
Créons un environnement virtuel avec pipenv avec la série python3.8, entrons dans l'environnement virtuel et vérifions la version et les packages installés.
$pipenv install
$pipenv shell
(django) $python -V
Python 3.8.2
(django) $pip list
Package Version
----------------------------- -------
asgiref 3.2.7
Django 3.0.6
django-cors-headers 3.2.1
django-environ 0.4.5
django-templated-mail 1.1.1
djangorestframework 3.11.0
djangorestframework-gis 0.15
djangorestframework-simplejwt 4.4.0
djoser 2.0.3
gunicorn 20.0.4
pip 20.0.2
psycopg2-binary 2.8.5
PyJWT 1.7.1
pytz 2020.1
setuptools 46.1.3
sqlparse 0.3.1
wheel 0.34.2
Si vous voyez le mot (django)
sur le bord gauche du shell, vous êtes dans un environnement virtuel. (Par souci de simplicité, la chaîne de caractères de (django)
ne sera pas décrite à partir de la prochaine fois)
Django est correctement installé!
Après avoir confirmé que vous êtes dans le répertoire django, utilisez les commandes de Django pour créer un projet.
$django-admin startproject config .
Ceci termine la création du projet Django. Vous devriez voir un répertoire de configuration et un fichier nommé manage.py
créés dans le répertoire django.
À ce stade, démarrez le serveur de débogage avec la commande python manage.py runserver localhost: 8000
, connectez-vous à loaclhost: 8000
depuis votre navigateur, et vous devriez voir cet écran plutôt que le visage de vos parents.
Ensuite, modifions les fichiers autour de Django comme suit.
Veuillez commenter SECRET_KEY car il sera utilisé plus tard.
backend/containers/django/config/settings.py
import os
from datetime import timedelta
import environ
env = environ.Env()
env.read_env('.env')
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = env.get_value('SECRET_KEY')
DEBUG = env.get_value('DEBUG')
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_gis',
'corsheaders',
'django.contrib.gis',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'config.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'config.wsgi.application'
DATABASES = {
'default': {
'ENGINE': env.get_value('DATABASE_ENGINE', default='django.db.backends.sqlite3'),
'NAME': env.get_value('DATABASE_DB', default=os.path.join(BASE_DIR, 'db.sqlite3')),
'USER': env.get_value('DATABASE_USER', default='django_user'),
'PASSWORD': env.get_value('DATABASE_PASSWORD', default='password'),
'HOST': env.get_value('DATABASE_HOST', default='localhost'),
'PORT': env.get_value('DATABASE_PORT', default='5432'),
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}
SIMPLE_JWT = {
'AUTH_HEADER_TYPES': ('JWT',),
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
}
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
'http://localhost:8080',
'http://127.0.0.1:8080',
)
Lorsque j'ai créé le Pipfile pour la première fois, j'ai ajouté un package appelé django-environ
, qui décrit les informations que je veux cacher, telles que SECRET_KEY et les informations de connexion à la base de données, dans le fichier .env
, etc., et le code source. C'est un package pour gérer séparément de setting.py
etc.
env = environ.Env()
env.read_env('.env')
Utilisez-le comme ça.
Créons immédiatement un fichier .env
.
backend/containers/django/.env
DEBUG=True
SECRET_KEY=<YOUR_SECRET_KEY>
DATABASE_ENGINE=django.contrib.gis.db.backends.postgis
DATABASE_DB=<YOUR_DB_NAME>
DATABASE_USER=<YOUR_DB_USER>
DATABASE_PASSWORD=<YOUR_DB_PASSWORD>
#entrypoint.Utilisé en sh
#compose.Résout le nom avec le nom du service décrit dans yml
DATABASE_HOST=postgres
DATABASE_PORT=5432
DATABASE=postgres
Après cela, je réparerai les fichiers liés à Gorigori. Étant donné que le chemin du répertoire principal est également décrit, nous allons créer, ajouter et modifier les fichiers nécessaires le cas échéant.
backend/containers/django/Dockerfile
#Tirez l'image ubuntu et installez Python
FROM ubuntu:20.04
SHELL ["/bin/bash", "-c"]
#Installer python
RUN apt-get update -y \
&& apt-get upgrade -y \
&& apt-get install -y python3.8 python3.8-dev \
&& source ~/.bashrc \
&& apt-get -y install vim
#Définir le répertoire de travail
WORKDIR /usr/src/app
#Définir les variables d'environnement
#Empêcher Python d'écrire sur des fichiers et des disques pyc
ENV PYTHONDONTWRITEBYTECODE 1
#Empêcher Python de mettre en mémoire tampon les E / S standard
ENV PYTHONUNBUFFERED 1
ENV DEBIAN_FRONTEND=noninteractive
#Installation de dépendance et installation de pipenv
RUN apt-get install -y curl \
&& curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
&& apt-get install -y python3.8-distutils \
&& python3.8 get-pip.py \
&& pip install -U pip \
&& apt-get install -y build-essential libssl-dev libffi-dev python-dev python3-dev libpq-dev
#Installation de pipenv
RUN pip install pipenv
#Copiez le Pipfile de votre machine locale dans le conteneur
COPY Pipfile ./
# Pipfile.Ignorez le verrouillage et installez le package décrit dans Pipfile sur votre système
#Puis désinstallez pipenv
RUN pipenv install --system --skip-lock \
&& pip uninstall -y pipenv virtualenv-clone virtualenv
#Dépendances lors de l'installation de bibliothèques géospatiales
RUN apt-get update -y \
&& apt-get upgrade -y \
&& apt-get install -y libgeos-dev binutils libproj-dev gdal-bin libgdal-dev \
&& apt-get install -y python3-gdal
RUN apt-get install -y netcat \
&& apt-get install -y expect
#Copier le script shell
# COPY ./entrypoint.sh /usr/src/app/entrypoint.sh
COPY . /usr/src/app/
#Exécuter le script shell
# ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
Vérifions si le conteneur fonctionne à ce stade.
$docker build . -t pipenv_sample
...
$docker run -it pipenv_sample
root@e6bdfb335bee:/usr/src/app#
Si vous pouvez vous connecter au conteneur en tant qu'utilisateur root de cette manière, vous avez probablement réussi!
# python3 -V
Python 3.8.2
# pip list
Package Version
----------------------------- ----------
appdirs 1.4.3
asgiref 3.2.7
certifi 2020.4.5.1
distlib 0.3.0
Django 3.0.6
django-cors-headers 3.2.1
django-environ 0.4.5
django-templated-mail 1.1.1
djangorestframework 3.11.0
djangorestframework-gis 0.15
djangorestframework-simplejwt 4.4.0
djoser 2.0.3
filelock 3.0.12
GDAL 3.0.4
gunicorn 20.0.4
numpy 1.17.4
pip 20.1
pipenv 2018.11.26
psycopg2-binary 2.8.5
PyJWT 1.7.1
pytz 2020.1
setuptools 46.1.3
six 1.14.0
sqlparse 0.3.1
virtualenv 20.0.20
virtualenv-clone 0.5.4
wheel 0.34.2
La version Python est 3.8.2 et les packages sont correctement installés!
Déconnectez-vous avec Control + d
.
Enfin, écrivons et sauvegardons un script shell pour la connexion au conteneur postgres qui s'exécute au démarrage.
backend/containers/django/entrypoint.sh
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $DATABASE_HOST $DATABASE_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
exec "$@"
À propos, supprimez les commentaires des deux commentaires près de la dernière ligne du Dockerfile que vous avez modifié ci-dessus.
backend/containers/django/Dockerfile
#cette
COPY ./entrypoint.sh /usr/src/app/entrypoint.sh
COPY . /usr/src/app/
#cette
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
Voilà pour le répertoire Django.
tree
backend
└── containers
├── django
│ ├── Dockerfile
│ ├── Pipfile
│ ├── Pipfile.lock
│ ├── config
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── entrypoint.sh
│ ├── manage.py
└── docker-compose.yml
Ensuite, nous allons lancer le conteneur PostgreSQL.
Commencez par aller dans le répertoire des conteneurs et créez un répertoire postgres, etc.
$cd ../../
$mkdir -p postgres/sql/
Vous devriez maintenant avoir un répertoire postgres et un répertoire sql à l'intérieur.
Ajoutons un Dockerfile dans le répertoire postgres.
backend/containers/postgres/Dockerfile
FROM mdillon/postgis:11
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
Dans mon cas, je voulais créer une application cartographique, donc j'utiliserai l'image PostGIS, qui est une extension de PostgreSQL, mais je pense que n'importe quelle image PostgreSQL fera l'affaire. (L'opération n'a pas été vérifiée)
Ensuite, stockez le fichier sql que vous souhaitez exécuter lorsque le conteneur démarre dans le répertoire sql.
backend/containers/postgres/sql/init.sql
CREATE EXTENSION postgis;
Cette fois, je n'ai stocké que le fichier sql pour activer l'extension, mais si vous avez des données que vous souhaitez enregistrer initialement, n'hésitez pas à les stocker.
Enfin, ajoutez le fichier .env_db.
En cela, écrivez le même <YOUR_DB_NAME> (USER / PASSWORD) que vous avez écrit lorsque vous avez créé le conteneur Django.
Un DB sera créé automatiquement avec le contenu décrit ici.
backend/containers/postgres/.env_db
#Si vous écrivez dans env, DB sera créé automatiquement
POSTGRES_DB=<YOUR_DB_NAME>
POSTGRES_USER=<YOUR_DB_USER>
POSTGRES_PASSWORD=<YOUR_DB_PASSWORD>
Ceci termine la construction de l'environnement postgres.
backend
└── containers
├── django
│ ├── Dockerfile
│ ├── Pipfile
│ ├── Pipfile.lock
│ ├── config
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── entrypoint.sh
│ ├── manage.py
├── docker-compose.yml
└── postgres
├── Dockerfile
└── sql
└── init.sql
docker-compose est un outil pratique à utiliser lors du démarrage de plusieurs conteneurs en même temps et de leur connexion.
Passons au répertoire des conteneurs et créons un fichier de configuration.
$cd ../
$touch docker-compose.yml
backend/containers/docker-compose.yml
version: "3.7"
services:
django:
#Nom du conteneur
container_name: django
#Répertoire contenant le fichier docker à construire
build: ./django
#Commandes à exécuter après un démarrage normal
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
#Répertoire à monter
- ./django:/usr/src/app/
ports:
#Port côté hôte: port côté conteneur
- 8000:8000
env_file:
#Fichier à définir dans la variable d'environnement
- ./django/.env
depends_on:
#Service de connexion
- postgres
postgres:
container_name: postgres
build: ./postgres
volumes:
#Les données de base de données sont enregistrées en créant un volume
#Vous pouvez prendre le répertoire et monter et laisser les données réelles directement sur le système d'exploitation hôte.
# /var/lib/postgresql/Les données DB sont stockées dans les données
- sample_postgis_data:/var/lib/postgresql/data
# down -Spécifiez le fichier à exécuter au premier démarrage, y compris lorsqu'il n'y a pas de volume avec v etc.
- ./postgres/sql:/docker-entrypoint-initdb.d
env_file: ./postgres/.env_db
ports:
#Le port côté hôte bat avec le psql local, alors faites-le autrement que 5432
- 5433:5432
volumes:
sample_postgis_data:
Après l'écriture, lançons docker-compose.
$docker-compose up -d --build
Connectons-nous à localhost: 8000
depuis un navigateur.
Si l'écran initial de Django vu du visage de mon frère s'affiche, c'est réussi.
Vous pouvez vous connecter au conteneur avec la commande suivante.
$docker exec -it <Nom du service> bash
En d'autres termes, dans ce cas, vous pouvez vous connecter avec ce qui suit.
$docker exec -it django bash
Ou
$docker exec -it postgres bash
Nous avons confirmé que le conteneur django a démarré, donc vérifions également le conteneur postgres.
$docker exec -it postgres bash
#psql -U <YOUR_DB_USER> -d <YOUR_DB_NAME>
psql (11.2 (Debian 11.2-1.pgdg90+1))
"help"Obtenez de l'aide avec.
<YOUR_DB_NAME>=#
<YOUR_DB_NAME>=# SELECT postgis_version();
postgis_version
---------------------------------------
2.5 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 ligne)
J'ai pu confirmer qu'il a été créé avec celui spécifié par la base de données et que postgis était également activé.
Utilisez la commande suivante pour arrêter temporairement le conteneur et supprimer l'image.
$docker-compose down -v
Enfin, construisons l'environnement nginx.
Tout d'abord, créez le répertoire nginx et créez également le Dockerfile.
$mkdir nginx
$cd nginx/
$touch Dockerfile
backend/containers/nginx/Dockerfile
FROM nginx:1.17.10
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
prochain
backend/containers/nginx/nginx.conf
upstream config {
#Si vous spécifiez le nom de service du conteneur, le nom sera résolu
server django:8000;
}
server {
#Attendez au port 80
listen 80;
location / {
proxy_pass http://config;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
#Acheminer statiquement les demandes de fichiers statiques
location /static/ {
alias /usr/src/app/static/;
}
}
Je pense que vous avez tous les fichiers nécessaires.
Ajoutez le service nginx comme indiqué ci-dessous et changez la commande
du service django de runserver
à gunicorn
.
backend/containers/docker-compose.yml
version: "3.7"
services:
django:
#Nom du conteneur
container_name: django
#Répertoire contenant le fichier docker à construire
build: ./django
#Commandes à exécuter après un démarrage normal
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
#Répertoire à monter
- ./django:/usr/src/app/
ports:
#Port côté hôte: port côté conteneur
- 8000:8000
env_file:
#Fichier à définir dans la variable d'environnement
- ./django/.env
depends_on:
#Service de connexion
- postgres
postgres:
container_name: postgres
build: ./postgres
volumes:
#Les données de base de données sont enregistrées en créant un volume
#Vous pouvez prendre le répertoire et monter et laisser les données réelles directement sur le système d'exploitation hôte.
# /var/lib/postgresql/Les données DB sont stockées dans les données
- sample_postgis_data:/var/lib/postgresql/data
# down -Spécifiez le fichier à exécuter au premier démarrage, y compris lorsqu'il n'y a pas de volume avec v etc.
- ./postgres/sql:/docker-entrypoint-initdb.d
env_file: ./postgres/.env_db
ports:
#Le port côté hôte bat avec le psql local, alors faites-le autrement que 5432
- 5433:5432
nginx:
container_name: nginx
build: ./nginx
volumes:
- ./django/static:/usr/src/app/static
ports:
- 80:80
depends_on:
- django
volumes:
sample_postgis_data:
Commençons le conteneur.
$docker-compose up -d --build
Si vous pouvez confirmer que le conteneur nginx peut livrer à partir du port 80, la construction de l'environnement est terminée.
Connectons-nous à localhost
.
Vous pouvez voir cet écran vu du visage de ma sœur.
Je vous remercie pour votre travail acharné. Après cela, faites bouillir ou cuire au four, faites ce que vous voulez!
backend
└── containers
├── django
│ ├── Dockerfile
│ ├── Pipfile
│ ├── Pipfile.lock
│ ├── config
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── entrypoint.sh
│ ├── manage.py
├── docker-compose.yml
├── nginx
│ ├── Dockerfile
│ └── nginx.conf
└── postgres
├── Dockerfile
└── sql
└── init.sql
Recommended Posts