Using ENV with Docker

When building a docker image to run/deploy your application you have two options for loading secrets.

Prerequisites

Before getting started with ENV service, ensure you have:

  • Signed up for a Hyphen account and have access to an organization
  • Have the hx command line installed and authenticated

Sample Docker configuration

Here’s a basic configuration for your Docker environment.

FROM node:20-alpine3.16 as base

#########################################

FROM base as builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . ./
RUN npm run build

#########################################

FROM base as server
WORKDIR /app
COPY  --chown=node:node --from=builder /node_modules ./node_modules
COPY  --chown=node:node --from=builder /dist ./dist
ENV PORT 3000
EXPOSE 3000
USER node
CMD ["npm", "run", "start-prod"]
node_modules/
.hxkey

Option 1: Including .env files

Pros

  • Quickest way to get started
  • Mirrors how the application is developed

Cons

  • Requires creating a new docker image to rotate secrets

If you choose to include your .env files in the container, you will need to:

  1. Pull the secrets
  2. Copy them into your container
  3. Use an open-source library to read them into your application.

More information on .env files and the many open-source libraries can be found at https://www.dotenv.org/


> hx pull default && hx pull production

It’s best practice to only pull secrets for the specific environment you’re running in, which is why we didn’t just run hx pull.

docker build . -t my-org/my-app

Given that the DOCKERFILE copies the contents of the directory into the image, this will copy over the .env files, making them available to your application.

Option 2: Exporting Secrets

Pros

  • Secrets rotation only requires a container restart
  • Treats secrets like secrets and makes them available only at runtime.

Cons

  • Differs from how the application is developed
  • Requires more setup

Running the hx env run command will export all secrets as environment variables, which you can reference as needed. In this example, we pass them to the docker run command, though you could also mount them during the build. This is often how secrets are passed to cloud providers (e.g., Google Cloud Run).

docker build . -t my-org/my-app
# Single environment variable
hx env run production -- sh -c 'docker run -t my-org/my-app -e MY_SECRET=$MY_SECRET'

# Multiple environment variables
hx env run production -- sh -c 'docker run -t my-org/my-app \
    -e MY_SECRET=$MY_SECRET \
    -e API_KEY=$API_KEY \
    -e DB_PASSWORD=$DB_PASSWORD'