skip to Main Content

Got [error] failed to initialize database, got error dial tcp 192.168.16.2:3306: connect: connection refused when run docker compose up -d

docker-compose.yml

version: "3"
services:
  app:
    container_name: app
    build:
      context: .
      dockerfile: api.Dockerfile
    restart: always
    ports:
      - 8071:8080
    environment:
      - GIN_MODE=$GIN_MODE
      - APP_PORT=$APP_PORT
      - DB_HOST=$DB_HOST
      - DB_PORT=$DB_PORT
      - DB_USER=$DB_USER
      - DB_PASS=$DB_PASS
      - DB_NAME=$DB_NAME
    depends_on:
      - mysql

  mysql:
    container_name: mysql
    image: mysql:8.0
    ports:
      - 3366:3306
    environment:
      MYSQL_USER: $DB_USER
      MYSQL_PASSWORD: $DB_PASS
      MYSQL_ROOT_PASSWORD: $DB_PASS
      MYSQL_DATABASE: $DB_NAME

    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

api.Dockerfile

FROM golang:1.22.3-alpine as builder

LABEL maintainer="lmhuong <[email protected]>"

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY go.mod go.sum ./

# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download

# Copy the source from the current directory to the Working Directory inside the container
COPY . .

# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

######## Start a new stage from scratch #######
FROM alpine:3.19

RUN apk --no-cache add ca-certificates

WORKDIR /root/

# Copy the Pre-built binary file from the previous stage
COPY --from=builder /app/main . 
# copy env file to root directory 
COPY --from=builder /app/.env.example .env

# Command to run the executable
CMD ["./main"]

.env.example

GIN_MODE=release # debug, release
APP_PORT=8080

DB_HOST=mysql
DB_PORT=3306
DB_USER=lmhuong711
DB_PASS=123
DB_NAME=my_db
DB_CHARSET=utf8mb4
DB_LOC=Local

EDIT:
db.go

package db

import (
    "database/sql"
    "fmt"
    "lmhuong711/vdt24-be/models"
    "log"
    "os"

    // "github.com/kristijorgji/goseeder"
    "github.com/lpernett/godotenv"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

var Db *gorm.DB

func InitDb() *gorm.DB {
    // goseeder.WithSeeder(connectToDbOrDie, func() {
    // })
    connectToDbOrDie()
    return Db
}

func connectToDbOrDie() *sql.DB {
    var err error
    err = godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }

    user := os.Getenv("DB_USER")
    password := os.Getenv("DB_PASS")
    host := os.Getenv("DB_HOST")
    port := os.Getenv("DB_PORT")
    database := os.Getenv("DB_NAME")

    dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, password, host, port, database)

    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

    if err != nil {
        fmt.Printf("Error connecting to database : error=%v", err)
        return nil
    }

    db.AutoMigrate(&models.Students{})
    db.AutoMigrate(&models.Domains{})
    db.AutoMigrate(&models.MapStudentDomain{})

    Db = db
    ret, err := db.DB()
    if err != nil {
        fmt.Printf("Error getting database connection : error=%v", err)
        return nil
    }
    return ret
}

I have try re run docker compose up --build --remove-orphans --force-recreate -d multiple times, prune containers but still have this error. I can connect to db by mysql -u lmhuong711 -p pass 123 successfully. But still have this error.

2

Answers


  1. Chosen as BEST ANSWER

    After add healthcheck to docker-compose, it seems like the error is fixed. Here is my docker-compose.yml

    version: "3"
    services:
      app:
        container_name: app
        build:
          context: .
          dockerfile: api.Dockerfile
        restart: always
        hostname: lmhuong711-goweb.com
        ports:
          - 8071:8080
        environment:
          - GIN_MODE=$GIN_MODE
          - APP_PORT=$APP_PORT
          - DB_HOST=$DB_HOST
          - DB_PORT=$DB_PORT
          - DB_USER=$DB_USER
          - DB_PASS=$DB_PASS
          - DB_NAME=$DB_NAME
        depends_on:
          mysql:
            condition: service_healthy
    
      mysql:
        container_name: mysql
        image: mysql:8.0
        expose:
          - 3306
        ports:
          - 3366:3306
        environment:
          MYSQL_USER: $DB_USER
          MYSQL_PASSWORD: $DB_PASS
          MYSQL_ROOT_PASSWORD: $DB_PASS
          MYSQL_DATABASE: $DB_NAME
          MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
        healthcheck:
          test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
          interval: 1s
          timeout: 3s
          retries: 30
        volumes:
          - db_data:/var/lib/mysql
    
    volumes:
      db_data:
    

  2. You are getting this error due to mysql host is not reachable. You have to add networks section in your docker-compose.yml and attach newly added network to your mysql and app services. Your docker-compose.yml should look like below:

    version: "3"
    services:
      app:
        container_name: app
        build:
          context: .
          dockerfile: api.Dockerfile
        restart: always
        ports:
          - 8071:8080
        networks:
          - backend
        environment:
          - GIN_MODE=$GIN_MODE
          - APP_PORT=$APP_PORT
          - DB_HOST=$DB_HOST
          - DB_PORT=$DB_PORT
          - DB_USER=$DB_USER
          - DB_PASS=$DB_PASS
          - DB_NAME=$DB_NAME
        depends_on:
          - mysql
    
      mysql:
        container_name: mysql
        image: mysql:8.0
        ports:
          - 3366:3306
        networks:
          - backend
        environment:
          MYSQL_USER: $DB_USER
          MYSQL_PASSWORD: $DB_PASS
          MYSQL_ROOT_PASSWORD: $DB_PASS
          MYSQL_DATABASE: $DB_NAME
    
        volumes:
          - db_data:/var/lib/mysql
    
    volumes:
      db_data:
      
    networks:
      backend:
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search