I have Go
as my API
and PostgreSQL
as my database.
I can run my backend using the docker container when executed in development environment. However, when I run my dockerfile
and docker-compose. The database is not connecting to postgres
.
Dockerfile
FROM golang:alpine
RUN mkdir /backend
ADD . /backend/
WORKDIR /backend
COPY go.mod .
COPY go.sum .
COPY .env .
RUN go mod download
RUN go build -o main .
EXPOSE 3002
CMD ["./main"]
docker-compose.yml
version: '3.3'
services:
postgres:
image: "postgres"
ports:
- "5432:5432"
env_file:
- .env
volumes:
- ./postgres/:/var/lib/postgresql/data/
restart: always
networks:
- "backend.network"
nginx:
image: nginx:latest
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- backend
- postgres
ports:
- "8080:8080"
links:
- 'postgres'
- 'backend'
networks:
- "backend.network"
backend:
build: "."
ports:
- "3002:3002"
depends_on:
- postgres
links:
- postgres
restart: "always"
networks:
- "backend.network"
networks:
backend.network:
.env
DB_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=pass
POSTGRES_NAME=db
Go connection
DB, err = gorm.Open("postgres", fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", config.Config("DB_HOST"), port, config.Config("POSTGRES_USER"), config.Config("POSTGRES_PASSWORD"), config.Config("POSTGRES_NAME")))
if err != nil {
panic("failed to connect database")
}
Error
failed to connect databasedial tcp 127.0.0.1:5432: connect: connection refused
exit status 1
I really don’t know what’s wrong with my dockerfile.
2
Answers
as @blami said:
your backend is trying to connect to "localhost" as each of your containers will have its own "localhost".
youc can use your machine host ip, or your database container ip. you can find it using docker inspect <container_name>
As @blami pointed out, the DB_HOST should be "postgres". Also, you are passing the .env file to the postgres image but not to the backend one (it may be using default values). If it keeps failing please comment the error you get.
Finally I would recommend to use a builder image to compile your server and then copy it to a smaller image using alpine (if you want to go a step further you can build the final image from scratch), making the container size as lightweight as we can, just like this:
Dockerfile notes based on best practices article:
Go binary note: -ldflags="-s -w" is often used to reduce the binary size by stripping the debugging information (more info here).