skip to Main Content

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


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

    Login or Signup to reply.
  2. 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:

    FROM golang:1.15-alpine as builder
    
    COPY . /backend
    
    WORKDIR /backend
    
    RUN go build -o main -ldflags="-s -w" . # If you are building the image below from scratch specify the CGO_ENABLED=0 env var
    
    -----
    
    FROM alpine:3.12.1
    
    COPY --from=builder /backend/main /usr/bin/
    
    EXPOSE 3002
    
    ENTRYPOINT ["/usr/bin/main"]
    

    Dockerfile notes based on best practices article:

    • Try to specify images version whenever possible as the lastest one may introduce new bugs to your app. However, it’s not strictly required.
    • Prefer COPY to ADD when the resource we are trying to copy is not an url.
    • If the purpose of the container is purely running a server it’s recommended to use ENTRYPOINT instead of CMD, which will ignore any parameters passed when running the container (if you want to use "exec" command then CMD is preferred).

    Go binary note: -ldflags="-s -w" is often used to reduce the binary size by stripping the debugging information (more info here).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search