Search code examples
google-app-enginegoogle-cloud-sqlcloud-sql-proxy

GAE cloud SQL proxy use TCP sockets (instead of UNIX)


We're setting up a node application on GAE, and one of the libraries we're using doesn't play well with unix sockets.

The Cloud Proxy setup inside GAE uses unix sockets, I've googled and searched the google docs but can't find information on configuring the cloud proxy created within the GAE (ie in production) to use TCP sockets.

(I've done it locally when testing, but can't figure out what I need to set in my app.yaml to make it happen in production)


Solution

  • To be able to use TCP sockets in your app, you have to migrate to Custom Runtime.

    You can generate the Dockerfile with the command

    $ gcloud beta app gen-config --custom

    After generating the Dockerfile for this runtime, modify it like the following:

    FROM gcr.io/google_appengine/nodejs
    RUN /usr/local/bin/install_node '>=4.3.2'
    RUN apt-get update
    RUN apt-get install mysql-client -yy
    RUN apt-get install wget -yy
    COPY . /app/
    RUN npm install --unsafe-perm || \
      ((if [ -f npm-debug.log ]; then \
          cat npm-debug.log; \
        fi) && false)
    RUN wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
    RUN chmod +x cloud_sql_proxy
    RUN echo -e “#!/bin/bash\n./cloud_sql_proxy -instances=YOUR-INSTANCE-DB=tcp:3306 &\nnode server.js” > script.sh
    RUN chmod +x script.sh
    CMD bash script.sh
    

    This, when deploying, will generate the container, and that container will have the proxy communicating via TCP.

    Before deploying, in your app.yaml file you must delete from env_variables INSTANCE_CONNECTION_NAME, as you are already indicating that in the Dockerfile.

    Don’t forget to enable the Cloud SQL API to run this.

    I have used the example in here, and you can see that the function connect in server.js has an if condition like this:

    if (process.env.INSTANCE_CONNECTION_NAME && process.env.NODE_ENV === 'production') {
        config.socketPath =/cloudsql/${process.env.INSTANCE_CONNECTION_NAME}
    }
    

    If you have something similar, delete it, as you are not providing now, in the environment variables, the INSTANCE_CONNECTION_NAME.

    This is a workaround to the situation, but I don’t see it possible if is not like this.