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).
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
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.
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.
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.
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