Finglish
Finglish

Reputation: 9956

How to access cloud run environment variables in Dockerfile

I have built a containerised python application which runs without issue locally using a .env file and and a docker-compose.yml file compiled with compose build.

I am then able to use variables within the Dockerfile like this.

ARG APP_USR
ENV APP_USR ${APP_USR}

ARG APP_PASS
ENV APP_PASS ${APP__PASS}

RUN pip install https://${APP_USR}:${APP_PASS}@github.org/*****/master.zip

I am deploying to cloud run via a synced bitbucket repository, and have defined under "REVISIONS" > "SECRETS AND VARIABLES",(as described here: https://cloud.google.com/run/docs/configuring/environment-variables) but I can not work out how to access these variables in the Dockerfile during build.

As I understand it, I need to create a cloudbuild.yaml file to define the variables, but I haven't been able to find a clear example of how to set this up using the Environment variables defined in cloud run.

Upvotes: 6

Views: 7316

Answers (2)

Seeven
Seeven

Reputation: 1079

My understanding is that it is not possible to directly use a Cloud Run revision's environment variables in the Dockerfile because the build is managed by Cloud Build, which doesn't know about Cloud Run revision before the deployment.

But I was able to use Secret Manager's secrets in the Dockerfile.

Sources:

Quick summary:

In your case, for APP_USR and APP_PASS:

  1. Grant the Secret Manager Secret Accessor (roles/secretmanager.secretAccessor) IAM role for the secret to the Cloud Build service account (see first source).

  2. Add an availableSecrets block at the end of the cloudbuild.yaml file (out of the steps block):

availableSecrets:
  secretManager:
  - versionName: <APP_USR_SECRET_RESOURCE_ID_WITH_VERSION>
    env: 'APP_USR'
  - versionName: <APP_PASS_SECRET_RESOURCE_ID_WITH_VERSION>
    env: 'APP_PASS'
  1. Pass the secrets to your build step (depends on how you summon docker build, Google's documentation uses 'bash', I use Docker directly):
  - id: Build
    name: gcr.io/cloud-builders/docker
    args:
      - build
      - '-f=Dockerfile'
      - '.'

      # Add these two `--build-arg` params:

      - '--build-arg'
      - 'APP_USR=$$APP_USR'

      - '--build-arg'
      - 'APP_PASS=$$APP_PASS'

    secretEnv: ['APP_USR', 'APP_PASS'] # <=== add this line
  1. Use these secrets as standard environment variables in your Dockerfile:
ARG APP_USR
ENV APP_USR=$APP_USR

ARG APP_PASS
ENV APP_PASS=$APP_PASS

RUN pip install https://$APP_USR:[email protected]/*****/master.zip

Upvotes: 3

guillaume blaquiere
guillaume blaquiere

Reputation: 75715

You have several way to achieve that.

You can, indeed, create your container with your .env in it. But it's not a good practice because your .env can contain secret (API Key, database password,...) and because your container is tight to an environment

The other solution is to deploy your container on Cloud Run (not a docker compose, it doesn't work on Cloud Run), and add the environment variable with the revision. use, for example, --set-env-vars=KEY1=Value1 format to achieve that.

If you have secrets, you can store them in secret manager and load it as env var at runtime, or as volume

The last solution, if you can specify where your container will get the .env file in your file tree (I'm not expert in Python to help you on that), you can use this trick that I described in this article. It's perfectly designed for configuration file, it's stored natively in Secret manager and therefore protect your secret automatically.

Upvotes: 4

Related Questions