Skip to content

Rails and Kamal deploys without a .env file

Rails reads ENV, and .kamal/secrets can read the environment too. Wrap rails server and kamal deploy with npx getmyenv run.

Oct 10, 2026 · 4 min read

An encrypted Production context leads to one terminal command, then the .kamal/secrets file, the app container and the hosts.
getmyenv run fills the environment, .kamal/secrets reads it, and kamal deploy ships the app to your hosts.

1. Rails reads ENV

Code like ENV.fetch("DATABASE_URL") works unchanged. The dotenv gem does not overwrite variables that are already set, so values from run win over any .env files it loads.

bash
npx getmyenv import rm .env npx getmyenv run -- bin/rails server

Rails reads the credentials key from config/master.key or from RAILS_MASTER_KEY. Store RAILS_MASTER_KEY in a context, and the key file can stay off your servers.

run refuses names that change how Ruby starts, like RUBYOPT and RUBY_YJIT_ENABLE. Set those in your Dockerfile instead.

2. Point .kamal/secrets at the environment

Kamal 2 reads secrets from .kamal/secrets. Each line can take its value from the environment. The file holds no values, so it is safe to commit.

# .kamal/secrets
KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
RAILS_MASTER_KEY=$RAILS_MASTER_KEY
DATABASE_URL=$DATABASE_URL

List the same names in config/deploy.yml, under env: secret: and registry: password:, as usual.

3. Deploy

kamal deploy reads the secrets on the machine that runs it: your laptop or a CI job. For a Read-only Production context, that machine needs a server token in GETMYENV_TOKEN, an IP on the token's allowlist, and your approval on Requests the first time.

bash
export GETMYENV_TOKEN=... # server token for Production npx getmyenv run production -- kamal deploy

With destinations, kamal deploy -d staging reads .kamal/secrets.staging. Pick the matching context: npx getmyenv run staging -- kamal deploy -d staging.

4. What Kamal keeps on the hosts

Kamal stores secret values in an env file on each host for the containers. That copy is plaintext, and getmyenv does not manage it. After a value changes, deploy again. Only the owner sets Read-only values, in the dashboard.

Server tokens and approval: /docs/machine-access. Containers: /docs/docker.

Related docs: Machine access, Languages, Docker and Compose