I am creating a web application with Go and the Gin framework. The idea is to use Docker to be able to run it in a container and also be able to debug it. So my Dockerfile is as follows:
FROM golang:1.21.6
WORKDIR /go/src/gitlab.com/main/server
COPY go.mod .
COPY go.sum .
RUN go mod download
RUN go install github.com/cosmtrek/air@latest
RUN go install github.com/swaggo/swag/cmd/swag@latest
RUN go install github.com/go-delve/delve/cmd/dlv@latest
EXPOSE 2345
EXPOSE 80
My docker compose looks like this:
version: "3.2"
services:
service-influxdb:
image: go-time-series
build:
context: ..
dockerfile: docker/Dockerfile
command: air -c .air.toml
volumes:
- ../:/go/src/gitlab.com/main/server
ports:
- 8080:80
- 10000:2345
environment:
- WEB_APP_VERSION=0.0.1
- WEP_APP_TITLE=Thori influx-DB
- WEP_APP_DESCRIPTION=Micro service for the manage of the influx-db services
- ENVIRONMENT=dev
- HOST=localhost:8080
- INFLUX_URL=http://localhost:8086
- INFLUX_TOKEN=1234
- INFLUX_ORG=Abc
- INFLUX_MINIMUN_DATE=1677-09-21 00:12:44
- INFLUX_MAXIMUN_DATE=2100-01-01 00:00:00
network_mode: host
I have the VS code configuration like this:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug in Docker",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "/go/src/gitlab.com/main/server",
"port": 10000,
"host": "127.0.0.1",
"showLog": true,
"trace": "log",
"logOutput": "rpc"
},
]
}
The .air.toml file mentioned in the docker-compose is as follows:
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
args_bin = []
bin = "./tmp/main"
full_bin = "dlv exec --accept-multiclient --headless --listen :2345 --api-version 2 ./tmp/main"
pre_cmd = ["swag init -g ./cmd/main.go"]
cmd = "go build -o ./tmp/main ./cmd/main.go"
post_cmd = []
delay = 0
exclude_dir = ["assets", "tmp", "vendor", "testdata", "docs"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = true
follow_symlink = true
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
main_only = false
time = true
[misc]
clean_on_exit = true
[screen]
clear_on_rebuild = true
keep_scroll = true
And finally, the main of my application looks like this:
func main() {
port := flag.Int("port", 80, "Listening port")
flag.Parse()
if config.Cfg.Environment == "prod" {
gin.ForceConsoleColor()
gin.SetMode(gin.ReleaseMode)
}
router := gin.Default()
loadSwagger(router)
loadAPI(router)
router.Run(fmt.Sprintf(":%d", *port))
}
func loadSwagger(router *gin.Engine) {
// @securityDefinitions.apikey ApiKeyAuth
// @in Header
// @name Authorization
docs.SwaggerInfo.Title = config.Cfg.WebAppTitle
docs.SwaggerInfo.Version = config.Cfg.WebAppVersion
docs.SwaggerInfo.Description = config.Cfg.WebAppDescription
docs.SwaggerInfo.Host = config.Cfg.Host
router.GET("/docs/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
I hope that my application is available locally on port 8080 and 10000 for debugging. However, when I try to access it from port 8080, nothing is running, and when I try to start debugging in VS CODE I also get an error.
The logs that appear are the following:
docker-service-influxdb-1 | [21:07:26] mkdir /go/src/gitlab.com/main/server/tmp
docker-service-influxdb-1 | [21:07:26] watching .
docker-service-influxdb-1 | [21:07:26] watching app
docker-service-influxdb-1 | [21:07:26] watching app/api
docker-service-influxdb-1 | [21:07:26] watching app/api/handlers
docker-service-influxdb-1 | [21:07:26] watching app/api/handlers/healthcheck
docker-service-influxdb-1 | [21:07:26] watching app/config
docker-service-influxdb-1 | [21:07:26] watching app/domain
docker-service-influxdb-1 | [21:07:26] watching app/domain/models
docker-service-influxdb-1 | [21:07:26] watching app/domain/ports
docker-service-influxdb-1 | [21:07:26] watching app/domain/services
docker-service-influxdb-1 | [21:07:26] watching app/repositories
docker-service-influxdb-1 | [21:07:26] watching cmd
docker-service-influxdb-1 | [21:07:26] watching docker
docker-service-influxdb-1 | [21:07:26] !exclude docs
docker-service-influxdb-1 | [21:07:26] !exclude tmp
docker-service-influxdb-1 | [21:07:26] > swag init -g ./cmd/main.go
docker-service-influxdb-1 | 2024/02/07 21:07:26 Generate swagger docs....
docker-service-influxdb-1 | 2024/02/07 21:07:26 Generate general API Info, search dir:./
docker-service-influxdb-1 | 2024/02/07 21:07:26 warning: failed to get package name in dir: ./, error: execute go list command, exit status 1, stdout:, stderr:no Go files in /go/src/gitlab.com/main/server
docker-service-influxdb-1 | 2024/02/07 21:07:26 Generating models.HealthCheck
docker-service-influxdb-1 | 2024/02/07 21:07:26 create docs.go at docs/docs.go
docker-service-influxdb-1 | 2024/02/07 21:07:26 create swagger.json at docs/swagger.json
docker-service-influxdb-1 | 2024/02/07 21:07:26 create swagger.yaml at docs/swagger.yaml
docker-service-influxdb-1 | [21:07:26] building...
docker-service-influxdb-1 | [21:07:27] running...
docker-service-influxdb-1 | API server listening at: [::]:2345
docker-service-influxdb-1 | 2024-02-07T21:07:27Z warning layer=rpc Listening for remote connections (connections are not authenticated nor encrypted)
I feel like I'm making a silly mistake, but I can't figure out what I'm doing wrong.
Delete the network_mode: host
line.
Your application is starting with HTTP port 80 and port 2345 for the debugger. You can see one of these ports in the console output, and the right-hand side of ports:
matches these port numbers too. However, host networking generally disables all Docker networking functionality, including the ability to remap ports. You could probably reach the application on host ports 80 and 2345 and not the remapped ports, but that's not what you're intending with this setup.