"Wir brauchen DevOps!"(die beliebteste Phrase am Ende eines Hackathons)
Zuerst einige Texte.
Wenn ein Entwickler ein ausgezeichneter Entwickler ist, der seine Idee auf jedem Computer unter jedem OK einsetzen kann, ist dies ein Plus. Wenn er jedoch nichts weiter als seine IDE versteht, ist dies kein Minus - am Ende wird er für den Code bezahlt und nicht für die Fähigkeit, ihn bereitzustellen. Ein enger, tiefer Spezialist auf dem Markt wird höher bewertet als die durchschnittliche Fähigkeit eines "Alleskönners". Für Leute wie uns, "IDE-Benutzer", haben sich gute Leute Docker ausgedacht.
Das Prinzip von Docker lautet wie folgt: "Es funktioniert für mich - es funktioniert überall." Das einzige Programm, das zum Bereitstellen einer Kopie Ihrer Anwendung benötigt wird, ist Docker. Wenn Sie Ihre Anwendung im Docker auf Ihrem Computer ausführen, wird sie garantiert mit demselben Erfolg in jedem anderen Docker ausgeführt. Und nichts als ein Docker muss installiert werden. Zum Beispiel habe ich nicht einmal Java auf dem virtuellen Server.
Wie funktioniert Docker?
Docker erstellt ein Image einer virtuellen Maschine mit darin installierten Anwendungen. Darüber hinaus entfaltet sich dieses Image als vollständig autonome virtuelle Maschine. Eine laufende Kopie des Bildes wird als "Container" bezeichnet. Sie können beliebig viele Images auf dem Server ausführen. Jedes dieser Images ist eine separate virtuelle Maschine mit einer eigenen Umgebung.
Was ist eine virtuelle Maschine? Dies ist der gekapselte Speicherort auf dem Server mit dem Betriebssystem, auf dem die Anwendungen installiert sind. In jedem Betriebssystem dreht sich normalerweise eine große Anzahl von Anwendungen, in unserem gibt es eine.
Das Containerbereitstellungsschema kann wie folgt dargestellt werden:

Für jede Anwendung erstellen wir ein eigenes Image und stellen dann jeden Container separat bereit. Sie können auch alle Anwendungen in einem Image zusammenfassen und als einen Container bereitstellen. Um nicht jeden Container separat bereitzustellen, können wir außerdem ein separates Docker-Compose-Dienstprogramm verwenden, das die Container und die Beziehung zwischen ihnen über eine separate Datei konfiguriert. Dann kann die Struktur der gesamten Anwendung folgendermaßen aussehen:

Ich habe die Datenbank aus mehreren Gründen absichtlich nicht zur allgemeinen Docker-Versammlung beigetragen. Erstens ist die Datenbank völlig unabhängig von den Anwendungen, die damit arbeiten. Es kann weit von einer Anwendung entfernt sein, es können manuelle Anforderungen von der Konsole sein. Persönlich sehe ich keinen Grund, die Datenbank von der Docker-Assembly abhängig zu machen, in der sie sich befindet. Deshalb habe ich es ertragen. Es wird jedoch häufig ein Ansatz praktiziert, bei dem die Datenbank in einem separaten Image platziert und in einem separaten Container gestartet wird. Zweitens möchte ich zeigen, wie der Docker-Container mit Systemen außerhalb des Containers interagiert.
Lassen Sie uns jedoch den Code schreiben. Wir werden die einfachste Anwendung im Frühjahr schreiben und reagieren, wodurch unsere Anrufe nach vorne in die Datenbank aufgenommen werden, und wir werden all dies über Docker aufheben. Die Struktur unserer Anwendung sieht folgendermaßen aus:

Es gibt viele Möglichkeiten, eine solche Struktur zu implementieren. Wir implementieren eine davon. Wir werden zwei Images erstellen, zwei Container daraus starten und das Backend wird eine Verbindung zu der Datenbank herstellen, die auf einem bestimmten Server irgendwo im Internet installiert ist (ja, solche Datenbankabfragen werden nicht schnell gehen, aber wir werden nicht vom Durst nach Optimierung getrieben, aber wissenschaftliches Interesse).
Der Beitrag wird in Teile geteilt:
0. Installieren Sie Docker.
1. Wir schreiben Bewerbungen.
2. Wir sammeln Bilder und starten Container.
3. Sammeln Sie Bilder und starten Sie Container auf einem Remote-Server.
4. Lösen Sie Netzwerkprobleme.
0. Installieren Sie Docker
Um Docker zu installieren, müssen Sie auf die
Site gehen und den dort beschriebenen Anweisungen folgen. Beachten Sie bei der Installation von Docker auf einem Remote-Server, dass Docker möglicherweise nicht mit Servern unter OpenVZ funktioniert. Außerdem können Probleme auftreten, wenn Sie iptables nicht aktiviert haben. Es wird empfohlen, den Server auf KVM mit iptables zu starten. Aber das sind meine Empfehlungen. Wenn alles für Sie funktioniert und ich bin froh, dass Sie nicht viel Zeit damit verbracht haben, herauszufinden, warum es nicht funktioniert, wie ich es tun musste.
1. Wir schreiben Bewerbungen
Schreiben wir eine einfache Anwendung mit dem primitivsten Backend für Spring Boot, einem sehr einfachen Frontend für ReactJS und einer MySQL-Datenbank. Die Anwendung verfügt über eine einzelne Seite mit einer einzelnen Schaltfläche, die die Zeit aufzeichnet, zu der in der Datenbank darauf geklickt wurde.
Ich verlasse mich auf die Tatsache, dass Sie bereits wissen, wie man Anwendungen beim Booten schreibt, aber wenn nicht, können Sie das fertige Projekt klonen. Alle Links am Ende des Artikels.
Backend auf Spring Boot
build.gradle:
plugins { id 'org.springframework.boot' version '2.1.4.RELEASE' id 'java' } apply plugin: 'io.spring.dependency-management' group = 'ru.xpendence' version = '0.0.2' sourceCompatibility = '1.8' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' runtimeOnly 'mysql:mysql-connector-java' testImplementation 'org.springframework.boot:spring-boot-starter-test' }
Protokollentität:
package ru.xpendence.rebounder.entity; import com.fasterxml.jackson.annotation.JsonFormat; import javax.persistence.*; import java.io.Serializable; import java.time.LocalDateTime; import java.util.Objects; @Entity @Table(name = "request_logs") public class Log implements Serializable { private Long id; private LocalDateTime created; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long getId() { return id; } @Column @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSS") public LocalDateTime getCreated() { return created; } @PrePersist public void prePersist() { this.created = LocalDateTime.now(); }
LogController, der mit vereinfachter Logik arbeitet und sofort in die Datenbank schreibt. Wir lassen den Service aus.
package ru.xpendence.rebounder.controller; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import ru.xpendence.rebounder.entity.Log; import ru.xpendence.rebounder.repository.LogRepository; import java.util.logging.Logger; @RestController @RequestMapping("/log") public class LogController { private final static Logger LOG = Logger.getLogger(LogController.class.getName()); private final LogRepository repository; @Autowired public LogController(LogRepository repository) { this.repository = repository; } @GetMapping public ResponseEntity<Log> log() { Log log = repository.save(new Log()); LOG.info("saved new log: " + log.toString()); return ResponseEntity.ok(log); } }
Alles ist, wie wir sehen, sehr einfach. Durch eine GET-Anfrage schreiben wir in die Datenbank und geben das Ergebnis zurück.
Wir werden die Anwendungseinstellungsdatei separat diskutieren. Es gibt zwei von ihnen.
application.yml:
spring: profiles: active: remote
application-remote.yml:
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://my-remote-server-database:3306/rebounder_database?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC username: admin password: 12345 jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate.dialect: org.hibernate.dialect.MySQL5Dialect server: port: 8099
Wie dies funktioniert, wissen Sie wahrscheinlich, dass Spring zuerst die Datei application.properties oder application.yml scannt - welche gefunden wird. Darin geben wir eine einzelne Einstellung an - welches Profil wir verwenden werden. Normalerweise sammle ich während der Entwicklung mehrere Profile und es ist sehr praktisch, sie mit dem Standardprofil zu wechseln. Als Nächstes findet Spring application.yml mit dem gewünschten Suffix und verwendet es.
Wir haben die Datenquelle, die JPA-Einstellungen und vor allem den externen Port unseres Backends angegeben.
ReactJS Frontend
Sie können das Frontend auch in einem Projekt auf Git sehen, oder Sie können es sogar nicht ansehen, sondern klonen und ausführen.
Sie können die einzelnen Arbeiten des Frontends überprüfen, indem Sie das Projekt herunterladen, in den Projektstammordner im Terminal (wo sich die Datei package.json befindet) wechseln und zwei Befehle nacheinander ausführen:
npm install // , maven npm start //
Dazu benötigen Sie natürlich den installierten Node Package Manager (npm), und dies ist der schwierigste Weg, den wir vermeiden, Docker zu verwenden. Wenn Sie das Projekt noch gestartet haben, wird das folgende Fenster angezeigt:

Na ja, es ist Zeit, sich den Code anzusehen. Ich werde nur den Teil angeben, der sich auf das Backend bezieht.
export default class Api { _apiPath = 'http://localhost:8099'; _logUrl = '/log'; getResource = async () => { const res = await fetch(`${this._apiPath}${this._logUrl}`); if (!res.ok) { throw new Error(`Could not fetch ${this._logUrl}` + `, received ${res.status}`) } return await res.json(); }; };
Das Frontend funktioniert vorhersehbar. Wir folgen dem Link, warten auf die Antwort und zeigen sie auf dem Bildschirm an.

Es lohnt sich, sich auf folgende Punkte zu konzentrieren:
- Die Front ist über Port 3000 nach außen offen. Dies ist der Standardport für React.
- Die Rückseite wird an Port 8099 geöffnet. Wir haben sie in den Anwendungseinstellungen festgelegt.
- Der Rücken klopft über das externe Internet an die Datenbank.
Die Anwendung ist fertig.
2. Sammeln Sie Bilder und starten Sie Container
Die Struktur unserer Versammlung wird wie folgt sein. Wir werden zwei Images erstellen - Frontend und Backend, die über externe Ports miteinander kommunizieren. Für die Basis erstellen wir kein Image, sondern installieren es separat. Warum so? Warum erstellen wir kein Bild für die Basis? Wir haben zwei Anwendungen, die sich ständig ändern und keine Daten in uns selbst speichern. Die Datenbank speichert Daten in sich selbst. Dies kann das Ergebnis eines mehrmonatigen Anwendungsbetriebs sein. Darüber hinaus kann auf diese Datenbank nicht nur von unserer Backend-Anwendung, sondern auch von vielen anderen zugegriffen werden - dafür handelt es sich auch um eine Datenbank, und wir werden sie nicht ständig neu zusammenstellen. Auch dies ist eine Gelegenheit, mit einer externen API zu arbeiten, die natürlich darin besteht, eine Verbindung zu unserer Datenbank herzustellen.
Front-End-Baugruppe
Um jede Anwendung (vorne oder hinten) auszuführen, benötigen Sie eine bestimmte Abfolge von Aktionen. Um die Anwendung unter React auszuführen, müssen wir Folgendes tun (vorausgesetzt, wir haben bereits Linux):
- Installieren Sie NodeJS.
- Kopieren Sie die Anwendung in einen bestimmten Ordner.
- Installieren Sie die erforderlichen Pakete (Befehl npm install).
- Starten Sie die Anwendung mit dem Befehl npm start.
Es ist diese Abfolge von Aktionen, die wir im Docker ausführen müssen. Dazu müssen wir im Stammverzeichnis des Projekts (an derselben Stelle wie package.json) die Docker-Datei mit den folgenden Inhalten platzieren:
FROM node:alpine WORKDIR /usr/app/front EXPOSE 3000 COPY ./ ./ RUN npm install CMD ["npm", "start"]
Mal sehen, was jede Zeile bedeutet.
FROM node:alpine
Mit dieser Zeile machen wir dem Docker klar, dass Sie beim Starten des Containers zunächst Docker aus dem Repository herunterladen und NodeJS installieren müssen, und zwar die leichteste (alle leichtesten Versionen gängiger Frameworks und Bibliotheken im Docker werden normalerweise als alpin bezeichnet).
WORKDIR /usr/app/front
Im Linux-Container werden dieselben Standardordner erstellt wie in anderen Linux-Ordnern - / opt, / home, / etc, / usr usw. Wir legen das Arbeitsverzeichnis fest, mit dem wir arbeiten werden - / usr / app / front.
EXPOSE 3000
Wir öffnen Port 3000. Die weitere Kommunikation mit der im Container ausgeführten Anwendung erfolgt über diesen Port.
COPY ./ ./
Kopieren Sie den Inhalt des Quellprojekts in den Arbeitsordner des Containers.
RUN npm install
Installieren Sie alle Pakete, die zum Ausführen der Anwendung erforderlich sind.
CMD ["npm", "start"]
Wir starten die Anwendung mit dem Befehl npm start.
Dieses Szenario wird in unserer Anwendung ausgeführt, wenn der Container gestartet wird.
Lassen Sie uns die Front gerade machen. Führen Sie dazu im Terminal im Stammordner des Projekts (in dem sich die Docker-Datei befindet) den folgenden Befehl aus:
docker build -t rebounder-chain-frontend .
Befehlswerte:
Docker ist ein Aufruf der Docker-Anwendung. Das wissen Sie.
Bauen - Erstellen Sie ein Bild aus Zielmaterialien.
-t <Name> - In Zukunft wird die Anwendung mit dem hier angegebenen Tag verfügbar sein. Sie können dies weglassen, dann generiert Docker ein eigenes Tag, aber es ist unmöglich, es von anderen zu unterscheiden.
. - zeigt an, dass Sie das Projekt aus dem aktuellen Ordner abholen müssen.

Daher sollte die Assembly mit dem folgenden Text enden:
Step 7/7 : CMD ["npm", "start"] ---> Running in ee0e8a9066dc Removing intermediate container ee0e8a9066dc ---> b208c4184766 Successfully built b208c4184766 Successfully tagged rebounder-chain-frontend:latest
Wenn wir sehen, dass der letzte Schritt abgeschlossen ist und alles erfolgreich ist, haben wir ein Bild. Wir können dies überprüfen, indem wir es ausführen:
docker run -p 8080:3000 rebounder-chain-frontend
Ich denke, die Bedeutung dieses Befehls wird allgemein verstanden, mit Ausnahme des Eintrags -p 8080: 3000.
Docker-Rebounder-Chain-Frontend ausführen - bedeutet, dass wir ein solches Docker-Image starten, das wir Rebounder-Chain-Frontend genannt haben. Ein solcher Container hat jedoch keinen Ausgang nach außen, sondern muss einen Port festlegen. Es ist das Team darunter, das es festlegt. Wir erinnern uns, dass unsere React-Anwendung auf Port 3000 ausgeführt wird. Der Befehl -p 8080: 3000 weist den Docker an, Port 3000 zu übernehmen und an Port 8080 weiterzuleiten (der geöffnet sein wird). Daher wird eine Anwendung, die auf Port 3000 ausgeführt wird, auf Port 8080 geöffnet und ist auf dem lokalen Computer an diesem Port verfügbar.
, : Mac-mini-Vaceslav:rebounder-chain-frontend xpendence$ docker run -p 8080:3000 rebounder-chain-frontend > rebounder-chain-frontend@0.1.0 start /usr/app/front > react-scripts start Starting the development server... Compiled successfully! You can now view rebounder-chain-frontend in the browser. Local: http://localhost:3000/ On Your Network: http://172.17.0.2:3000/ Note that the development build is not optimized. To create a production build, use npm run build.
Lassen Sie sich von der Aufzeichnung nicht stören
Local: http://localhost:3000/ On Your Network: http://172.17.0.2:3000/
React glaubt es. Es ist wirklich im Container auf Port 3000 verfügbar, aber wir haben diesen Port an Port 8080 weitergeleitet, und vom Container aus wird die Anwendung auf Port 8080 ausgeführt. Sie können die Anwendung lokal ausführen und dies überprüfen.
Wir haben also einen vorgefertigten Container mit einer Front-End-Anwendung. Jetzt sammeln wir das Backend.
Backend erstellen.
Das Skript zum Starten einer Anwendung in Java unterscheidet sich erheblich von der vorherigen Assembly. Es besteht aus folgenden Elementen:
- Installieren Sie die JVM.
- Wir sammeln Glasarchiv.
- Wir starten es.
In Dockerfile sieht dieser Prozess folgendermaßen aus:
Der Prozess des Zusammenstellens eines Bildes unter Einbeziehung eines Dzharnik in einigen Punkten ähnelt dem für unsere Front.
Das Zusammenstellen und Starten des zweiten Images entspricht im Wesentlichen dem Zusammenstellen und Starten des ersten Images.
docker build -t rebounder-chain-backend . docker run -p 8099:8099 rebounder-chain-backend
Wenn nun beide Container ausgeführt werden und das Backend mit der Datenbank verbunden ist, funktioniert alles. Ich erinnere Sie daran, dass Sie die Verbindung zur Datenbank vom Backend selbst registrieren müssen und sie über ein externes Netzwerk funktionieren muss.
3. Sammeln Sie Bilder und führen Sie Container auf einem Remote-Server aus
Damit alles auf einem Remote-Server funktioniert, muss Docker bereits darauf installiert sein. Führen Sie anschließend einfach die Images aus. Wir werden den richtigen Weg gehen und unsere Bilder in der Docker-Cloud auf unser Konto übertragen. Danach sind sie von überall auf der Welt verfügbar. Natürlich gibt es viele Alternativen zu diesem Ansatz sowie alles, was in der Post beschrieben wird, aber lassen Sie uns noch ein bisschen mehr Druck machen und unsere Arbeit gut machen. Schlecht, wie Andrei Mironov sagte, wir haben immer Zeit dafür.
Erstellen eines Kontos auf dem Docker-Hub
Als erstes müssen Sie ein Konto auf dem Docker-Hub einrichten. Gehen Sie dazu zum
Hub und registrieren Sie sich. Es ist nicht schwer.
Als nächstes müssen wir zum Terminal gehen und uns bei Docker anmelden.
docker login
Sie werden aufgefordert, einen Benutzernamen und ein Passwort einzugeben. Wenn alles in Ordnung ist, wird im Terminal eine Benachrichtigung angezeigt, dass die Anmeldung erfolgreich war.
Festschreiben von Bildern an den Docker Hub
Als nächstes müssen wir unsere Bilder markieren und sie an den Hub übergeben. Dies erfolgt durch das Team nach folgendem Schema:
docker tag /_:
Daher müssen wir den Namen unseres Images, Login / Repository und das Tag angeben, unter dem unser Image an den Hub übertragen wird.
In meinem Fall sah es so aus:

Mit dem folgenden Befehl können wir überprüfen, ob dieses Image im lokalen Repository vorhanden ist:
Mac-mini-Vaceslav:rebounder-chain-backend xpendence$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE xpendence/rebounder-chain-backend 0.0.2 c8f5b99e15a1 About an hour ago 141MB
Unser Image ist bereit, sich zu engagieren. Commit:
docker push xpendence/rebounder-chain-backend:0.0.2
Ein erfolgreicher Festschreibungsdatensatz sollte angezeigt werden.
Machen Sie dasselbe mit dem Frontend:
docker tag rebounder-chain-frontend xpendence/rebounder-chain-frontend:0.0.1 docker push xpendence/rebounder-chain-frontend:0.0.1
Wenn wir jetzt zu hub.docker.com gehen, sehen wir zwei gesperrte Bilder. Welche sind von überall verfügbar.


Glückwunsch Wir müssen nur zum letzten Teil unserer Arbeit übergehen - um Bilder auf einem Remote-Server zu starten.
Führen Sie Images auf einem Remote-Server aus
Jetzt können wir unser Image auf jedem Computer mit Docker ausführen, indem wir nur eine Zeile im Terminal vervollständigen (in unserem Fall müssen wir zwei Zeilen nacheinander in verschiedenen Terminals ausführen - eine für jedes Image).
docker run -p 8099:8099 xpendence/rebounder-chain-backend:0.0.2 docker run -p 8080:3000 xpendence/rebounder-chain-frontend:0.0.1
Dieser Start hat jedoch ein Minus. Wenn das Terminal geschlossen ist, wird der Prozess beendet und die Anwendung funktioniert nicht mehr. Um dies zu vermeiden, können wir die Anwendung im "getrennten" Modus ausführen:
docker run -d -p 8099:8099 xpendence/rebounder-chain-backend:0.0.2 docker run -d -p 8080:3000 xpendence/rebounder-chain-frontend:0.0.1
Jetzt gibt die Anwendung kein Protokoll an das Terminal aus (dies kann wiederum separat konfiguriert werden), aber selbst wenn das Terminal geschlossen ist, funktioniert es nicht mehr.
4. Netzwerkprobleme lösen
Wenn Sie alles richtig gemacht haben, können Sie die größte Enttäuschung auf dem Weg zum Folgen dieses Beitrags erwarten - es kann sich herausstellen, dass nichts funktioniert. Zum Beispiel funktionierte alles perfekt für Sie und auf dem lokalen Computer (wie zum Beispiel auf meinem Mac), aber bei der Bereitstellung auf einem Remote-Server sahen sich die Container nicht mehr (wie zum Beispiel auf meinem Remote-Server unter Linux). Was ist das Problem? Aber das Problem ist das, und am Anfang habe ich darauf hingewiesen. Wie bereits erwähnt, erstellt Docker beim Starten des Containers eine separate virtuelle Maschine, rollt dort Linux und installiert dann die Anwendung unter diesem Linux. Dies bedeutet, dass der bedingte lokale Host für den laufenden Container auf den Container selbst beschränkt ist und die Anwendung nicht über die Existenz anderer Netzwerke informiert ist. Aber wir müssen:
a) Die Container sahen sich.
b) Das Backend hat die Datenbank gesehen.
Es gibt zwei Lösungen für das Problem.
1. Erstellen eines internen Netzwerks.
2. Container auf Host-Ebene bringen.
1. Auf Docker-Ebene können Sie außerdem standardmäßig drei Netzwerke erstellen -
Bridge ,
None und
Host .
Bridge ist ein internes Docker-Netzwerk, das vom Host-Netzwerk isoliert ist. Sie können nur über die Ports auf Container zugreifen, die Sie öffnen, wenn der Container mit dem Befehl
-p gestartet wird . Sie können eine beliebige Anzahl von Netzwerken erstellen, z. B.
Bridge .
Keines ist ein separates Netzwerk für einen bestimmten Container.
Host ist das Host-Netzwerk. Wenn Sie dieses Netzwerk auswählen, ist Ihr Container über den Host vollständig zugänglich. Der Befehl
-p funktioniert hier einfach nicht. Wenn Sie den Container in diesem Netzwerk bereitgestellt haben, müssen Sie keinen externen Port angeben. Auf den Container kann über seinen internen Port zugegriffen werden. Wenn Dockerfile EXPOSE beispielsweise auf 8090 eingestellt ist, ist die Anwendung über diesen Port verfügbar.

Da wir Zugriff auf die Serverdatenbank benötigen, verwenden wir die letztere Methode und legen die Container im Remote-Servernetzwerk an.
Dies geschieht ganz einfach. Wir entfernen die Erwähnung von Ports aus dem Container-Startbefehl und geben das Host-Netzwerk an:
docker run --net=host xpendence/rebounder-chain-frontend:0.0.8
Verbindung zur Basis habe ich angegeben
localhost:3306
Die Verbindung der Vorderseite mit der Rückseite musste vollständig extern festgelegt werden:
http://<__:__>
Wenn Sie den internen Port an den externen Port weiterleiten, was bei Remoteservern häufig der Fall ist, müssen Sie den internen Port für die Datenbank und den externen Port für den Container angeben.
Wenn Sie mit Verbindungen experimentieren möchten, können Sie ein Projekt herunterladen und erstellen, das ich speziell geschrieben habe, um die Verbindung zwischen Containern zu testen. Geben Sie einfach die gewünschte Adresse ein, drücken Sie Senden und sehen Sie im Debug-Modus, was zurückgeflogen ist.
Das Projekt liegt
hier .
Fazit
Es gibt unzählige Möglichkeiten, ein Docker-Image zu erstellen und auszuführen. Für Interessierte empfehle ich Ihnen, Docker-Compose zu lernen. Hier haben wir nur eine der Möglichkeiten untersucht, mit Docker zu arbeiten. Natürlich scheint dieser Ansatz zunächst nicht so einfach zu sein. Aber hier ist ein Beispiel: Während des Schreibens eines Beitrags hatte ich ausgehende Verbindungen auf einem Remote-Server. Und während des Debugging-Prozesses musste ich die Einstellungen für die Datenbankverbindung mehrmals ändern. Die gesamte Assembly und Bereitstellung passte in meinen Satz von 4 Zeilen, nachdem ich das Ergebnis auf einem Remote-Server gesehen hatte. Im extremen Programmiermodus ist Docker unverzichtbar.
Wie versprochen poste ich die Bewerbungsquellen:
BackendFrontend