Erstellen Sie mit Docker Compose eine Entwicklungsumgebung für Django + MySQL + nginx

Betriebsumgebung und Geschichte

Um eine Webanwendung zu entwickeln, möchte ich mit Docker eine Mass-Docking-Entwicklungsumgebung ** Django + MySQL + nginx ** erstellen.

Verzeichnisaufbau

Die anfängliche Verzeichnisstruktur ist wie folgt.

app
├── docker-compose.yml
├── mysql
│   ├── Dockerfile
│   └── init.d
│       └── init.sql
├── nginx
│   ├── conf
│   │   └── app_nginx.conf
│   └── uwsgi_params
└── python
    ├── .dockerignore
    ├── Dockerfile
    └── requirements.txt

Aus diesem Zustand

Im Folgenden finden Sie ein Beispiel für die Erstellung einer Anwendung namens "app" mit Django. Ersetzen Sie es durch den Namen der Anwendung, die Sie erstellen möchten.

docker-compose.yml sieht endlich so aus

Schreiben wir zuerst das Ergebnis. Durch Versuch und Irrtum, während ich googelte und Bücher las und rücksichtslose Fehlermeldungen bekämpfte, kam ich schließlich zu docker-compose.yml wie diesem. Wenn ich auf die lange Reise zurückblicke, wird der innere Augenwinkel heiß.

docker-compose.yml


version: '3.7'

services:
  python:
    build:
      context: ./python
      dockerfile: Dockerfile
    command: uwsgi --socket :8001 --module app.wsgi --py-autoreload 1 --logto /tmp/uwsgi.log
    restart: unless-stopped
    container_name: Django
    networks:
      - django_net
    volumes:
      - ./src:/code
      - ./static:/static
    expose:
      - "8001"
    depends_on:
      - db

  db:
    build:
      context: ./mysql
      dockerfile: Dockerfile
    restart: unless-stopped
    container_name: MySQL
    networks:
      - django_net
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: "*******"
      TZ: "Asia/Tokyo"
    volumes:
      - app.db.volume:/var/lib/mysql
      - ./mysql/init.d:/docker-entrypont-initdb.d

  nginx:
    image: nginx:1.17
    restart: unless-stopped
    container_name: nginx
    networks:
      - django_net
    ports:
      - "80:80"
    volumes:
      - ./nginx/conf:/etc/nginx/conf.d
      - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
      - ./static:/static
    depends_on:
      - python

networks:
  django_net:
    driver: bridge

volumes:
  app.db.volume:
    name: app.db.volume

Wenn Sie die Komposition entsprechend abkürzen, sieht es so aus. 図1.png

Django-Einstellungen

Wie auch immer, aus den Django-Einstellungen. Bearbeiten Sie `` `Dockerfile``` direkt unter dem" Python "-Verzeichnis wie folgt.

./python/Dockerfile


FROM python:3.8.5
WORKDIR /code
ADD requirements.txt /code/
RUN pip install --upgrade pip && pip install -r requirements.txt
ADD . /code/

Erstellen Sie zunächst ein Arbeitsverzeichnis mit dem Namen "Code" und wechseln Sie dorthin. Nachdem Sie `require.txt``` zu diesem Verzeichnis hinzugefügt haben, installieren Sie die erforderlichen Pakete mit` pip``` und fügen Sie schließlich `` `code```` zum Container hinzu.

Daher sind die Pakete, die mit `pip``` installiert werden sollen, in` require.txt``` wie folgt aufgeführt. Dieses Mal benötigen Sie drei Dinge: Django selbst, uWSGI für die Socket-Kommunikation mit nginx und mysqlclient für die Verbindung zu MySQL.

:./python/requirements.txt


Django==2.2.12
uwsgi==2.0.18
mysqlclient==1.4.6

Übrigens, lassen Sie uns auch `` `.dockerignore``` bearbeiten. Es wäre ein Problem, wenn zusätzliche Dateien in den Container gelegt würden.

:./python/.dockerignore


**/__pycache__
**/.DS_Store
**/.Thumbs.db
**/.git
**/.gitignore

Basierend auf den bisherigen Einstellungen sieht es wie folgt aus, wenn Sie Django in `` `docker-compose.yml``` einstellen.

docker-compose.yml (Auszug)


python:
  build:
    context: ./python        # docker-compose.Relativer Pfad zu Dockerfile von yml
    dockerfile: Dockerfile   #Explizite Angabe, dass die Einstellung in "Dockerfile" geschrieben ist
  command: uwsgi --socket :8001 --module app.wsgi --py-autoreload 1 --logto /tmp/uwsgi.log
  restart: unless-stopped    #Wenn der Container abnormal stoppt, starten Sie ihn neu
  container_name: Django     #Containernamen definieren
  networks:
    - django_net             #Netzwerkname "django_Geben Sie "net" an
  volumes:
    - ./src:/code            # ./In src/Code einbinden
    - ./static:/static       # ./Zu statisch/Statisch montieren
  expose:
    - "8001"     #Öffnen Sie den Port 8001, damit uwsgi mit nginx kommunizieren kann
  depends_on:
    - db

Die uWSGI-Einstellungen sind verwirrend, aber wenn Sie den Teil `app.wsgi``` als` [Django-Projektname] .wsgi``` behalten, ist der Rest magisch.

MySQL-Einstellungen

Um ehrlich zu sein, bin ich mir bei den MySQL-Einstellungen nicht sicher. Meistens hasse ich RDB auf einer Ebene, auf der ich keine zufriedenstellenden Abfragen schreiben kann.

Aufgrund der Prüfung verschiedener Handbücher scheint dies die beste Vorgehensweise zu sein. Ich weiß es nicht.

./mysql/Dockerfile


FROM mysql:5.7
COPY init.d/* /docker-entrypoint-initdb.d/

sql:./mysql/init.d/init.sql


CREATE DATABASE IF NOT EXISTS app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS 'app_user'@'%' IDENTIFIED BY '[Passwort]';
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%';
FLUSH PRIVILEGES;

Übrigens ist die `app.db``` (Datenbankname), die von der oben genannten` init.sql erstellt wurde, für die Einstellung von` `settings.py erforderlich, die später beschrieben wird. Also werde ich nicht vergessen.

Basierend auf dieser Einstellung sieht es folgendermaßen aus, wenn Sie MySQL mit `` `docker-compose.yml``` konfigurieren:

docker-compose.yml (Auszug)


db:
  build:
    context: ./mysql         # docker-compose.Relativer Pfad zu Dockerfile von yml
    dockerfile: Dockerfile   #Explizite Angabe, dass die Einstellung in "Dockerfile" geschrieben ist
  restart: unless-stopped    #Wenn der Container abnormal stoppt, starten Sie ihn neu
  container_name: MySQL      #Containernamen definieren
  networks:
    - django_net             #Netzwerkname "django_Geben Sie "net" an
  ports:
    - "3306:3306"            #Geben Sie die zu kommunizierende Portnummer an
  environment:
    MYSQL_ROOT_PASSWORD: "*******"  #Legen Sie das Root-Passwort mit der Umgebungsvariablen fest
    TZ: "Asia/Tokyo"                #Zeitzone mit Umgebungsvariable einstellen
  volumes:
    - app.db.volume:/var/lib/mysql   #Volume the database "App.db.Auf "Lautstärke" speichern
    - ./mysql/init.d:/docker-entrypont-initdb.d

Wir haben beschlossen, die Datenbank auf einem Volume mit dem Namen "app.db.volume" zu speichern. Legen Sie daher "Volumes" fest.

docker-compose.yml (Auszug)


volumes:
  app.db.volume:
    name: app.db.volume

Nginx-Einstellungen

Ich bin mir auch nicht sicher über die uWSGI-Einstellungen. Um ehrlich zu sein, hatte ich keine Lust, uWSGI zu untersuchen. Es tut uns leid.

Es scheint, dass Sie die Parameter wie folgt entsprechend einstellen sollten. Ich weiß es nicht.

./nginx/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;

Es ist also die Einstellung von nginx, aber zuerst müssen Sie Port 8001 für die Socket-Kommunikation mit uWSGI öffnen.

Außerdem wird der Abhörport für Nginx festgelegt. Meine Einstellung ist Nummer 80, aber dies ist die Einstellung der virtuellen Maschine, auf der der Container ausgeführt wird, und Stellen Sie die Daten, die durch Nummer 80 des Gasts (virtuelle Maschine) fließen, auf Nummer 8081 des Hosts ein. Is.

Wenn Sie jetzt mit dem Host-Browser auf "127.0.0.1:8081" zugreifen, wird die Webanwendung angezeigt, die als Gast ausgeführt wird.

conf:./nginx/conf/app_nginx.conf


upstream django {
  ip_hash;
  server python:8001;  #Port für die Kommunikation zwischen Django und Nginx auf uWSGI
}

server {
  listen      80;      #Standby-Port
  server_name 127.0.0.1;
  charset     utf-8;

  location /static {
    alias /static;
  }
  
  client_max_body_size 75M;
  
  location / {
    uwsgi_pass  django;
    include     /etc/nginx/uwsgi_params;
  }
}

server_tokens off;

Basierend auf dieser Einstellung ergibt das Setzen von nginx in `docker-compose.yml```: Ähnlich wie bei den Django-Einstellungen wird . / Static``` auf`` / static``` gemountet, sodass statische Inhalte, die Django nicht verarbeitet, mit nginx zurückgegeben werden können.

docker-compose.yml (Auszug)


nginx:
  image: nginx:1.17         #Holen Sie sich das Bild von Nginx richtig
  restart: unless-stopped   #Wenn der Container abnormal stoppt, starten Sie ihn neu
  container_name: nginx     #Containernamen definieren
  networks:
    - django_net            #Netzwerkname "django_Geben Sie "net" an
  ports:
    - "80:80"               #Geben Sie die zu kommunizierende Portnummer an
  volumes:
    - ./nginx/conf:/etc/nginx/conf.d
    - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
    - ./static:/static      # ./Zu statisch/Statisch montieren
  depends_on:
    - python

Außerdem habe ich gesagt, dass ich bisher "django_net" verwenden würde, aber ich habe es überhaupt nicht festgelegt. Vergessen Sie also nicht, auch das Element "Netzwerke" festzulegen.

docker-compose.yml (Auszug)


networks:
  django_net:
    driver: bridge

Django-Projekteinstellungen

Übrigens sind alle Einstellungen von Docker abgeschlossen. Alles was Sie tun müssen, ist die Einstellungen für Django selbst zu belassen.

Lassen Sie uns zunächst das Projekt starten.

$ docker-compose run python django-admin.py startproject app .

Wenn Sie nach dem Drücken dieses Befehls in `src``` und` static``` schauen, sollten Sie verschiedene Dateien für Django sehen.

Bearbeiten Sie dann `` `. / Src / app / settings.py```.

python:./src/app/settings.py


DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',    #Auskommentieren
        'ENGINE': 'django.db.backends.mysql',        #hinzufügen
        # 'NAME': os.path.join(BASE_DIR, 'app_db'),  #Auskommentieren
        'NAME': 'app_db',    # init.Stellen Sie sicher, dass es mit dem Datenbanknamen identisch ist, der in SQL CREATE war
        'USER': 'app_user',  #hinzufügen
        'PASSWORD': '*****', #Hinzufügen (wie das in der Umgebungsvariablen angegebene Kennwort)
        'PORT': '3306',      #hinzufügen
        'HOST': 'db',        #hinzufügen
    }
}

STATIC_URL = '/static/'   #hinzufügen
STATIC_ROOT = '/static/'  #hinzufügen

...(Weggelassen)

LANGUAGE_CODE = 'ja'      #Bearbeiten
TIME_ZONE = 'Asia/Tokyo'  #Bearbeiten

Alles was Sie tun müssen, ist den bekannten Befehl in Django mit Docker-Compose zu drücken.

$ docker-compose run python ./manage.py migrate          #DB-Migration
$ docker-compose run python ./manage.py createsuperuser  #Administratoreinstellungen
$ docker-compose run python ./manage.py collectstatic    #Statische Datei kopieren

Starten und stoppen Sie den Container

Bewegen wir nun den Container. Komm raus, Django!

$ docker-compose up -d

Und wenn ich über den Host-Browser auf 127.0.0.1:8081 zugreife ... スクリーンショット 2020-10-27 21.26.10.png Ich habs gemacht! !! **Hallo! Docker! Hallo! Django! ** ** **

Um den Container anzuhalten, machen Sie `` `stop```.

$ docker-compose stop

Rücksichtslose Fehlermeldungen

Übrigens, wenn Sie es in einem Artikel wie diesem zusammenstellen, scheint es missverstanden zu werden, als ob ich es als knusprig eingestellt hätte, also werde ich aufschreiben, wie viele Drehungen und Wendungen ich durchgemacht habe.

Zuerst diese Fehlermeldung.

ERROR: The Compose file './docker-compose.yml' is invalid because:
services.pithon.volumes contains an invalid type, it should be an array

Ich war wütend und wütend darüber, was daran falsch war, aber ich konnte keine direkte Lösung finden.

Plötzlich bemerkte ich, dass "es sollte ein Array sein" (es sollte ein Array sein, aber es sollte nicht sein) der Punkt ist, und als ich die Syntax von YAML überprüfte ... Drücken Sie das Array durch aus. Bitte setzen Sie nach "-" "ein Leerzeichen mit halber Breite](https://magazine.rubyist.net/articles/0009/0009-YAML.html#%E9%85%8D % E5% 88% 97) wird angegeben.

Wenn Sie genau hinschauen, hier,

volumes:
  - ./src:/code

Aber,

volumes:
  -./src:/code  # 「-Es gibt kein halbes Feld danach

Es war so. ** Ich habe 2 Stunden gebraucht, um das zu bemerken **.

** Dieser verdammte Taschenrechner! !! Bist du der nervige Mann eines Verwandten? !! ** **. Diese Behandlung wird durchgeführt, weil nur ein Raum mit halber Breite vorhanden war. Ich kann es nicht mehr machen Erstens mag ich den Namen "Yamuru" nicht. Ist es koreanisches Essen (das ist Namuru)?

Dann diese Fehlermeldung.

Unsupported config option for services.nginx: 'deponds_on'

Wie Sie bei näherer Betrachtung sehen können, ist `abhängiges_``` korrekt, nicht` deponds_on```. Es ist eine dumme Rechtschreibfehler, aber ** ich habe zwei Stunden gebraucht, um das zu bemerken **.

** Dieser verdammte Taschenrechner! !! Gib meine kostbare Zeit im Leben zurück! !! ** ** ** Ich interessiere mich nicht wirklich für Gesichtserkennung mit tiefem Lernen, und ich möchte einen raffinierten Computer, der diese Art von menschlichem Fehler sanft korrigiert.

Ja, auch diese Fehlermeldung.

ERROR: Service 'nginx' depends on service 'python' which is undefined.

Der Grund, warum ich diesen Fehler bekam, war, dass ich `python``` als` pithon``` falsch eingegeben habe (siehe die erste Fehlermeldung). ** Ich habe eine Stunde gebraucht, um das zu bemerken **.

** Dieser verdammte Taschenrechner! !! Dein Kopf ist ein fröhlicher Satz! !! ** **. Ich bin überrascht über die Entwicklung wie ein Zwei-Frame-Cartoon, aber die Ursache ist im Dvorak-Array sind y und ich nebeneinander. Es scheint.

Freuen Sie sich auf das nächste Mal

Verstehst du jetzt, wie sehr ich Computer hasse, warum ich mich für maschinelles Lernen an der Graduiertenschule entschieden habe und warum sowohl Forscher als auch Ingenieure aufgehört haben (eine Geschichte, die sich völlig vom Zweck dieses Artikels unterscheidet).

** Es ist genau richtig, als Spielzeug zu spielen, aber ich habe keine Lust, es als Job zu machen **. Kurz gesagt, er ist in keiner Weise inkompetent. Ich bin dir wirklich dankbar.

Am Ende war es eine sehr herzerwärmende Pointe, aber beim nächsten Mal möchte ich eine Produktionsumgebung auf AWS erstellen. Bleib dran.

Recommended Posts

Erstellen Sie mit Docker Compose eine Entwicklungsumgebung für Django + MySQL + nginx
Einfache Erstellung der Docker Compose + Django-Entwicklungsumgebung
Erstellen Sie mit Docker eine PureScript-Entwicklungsumgebung
Erstellen Sie mit Docker eine Wordpress-Entwicklungsumgebung
Einfache Konstruktion der Docker + Django-Entwicklungsumgebung
Erstellen Sie mit Docker ein SPA für Laravel 6.2 / Vue.js / Nginx / Mysql / Redis
Verfahren zum Erstellen einer Rails-Anwendungsentwicklungsumgebung mit Docker [Rails, MySQL, Docker]
Erstellen Sie eine Entwicklungsumgebung für Docker + Rails6 + Postgresql
Erstellen Sie mit Docker schnell eine WordPress-Entwicklungsumgebung
Erstellen Sie eine Entwicklungsumgebung für Docker, Java und Code
[Kopieren und Einfügen] Erstellen Sie mit Docker Compose Part 2 eine Laravel-Entwicklungsumgebung
Erstellen Sie mit Docker eine lokale Entwicklungsumgebung für Rails-Tutorials (Rails 6 + PostgreSQL + Webpack)
Erstellen Sie mit Docker eine Node.js-Umgebung
Erstellen Sie mit Docker CE für Windows eine Webanwendungsentwicklungsumgebung, die Java, MySQL und Redis verwendet
Erstellen Sie eine Entwicklungsumgebung für Rails-Anwendungen mit Docker [Docker, Rails, Puma, Nginx, MySQL]
So beenden Sie Docker für Mac und erstellen eine Docker-Entwicklungsumgebung mit Ubuntu + Vagrant
Erstellen Sie eine Laravel / Docker-Umgebung mit VSCode devcontainer
[Win10] Erstellen Sie eine JSF-Entwicklungsumgebung mit NetBeans
Erstellen Sie mit Docker eine Spring Boot-Entwicklungsumgebung
Erstellen Sie eine Java-Entwicklungsumgebung mit VS Code
Erstellen Sie eine Debug-Umgebung auf einem Container. Erstellen Sie mit Docker eine lokale Entwicklungsumgebung für Rails-Tutorials.
Erstellen einer Entwicklungsumgebung für Java-Webanwendungen mit Docker für Mac Teil1
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 6.x)
Erstellen Sie mit CentOS7 + Nginx + pm2 + Nuxt.js eine Entwicklungsumgebung auf AWS EC2
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 5.x)
Vorlage: Erstellen Sie eine Ruby / Rails-Entwicklungsumgebung mit einem Docker-Container (Ubuntu-Version).
Erstellen Sie mit Docker für Mac Teil2 eine Entwicklungsumgebung für Java-Webanwendungen
Vorlage: Erstellen Sie eine Ruby / Rails-Entwicklungsumgebung mit einem Docker-Container (Mac-Version).
So erstellen Sie eine Docker-Umgebung mit Gradle for IntelliJ
[Hinweis] Erstellen Sie eine Python3-Umgebung mit Docker in EC2
Erstellen einer Docker-Umgebung mit WSL
Erstellen Sie eine Entwicklungsumgebung, um Ruby on Jets + React-Apps mit Docker zu erstellen
Build Rails (API) x MySQL x Nuxt.js Umgebung mit Docker
Versuchen Sie, mit Docker eine Java-Entwicklungsumgebung zu erstellen
[Rails] [Docker] Kopieren und Einfügen ist in Ordnung! So erstellen Sie eine Rails-Entwicklungsumgebung mit Docker
Ich habe eine Entwicklungsumgebung mit Rails6 + Docker + PostgreSQL + Materialise erstellt.
So erstellen Sie mit Docker ~ Express ~ eine [TypeScript + Vue + Express + MySQL] -Umgebung
Erstellen Sie mit IntelliJ IDEA eine Entwicklungsumgebung "Spring Thorough Introduction"
Ich habe versucht, mit Docker eine Padrino-Entwicklungsumgebung zu erstellen
Erstellen Sie mit Docker eine Vue3-Umgebung!
Erstellen Sie die Node.js-Umgebung mit Docker Compose
Erstellen Sie mit Pleiades 4.8 eine Tomcat 8.5-Umgebung
Umgebungsbau mit Docker für Anfänger