I am trying to connect an application (docker container) to a Google Cloud SQL database using a cloudsql-proxy docker container. Therefore, I've created a docker-compose file with the following cloudsql-proxy container: (XXX replaced with my cloud sql instance id)
version: "3"
volumes:
sqlproxy:
services:
cloudsql-proxy:
container_name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: /cloud_sql_proxy --dir=/cloudsql -instances=XXX=tcp:0.0.0.0:3306 -credential_file=/config/credentials.json
ports:
- "3306:3306"
volumes:
- /usr/share/service-accounts/cloudsql-client.json:/config/credentials.json
- sqlproxy:/cloudsql
- /etc/ssl/certs:/etc/ssl/certs
restart: always
Whenever I try to connect to the cloudsql mysql database from within another container running on the same machine, e.g. a second container within the docker-compose file, I get the error
"ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (111 "Connection refused")"
I tried to connect to the cloudsql-proxy with three different approaches, but still the same error. All containers (cloud sql proxy and test container to connect) are on one single google compute engine instance:
a) mysql-client: mysql --host 127.0.0.1
b) jdbc url: jdbc:mysql://127.0.0.1:3306/test
c) jdbc url: jdbc:mysql://cloudsql-proxy:3306/test
Within my gc firewall, I opened port 3306 for 0.0.0.0/0 for testing purposes, stopped and startet the cloud sql instance etc. but the error remains. The logs of the proxy container are OK:
2018/05/02 16:02:03 using credential file for authentication; [email protected]
2018/05/02 16:02:03 Listening on 0.0.0.0:3306 for x:x:x
2018/05/02 16:02:03 Ready for new connections
Is there something fundamental wrong with my approach or did I miss something? Might this be a docker problem? I can ping the proxy container from other containers.
This is not a Docker issue and changing the Google Cloud firewall would allow machines on the Internet to connect to port 3306 on the instance.
Figure 1
+--------------------------------------------+
| GCE instance |
| |
| +-----------------+ +-----------------+ |
| |MySQL 127.0.0.1| |Test 127.0.0.1| |
| | | | | |
| +------3306-------+ +-----------------+ |
| | |
| | |
+--------3306--------------------------------+
The first figure shows that the container Test
cannot reach the container MySQL as it is only aware of itself (127.0.0.1 on the loopback network). The error you are mentionning happens because MySQL is not running on port 3306 on the container Test
.
An option to reach the container MySQL
from Test
is to add an overlay network.
# I recommend using the latest version
version: "3.6"
volumes:
sqlproxy:
networks:
mysql_net:
driver: overlay
services:
cloudsql-proxy:
...
# This is not required
# ports:
# - "3306:3306"
...
networks:
mysql_net:
aliases:
database
test-container:
# Reach the container MySQL using the alias
command: mysql -u <user> -p --host database
...
networks:
mysql_net:
As the second figure shows, the two containers now share a common subnetwork. The container Test
should be able to reach the container MySQL
.
Figure 2
+-----------------------------------------------------------+
| GCE instance |
| |
| +-------------------------------+ +-------------------+ |
| MySQL 127.0.0.1 | |Test 127.0.0.1 | |
| | 10.0.0.3/8 (database)| | 10.0.0.4/8| |
| | | | | |
| | | | | |
| +------------3306---------------+ +-------------------+ |
| |
+-----------------------------------------------------------+
As the IP of the container is unknown, you have to use an alias (like a domain name). In the example, the alias is database
. The second figure assumes that the overlay network mysql_net
has mask 255.0.0.0
and the given IPs to the containers MySQL
and Test
are respectively 10.0.0.3
and 10.0.0.4
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With