Search code examples
spring-bootdockergoogle-compute-enginegoogle-cloud-sqlcloud-sql-proxy

Docker image with Spring boot fails to connect to CloudSQL


I want to create web services with Spring boot, add it to docker image, connect to cloud sql and then run on Compute Engine.

I am using docker compose to combine the image for project and cloud sql proxy image. However, no matter what jdbc URL I give it fails to connect. Right now, I am trying all of this locally

I have tried following URLs:

1. spring.datasource.url=jdbc:mysql:///cloudsql/myinstancename/${MYSQL_DATABASE}
2. spring.datasource.url=jdbc:mysql://cloudsql/myinstancename/${MYSQL_DATABASE}
3. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/${MYSQL_DATABASE}

docker-compose.yml

version: '3'

services:
  app:
    image: appname

    volumes:
      - cloudsql:/cloudsql
    depends_on:
      - sql_proxy
    ports:
      - 8080:8080

# SQL proxy is built correctly, says
# Listening on /cloudsql/myinstancename for myinstancename
# sql_proxy_1  |  Ready for new connections

  sql_proxy:
    environment:
      - MYSQL_ROOT_PASSWORD=password!#
      - MYSQL_DATABASE=appname
      - MYSQL_USER=root
    image: gcr.io/cloudsql-docker/gce-proxy:1.12
    command:
      /cloud_sql_proxy
      -dir=/cloudsql
      -instances=myinstancename  # (I have added this correctly)
      -credential_file=/root/keys/keyfile.json
    volumes:
      - E:\mykey.json:/root/keys/keyfile.json:ro
      - cloudsql:/cloudsql
    ports:
      - 3306:3306


volumes:
  # This empty property initializes a named volume.
  cloudsql:

application.properties:

spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql:///cloudsql/myinstancename/${MYSQL_DATABASE}
spring.datasource.username=${MYSQL_USER}
spring.datasource.password=${MYSQL_ROOT_PASSWORD}
spring.security.enabled=false
security.ignored=/**

Solution

  • Currently, you are using the Cloud SQL proxy in a sidecar pattern that is mounting a unix socket in /cloudsql/<INSTANCE_CONNECTION_NAME> that can be used to connect to your Cloud SQL instance. Unfortunately, most Java JDBC drivers don't support unix sockets. You can switch the Cloud SQL Proxy to provide a tcp socket instead with something like the following: "-instances=<INSTANCE_CONNECTION_NAME>=tcp:3306".

    Alternatively, you can use the Cloud SQL JDBC Socket Factory. This is a Java library that allows you to create authenticated connections to a Cloud SQL instance, but doesn't require using the proxy.