Ich habe diesen Artikel schon einmal geschrieben. Erstellen Sie mit Docker eine Django-Entwicklungsumgebung! (Docker-compose / Django / postgreSQL / nginx)
Der ursprüngliche Artikel wurde vor langer Zeit geschrieben (ungefähr ein Jahr?). Aber jetzt, da ich etwas Wissen gesammelt habe, dachte ich, ich könnte es ein bisschen besser machen, also entschied ich mich, die Herausforderung anzunehmen!
Ich werde nicht über Details wie die Installation von Docker sprechen. Wenn Sie interessiert sind, lesen Sie bitte den Originalartikel! (Hier Ich denke, etwas wird hilfreich sein.)
Als deutlicher Unterschied zum vorherigen Artikel wird Django als API-Verteilungsserver betrachtet, und Vue.js und React werden für die Front-End-Implementierung angenommen, sodass statische Dateiverteilung und Vorlageneinstellungen durchgeführt werden. Bitte beachten Sie, dass wir nichts anderes tun, als "docker-compose.yml" und "docker-compose.yml.prod" zu erstellen, um die Produktionsumgebung von der Entwicklungsumgebung zu trennen.
Am Ende sieht die Verzeichnisstruktur so aus!
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
Jeder Container wird im Containerverzeichnis unter dem Backend-Verzeichnis abgelegt.
Das Postgres-Verzeichnis wurde im Vergleich zum vorherigen Artikel hinzugefügt.
Beginnen wir jetzt mit dem obersten Django-Verzeichnis!
Zuerst erstellen wir drei Verzeichnisse: Backend, Container und Django! Wechseln Sie dann in das Django-Verzeichnis.
$mkdir -p backend/containers/django
$cd backend/containers/django
Zuerst erstellen wir eine Pipfile im Django-Verzeichnis. Die Version jedes Pakets ist die neueste Version zum Zeitpunkt des Schreibens dieses Artikels, und es gibt keine besondere Präferenz. Fühlen Sie sich frei, es zu ändern. (Betrieb ist nicht garantiert)
Wenn das zu installierende Paket willkürlich ist und nur die Umgebung erstellt werden soll, gibt es kein Problem, wenn nur "django", "gunicorn" und "django-environ" enthalten sind.
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"
Erstellen wir eine virtuelle Umgebung mit pipenv mit der Python3.8-Serie, geben Sie die virtuelle Umgebung ein und überprüfen Sie die Version und die installierten Pakete.
$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
Wenn Sie das Wort "(django)" am linken Rand der Shell sehen, befinden Sie sich in einer virtuellen Umgebung. (Der Einfachheit halber wird die Zeichenfolge von "(django)" ab dem nächsten Mal nicht mehr beschrieben.)
Django ist richtig installiert!
Nachdem Sie bestätigt haben, dass Sie sich im Django-Verzeichnis befinden, verwenden Sie die Befehle von Django, um ein Projekt zu erstellen.
$django-admin startproject config .
Damit ist die Erstellung des Django-Projekts abgeschlossen. Sie sollten ein Konfigurationsverzeichnis und eine Datei mit dem Namen "manage.py" sehen, die im django-Verzeichnis erstellt wurden.
Starten Sie zu diesem Zeitpunkt den Debug-Server mit dem Befehl python manage.py runserver localhost: 8000
, stellen Sie über Ihren Browser eine Verbindung zu loaclhost: 8000
her, und Sie sollten diesen Bildschirm und nicht das Gesicht Ihrer Eltern sehen.
Als nächstes ändern wir die Dateien um Django wie folgt.
Bitte kommentieren Sie SECRET_KEY aus, da es später verwendet wird.
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',
)
Als ich das Pipfile zum ersten Mal erstellt habe, habe ich ein Paket namens "django-environ" hinzugefügt, das die Informationen, die ich ausblenden möchte, wie z. B. SECRET_KEY- und DB-Verbindungsinformationen, in der ".env" -Datei usw. und den Quellcode beschreibt. Es ist ein Paket zur getrennten Verwaltung von settings.py
usw.
env = environ.Env()
env.read_env('.env')
Verwenden Sie es so.
Lassen Sie uns sofort eine .env-Datei erstellen.
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.Verwendet in sh
#compose.Löst den Namen mit dem in yml beschriebenen Dienstnamen auf
DATABASE_HOST=postgres
DATABASE_PORT=5432
DATABASE=postgres
Danach werde ich die Dateien in Bezug auf Gorigori reparieren. Da auch der Pfad aus dem Backend-Verzeichnis beschrieben wird, werden die erforderlichen Dateien entsprechend erstellt, hinzugefügt und geändert.
backend/containers/django/Dockerfile
#Ziehen Sie das Ubuntu-Image und installieren Sie Python
FROM ubuntu:20.04
SHELL ["/bin/bash", "-c"]
#Installieren Sie 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
#Arbeitsverzeichnis einstellen
WORKDIR /usr/src/app
#Umgebungsvariablen festlegen
#Verhindern Sie, dass Python in Pyc-Dateien und -Discs schreibt
ENV PYTHONDONTWRITEBYTECODE 1
#Verhindern Sie, dass Python Standard-E / A puffert
ENV PYTHONUNBUFFERED 1
ENV DEBIAN_FRONTEND=noninteractive
#Abhängigkeitsinstallation und Pipenv-Installation
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 von pipenv
RUN pip install pipenv
#Kopieren Sie die Pipfile von Ihrem lokalen Computer in den Container
COPY Pipfile ./
# Pipfile.Ignorieren Sie die Sperre und installieren Sie das in Pipfile beschriebene Paket auf Ihrem System
#Dann deinstallieren Sie pipenv
RUN pipenv install --system --skip-lock \
&& pip uninstall -y pipenv virtualenv-clone virtualenv
#Abhängigkeiten bei der Installation von Geodatenbibliotheken
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
#Shell-Skript kopieren
# COPY ./entrypoint.sh /usr/src/app/entrypoint.sh
COPY . /usr/src/app/
#Führen Sie das Shell-Skript aus
# ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
Lassen Sie uns überprüfen, ob der Container zu diesem Zeitpunkt funktioniert.
$docker build . -t pipenv_sample
...
$docker run -it pipenv_sample
root@e6bdfb335bee:/usr/src/app#
Wenn Sie sich wie folgt als Root-Benutzer beim Container anmelden können, sind Sie wahrscheinlich erfolgreich!
# 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
Die Python-Version ist 3.8.2 und die Pakete sind ordnungsgemäß installiert!
Melden Sie sich mit Control + d
ab.
Lassen Sie uns abschließend ein Shell-Skript schreiben und speichern, um eine Verbindung zum Postgres-Container herzustellen, der beim Start ausgeführt wird.
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 "$@"
Kommentieren Sie übrigens die beiden Kommentare in der Nähe der letzten Zeile der Docker-Datei, die Sie oben bearbeitet haben.
backend/containers/django/Dockerfile
#Dies
COPY ./entrypoint.sh /usr/src/app/entrypoint.sh
COPY . /usr/src/app/
#Dies
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
Das war's für das Django-Verzeichnis.
--Verzeichnisaufbau
tree
backend
└── containers
├── django
│ ├── Dockerfile
│ ├── Pipfile
│ ├── Pipfile.lock
│ ├── config
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── entrypoint.sh
│ ├── manage.py
└── docker-compose.yml
Als nächstes starten wir den PostgreSQL-Container.
Wechseln Sie zunächst in das Containerverzeichnis und erstellen Sie ein Postgres-Verzeichnis usw.
$cd ../../
$mkdir -p postgres/sql/
Sie sollten jetzt ein Postgres-Verzeichnis und ein SQL-Verzeichnis darin haben.
Fügen wir eine Docker-Datei in das postgres-Verzeichnis ein.
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
In meinem Fall wollte ich eine Kartenanwendung erstellen, daher werde ich das PostGIS-Image verwenden, eine Erweiterung von PostgreSQL, aber ich denke, dass jedes PostgreSQL-Image ausreicht. (Betrieb wurde nicht verifiziert)
Speichern Sie als Nächstes die SQL-Datei, die Sie ausführen möchten, wenn der Container im SQL-Verzeichnis gestartet wird.
backend/containers/postgres/sql/init.sql
CREATE EXTENSION postgis;
Dieses Mal habe ich nur die SQL-Datei zum Aktivieren der Erweiterung gespeichert. Wenn Sie jedoch Daten haben, die Sie zunächst registrieren möchten, können Sie diese gerne speichern.
Fügen Sie abschließend die Datei .env_db hinzu.
Schreiben Sie hier den gleichen <YOUR_DB_NAME> (USER / PASSWORD), den Sie beim Erstellen des Django-Containers geschrieben haben.
Mit den hier beschriebenen Inhalten wird automatisch eine Datenbank erstellt.
backend/containers/postgres/.env_db
#Wenn Sie in env schreiben, wird die Datenbank automatisch erstellt
POSTGRES_DB=<YOUR_DB_NAME>
POSTGRES_USER=<YOUR_DB_USER>
POSTGRES_PASSWORD=<YOUR_DB_PASSWORD>
Damit ist der Aufbau der Postgres-Umgebung abgeschlossen.
--Verzeichnisaufbau
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 ist ein praktisches Werkzeug, um mehrere Container gleichzeitig zu starten und zu verbinden.
Wechseln wir in das Containerverzeichnis und erstellen eine Konfigurationsdatei.
$cd ../
$touch docker-compose.yml
backend/containers/docker-compose.yml
version: "3.7"
services:
django:
#Containername
container_name: django
#Verzeichnis mit der zu erstellenden Docker-Datei
build: ./django
#Befehle, die nach dem normalen Start ausgeführt werden sollen
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
#Verzeichnis zum Mounten
- ./django:/usr/src/app/
ports:
#Host-seitiger Port: Container-seitiger Port
- 8000:8000
env_file:
#Datei, die in der Umgebungsvariablen festgelegt werden soll
- ./django/.env
depends_on:
#Service zum Verbinden
- postgres
postgres:
container_name: postgres
build: ./postgres
volumes:
#DB-Daten werden durch Erstellen eines Volumes gespeichert
#Sie können das Verzeichnis nehmen und die tatsächlichen Daten direkt auf dem Host-Betriebssystem bereitstellen.
# /var/lib/postgresql/DB-Daten werden in Daten gespeichert
- sample_postgis_data:/var/lib/postgresql/data
# down -Geben Sie die Datei an, die beim ersten Start ausgeführt werden soll, auch wenn kein Volume mit v usw. vorhanden ist.
- ./postgres/sql:/docker-entrypoint-initdb.d
env_file: ./postgres/.env_db
ports:
#Der Port auf der Hostseite schlägt mit dem lokalen psql, also machen Sie es anders als 5432
- 5433:5432
volumes:
sample_postgis_data:
Lassen Sie uns nach dem Schreiben Docker-Compose starten.
$docker-compose up -d --build
Lassen Sie uns über einen Browser eine Verbindung zu localhost: 8000
herstellen.
Wenn der Startbildschirm von Django aus dem Gesicht meines Bruders angezeigt wird, ist er erfolgreich.
Sie können sich mit dem folgenden Befehl beim Container anmelden.
$docker exec -it <Dienstname> bash
Mit anderen Worten, in diesem Fall können Sie eine Verbindung mit dem Folgenden herstellen.
$docker exec -it django bash
Oder
$docker exec -it postgres bash
Wir haben bestätigt, dass der Django-Container gestartet wurde. Überprüfen wir daher auch den Postgres-Container.
$docker exec -it postgres bash
#psql -U <YOUR_DB_USER> -d <YOUR_DB_NAME>
psql (11.2 (Debian 11.2-1.pgdg90+1))
"help"Holen Sie sich Hilfe bei.
<YOUR_DB_NAME>=#
<YOUR_DB_NAME>=# SELECT postgis_version();
postgis_version
---------------------------------------
2.5 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 Zeile)
Ich konnte bestätigen, dass es mit dem von der Datenbank angegebenen erstellt wurde und dass Postgis ebenfalls aktiviert war.
Verwenden Sie den folgenden Befehl, um den Container vorübergehend anzuhalten und das Bild zu löschen.
$docker-compose down -v
Lassen Sie uns abschließend die Nginx-Umgebung erstellen.
Erstellen Sie zunächst das Nginx-Verzeichnis und anschließend auch die Docker-Datei.
$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
Nächster
backend/containers/nginx/nginx.conf
upstream config {
#Wenn Sie den Dienstnamen des Containers angeben, wird der Name aufgelöst
server django:8000;
}
server {
#Halten Sie sich an Port 80 bereit
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;
}
#Routenanforderungen für statische Dateien
location /static/ {
alias /usr/src/app/static/;
}
}
Ich denke, Sie haben alle notwendigen Dateien.
Fügen Sie den Nginx-Dienst wie unten gezeigt hinzu und ändern Sie den "Befehl" des Django-Dienstes von "Runserver" in "Gunicorn".
backend/containers/docker-compose.yml
version: "3.7"
services:
django:
#Containername
container_name: django
#Verzeichnis mit der zu erstellenden Docker-Datei
build: ./django
#Befehle, die nach dem normalen Start ausgeführt werden sollen
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
#Verzeichnis zum Mounten
- ./django:/usr/src/app/
ports:
#Host-seitiger Port: Container-seitiger Port
- 8000:8000
env_file:
#Datei, die in der Umgebungsvariablen festgelegt werden soll
- ./django/.env
depends_on:
#Service zum Verbinden
- postgres
postgres:
container_name: postgres
build: ./postgres
volumes:
#DB-Daten werden durch Erstellen eines Volumes gespeichert
#Sie können das Verzeichnis nehmen und die tatsächlichen Daten direkt auf dem Host-Betriebssystem bereitstellen.
# /var/lib/postgresql/DB-Daten werden in Daten gespeichert
- sample_postgis_data:/var/lib/postgresql/data
# down -Geben Sie die Datei an, die beim ersten Start ausgeführt werden soll, auch wenn kein Volume mit v usw. vorhanden ist.
- ./postgres/sql:/docker-entrypoint-initdb.d
env_file: ./postgres/.env_db
ports:
#Der Port auf der Hostseite schlägt mit dem lokalen psql, also machen Sie es anders als 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:
Beginnen wir den Container.
$docker-compose up -d --build
Wenn Sie bestätigen können, dass der Nginx-Container von Port 80 aus liefern kann, ist die Umgebungskonstruktion abgeschlossen.
Verbinden wir uns mit localhost
.
Sie können diesen Bildschirm vom Gesicht meiner Schwester aus sehen.
Danke für deine harte Arbeit. Danach kochen oder backen, bitte machen Sie, was Sie wollen!
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