Docker services can access environment variables and secret files like other kinds of services at run time. However, because of the way that Docker builds work, you won't have access to environment variables and secret files as usual at build time.

## Security

Before going into how to use your environment variables and secret files for Docker builds, you should know that using secrets with Docker can result in your image containing sensitive information. Although we store your images securely, Docker registries should be treated like code repositories: it's best practice to not store secrets in them. You should avoid using secrets in your Docker builds to eliminate the chance of accidentally storing sensitive material.

That being said, some build processes _require_ credentials to access private resources, for example. For these, it's best to use [secret files](/content/docs/docker-secrets#secret-files-in-docker-builds/index.html).

## Secret Files in Docker Builds

The best way to use secrets in your Docker build is with secret files. Unlike build args, secret mounts aren't persisted in your built image.

Render builds Docker images with [BuildKit](https://docs.docker.com/build/buildkit/). Each of your service's secret files, including secret files from linked environment groups, is available to the build as a [build secret](https://docs.docker.com/build/building/secrets/).

To use a secret file in a `RUN` instruction, add a secret mount to that instruction:

```dockerfile
RUN --mount=type=secret,id=SECRET_ID,dst=/etc/secrets/FILENAME,required=true your-command
```

Replace `SECRET_ID` with the [ID of the secret file](/content/docs/docker-secrets#secret-file-ids/index.html). Replace `FILENAME` with the name of the secret file.

For example, if you have a secret file named `.env`, this instruction prints the content of `.env` in your build:

```dockerfile
RUN --mount=type=secret,id=_env,dst=/etc/secrets/.env,required=true cat /etc/secrets/.env
```

- The secret file is available only while its instruction runs. Add the secret mount to each instruction that uses the file.  
- To use more than one secret file in an instruction, add one `--mount=type=secret,...` for each file.  
- You can set `dst` to any path, such as the path where a tool reads its configuration. If you omit `dst`, the file is at `/run/secrets/SECRET_ID`.  
- With `required=true`, your build fails if no secret file has the ID. Without it, the instruction runs without the file.  
- If the instruction runs as a non-root `USER`, add `uid=` with the ID of that user (for example, `uid=1000`). By default, only `root` can read a secret mount.

You don't need a `# syntax` directive to use secret mounts. If your Dockerfile starts with `# syntax = docker/dockerfile:1.2`, remove that line or change it to `# syntax=docker/dockerfile:1`. Version 1.2 of the Dockerfile frontend is old and doesn't support newer syntax, such as `COPY --link` and `RUN <<EOF`.

Read more about build secrets in the [Docker docs](https://docs.docker.com/build/building/secrets/).

### Secret File IDs

The ID of a secret file is its filename, with an underscore (`_`) in place of each character that isn't a letter, a digit, `_`, or `-`:

| Filename              | Secret ID          |
|----------------------|--------------------|
| `.env`               | `_env`             |
| `credentials.json`   | `credentials_json`  |
| `gcp-key.json`       | `gcp-key_json`     |

### Exclude Secret Files from Your Image

Render also copies your secret files into the root of your Docker build context. If your Dockerfile copies the full build context (for example, with `COPY . .`), your image contains your secret files.

To prevent this, add the names of your secret files to the `.dockerignore` file in the root of your build context:

```.dockerignore
.env
credentials.json
```

Secret mounts continue to work for files in `.dockerignore`.

### Building Images with Secrets Locally

To build your image locally, add a `--secret` flag to `docker build` for each secret file:

```bash
docker build --secret id=SECRET_ID,src=LOCAL_FILENAME .
```

Use the same `SECRET_ID` as in your Dockerfile. Replace `LOCAL_FILENAME` with the path to a local copy of the secret file.

Docker Engine 23.0 and later use BuildKit by default. For earlier versions, set `DOCKER_BUILDKIT=1`.

## Accessing Secret Files at Runtime

If you add [secret files](/content/docs/configure-environment-variables#secret-files/index.html) to a Docker-based service, those services are available at runtime at `/etc/secrets/<filename>`.

When accessing secret files in Docker services, you might encounter permission errors like the following:

```
cp: cannot open '/etc/secrets/myfile' for reading: Permission denied
```

To resolve this, make sure your application user is in group `1000`. You can set this in your Dockerfile:

```dockerfile
# Alpine-based images do not have usermod by default and must install it:
# RUN apk add shadow

# Add your application user to group 1000
RUN usermod -a -G 1000 your-app-user
```

## Environment Variables in Docker Builds

Docker doesn't provide a way to pass in environment variables to a build. It does, however, provide build args. Render injects your service's environment variables as build args with the same keys and values. You can make use of build args in your Dockerfile using the [`ARG` instruction](https://docs.docker.com/engine/reference/builder/#arg).

We recommend against using `ARG` instructions for secrets. Consider using [secret files](/content/docs/docker-secrets#secret-files-in-docker-builds/index.html) instead for build-time secrets.
