I have a problem with connecting Api with MySQL database running in containers. I have Dockerfile for Golang Api:
FROM golang:latest
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
WORKDIR /app/bin
EXPOSE 8080
RUN go run ./../cmd/web/
I usually connect with database in the application using database/sql:
dsn = "user1:pass@tcp(wpmysql:3306)/wp?parseTime=true"
db, err := sql.Open("mysql", dsn)
My docker-compose.yml:
version: '3'
services:
db:
image: mysql:5.7
container_name: ${MYSQL_CONTAINER_NAME}
ports:
- 3306:3306
command: --init-file /usr/src/app/init.sql
volumes:
- ./init.sql:/usr/src/app/init.sql
environment:
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASS}
- MYSQL_DATABASE=${MYSQL_DB}
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
networks:
- fullstack
web:
container_name: wpapi
build: .
ports:
- 8080:8080
restart: on-failure
volumes:
- .:/usr/src/app/
depends_on:
- db
networks:
- fullstack
networks:
fullstack:
driver: bridge
In the same directory as docker-compose.yml is file .env:
DB_PASSWORD=pass
MYSQL_PORT=3306
MYSQL_USER=user1
MYSQL_PASS=pass
MYSQL_DB=wp
MYSQL_CONTAINER_NAME=wpmysql
After call commends:
$ docker-compose up -d db
$ docker-compose build web
I get error ERROR main.go:46: dial tcp: lookup wpmysql on 37.8.214.2:53: no such host
. List of containers looks like:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fbaf67df5bf 2778fcda2046 "/bin/sh -c 'go run …" 14 seconds ago Up 13 seconds 8080/tcp mystifying_shannon
7f6c76cc9c4f mysql:5.7 "docker-entrypoint.s…" 40 minutes ago Up About a minute 0.0.0.0:3306->3306/tcp, 33060/tcp wpmysql
Moreover when I try to connect in application by dsn = "user1:pass@tcp(localhost:3306)/wp?parseTime=true"
or dsn = "root:pass@tcp(localhost:3306)/wp?parseTime=true"
I get another error:
dial tcp 127.0.0.1:3306: connect: connection refused
although I can go into container (docker exec -it wpmysql bash -l
) and sign in
with root
and user1
credentials
In your docker file you have:
RUN go run ./../cmd/web/
This will attempt to build AND run your executable during the build process. The network fullstack
is not available at this time. I think you probably meant to use:
CMD go run ../cmd/web/
This will set the default command run when you start (i.e. docker-compose up
) the container to go run ../cmd/web/
. Even better would be:
RUN go build ../cmd/web/
CMD ../cmd/web/web
This will build your application as part of the process of building the container and then set the executable produced as the default command. The benefit of doing this is that compile errors become apparent when you build the image (and it means the application is not built every time you start the container).