COMS W4111.001-Introduction to Databases
Fall 2026

Cloud Run Setup

1. Select your existing Part 2 project

These instructions continue from Parts 1 and 2 of Project 1. You should already have a Google Cloud account, education billing account, project, virtual machine, Compute Engine default service account, provided proxy JSON key file, and assigned PostgreSQL credentials. Only one teammate needs to perform this setup. See the Part 3 assignment for the starter download and repository instructions.

  1. Go to console.cloud.google.com. Click your profile icon and confirm that you are signed in with your university account.
  2. Open the project selector at the top of the page. Select the existing project you used for Part 2 and check its project ID.
  3. Open Billing and check that this project is already linked to your course education billing account. If billing is disabled or the account is incorrect, contact staff; do not create a personal paid billing account.

Check that your Part 2 project remains selected before each section below. Keep your provided proxy-key.json file and Part 2 PostgreSQL username and password ready, but never put them in GitHub. Running Cloud Run, builds, image storage, and Secret Manager uses credits. We will use request-based billing and limit the service to one instance to reduce costs; this is not an absolute spending or database-connection cap.

2. Check your GitHub repository

You should already have created your team's private repository and uploaded the starter contents from the assignment ZIP.

  1. Open your team's private repository on GitHub and select main.
  2. Confirm that server.py, requirements.txt, Procfile, and .python-version are at the repository root, with templates/ and static/ alongside them. They must not be nested inside an extra starter directory.
  3. Open .python-version and confirm that it contains exactly 3.14.6.
  4. Open Procfile and confirm that its web entry is:
web: gunicorn --bind 0.0.0.0:$PORT --workers 1 server:app

This is file content, not a command to run. The build will use it to start the Flask application in server.py. Keep credentials out of the repository, even though it is private.

3. Upload the database secrets

  1. Use the Console search bar to open Secret Manager in your Part 2 project. If prompted, click Enable and wait for the service to become available. At the top of the page, make sure the Secrets tab is selected, not Regional secrets, before clicking Create secret.
  2. Click Create secret. Enter cloud-sql-proxy-key as the name. For the secret value, click Upload file and select the provided proxy-key.json file. Click Create secret.
  3. Create a second secret named db-user, with your team's actual Part 2 PostgreSQL username as its value.
  4. Create a third secret named db-password, with that PostgreSQL account's current password as its value. Enter the username and password without surrounding quotes or extra whitespace.
  5. Return to the secret list and select the checkboxes next to all three secrets. Click Show Info Panel if needed, then Add principal.
  6. In New principals, enter your project's Compute Engine default service account (format: [PROJECT_NUMBER]-compute@developer.gserviceaccount.com). To find its exact email address: open a new tab, navigate to Compute Engine → VM instances, click your Part 2 VM, scroll down to API and identity management, and copy the Service account email. (This is the default identity that runs your Cloud Run service.)
  7. Under Select a role, choose Secret Manager → Secret Manager Secret Accessor and click Save.

Important: Choose Secret Manager Secret Accessor, not Secret Manager Viewer. Viewer cannot read the stored credentials. Grant access to the default account running Cloud Run, not the identity inside the uploaded JSON key. Never grant secret access to allUsers or include secret values in screenshots, source code, or build environment variables.

4. Connect GitHub and configure the service

  1. Use the Console search bar to open Cloud Run. If prompted to enable the service, ensure it is the Cloud Run Admin API, click Enable, and wait for it to become available. Go to Services → Connect repo to open the service creation page.
  2. Select Cloud Build, not Developer Connect, and click Set up with Cloud Build.
  3. In Set up with Cloud Build, authenticate with GitHub if prompted. When asked where to install the Google Cloud Build GitHub App, select your own GitHub user account, where you published your team's repository. Under Repository access, choose Only select repositories and select the private repository you just published. Complete the authorization. If using an existing app installation, preserve access needed by its other projects.
  4. Back in Set up with Cloud Build, select your team repository. Read and check the acknowledgement beginning "I understand that GitHub content for the selected repositories will be transferred to this GCP project", then click Next. If the repository is missing, use Manage connected repositories to check the app's access. Do not make the repository public.
  5. Under Build Type, select Go, Node.js, Python, Java, .NET Core, Ruby or PHP via Google Cloud's buildpacks.
  6. Click Save to return to Create service. Set:
    • Service name: project1-web
    • Region: us-east1
    • Authentication: Require authentication for now; you will grant public access in Section 7.
    • Service scaling: Autoscaling, with minimum 0 and maximum 1 instances
  7. Expand Containers, Networking, Security. The first container card is your Flask application. Each container has its own Settings, Variables & Secrets, and Volumes tabs. You will configure Flask in Section 5 and add the proxy container below it in Section 6. Use Done at the bottom of a container card when you finish editing it; this does not create the service.

5. Configure the Flask container

  1. On the Create service page, scroll to the first (Flask) container card and open it if it is collapsed. Keep its generated name. Click its Variables & Secrets tab; leave its Settings and Volumes unchanged for now.
  2. Click Add variable for each ordinary runtime variable:
    • DB_HOST: 127.0.0.1
    • DB_PORT: 5454
    • DB_NAME: proj1part2
  3. Click Reference a secret. Set the environment variable name to DB_USER, select secret db-user, choose version 1, and click Done.
  4. Repeat for DB_PASSWORD, referencing db-password, version 1. Do not copy the password into an ordinary variable or mount the JSON key in Flask.
  5. Click Done at the bottom of the Flask container card, then scroll below it to Add Container. Do not click the page's Create button yet.

6. Add the Cloud SQL Auth Proxy sidecar

The service will have two containers. Flask receives web requests; the proxy connects Flask to the existing course PostgreSQL instance. Do not add a second database server or a separate built-in Cloud SQL connection on top of this proxy configuration.

  1. Still on the Create service page, click Add Container below the Flask card. Name the new container cloud-sql-proxy and enter this image:
gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.26.3
  1. In the proxy container's Settings tab, set its CPU to 1 and memory to 128 MiB. Leave Container command blank. Copy all four arguments below together, paste them into Container arguments, and press the Space key:
--address=0.0.0.0
--port=5454
--credentials-file=/secrets/cloud-sql-proxy-key
coms4111-db-ta:us-east1:server-4111-fall-2026

Check that the field now shows four separate arguments, not one combined entry. If the paste did not separate them, enter each argument individually. Do not include surrounding quotes.

  1. In the proxy's Settings tab, scroll down to Health checks and click Add health check. Select Startup check and probe type TCP. Set:
    • Port: 5454
    • Initial delay: 0 seconds
    • Period: 2 seconds
    • Failure threshold: 30
    • Timeout: 1 second
    Click Add to save the check.
  2. Scroll back to the tabs at the top of the cloud-sql-proxy card. Select Volumes, then click Mount volume → Secret. Enter:
    • Mount path: /secrets (the directory, not the full filename)
    • Secret: cloud-sql-proxy-key
    • Path 1: cloud-sql-proxy-key
    • Version 1: 1
    Click Save. Confirm that the resulting file is /secrets/cloud-sql-proxy-key and that the mount is attached only to the proxy container. Click Done for the proxy card.
  3. Scroll up to the Flask container card, open it, and select Settings. Under Container startup order, select cloud-sql-proxy as the container that must start first. Flask depends on the proxy, not the reverse. Click Done for the Flask card.
  4. After both containers are configured, scroll to the bottom of the Create service page and click Create. The initial build and deployment will start automatically.

The proxy must listen on 0.0.0.0 so its startup probe can reach it. Flask connects through 127.0.0.1:5454. This does not expose the database port as a public Cloud Run endpoint.

7. Grant public access

  1. Return to the Cloud Run Services list. Select the checkbox beside project1-web, rather than clicking the service name.
  2. Click Show Info Panel if needed, then open Permissions → Add principal.
  3. Enter allUsers in New principals.
  4. Select Cloud Run Invoker and click Save.
  5. Confirm Allow public access when prompted. This grant applies to this service, not your secrets or the entire project.

8. Check the website

Important: This example is public and has no login protection. Anyone with the URL can submit names. Use only invented data.

  1. Go to Cloud Build → History, open the build for your repository, and wait for it to succeed. Then return to Cloud Run → Services → project1-web and check that the service is ready before opening the website.

    If the build fails, read its logs in Cloud Build. For startup errors, open the Cloud Run service and check its Logs tab. An error mentioning port 8080 can be caused by a failed proxy probe; check the proxy arguments, secret mount, and startup check. For permission errors, contact staff; enabling an API does not grant IAM roles. Do not create another trigger.

  2. Copy the service's displayed HTTPS URL and open it in an incognito/private browser window.
  3. Append /another to the URL to check Flask routing. This route does not query the database.
  4. Open /db-check. Its JSON response should include select_1: 1 and current_schema_accessible: true. demo_table_exists is a Boolean indicating whether the example table already exists. This check does not create tables or schemas. If database access fails, check your actual Part 2 credentials and the version-1 secret references; contact staff about missing schema permissions rather than changing schemas or grants.
  5. Open the homepage at the service's root URL. The starter does not create tables on import or deployment. If the example table is absent and it is safe to create it in your existing current schema, click Initialize example table. This button appears while the example table is missing and disappears once it exists. The action creates test with columns id SERIAL PRIMARY KEY and name TEXT NOT NULL, and inserts three example names if the table is empty. It does not create a schema. Do not initialize if a pre-existing table named test contains meaningful data. If you are unsure what an existing table contains, ask staff first.
  6. Submit an invented name using the Add form. Refresh the page and confirm that the name was saved in PostgreSQL. The starter uses parameterized SQL for this insert; continue using parameters when adding your own queries.

Your website is now configured. Subsequent pushes or merges to main trigger automatic deployment. You can now begin replacing the demonstration with your Part 3 application.