Access MySQL in one container from another container
Thanks to the above answers I was able to resolve my problem.
Anyone who understands basics of docker networks and just want the solution can completely ignore this answer.
I am writing this answer for anyone who might be just starting docker and do not have a clear understanding of docker networks.
Problem: Communication between different docker containers.
To communicate between n different containers in docker we need to first understand how docker network works:
- Whenever we install docker in our host, a docker0 virtual interface/bridge is created.This is basically a Virtual Ethernet bridge that automatically talks to any other network interfaces that are attached to it.
- The docker 0 interface has an ip adress, lets say 172.0.0.x.
- The subsequent containers subnet from this IP.
- Therefore any communication between the containers can happen either through the docker bridge or using the host private IP.
The above diagram may help you understand it better.
Docker0 :The Docker0 interface with IP.
Now, to get into the commands:
Use this command to get the IP of a container:
How to get a Docker container's IP address from the host?
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
SQL container:
docker run --name mysql55c -p 4500:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=db_ngen -d mysql:5.5
The above command creates a container called mysql55c with ip sub-netted from docker0.
Golang container
docker run -w /go/src/app -it -d --name golangapp --link mysql55c:db -v $(pwd):/go/src/app golang bash
The above container creates a container with name golangapp.
The important thing to observe is the --link
command.
This command allowed both the containers to discover each other.
But after docker network feature has been introduced this can be done using docker default bridge network or user defined networks.
The container Ip's:
Now, we can see that we can communicate between the containers using the default docker bridge network.
For Reference:
Overlay Network
User Defined Bridge
Default Bridge Network
Hope the above helps, feel free to correct me if I am wrong anywhere.
Thank you :)
This should work, follow these steps:
- Run mysql container
docker run --name mysql55c -p 4200:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.5
- Create
Dockerfile
for golang with following contents:
FROM golang:latestCOPY . /RUN go get "github.com/go-sql-driver/mysql"CMD go run /main.go
- Create
main.go
with following contents:
package mainimport( _ "github.com/go-sql-driver/mysql" "database/sql" "log")func main() { // Open up our database connection. db, err := sql.Open("mysql", "root:root@tcp(192.168.0.33:4200)/mysql") // if there is an error opening the connection, handle it if err != nil { log.Print(err.Error()) } else { log.Print("DB connected successfully") } defer db.Close()}
- Build golang container image using
docker build -t goapp .
- Run golang container
docker run -itd goapp
- Check logs of the golang container:
$ docker logs dbd5294abd612019/06/19 13:24:17 DB connected successfully
NOTE: I ran mysql container which is exposed on 4200 port of the host. In golang code my connection string was root:root@tcp(192.168.0.33:4200)/mysql
where 192.168.0.33
is private ip of my machine.
The main takeaway for you should be that your db connection string should point to private/public ip of your host. If you run golang without container linking.
If container linking is used while running golang suppose docker run -itd --link mysql55c:mydb goapp
then mysql connection string in your golang code should be root:root@tcp(mydb:4200)/mysql
Try this and let me know.