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/
.hxkeyOption 1: Using hyphen-entrypoint.sh
Pros
- Secrets rotation only requires a container restart
- Treats secrets like secrets and makes them available only at runtime.
- One-time setup works consistently across environments and CI/CD and doesn't require changes when new secrets are added
Cons
- Differs from how the application is developed
When you run hx init, a hyphen-entrypoint.sh script is automatically created in your project directory. This script is designed specifically for Docker deployments and handles:
- Downloading the Hyphen CLI if not already present
- Authenticating with your Hyphen API key
- Pulling environment variables for the specified environment
- Running your application with those variables loaded
Note: If the
hyphen-entrypoint.shis missing (e.g. because you raninitwith an older version of hx) or needs to be updated, you can re-create it withhx entrypoint(and use--forceif needed to overwrite it).
Required Environment Variables
The entrypoint script requires five environment variables to be set in your container:
HYPHEN_API_KEY: Your Hyphen API key for authenticationHYPHEN_APP_ENVIRONMENT: The environment to pull variables from (e.g., "development", "production", "default")HYPHEN_APP_ID: Your application ID (e.g., "app_68f65adbb2aca958a8ff6ea9")HYPHEN_PROJECT_ID: Your project ID (e.g., "proj_68ee9033968a1e3b98be5501")HYPHEN_ORGANIZATION_ID: Your organization ID (e.g., "org_681bd71a0cd803794aebd33a")
Sample Dockerfile with Entrypoint
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 /app/package.json ./package.json
COPY --chown=node:node --from=builder /app/dist ./dist
COPY --chown=node:node --from=builder /app/hyphen-entrypoint.sh ./hyphen-entrypoint.sh
RUN chown -R node:node /app
RUN chmod +x ./hyphen-entrypoint.sh
ENV PORT=3000
EXPOSE 3000
USER node
ENTRYPOINT ["./hyphen-entrypoint.sh"]
CMD ["npm", "run", "start-prod"]Build and Run
docker build . -t my-org/my-appdocker run -t my-org/my-app \
-e HYPHEN_API_KEY=$HYPHEN_API_KEY \
-e HYPHEN_APP_ENVIRONMENT=production \
-e HYPHEN_APP_ID=app_YOUR_APP_ID \
-e HYPHEN_PROJECT_ID=proj_YOUR_PROJECT_ID \
-e HYPHEN_ORGANIZATION_ID=org_YOUR_ORG_IDYou can find these IDs in your .hx file after running hx init, or in the Hyphen dashboard.
The entrypoint script will automatically handle downloading the CLI, authenticating, pulling secrets, and starting your application with the correct environment variables loaded.
Option 2: 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:
- Pull the secrets
- Copy them into your container
- 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 productionIt'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-appGiven 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 3: 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'Updated 7 days ago
