# Set an environment variable

Environment variables can be stored and configured for use in CircleCI jobs in several ways to provide variety in scope and authorization level.

**Using Docker?** Authenticating Docker pulls from image registries is recommended when using the Docker execution environment. Authenticated pulls allow access to private Docker images, and may also grant higher rate limits, depending on your registry provider. For further information see [Using Docker authenticated pulls](https://circleci.com/docs/guides/execution-managed/private-images/).

## Set an environment variable in a shell command

While CircleCI does not support interpolation when setting environment variables, it is possible to set variables for the current shell by [using `BASH_ENV`](https://circleci.com/docs/guides/security/env-vars/#parameters-and-bash-environment). This approach is useful for both modifying your `PATH` and setting environment variables that reference other variables.

To access environment variables in the same step where they are set, you **must** run `source "$BASH_ENV"` after writing to `$BASH_ENV`. This is because writing to `$BASH_ENV` only adds commands to a file, it does not execute them. The `source` command reads and executes the file’s contents in the current shell, making the variables available immediately. Without sourcing, the variables will only be available in subsequent steps when CircleCI automatically sources `$BASH_ENV` at the start of each new step.

`````````
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/base:2023.06
    steps:
      - run:
          name: Update PATH and Define Environment Variable at Runtime
          command: |
            echo 'export PATH=/path/to/foo/bin:"$PATH"' >> "$BASH_ENV"
            echo "export VERY_IMPORTANT=VALUE_CONTENT" >> "$BASH_ENV"
            # Source BASH_ENV to make variables available in this step
            source "$BASH_ENV"
`````````

Depending on your shell, you may have to append the new variable to a shell startup file like `~/.tcshrc` or `~/.zshrc`.

For more information, refer to your shell’s documentation on setting environment variables.

## Set an environment variable in a step

To set an environment variable in a step, use the [`environment` key](https://circleci.com/docs/reference/configuration-reference/#run).

`````````
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/base:2023.06
    steps:
      - checkout
      - run:
          name: Run migrations
          command: sql/docker-entrypoint.sh sql
          # Environment variable for a single command shell
          environment:
            DATABASE_URL: postgresql://postgres@localhost:5432/test_db
`````````

Since every `run` step is a new shell, environment variables are not shared across steps. If you need an environment variable to be accessible in more than one step, export the value [using `BASH_ENV`](https://circleci.com/docs/guides/security/env-vars/#parameters-and-bash-environment).

## Set an environment variable in a job

To set an environment variable in a job, use the [`environment` key](https://circleci.com/docs/reference/configuration-reference/#job-name).

`````````
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/base:2022.04-20.04
    environment:
      FOO: bar
`````````

Integers longer than 6 digits will be converted to an exponential number. To avoid this, store them as a string instead (for example, "1234567").

## Set an environment variable in a context

1.  In the CircleCI web app, select **Org** from the sidebar.
    
2.  Select the context you want to associate your environment variable with, or create a new one by clicking the **Create Context** button.
    
3.  Select **Add Environment Variable** and enter a name and value.
    
4.  Use your new environment variable in your `.circleci/config.yml` once the context is added under the workflows key, as follows:
    
    `````````
    version: 2.1
    
    workflows:
      test-env-vars:
        jobs:
          - build:
              context: my_context_name # has an env var called MY_ENV_VAR
    
    jobs:
      build:
        docker:
          - image: cimg/base:2023.06
        steps:
          - checkout
          - run:
              name: "echo an env var that is part of our context"
              command: |
                echo $MY_ENV_VAR
    `````````
    

Creating a context allows you to share environment variables across multiple projects, and control who has access. For more information about controlling access to environment variables with contexts, refer to the [Restricting a context](https://circleci.com/docs/guides/security/contexts/#restrict-a-context) documentation.

## Set an environment variable in a project

1.  On the CircleCI web app, go to your project’s settings. You can do this two ways: Navigate to **Projects** on the side navigation, and then click the ellipsis button in the project’s row, or select the **Project Settings** button on the project’s individual **Pipelines** page.
    
2.  Select **Environment Variables** in the side navigation.
    
3.  Select **Add Variable** to enter a name and value of the new environment variable.
    
4.  Use your new environment variables in your `.circleci/config.yml` as follows:
    
    `````````
    version: 2.1
    
    workflows:
      test-env-vars:
        jobs:
          - build
    
    jobs:
      build:
        docker:
          - image: cimg/base:2023.06
        steps:
          - checkout
          - run:
              name: "echo an env var that is part of our project"
              command: |
                echo $MY_ENV_VAR # this env var must be set within the project
    `````````
    

Once created, environment variables are hidden and uneditable in the application. Changing an environment variable is only possible by deleting and recreating it.

## Set an environment variable in a container

Environment variables can also be set for a Docker container. To do this, use the [`environment` key](https://circleci.com/docs/reference/configuration-reference/#docker).

Environment variables set in this way are not available to _steps_ run within the container, they are only available to the entrypoint/command run _by_ the container. By default, CircleCI will ignore the entrypoint for a job’s primary container. For the primary container’s environment variables to be useful, you will need to preserve the entrypoint. For more information, see the [Adding an entrypoint](https://circleci.com/docs/guides/execution-managed/custom-images/#adding-an-entrypoint) section of the Custom images guide.

`````````
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/base:2023.06
        # environment variables available for entrypoint/command run by docker container
        environment:
          MY_ENV_VAR_1: my-value-1
          MY_ENV_VAR_2: my-value-2
`````````

The following example shows separate environment variable settings for the primary container image (listed first) and the secondary or service container image.

While hard-coded environment variable values will be passed on correctly to the secondary or service container, contexts or project specific environment variables will not be interpolated for non-primary containers.

`````````
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/base:2023.06
        environment:
          MY_ENV_VAR_1: my-value-1
          MY_ENV_VAR_2: my-value-2
      - image: cimg/postgres:15.3.0
        environment:
          MY_ENV_VAR_3: my-value-3
          MY_ENV_VAR_4: my-value-4
`````````

### Encoding multi-line environment variables

If you are having difficulty adding a multiline environment variable, use `base64` to encode it.

`````````
$ echo "foobar" | base64 --wrap=0
Zm9vYmFyCg==
`````````

Store the resulting value in a CircleCI environment variable.

`````````
$ echo $MYVAR
Zm9vYmFyCg==
`````````

Decode the variable in any commands that use the variable.

`````````
$ echo $MYVAR | base64 --decode | docker login -u my_docker_user --password-stdin
Login Succeeded
`````````

Not all command-line programs take credentials in the same way that `docker` does.