Neulich habe ich eine Flask-App mit "Docker-Compose" erstellt und auf Qiita eingeführt.
■ Ich habe ein Spiel WebApp mit Flask + Docker + Vue.js + AWS ...
■ Quellcode und Spielregeln sind auf Github verfügbar
Dieses Mal habe ich mich mit der "Docker-Compose-Konfiguration" in der Flask-App-Entwicklung befasst. Ich hoffe, es ist hilfreich für diejenigen, die erwägen, Webanwendungen mit mehreren Containern zu entwickeln: entspannt:
Containerisierungstechnologie, die zunächst schwer zu bekommen ist. Aber wenn Sie sich erst einmal daran gewöhnt haben, können Sie nicht mehr loslassen.
Warum nicht in einen Behälter packen? Es ist keine schlechte Sache, und je nach Umfang und Inhalt kann ein Container ausreichen.
Die einfache Aufteilung in mehrere Behälter bietet viele Vorteile. Wir werden die Rollen in grundlegende ** 1 Container 1 Aufgabe ** aufteilen.
Auch ein schneller Export hat solche Vorteile. Ich denke eher, dass es viele Fälle gibt, in denen mehrere Container zusammenarbeiten, wenn ein System mit Docker erstellt wird.
Führen Sie den Befehl im selben Verzeichnis wie die Datei "docker-compose.yml" aus. Erstellen und steuern Sie den Docker-Container basierend auf der Yaml-Datei.
up
Mehrere Container erstellen / starten
docker-compose up -d
-d
Startet im Hintergrund im Trennmodus
Wenn Sie einen Containernamen als Argument verwenden, wird nur dieser Container gestartet.
docker-compose up -d hoge
#Starten Sie nur den Behälter
kill
Den laufenden Container gewaltsam anhalten
docker-compose kill
down
Stoppen Sie den Container und löschen Sie das erstellte Containernetzwerk.
docker-compose down
build
Erstellen Sie den Service.
Einfach ausgedrückt, erstellen Sie ein "Bild".
docker-compose build
Am gestarteten Container anbringen
docker exec -it ID_OR_NAME bash
Der Teil "ID_OR_NAME" kann einfach durch Eingabe des in yaml definierten "Containernamens" angehängt werden. Es wird häufig für die DB-Initialisierung, die Bestätigung des Ausgabeinhalts, die einfache Dateibestätigung usw. im Container verwendet.
docker-compose.yml Von hier aus werden wir die Einstellung "Docker-Compose" in der Flask-App des Hauptthemas berühren.
docker-compose.yml
version: "3"
services:
nginx:
build: nginx
container_name: nginx
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./docker_data/log/nginx:/var/log/nginx
depends_on:
- flask
networks:
- front
flask:
build: .
container_name: flask
environment:
# PROD, DEV, TEST
FLASK_ENV: PROD
volumes:
- .:/introdon
- ./docker_data/log/flask/gunicorn_access.log:/var/log/gunicorn_access.log
- ./docker_data/log/flask/gunicorn_error.log:/var/log/gunicorn_error.log
depends_on:
- db
- db_test
networks:
- front
- back
- test
expose:
- 5000
db:
build: db
container_name: mariadb
ports:
- "53306:3306"
volumes:
- ./db/my.conf:/etc/mysql/conf.d/my.cnf
- ./docker_data/mysql:/var/lib/mysql
- ./docker_data/log/mysql:/var/log/mysql
networks:
- back
environment:
MYSQL_DATABASE: introdon
env_file: ./db/envfile #wegen Passwortbeschreibung ignorieren
db_test:
build: db
container_name: mariadb_test
ports:
- "63306:3306"
volumes:
- ./db/my.conf:/etc/mysql/conf.d/my.cnf
networks:
- test
environment:
MYSQL_DATABASE: introdon_test
env_file: ./db/envfile #wegen Passwortbeschreibung ignorieren
networks:
front:
driver: bridge
back:
driver: bridge
test:
driver: bridge
Das Folgende ist eine kurze Übersicht über die Grundlagen.
services: Schreiben Sie den zu startenden Container mit einem beliebigen Namen. Dieses Mal gibt es vier Container: nginx, flask, db und db_test.
build: Schreiben Sie die Build-Quelle des Bildes.
build: .
Erstellen Sie basierend auf der Docker-Datei im entsprechenden Verzeichnis.
In diesem Fall handelt es sich um eine Docker-Datei im selben Verzeichnis wie die .
yml-Datei.
ports: Portzuordnung mit lokal. Die linke Seite ist lokal und die rechte Seite ist der Port im Container.
ports:
- "63306:3306"
Wenn Sie im obigen Fall eine Verbindung zur lokalen Nummer 63306 herstellen, werden Sie mit der Nummer 3306 im Container verbunden.
Geben Sie die Portzuordnung als Zeichenfolge ein. Die yml-Spezifikation erkennt das xx: yy-Format als 60-fache Zahl und kann als Zeit erkannt werden. Machen Sie es daher zu einer Zeichenfolge.
Sie müssen einen Port verwenden, der nicht lokal verwendet wird. Wenn er bereits verwendet wird, wird eine Fehlermeldung mit "up" angezeigt. Wenn Sie eine Fehlermeldung erhalten, überprüfen Sie den Überwachungsport.
sudo lsof -i -P | grep "LISTEN"
volumes: Binden Sie die lokale Datei und die Datei im Container.
--Daten können lokal gespeichert und beibehalten werden.
depends_on: Geben Sie den abhängigen Container an. Mit anderen Worten, Es bedeutet "Bitte starten Sie diesen Container, nachdem der angegebene Container gestartet wurde".
networks: Erstellen Sie ein Netzwerk. Wenn Sie ein Netzwerk mit einem beliebigen Namen angeben, können Sie eine Verbindung zu einem Container herstellen, der dasselbe Netzwerk definiert.
networks driver: Die Standardeinstellung ist "Brücke". Der Fahrer ist wie folgt.
--bridge
: Wird für die Kommunikation auf demselben Host verwendet
Als nächstes werde ich jeden Container einzeln erklären. : Pfeil nach unten:
Flaschencontainereinstellungen, die für die Anwendungsserverrolle verantwortlich sind.
#Auszug
flask:
build: .
container_name: flask
environment:
# PROD, DEV, TEST
FLASK_ENV: PROD
volumes:
- .:/introdon
- ./docker_data/log/flask/gunicorn_access.log:/var/log/gunicorn_access.log
- ./docker_data/log/flask/gunicorn_error.log:/var/log/gunicorn_error.log
depends_on:
- db
- db_test
networks:
- front
- back
- test
expose:
- 5000
Der Container wird aus der Docker-Datei im selben Verzeichnis erstellt. Der Containername ist Kolben.
Der Modus der App wird durch die Umgebungsvariable FLASK_ENV
geändert.
--PROD: Produktionsumgebungsmodus mit Gunicorn und WSGI --DEV: Entwicklungsmodus. Fehler und Debug-Inhalte werden angezeigt, und das automatische Neuladen wird ebenfalls durchgeführt. --TEST: Pytest wird ausgeführt. Verwenden Sie zum Testen einen DB-Container
volumes:
--flask Volumen Sie den App-Code in einen Container. --Erstellen Sie ein Docker_Data-Verzeichnis auf dem Host und machen Sie das Gunicorn-Zugriffsprotokoll und das Fehlerprotokoll dauerhaft.
depends_on Starten Sie den App-Container, nachdem die Container db und db_test gestartet wurden. Es startet nur den Container und überwacht nicht den internen Start. Es ist üblich, Tests auszuführen und Fehler zu erhalten, bevor die Datenbank im abhängigen Container aktiv ist. Warten Sie in diesem Fall einige Sekunden und starten Sie es dann. Es wird erfolgreich getestet.
networks --front: Verbindung mit Nginx, das für den Webserver verantwortlich ist --back: Es wird mit dem Produktions-DB-Container verbunden. --test: Es wird eine Verbindung zum DB-Container zum Testen hergestellt.
expose Stellen Sie den Port nur dem verknüpften Dienst zur Verfügung. In diesem Fall kann mit PORT: 5000 nur auf den vorderen Webserver, den hinteren DB-Server und den Test-DB-Testserver zugegriffen werden. Mit PORT: 5000 kann nicht von der Host-Umgebung aus darauf zugegriffen werden.
Dockerfile Eine Docker-Datei für den Flask-Container, auf dem der App-Server ausgeführt wird.
FROM python:3.8
WORKDIR /introdon
COPY Pipfile ./
COPY Pipfile.lock ./
RUN pip install pipenv && \
pipenv install --system
ENV PYTHONPATH /introdon
CMD ["./flask_env.sh"]
FROM python:3.8 Erstellen Sie mit dem offiziellen Python-Image der Version 3.8.
Verwenden Sie Pipfile, um das Python-Paket mit pipenv zu installieren.
pipenv install --system
Installieren Sie direkt auf dem System mit --system
, ohne die virtuelle Python-Umgebung zu verwenden.
Zum Zeitpunkt der Erstellung wird eine Warnung mit der Meldung "Es gibt keine virtuelle Umgebung" angezeigt, aber es gibt kein Problem, da sie direkt installiert wird.
Wenn Sie neugierig sind, können Sie die Datei require.txt erstellen und mit pip installieren.
Mit pipenv können Sie abhängige Pakete und deren Versionen streng verwalten und reproduzieren.
CMD ["./flask_env.sh"]
Wenn der Container hoch ist, führe ich flask_env.sh
aus.
In dieser Shell-Datei wird der Modus "Produktion, Entwicklungsmodus, Test" entsprechend der Umgebungsvariablen getrennt und die Anwendung gestartet.
Ein Container, der die Rolle eines Webservers spielt.
#Auszug
nginx:
build: nginx
container_name: nginx
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./docker_data/log/nginx:/var/log/nginx
depends_on:
- flask
networks:
- front
ports: Für die Produktionsfreigabe ist 80:80 festgelegt. Wenn die Hostumgebung in der Entwicklungsphase mit Nr. 80 kollidiert, können Sie die linke Seite der Hostseite für die Entwicklung ändern.
volumes: Die auf dem Host gespeicherte Einstellungsdatei wird auf der Containerseite geladen. Ich habe die Nginx-Protokolldaten auf dem Host gespeichert und dauerhaft gemacht.
später, Starten Sie den Nginx-Behälter, nachdem der Kolbenbehälter gestartet wurde Sie befinden sich im vorderen Netzwerk und sind mit dem Flaschenbehälter verbunden.
Dockerfile Es ist kurz, aber hier ist die Docker-Datei.
FROM nginx:1.17.9
CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
Das Volume / etc / nginx / nginx.conf
wird als Einstellungsdatei gestartet.
Ein Container, der die Rolle eines DB-Servers spielt.
#Auszug
db:
build: db
container_name: mariadb
ports:
- "53306:3306"
volumes:
- ./db/my.conf:/etc/mysql/conf.d/my.cnf
- ./docker_data/mysql:/var/lib/mysql
- ./docker_data/log/mysql:/var/log/mysql
networks:
- back
environment:
MYSQL_DATABASE: introdon
env_file: ./db/envfile #wegen Passwortbeschreibung ignorieren
Mapping PORT bei 53306: 3306.
volumes: Die auf dem Host gespeicherte Einstellungsdatei wird gelesen. Darüber hinaus bleiben MySQL-Daten erhalten, indem sie auf der Hostseite gespeichert werden. Das Protokoll wird auch in Verzeichnisse unterteilt und auf der Hostseite gespeichert.
networks: Ich bin über ein "Back" -Netzwerk mit dem Kolbenbehälter verbunden.
environment:
Der Datenbankname und andere Dinge, die jeder sehen kann, werden in yaml so beschrieben, wie sie sind.
Elemente, die Sie geheim halten möchten, wie Benutzernamen und Kennwörter, werden als separate Dateien gelesen.
env_file: ./db/envfile
Dockerfile Unten ist die Docker-Datei.
FROM mariadb
RUN apt-get update && \
apt-get install -y locales && \
rm -rf /var/lib/apt/lists/* && \
echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
Ich möchte Japanisch für DB verwenden, also installiere locale
auf dem Container-Betriebssystem und
Ich ändere die Gebietsschemaeinstellung auf "ja_JP.UTF-8".
my.conf Dies ist eine Einstellungsdatei, die in den Container geladen werden soll.
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
general_log_file=/var/log/mysql/mysql.log
general_log=1
[client]
default-character-set=utf8mb4
[mysqld]
Dies ist die Einstellung auf der MySQL-Deamon-Seite.
Auf UTF8 setzen.
Legen Sie auch das Ausgabeziel des Protokolls fest.
Setzen Sie general_log
auf 1 oder ON
, um die Protokollausgabe von ausgeführtem SQL zu aktivieren.
Wenn nicht angegeben oder 0 oder "AUS" ist, wird die Protokollausgabe deaktiviert.
[client] Dies ist die Einstellung auf der Clientseite der Verbindungsquelle. Auch hier ist der Zeichencode auf UTF8 gesetzt.
envfile Dies ist eine separate Datei für die Einstellungen, die durch "env_file" in der yml-Datei angegeben werden.
MYSQL_ROOT_PASSWORD=XXXXXXXXX
MYSQL_USER=XXXXXXXXX
MYSQL_PASSWORD=XXXXXXXXX
Sie können es in der Versionsverwaltung ignorieren, indem Sie es in Dateien aufteilen.
Ich wollte die Dateien, auf die das Passwort verweist, zu einer zusammenfassen Diese Umgebungsdatei wird nicht nur zum Erstellen des DB-Containers verwendet, sondern auch zum Festlegen der DB-Verbindung im Kolbencontainer.
Ich habe das python-dotenv
-Paket verwendet, um von der Kolbenseite zu lesen.
introdon/config_flask.py
import os
from dotenv import load_dotenv
load_dotenv('db/envfile')
MYSQL_USER = os.environ['MYSQL_USER']
MYSQL_PASSWORD = os.environ['MYSQL_PASSWORD']
(1) Verwenden Sie die dotenv-Methode load_dotenv, um den Inhalt der envfile in die Umgebungsvariable zu importieren. (2) Geben Sie in os.environ mit key an und rufen Sie die entsprechende Umgebungsvariable ab ③ Stellen Sie mit SQL Alchemy eine Verbindung zum DB-Container her, indem Sie den erhaltenen Benutzer und das Kennwort verwenden.
Es gibt unerwartete Möglichkeiten, eine Verbindung zum gestarteten DB-Container herzustellen, z. B. das Erfassen und Bestätigen von Daten. Es gibt verschiedene Möglichkeiten, einen DB-Container zu verbinden.
CLI Es gibt zwei Arten von Verbindungen mit Befehlen.
① An den Container anschließen und mit der DB verbinden
#Am Behälter befestigen
docker exec -it mariadb bash
#Melden Sie sich nach dem Anhängen bei der Datenbank an
mysql -uXXXXX -pXXXXX
② Melden Sie sich direkt bei der DB an
mysql -h 127.0.0.1 -uXXXXX -pXXXXX -P 53306
127.0.0.1 ist die lokale Loopback-Adresse. Es ist ein sogenannter lokaler Host.
Verwenden Sie PORT: 53306 mit -P 53306
.
53306 ist der hostseitige Port, der für die Zuordnung zum DB-Container in der yml-Datei angegeben ist.
Nach ①② können Sie Daten durchsuchen und erfassen, indem Sie in MySQL arbeiten.
Intellij Es ist ärgerlich, es jedes Mal mit CLI einzugeben. Ich möchte es in einer Tabelle wie Excel durchsuchen. ..
Intellij (Jetbrains IDE) erleichtert das Einrichten. Nach dem Einrichten ist das Durchsuchen und Bearbeiten so einfach wie das Berühren von Excel. (Möglicherweise hat Visual Studio eine ähnliche Funktion)
Es wurde in früheren Artikeln behandelt, bitte beziehen Sie sich darauf. [Zusammenfassung der Einstellungsmethode für den Betrieb von AWS über IntelliJ (Jetbrains). Einfache Verbindung mit #DB](https://qiita.com/akinko/items/d7001a8fe3ac87e1790c#db%E3%81%A8%E3%81%AE%E7%B0%A1%E5%8D%98%E6% 8E% A5% E7% B6% 9A) Im Artikel AWS, nicht lokal MongoDB, nicht MariaDB Es gibt einen Unterschied, aber Sie können eine Verbindung zum DB-Container herstellen, indem Sie den rot markierten Teil ändern. Der Eingabeinhalt verwendet (2) eine lokale Schleife oder einen Port.
Der DB-Container in AWS hat dieselbe Verbindungsmethode wie local. Es ist jedoch viel einfacher, AWS mit Intellij (IDE) zu verbinden.
Mit CLI können Sie nach der SSH-Verbindung zu AWS endlich auf DB-Daten zugreifen, indem Sie SQL-Operationen mit MySQL ausführen. Wie Sie wissen, wird es in der schwer lesbaren Notation von mysql erworben.
Dies ist auch [früherer Artikel](https://qiita.com/akinko/items/d7001a8fe3ac87e1790c#db%E3%81%A8%E3%81%AE%E7%B0%A1%E5%8D%98%E6%8E Wenn Sie es mit Bezug auf% A5% E7% B6% 9A) einstellen, können Sie es einfach mit einem Klick wie dem Öffnen von Excel handhaben.
Übrigens werde ich zum Testen kurz auf den DB-Container eingehen. Es ist fast das gleiche wie der DB-Server.
#Auszug
db_test:
build: db
container_name: mariadb_test
ports:
- "63306:3306"
volumes:
- ./db/my.conf:/etc/mysql/conf.d/my.cnf
networks:
- test
environment:
MYSQL_DATABASE: introdon_test
env_file: ./db/envfile #wegen Passwortbeschreibung ignorieren
Die Daten müssen nicht beibehalten werden. Lesen Sie einfach die Konfigurationsdatei. Um Unfälle zu vermeiden, wurde der Name DATABASE in introdon_test geändert, was sich vom tatsächlichen unterscheidet.
Intellij (mit IDE) wird nicht nur zum Verbinden des DB-Containers, sondern auch zum Bedienen und Verwalten von Docker empfohlen.
Sie können es mit der Maus über die Seitenleiste von IntelliJ bedienen. Sie können den Status des Containers auch in Echtzeit überprüfen.
--Log: Standardausgabe des Containers --Eigenschaften: Durchsuchen Sie die Container-ID, die Bild-ID usw. --Umgebungsvariablen: Liste der festgelegten Umgebungsvariablen --Portbindung: Listet Portbindungen mit Hosts auf --Datei: Verzeichnisstruktur auflisten. Darüber hinaus können Sie es öffnen, indem Sie auf die Datei doppelklicken.
Es ist so praktisch, dass ich keine Lust habe, ehrliche Befehle zu verwenden. .. : dancer_tone1:
Sie können Apps mit Docker entwickeln.
Mit anderen Worten, es verschmutzt die Einheimischen überhaupt nicht, im Gegenteil ** Sie können ohne Verwendung einer lokal installierten Programmiersprache entwickeln **.
Die Einstellmethode wird im Folgenden Schritt für Schritt erläutert. : Pfeil nach unten:
Dies ist eine Einstellung für die Entwicklung mit Python im Docker-Container.
Stellen Sie das im Projekt verwendete SDK (in diesem Fall die Programmiersprache und -version) ein.
Projektstruktur> Projekt SDK:> Bearbeiten
Normalerweise denke ich, dass die lokale Standardpython oder die Python der virtuellen Umgebung wie pyenv ausgewählt ist, aber im Gegensatz zu üblich gehen Sie wie folgt vor. Wählen Sie "Docker Compose" und
Wenn Sie mit den oben genannten Einstellungen speichern, können Sie abhängig vom Docker-Container mit der Entwicklung sowohl zum Debuggen als auch zum Testen fortfahren. : raise_hands_tone2:
Sie können dies bereits mit den oben genannten Einstellungen tun, aber machen wir es noch einfacher.
Diese Kolben-App dient zum Umschalten zwischen Produktions-, Entwicklungs- und Testmodus, abhängig vom Wert der Umgebungsvariablen des Kolbenbehälters. Jedes Mal, wenn ich teste Schreiben Sie die Umgebungsvariable von docker-compose.yml neu, laden Sie sie hoch und geben Sie sie zurück, wenn der Test beendet ist. .. Es ist mühsam. Ich möchte so bequem wie möglich leben.
In den Run / Debug-Einstellungen gebe ich Umgebungsvariablen für Folgendes ein: Wenn Sie nun anhand der Konfigurationsdatei testen, werden die Umgebungsvariablen überschrieben und anschließend ausgeführt. Sie müssen es nach dem Test nicht einmal zurückschreiben.
Abgesehen davon, wie Sie unter "Docker Compose> Befehl und Optionen" sehen können, wird beim Versuch, dies manuell über die CLI auszuführen, viel eingegeben, und es wird jedes Mal ärgerlich. Einmal mit Intllij eingestellt, ist es nur ein Klick ab dem zweiten Mal.
Docker-Compose war zunächst schwer zu bekommen. Sobald Sie sich daran gewöhnt haben, wird die Entwicklung von Webanwendungen erheblich beschleunigt: Flugzeug: Es ist ziemlich wiederverwendbar: Recycling: Mögen Sie alle schnell anfangen, sich zu entwickeln und eine Welt werden, in der Sie sich schnell entfalten können: Welle:
Recommended Posts