J'ai essayé de déployer et d'exécuter un serveur API en utilisant le framework Web de Golang Gin sur un conteneur Docker, mais je n'ai pas pu accéder à l'API. J'ai été troublé pendant assez longtemps.
En conséquence, j'ai trouvé que c'était un problème d'écriture du code du serveur Gin, mais j'écrirai la solution ici au cas où.
À propos, cette erreur s'est produite sur le serveur Ubuntu (t2.small) sous Windows 10 et AWS (bien que l'environnement d'exécution ne semble pas avoir grand-chose à voir avec l'apparition de cette erreur).
J'essayais de configurer un serveur API en utilisant Gin. Puisqu'il est encore au stade de la construction de l'environnement, le code est un simulacre comme celui ci-dessous.
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] ")
}
C'est un serveur qui renvoie simplement le json {" state ":" success "}
lorsqu'une requête pour un chemin particulier arrive avec la méthode GET
ou DELETE
.
Et le Dockerfile pour exécuter ce serveur est ci-dessous.
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"]
Puisque le fichier Go ci-dessus, etc. se trouve dans le répertoire appelé ʻapi sur l'hôte, copiez-le sur le conteneur et démarrez le serveur. J'ai construit ce Dockerfile avec le nom ʻapi
et l'ai lancé avec la commande suivante.
docker run -p 8083:8080 api
Mappage du port «8083» sur l'hôte vers le port «8080» sur le conteneur. Lorsque vous exécutez la commande ci-dessus, la sortie suivante sera sortie et vous pourrez confirmer que le serveur Gin est opérationnel.
[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
Je n'ai pas spécifié de port, donc il fonctionne sur le port 8080
par défaut. À première vue, cela semble fonctionner correctement, mais lorsque j'essaie d'accéder à http: localhost: 8083
avec curl du côté hôte, j'obtiens l'erreur suivante.
curl: (52) Empty reply from server
Tout d'abord, assurez-vous que le programme Go s'exécute réellement sur le conteneur. Allons à l'intérieur du conteneur docker lancé à cet effet.
#Allez dans le conteneur en cours d'exécution du serveur api
docker exec -it api /bin/ash
L'Alpine sur laquelle ce conteneur est basé n'avait pas / bin / bash
, donc utilisez / bin / ash
. Tapez ensuite la commande suivante pour voir si le programme fonctionne correctement.
#Puisque curl n'est pas inclus en premier lieu, installez-le
apk add --no-cache curl
#Juste au cas où, désactivez le proxy et accédez au serveur api avec curl
curl -x "" http://localhost:8080/accounting-api
Voici le résultat de l'exécution de curl.
{"state": "success"}
Les résultats s'améliorent. Donc, il semble que le programme du serveur Gin fonctionne correctement sur le conteneur.
Le programme semble fonctionner sur le conteneur, donc je soupçonne ensuite que la partie de mappage de port ne fonctionne pas. Quand je l'ai recherché, il semble que la commande ʻEXPOSE` puisse être écrite dans le Dockerfile, je vais donc l'ajouter.
EXPOSE 8080
Faire cela n'a pas aidé.
En premier lieu, selon les Documents officiels, la commande ʻEXPOSE ne fait rien et informe le développeur qu'elle ouvrira un port spécifique. Il semble qu'il n'a qu'un rôle similaire à celui d'un document pour. Donc, le simple fait d'ajouter la commande ʻEXPOSE
ne pouvait pas résoudre le problème.
Étant donné que le développement était essentiellement effectué avec Docker sur Windows, j'ai examiné les paramètres du pare-feu Windows, mais cela n'avait pas non plus de sens.
En premier lieu, lorsque j'ai construit ce Dockerfile sur Ubuntu et l'ai lancé, je ne pouvais pas non plus accéder au serveur API, donc j'ai su dès le début que ce n'était pas dû au pare-feu Windows.
Dans le programme Go, j'ai essayé de spécifier le port dans la partie qui démarre le serveur GIn, et maintenant je peux bien y accéder. Plus précisément, c'est la partie suivante.
r := gin.Default()
r.Run(":8080")
Je m'en fichais car il démarre avec 8080
par défaut même si je ne spécifie rien, mais cela semble inutile si je ne le spécifie pas correctement.
Je ne sais pas pourquoi le port est mauvais par défaut et doit être explicitement indiqué. Je l'ajouterai quand je le comprendrai.
Recommended Posts