[GO] Lösung für unzugänglichen Gin-Server, der auf dem Docker-Container ausgeführt wird

Überblick

Ich habe versucht, einen API-Server mithilfe des Golang-Webframeworks Gin auf einem Docker-Container bereitzustellen und auszuführen, konnte jedoch nicht auf die API zugreifen. Ich war ziemlich lange beunruhigt.

Als Ergebnis stellte ich fest, dass es ein Problem beim Schreiben des Codes des Gin-Servers war, aber ich werde die Lösung hier für alle Fälle aufschreiben.

Dieser Fehler trat übrigens auf dem Ubuntu-Server (t2.small) unter Windows 10 und AWS auf (obwohl die Ausführungsumgebung nicht viel mit dem Auftreten dieses Fehlers zu tun zu haben schien).

Status

Ich habe versucht, einen API-Server mit Gin einzurichten. Da sich die Umgebung noch im Aufbau befindet, handelt es sich bei dem Code um einen Schein wie den folgenden.

package main

import (
	"log"
	"os"
	"github.com/gin-gonic/gin"
)

func main() {
	logConfig()

	r := gin.Default()
	r.GET("/accounting-api", func(c *gin.Context) {
		log.Println("GET")
		c.JSON(200, gin.H{
			"state": "success",
		})
	})
	r.DELETE("/accounting-api", func(c *gin.Context) {
		log.Println("DELETE")
		c.JSON(200, gin.H{
			"state": "success",
		})
	})
	log.Println("Start Server")
	r.Run()
}

func logConfig() {
	logFile, _ := os.OpenFile("log/log.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	log.SetOutput(logFile)
	log.SetFlags(log.LstdFlags | log.Lmicroseconds | log.Lshortfile)
	log.SetPrefix("[LOG] ")
}

Es ist ein Server, der einfach den json "{" state ":" success "}" zurückgibt, wenn eine Anforderung für einen bestimmten Pfad mit der Methode "GET" oder "DELETE" eingeht.

Die Docker-Datei zum Ausführen dieses Servers finden Sie weiter unten.

FROM golang:alpine
RUN apk update && apk add --no-cache git
RUN go get -u github.com/gin-gonic/gin && mkdir /usr/src && mkdir /usr/src/api
COPY ./api /usr/src/api
WORKDIR /usr/src/api
CMD ["go","run","main.go"]

Da sich die obige Go-Datei usw. auf dem Host im Verzeichnis "api" befindet, kopieren Sie sie in den Container und starten Sie den Server. Ich habe diese Docker-Datei mit dem Namen "api" erstellt und sie mit dem folgenden Befehl gestartet.

docker run -p 8083:8080 api

Zuordnung von Port 8083 auf dem Host zu Port 8080 auf dem Container. Wenn Sie den obigen Befehl ausführen, wird die folgende Ausgabe ausgegeben, und Sie können bestätigen, dass der Gin-Server aktiv ist.

[GIN-debug] GET    /accounting-api           --> main.main.func1 (3 handlers)
[GIN-debug] DELETE /accounting-api           --> main.main.func4 (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on localhost:8080

Ich habe keinen Port angegeben, daher wird dieser standardmäßig auf Port 8080 ausgeführt. Auf den ersten Blick sieht es so aus, als würde es richtig funktionieren, aber wenn ich versuche, mit Curl auf der Hostseite auf "http: localhost: 8083" zuzugreifen, wird der folgende Fehler angezeigt.

curl: (52) Empty reply from server

Was ich versucht habe, um den Fehler zu beheben

1. Gehen Sie in den Container und prüfen Sie, ob Sie auf die API zugreifen können

Stellen Sie zunächst sicher, dass das Go-Programm wirklich auf dem Container ausgeführt wird. Gehen wir in den Docker-Container, der zu diesem Zweck gestartet wurde.

#Gehen Sie in den laufenden Container des API-Servers
docker exec -it api /bin/ash

Der Alpin, auf dem dieser Container basiert, hatte kein "/ bin / bash", also benutze "/ bin / ash". Geben Sie dann den folgenden Befehl ein, um festzustellen, ob das Programm ordnungsgemäß funktioniert.

#Da Curl überhaupt nicht enthalten ist, installieren Sie es
apk add --no-cache curl
#Deaktivieren Sie für alle Fälle den Proxy und greifen Sie mit curl auf den API-Server zu
curl -x "" http://localhost:8080/accounting-api

Hier ist das Ausführungsergebnis von Curl.

{"state": "success"}

Die Ergebnisse werden gut. Es scheint also, dass das Gin-Serverprogramm ordnungsgemäß auf dem Container ausgeführt wird.

2. Stellen Sie den Port in der Docker-Datei frei

Das Programm scheint auf dem Container zu laufen, daher vermute ich als nächstes, dass der Port-Mapping-Teil nicht funktioniert. Es scheint, dass Sie einen Befehl namens "EXPOSE" in die Docker-Datei schreiben können, also werde ich ihn hinzufügen.

EXPOSE 8080

Das hat nicht geholfen.

Erstens führt der Befehl "EXPOSE" gemäß den offiziellen Dokumenten tatsächlich nichts aus und informiert den Entwickler darüber, dass ein bestimmter Port geöffnet wird. Es scheint, dass es nur eine dokumentähnliche Rolle für hat. Das Hinzufügen des Befehls "EXPOSE" konnte das Problem also nicht lösen.

3. Überprüfen Sie die Windows-Firewall-Einstellungen

Da die Entwicklung im Wesentlichen mit Docker unter Windows durchgeführt wurde, habe ich die Windows-Firewall-Einstellungen überprüft, aber dies ergab auch keinen Sinn.

Als ich dieses Dockerfile unter Ubuntu erstellte und startete, konnte ich nicht auf den API-Server zugreifen, sodass ich von Anfang an wusste, dass es nicht an der Windows-Firewall lag.

4. (Dies ist die Lösung) Geben Sie den Port auf der Gin-Serverseite an

Im Go-Programm habe ich versucht, den Port in dem Teil anzugeben, der den GIn-Server startet, und jetzt kann ich gut darauf zugreifen. Insbesondere ist es der folgende Teil.

r := gin.Default()
r.Run(":8080")

Es war mir egal, weil es standardmäßig mit 8080 startet, auch wenn ich nichts spezifiziere, aber es scheint nutzlos zu sein, wenn ich es nicht richtig spezifiziere.

Ich bin nicht sicher, warum der Port standardmäßig schlecht ist und muss explizit angegeben werden. Ich werde es hinzufügen, wenn ich es verstehe.

Recommended Posts

Lösung für unzugänglichen Gin-Server, der auf dem Docker-Container ausgeführt wird
Erstellen Sie einen CGI-Server, der unter Python 3 in Docker ausgeführt wird
Versuchen Sie, Tensorflow auf Docker + Anaconda auszuführen
Tipps zum Ausführen Gehen Sie mit Docker
Starten Sie den Docker-Container, wenn Sie Pytest ausführen
Führen Sie Matplotlib auf einem Docker-Container aus
Docker-Datei: Installieren Sie Docker auf einem Linux-Server
Führen Sie matplotlib in einem Windows Docker-Container aus
Geben Sie in stdin den laufenden Docker-Container ein