Access Cloud SQL from Docker on Cloud Run
Tags: googlecloud, cloudrun, docker, cloudsql
Published: 2021-10-01 06:52:24

This is a brief note for developers to access Cloud SQL from Docker on Cloud Run.

# 1. Create a Cloud SQL instance and Cloud Run service
I do not talk about the basics of Cloud SQL and Cloud Run in this article. Please refer the official documents.
[Quickstart for Cloud SQL for MySQL](https://cloud.google.com/sql/docs/mysql/quickstart)
[Deploying container images : Cloud Run](https://cloud.google.com/run/docs/deploying)

# 2. Set up Cloud Run connection to Cloud SQL
We need to add a permission to Cloud Run service to connect to a Cloud SQL.

Get your `Connection name` of your Cloud SQL instance. The format is should look like `PROJECT-ID:REGION:INSTANCE-ID`.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98t2t0u4ih2fydc8kzkc.png)

Set your SQL instance in Cloud Run setting page with your `Connection name`.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnsb8i9gmj8n1vrk3fwd.png)

# 3. Install `cloud_sql_proxy` in your Docker image
To connect to Cloud SQL from docker, you need to install `cloud_sql_proxy` in your Docker image.

The command to install is like this [Official doc](https://cloud.google.com/sql/docs/mysql/sql-proxy). I recommend to include the command in your Dockerfile as `RUN` statement.
```console
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
chmod +x cloud_sql_proxy
```

# 4. Start cloud_sql_proxy at Docker startup

The following command needs to be executed before to connect to Cloud SQL instance. `$CLOUD_SQL_CONNECTION_NAME` is your Cloud SQL connection name that you got in Step 2. I use an environment variable to keep the value but you can write down your connection name directly here.
```console
./cloud_sql_proxy -instances=$CLOUD_SQL_CONNECTION_NAME=tcp:0.0.0.0:3306
```

`tcp:0.0.0.0:3306` is just an example setting. So you may use another like `127.0.0.1` for host and another PORT instead of `3306`.

# 5. Run your image on Cloud Run and access to Cloud SQL
Done 😉. By the settings you've done, you can connect Cloud SQL from Docker container. The things you should care to access from your code is
- hostname: You've set in step 4
- post: You've set in step 4
- user: You should've set when your created Cloud SQL instance or if you did not create any user, `root` user should exist.
- password: You should've set when your created Cloud SQL instance
- database name: Please create a database in your Cloud SQL instance

# Appendix A: Simple Dockerfile
If you use Node.js to run a server, you can use the following Dockerfile.

```Dockerfile
FROM node:14

# Create app directory
WORKDIR /usr/src/app

# Cloud Sql Proxy
RUN apt-get update \
  && apt-get install --no-install-recommends -y \
    wget \
  ;
RUN wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
RUN chmod +x cloud_sql_proxy

COPY . .

RUN yarn

CMD ["sh", "-c", "./cloud_sql_proxy -instances=$CLOUD_SQL_CONNECTION_NAME=tcp:0.0.0.0:3306 & yarn start"]
```

# Appendix B: Why do we need Cloud SQL proxy.
The first reason we need the proxy is to access instance securely. We can use public IP address with password to access a SQL instance but it is very dangerous. The second reason is Docker, even with the setting we've done in Step 2. We cannot use the unix socket for accessing Cloud SQL [Ref. Connect with Unix sockets](https://cloud.google.com/sql/docs/mysql/connect-run#connecting_to). This is because the setting is to enable unix socket for a Cloud Run instance but it's not to enable unix socket of Docker in the Cloud Run instance.