I tried to deploy and run an API server using Golang's web framework Gin on a Docker container, but I could not access the API. I was bothered for quite a long time.
As a result, I found that it was a problem of how to write the code of the Gin server, but I will write down the solution here just in case.
By the way, this error happened on Ubuntu server (t2.small) on Windows 10 and AWS (although the execution environment didn't seem to have much to do with the occurrence of this error).
I was trying to set up an API server using Gin. Since it is still in the stage of building the environment, the code is a mock like the one below.
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] ")
}
It's a server that simply returns a json of {"state ":" success "}
when a request for a particular path comes in with the GET
or DELETE
method.
And the Dockerfile to run this server is below.
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"]
Since the above Go file etc. is in the directory ʻapi on the host, copy it to the container and start the server. I built this Dockerfile with the name ʻapi
and launched it with the following command.
docker run -p 8083:8080 api
Mapping port 8083
on the host to port 8080
on the container. When you execute the above command, the following output will be output, and you can confirm that the Gin server is up.
[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
I didn't specify a port, so it's running on port 8080
by default. At first glance, it looks like it's working properly, but when I try to access http: localhost: 8083
with curl on the host side, I get the following error.
curl: (52) Empty reply from server
First of all, make sure that the Go program is really running on the container. Let's go inside the docker container that was launched for that purpose.
#Go inside the running container of the api server
docker exec -it api /bin/ash
Alpine, which is the base of this container, did not have / bin / bash
, so use / bin / ash
. Then type the following command to see if the program is working properly.
#Since curl is not included in the first place, install it
apk add --no-cache curl
#Just in case, disable the proxy and access the api server with curl
curl -x "" http://localhost:8080/accounting-api
Here is the execution result of curl.
{"state": "success"}
The results are getting good. So, it seems that the Gin server program is running properly on the container.
The program seems to be running on the container, so next I suspect that the port mapping part is not working. When I looked it up, it seems that the command ʻEXPOSE` can be written in the Dockerfile, so I will add it.
EXPOSE 8080
Doing this didn't help.
In the first place, according to the official docs, the ʻEXPOSE command doesn't really do anything and tells the developer to open a specific port. It seems that it only has a document-like role for. So, just adding the ʻEXPOSE
command couldn't solve the problem.
Since development was basically done with Docker on Windows, I reviewed the Windows firewall settings, but this also didn't make sense.
In the first place, when I built this Dockerfile on Ubuntu and launched it, I could not access the API server as well, so I knew from the beginning that it was not due to the Windows firewall.
In the Go program, I tried to specify the port in the part that starts the GIn server, and now I can access it well. Specifically, it is the following part.
r := gin.Default()
r.Run(":8080")
I didn't care because it starts up with 8080
by default even if I don't specify anything, but it seems to be useless if I don't specify it properly.
I'm not sure why the port is bad by default and must be explicitly stated. I will add it when I understand it.
Recommended Posts