Connecting go with mysql using Docker

I’m trying to connect MySQL with golang using docker, for local MySQL instance it’s working perfectly but
when trying to access docker container mysql instance, always getting connection refused.

Can anyone help me to solve this issue?

.env

MYSQL_IDS_USERNAME=root
MYSQL_IDS_PASSWORD=12345678
MYSQL_IDS_HOST=localhost
MYSQL_IDS_PORT=3306
MYSQL_IDS_SCHEMA=ids_db
MYSQL_ROOT_PASSWORD=12345678

docker-compose.yml

version: '3.7'

services:
  mysql:
    image: mysql:latest
    volumes:
      - "./db_data:/var/lib/mysql"
    env_file:
      - ".env"
    ports:
      - "3307:3306"
    networks:
      - appmysql

  id_service:
    container_name: id_service
    build:
      context: .
      dockerfile: Dockerfile
    image: rezwanulhaque/id-service:latest
    volumes:
      - "./logs:/app/lib/logs"
    ports:
      - "7001:7001"
    depends_on:
      - mysql
    networks:
      - appmysql
networks:
  appmysql:
    driver: bridge

Dockerfile

# Start from golang base image
FROM golang:1.14-alpine3.11 AS builder

#ENV GO111MODULE=on

# Add Maintainer info
LABEL maintainer="Rezwanul Haque <rezwanul.cse@gmail.com>"

# Install git.
# Git is required for fetching the dependencies.
RUN apk update && apk add --no-cache git

# Configure the repo url
ENV REPO_URL=github.com/Rezwanul-Haque/ID-Service

# Setup our $GOPATH
ENV GOPATH=/app

# Set the current working directory inside the container
ENV APP_PATH=$GOPATH/src/$REPO_URL
ENV WORKPATH=$APP_PATH/src/
COPY src $WORKPATH
WORKDIR $WORKPATH

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

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

# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux go build -o id-service .

# Start a new stage from scratch
#FROM alpine:latest
#
#RUN ls bin/
## Copy the Pre-built binary file from the previous stage. Observe we also copied the .env file
#COPY --from=builder /app/id-service .
#COPY --from=builder /app/.env .
#
# Expose port 7001 to the outside world
EXPOSE 7001

# Command to run the executable
ENTRYPOINT ["./id-service"]

db.go

var (
	Client *sql.DB

	username = os.Getenv("MYSQL_IDS_USERNAME")
	password = os.Getenv("MYSQL_IDS_PASSWORD")
	host     = os.Getenv("MYSQL_IDS_HOST")
	port     = os.Getenv("MYSQL_IDS_PORT")
	schema   = os.Getenv("MYSQL_IDS_SCHEMA")
)

func init() {
	dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8",
		username, password, host, port, schema,
	)
	var err error
	Client, err = sql.Open("mysql", dataSourceName)
	if err != nil {
		logger.Error("connecting to database failed: ", err)
		panic(err)
	}

	if err = Client.Ping(); err != nil {
		panic(err)
	}
	logger.Info("database successfully configured")
}

Docker compose makes your mysql available under that name in DNS, on localhost there is no database running from the view of the applications container.

But using the below command I can access my docker container MySQL instance.

mysql -h localhost -P 3307 --protocol=tcp -u root --password='12345678

Are you running that on your host or from within your applications container?

I’m new to Docker so I run docker-compose up -d then when checking the docker’s application service which is my case ID_service it shows connection refused. then I check MySQL service it’s running so I try

mysql -h localhost -P 3307 --protocol=tcp -u root --password='12345678

this to check if MySQL running correctly or not. I can access MySQL 3307(public) port from my host PC which is exposed as public from the container.

Each docker container is isolated, you consider it its own computer for making things simple. So “localhost” from your applications container is different from you host computer.

Your host computer has something set up that maps its own ports to those of theysql container.

And as I already said, from within the compose network the database is available under the name mysql per DNS.

As my Docker container has two services mysql and Id_service and a bridge network “appmysql” so for id_service to access mysql I need to use appmysql network’s IP to access mysql from app service, is that right?

You must allow remote connections in my.cnf file (see bind-address option) and grant access to remote user in your case ‘root’ @’%’.

You have 2 containers. One for each service.

Each service is available per DNS under its service name. Just use mysql in your go application as host for the database.

This has already happened, otherwise connection from host computer to container MySQL hasn’t been possible.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.