① Umgebungskonstruktion - die einfachste Webserverkonstruktion
Wenn Sie Punkte kommentieren, die schwer zu verstehen oder ungenau sind, führt dies zu Motivation. Vor dieser Zeit schrieb ich einen Artikel mit einem Dienst namens Zenn Originaler Artikel Geben Sie vorerst von Docker-Compose ein und lernen Sie Docker, während Sie das grundlegende Design des Webservers lernen ① | Zenn
Ich hoffe, es wird für die folgenden Personen nützlich sein
Ich denke, es ist fast 3 im 5. Monat der Selbststudienprogrammierung Als persönliche Nachricht gibt es mehr Personen im Zustand 1. Ich hoffe, dass der Inhalt dieses Artikels ankommen wird. ** Ich finde es bequem, Docker irgendwie zu verstehen! **, ** Erweitern Sie das Interesse an der Funktionsweise von Web-Apps **. Ich hoffe, ich kann dieses Bewusstsein teilen.
Der gleiche Inhalt wie dieser Artikel kann mit EC2 unter AWS oder mit dem vertraglich vereinbarten VPS reproduziert werden. Wenn Sie jedoch Docker verwenden, können Sie ** völlig kostenlos ** herausfordern! Einfacher und keine Angst vor ungeplanten Abrechnungen
--Kennen Sie die Mindestkonfiguration, die erforderlich ist, damit eine Web-App funktioniert
Daher werde ich am Ende dieses Artikels die Anwendung auf Docker bereitstellen und dabei den Unterschied zur Entwicklungsumgebung in der virtuellen Produktionsumgebung ansprechen.
Appendix
Anhang ist ergänzender Inhalt Ich habe den Inhalt geschrieben, der in diesem Abschnitt am Anfang bekannt sein kann Wenn Sie es nicht erneut wissen müssen, können Sie es überspringen. Wenn Sie nicht wissen, was Sie tun, können Sie Ihre Hand tatsächlich bewegen und in der Ecke Ihres Kopfes halten.
--Editor (verifiziert mit VS Code) Visual Studio Code - Code Editing. Redefined
Kenntnisse über grundlegende Linux-Befehle (cd, ls, vi ..., auch wenn Sie sie nicht haben, können Sie sie kopieren)
Docker desktop Docker Desktop for Mac and Windows | Docker
――Was ist Docker? Das Folgende wird für diejenigen empfohlen, die sagen
[Serie] Der verständlichste Container der Welt & Einführung in Docker ~ Teil 1: Was ist ein Container? ~ | SIOS Tech. Lab Es wird empfohlen, dass Sie das Konzept schnell verstehen und Ihre Hände hierher bewegen.
Der App-Teil verwendet Rails for FW (Framework), Sie müssen Rails nicht kennen
(Ich habe keine andere Entwicklungserfahrung als Rails, daher gibt es möglicherweise unangemessene Inhalte in anderen FWs.)
macOS Catalina docker desktop: 2.3.05 (docker engin: 19.03.12, docker-compose: 1.27.2) Nginx: 1.18 Rails: 6.03 PostgreSQL: 11.0
In der Umgebung, die von nun an mit Docker erstellt werden soll ** Nginx fungiert als Reverse-Proxy, liefert statische Inhalte im Auftrag von "app: Rails" (= Proxy) und leitet nur Anfragen nach dynamischen Inhalten an "app: Rails" weiter Es ist geworden **
Das möchte ich nach und nach verstehen
Es ist eine Konfiguration, die Sie häufig sehen (Datenbank und andere Teile weggelassen) Die Dienste Web (Nginx) und App (Rails) werden auf Docker in unabhängigen Containern ausgeführt. Es versteht sich, dass jede Abhängigkeit usw. durch Docker-Compose definiert wird
Nginx - Erstellen Sie eine Rails-Umgebung Ich werde auf den folgenden wunderbaren Artikel verweisen (lacht) Nginx, Rails 6, PostgreSQL-Umgebung (und sogar Bootstrap) können sofort erstellt werden! Wir verbessern uns nach und nach, daher freuen wir uns über Ihre Kommentare.
Quellcode für diesen Artikel basierend auf den oben genannten vorbereitet https://github.com/naokit-dev/try_nginx_on_docker.git
#Erstellen Sie ein Verzeichnis zum Platzieren der Anwendung (Anwendungsstamm)
mkdir try_nginx_on_docker
#Gehen Sie zum Anwendungsstamm
cd $_
#Quellcode abrufen
git clone https://github.com/naokit-dev/try_nginx_on_docker.git
#Verschieben Sie den Quellcode in das Anwendungsstammverzeichnis
cp -a try_nginx_on_docker/. .
rm -rf try_nginx_on_docker
Ich denke, es wird die folgende Konfiguration haben
.(try_nginx_on_docker)
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── README.md
├── docker
│ └── nginx
│ ├── default.conf
│ ├── load_balancer.conf
│ └── static.conf
├── docker-compose.prod.yml
├── docker-compose.yml
├── entrypoint.sh
├── setup.sh
└── temp_files
├── copy_application.html.erb
├── copy_database.yml
└── copy_environment.js
Teil des Quellcodes
docker-compose.yml
Es sind 4 Container definiert
version: "3.8"
services:
web:
image: nginx:1.18
ports:
- "80:80"
volumes:
- ./docker/nginx/static.conf:/etc/nginx/conf.d/default.conf
- public:/myapp/public
- log:/var/log/nginx
- /var/www/html
depends_on:
- app
db:
image: postgres:11.0-alpine
volumes:
- postgres:/var/lib/postgresql/data:cached
ports:
- "5432:5432"
environment:
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=ja_JP.UTF-8"
TZ: Asia/Tokyo
app:
build:
context: .
image: rails_app
tty: true
stdin_open: true
command: bash -c "rm -f tmp/pids/server.pid && ./bin/rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp:cached
- rails_cache:/myapp/tmp/cache:cached
- node_modules:/myapp/node_modules:cached
- yarn_cache:/usr/local/share/.cache/yarn/v6:cached
- bundle:/bundle:cached
- public:/myapp/public
- log:/myapp/log
- /myapp/tmp/pids
tmpfs:
- /tmp
ports:
- "3000-3001:3000"
environment:
RAILS_ENV: ${RAILS_ENV:-development}
NODE_ENV: ${NODE_ENV:-development}
DATABASE_HOST: db
DATABASE_PORT: 5432
DATABASE_USER: ${POSTGRES_USER}
DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
WEBPACKER_DEV_SERVER_HOST: webpacker
depends_on:
- db
- webpacker
webpacker:
image: rails_app
command: ./bin/webpack-dev-server
volumes:
- .:/myapp:cached
- public:/myapp/public
- node_modules:/myapp/node_modules:cached
environment:
RAILS_ENV: ${RAILS_ENV:-development}
NODE_ENV: ${NODE_ENV:-development}
WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
tty: false
stdin_open: false
ports:
- "3035:3035"
volumes:
rails_cache:
node_modules:
yarn_cache:
postgres:
bundle:
public:
log:
html:
source setup.sh
Wenn das Setup normal abgeschlossen ist Nach dem Starten des Containers mit dem folgenden Befehl im Anwendungsstammverzeichnis
docker-compose up
#Beim Start im Hintergrund-d Option
docker-compose up -d
Wenn Sie über Ihren Browser auf localhost
oder localhost: 80
zugreifen
Sie können sehen, "Yay! Sie sind auf Schienen!" ** Jeder kann problemlos eine Entwicklungsumgebung erstellen! Der erste Vorteil von Docker **
Lassen Sie uns den Container überprüfen, der hier ausgeführt wird (Wenn Sie "Docker-Compose Up" ohne die Option "-d" ausführen, wird ein neues Terminal geöffnet. Für VS-Code "Control" + "@" \ * Mac-Umgebung)
docker ps
Stellen Sie einfach sicher, dass die vier Container Web (Nginx), App (Rails), Webpacker (Webpack-Dev-Server) und DB (PostgreSQL) ausgeführt werden
Wenn Sie dies bestätigen können, schließen Sie den Behälter einmal
docker-compose down
Ich benutze die Rails App noch nicht Hier werden wir Folgendes herausfordern
--Überprüfen Sie die Mindesteinstellung von Nginx
Versuchen Sie, den Container alleine zu starten (nur Nginx), während Sie Docker-compose verwenden
Versuchen Sie, einfachen statischen Inhalt (HTML) nur mit Nginx bereitzustellen
Bearbeiten Sie "docker-compose.yml", um die Nginx-Einstellungen zu ändern
services:
web:
image: nginx:1.18
ports:
- "80:80"
volumes:
#Hier umschreiben./docker/nginx/default.conf... -> ./docker/nginx/static.conf...
- ./docker/nginx/static.conf:/etc/nginx/conf.d/default.conf
- public:/myapp/public
- log:/var/log/nginx
depends_on:
- app
...
** Ein wenig über Docker-Lautstärke **
./docker/nginx/static.conf: / etc / nginx / conf.d / default.conf
von Volumes:
is<Host-Pfad>: <Container-Pfad> Dadurch wird
static.conf auf der Hostseite (lokal) als Volume bereitgestellt, sodass es im Container als
default.conf` behandelt werden kann.
Denken Sie daran, dass ** ein Volume-Mount wie dieser erforderlich ist **, da sich der Speicher auf der Host-Seite und im Container unabhängig verhält.
Die Nginx-Einstellungen werden in "docker / nginx / static.conf" beschrieben. Der Inhalt ist wie folgt.
server { #Von hier
listen 80; # must
server_name _; # must
root /var/www/html; # must
index index.html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
} #Ein Serverblock bis hierher=Spezifikationen eines virtuellen Servers, der von Nginx verwaltet wird
** Server **: Definieren Sie einen virtuellen Server basierend auf den Inhalten in "{}" (Serverblock).
Hier müssen die folgenden 3 Punkte gesetzt werden
** listen **: Geben Sie die Überwachungs-IP und den Port an (xxx.xxx.xxx.xxx:80, localhost: 80, 80). ** Servername **: Der dem virtuellen Server zugewiesene Name. Nginx sucht nach virtuellen Servern, die dem Hostnamen (example.com) und der IP-Adresse (xxx.xxx.xxx.xxx) entsprechen, die in der Anforderung enthalten sind. ("_" Bedeutet, dass alle Bedingungen erfüllt werden. Außerdem können Platzhalter und reguläre Ausdrücke verwendet werden.) ** root **: Gibt das Dokumentstammverzeichnis an, das Verzeichnis, in dem sich der Inhalt befindet
Übrigens ist für das Protokoll derselbe Pfad wie oben in der Datei "etc / nginx / nginx.conf" definiert
Auch wenn es hier keine Beschreibung gibt, sollten sowohl error_log als auch access_log unter / var / log / nginx /
aufgezeichnet werden
Wenn Sie beispielsweise "access_log /var/log/nginx/static.access.log;" festlegen, scheint es möglich zu sein, ein Protokoll aufzuzeichnen, das für den jeweiligen virtuellen Server (Serverblock) spezifisch ist.
Im vorherigen "Docker-Compose-Up" wurden alle Container von Nginx, Rails, Webpack-Dev-Server und DB gestartet. Sie können jedoch auch nur einen bestimmten Container mithilfe der Docker-Compose-Option starten. Ist möglich
--no-deps
: Ignorieren Sie Abhängigkeiten zwischen Containern (hier Web: nur Nginx)
-d
: Startet den Container im Hintergrund, die Shell kann weiter tippen
-p
: Portzuordnung \ web
: durch compose definierter nginx container
Starten Sie den Nginx-Container mit dem folgenden Befehl
docker-compose run --no-deps -d -p 80:80 web
(Die Portzuordnung wird auch in compose angegeben, muss jedoch erneut angegeben werden, und Port 80 auf der Hostseite wird Port 80 im Webcontainer zugeordnet.)
Überprüfen Sie den Unterschied zum Ausführen von Docker-Compose ohne Optionen
docker ps
Im Gegensatz zu früher denke ich, dass nur der Nginx-Container läuft
Rufen Sie die Shell im Container auf
docker-compose run --no-deps web bash
Unten finden Sie die Arbeit im Webcontainer
# index.Erstellen Sie HTML
touch /var/www/html/index.html
# index.Fügen Sie den Inhalt von HTML hinzu
echo "<h1>I am Nginx</h1>" > /var/www/html/index.html
# index.Überprüfen Sie HTML
cat /var/www/html/index.html
<h1>I am Nginx</h1>
Nachdem Sie "index.html" direkt unter dem Dokumentstamm im Container erstellt haben, schließen wir die Shell mit "exit".
Wenn Sie über Ihren Browser auf localhost zugreifen, Sie können sehen, dass es wie unten gezeigt als HTML geliefert wird.
** Nginx hat hier ein einfaches Verhalten beim Durchsuchen des Dokumentstamms nach Inhalten, die der Anforderung entsprechen, und beim Zurückgeben der Übereinstimmung **
Wenn Sie dies bestätigen können, schließen Sie den Behälter einmal
docker-compose down
Nginx definiert basierend auf den Informationen im Feld Host, die in der Anforderung vom Client enthalten sind, an welchen virtuellen Server weitergeleitet werden soll.
** Was passiert also, wenn keiner der virtuellen Server mit der Anforderung übereinstimmt? ** ** ** Es schien wichtig zu sein, über das Design nachzudenken, also lasst es uns hier überprüfen.
Im Serverblock der vorherigen Konfigurationsdatei habe ich "Servername" so definiert, dass er auf jede Anforderung anwendbar ist, aber ich werde ihn mit einem zufälligen Namen umschreiben, der nicht mit der Anforderung übereinstimmt
server_name undefined_server;
Starten Sie den Nginx-Container erneut
docker-compose run --no-deps -p 80:80 web
Wenn ich über einen Browser auf localhost zugreife, obwohl es keinen virtuellen Server gibt, der der Anforderung entspricht Unerwartet sollten Sie das gleiche "Ich bin Nginx" wie zuvor sehen
default server
Nginx wird verwendet, um die Anforderung mit dem Standardserver zu verarbeiten, wenn die Anforderung keinem virtuellen Server entspricht, und die Spezifikation besteht darin, den oben beschriebenen virtuellen Server zuerst als Standardserver zu behandeln.
In the configuration above, the default server is the first one — which is nginx’s standard default behaviour. It can also be set explicitly which server should be default, with the default_server parameter in the listen directive: How nginx processes a request
Alternativ können Sie in der Listen-Direktive explizit "default_server" angeben.
listen 80 default_server;
In diesem Experiment stimmt "undefined_server" nicht mit der Anforderung überein, aber es gibt nichts anderes, das übereinstimmt Wahrscheinlich als Standardserver weitergeleitet
** Wenn keiner der virtuellen Server mit der Anforderung übereinstimmt => an Standardserver weitergeleitet **
Ich bin der Meinung, dass es hilfreich ist, den Fehler zu isolieren, z. B. wenn keine gute Verbindung zum Backend-Server besteht.
Lassen Sie uns den Behälter einmal schließen
docker-compose down
** Über die Bedeutung, dass Volumen an erster Stelle notwendig ist (= Persistenz ist notwendig) ** Docker erstellt und verwaltet Volumes, um die Daten im Container beizubehalten
Ich bin mir nicht sicher, also werde ich es überprüfen
Rufen Sie die Shell im Webcontainer auf
docker-compose run --no-deps web bash
Unten finden Sie die Arbeit im Webcontainer
#Erstellen Sie ein Verzeichnis zur Überprüfung
mkdir /var/www/test
#Erstellen Sie eine Datei zur Überprüfung
touch /var/www/test/index.html
#Existenz prüfen
ls /var/www/test/
Der Punkt ist, dass / var / www / test
jetzt ein Pfad ist, der nicht als Volume in docker-compose.yml
verwaltet wird.
Lassen Sie uns die Shell einmal mit "exit" schließen (der Container wird ebenfalls geschlossen)
Starten Sie den Webcontainer erneut und rufen Sie die Shell auf
docker-compose run --no-deps web bash
Ich werde versuchen, die vorherige Datei zu finden
cat /var/www/test/index.html
ls /var/www
Was denken Sie, Ich glaube nicht, dass Sie sowohl das Verzeichnis "/ var / www / test" als auch die Datei "/ var / www / test / index.html" finden können
** Wenn der Container geschlossen ist, bleiben die Daten im Container nicht erhalten ** Dies ist das Prinzip Zur Umgehung dieses Mechanismus stehen Volumes zur Verfügung
Schließen Sie das Terminal mit "exit"
Stoppen Sie alle Container
docker-compose down
** Volumentyp **
In Docker gibt es die folgenden Datenträgertypen, die jedoch insofern identisch sind, als sie die Daten im Container beibehalten.
Schauen Sie sich docker-compose.yml an
version: "3.8"
services:
web:
image: nginx:1.18
ports:
- "80:80"
volumes:
- ./docker/nginx/static.conf:/etc/nginx/conf.d/default.conf #host volume
- public:/myapp/public # named volume
- log:/var/log/nginx # named volume
- html:/var/www/html # named volume
...
volumes: #Definieren Sie hier die Freigabe zwischen verschiedenen Containern
public:
log:
html:
host volume
Ich habe es im Teil mit den Nginx-Einstellungen erwähnt
Hängen Sie den hostseitigen Pfad als Volume im Teil ./docker/nginx/static.conf: / etc / nginx / conf.d / default.conf
ein
** Bild des Kopierens von Dateien auf dem Host auf die Containerseite **
named volume
html: / var / www / html
Teil
Ich mounte das Volume mit dem Namen "html"
Durch Definieren mit diesem Namen im Block "Volumes" in derselben Zeile wie im Block "Services"
** Ermöglicht die gemeinsame Nutzung von Volumes zwischen mehreren Containern **
Und ** dieses Volume bleibt unabhängig von der Host-Seite bestehen **
Endlich ** anonymer Band ** Im offiziellen Dokument ist der einzige Unterschied zum benannten Volume ** mit oder ohne Namen ** Anstatt tatsächlich keinen Namen zu haben **, wird der Teil, der dem Namen des benannten Volumes entspricht, als Hash für jeden Container angegeben ** Es ist ein bisschen verwirrend, kann aber in Fällen verwendet werden, in denen Sie die Host-Seite nicht mounten müssen, sie aber beibehalten müssen ** und nicht erwarten, dass sie in mehreren Containern geteilt wird **. (Es ist immer noch schwer vorstellbar, aber im folgenden Inhalt werde ich auf eine Szene stoßen, in der es sich um einen anonymen Band handeln muss.)
Hier werde ich es für ein etwas tieferes Verständnis überprüfen.
Ändern Sie / var / www / html
, das ursprünglich als benanntes Volume definiert wurde, in anonymes Volume
Ich werde das in diesem Abschnitt durchgeführte Verfahren zum Erstellen einer HTML-Datei wiederholen.
docker-compose.yml
version: "3.8"
services:
web:
image: nginx:1.18
ports:
- "80:80"
volumes:
- ./docker/nginx/static.conf:/etc/nginx/conf.d/default.conf
- public:/myapp/public
- log:/var/log/nginx
- /var/www/html #Geben Sie nur den Pfad auf der Containerseite an und wechseln Sie zu einem anonymen Volume
...
volumes:
public:
log:
# html:Kommentar hier raus
Starten Sie Nginx als Webserver
docker-compose run --no-deps -d -p 80:80 web
Rufen Sie die Shell
docker-compose run --no-deps web bash
Dies ist wichtig, aber wenn Sie den Container überprüfen, der derzeit in einem anderen Terminal ausgeführt wird
docker ps
** Sie können sehen, dass sich der Container mit zwei laufenden Containern und der laufenden Shell von dem Container mit Portzuordnung um 80:80 unterscheidet. **
Erstellen Sie HTML im Container so wie es ist
# index.Erstellen Sie HTML
touch /var/www/html/index.html
# index.Bestätigen Sie die Existenz von HTML
ls /var/www/html
Lassen Sie uns wie zuvor über den Browser auf localhost
zugreifen
Der Browser zeigt dann einen 403-Fehler an Überprüfen des Nginx-Fehlerprotokolls
tail -f 20 /var/log/nginx/error.log
...directory index of "/var/www/html/" is forbidden...
Ein Fehler wird protokolliert, wenn das Verzeichnis nicht gefunden werden kann
Durch Ändern auf benanntes Volume-> anonymes Volume
** Der Inhalt unter / var / www / html /
wird nicht zwischen den beiden Containern geteilt **
Da der Container, der die Anforderung an Port 80 vom lokalen empfangen hat, nicht mehr auf "index.html" verweisen kann
Es ist wahrscheinlich, dass ein solcher Fehler aufgetreten ist
** Persistenz, aber nicht Volumen mit anderen Containern teilen **, ich denke, Sie könnten die Eigenschaften berühren
Wenn Sie dies bestätigen können, schließen Sie die Shell mit "exit"
Lassen Sie uns den Behälter jedes Mal schließen
docker-compose down
(Der geänderte Inhalt von docker-compose.yml kann unverändert bleiben.)
...
Der Inhalt des Anhangs wurde heißer als ich erwartet hatte und er wurde länger, also werde ich ihn hier brechen (um meine Motivation zu behalten)
Weiter zu ②
Recommended Posts