kamal envify
Creates .env
by evaluating .env.erb
(or .env.staging.erb
-> .env.staging
when using -d staging) and push env files to the servers containing runtime secrets.
You can use this to manage secrets externally from your repository. .env
is used for both build and runtime secrets.
If you want to manage the .env
file yourself, you can instead push the runtime secrets with kamal env push
(see kamal env).
1Password as a secret store
If you’re using a centralized secret store, like 1Password, you can create .env.erb
as a template which looks up the secrets. Example of a .env.erb file:
<% if (session_token = `op signin --account my-one-password-account --raw`.strip) != "" %># Generated by kamal envify
GITHUB_TOKEN=<%= `gh config get -h github.com oauth_token`.strip %>
KAMAL_REGISTRY_PASSWORD=<%= `op read "op://Vault/Docker Hub/password" -n --session #{session_token}` %>
RAILS_MASTER_KEY=<%= `op read "op://Vault/My App/RAILS_MASTER_SECRET" -n --session #{session_token}` %>
MYSQL_ROOT_PASSWORD=<%= `op read "op://Vault/My App/MYSQL_ROOT_PASSWORD" -n --session #{session_token}` %>
<% else raise ArgumentError, "Session token missing" end %>
This template can safely be checked into Git. Then everyone deploying the app can run kamal envify
when they setup the app for the first time or passwords change to get the correct .env
file.
If you need separate env variables for different destinations, you can set them with .env.destination.erb
for the template, which will generate .env.staging
when run with kamal envify -d staging
.
Note: If you utilize biometrics with 1Password you can remove the session_token
related parts in the example and just call op read op://Vault/Docker Hub/password -n
.
Bitwarden as a secret store
If you are using open source secret store like bitwarden, you can create .env.erb
as a template which looks up the secrets.
You can store SOME_SECRET
in a secure note in bitwarden vault:
$ bw list items --search SOME_SECRET | jq
? Master password: [hidden]
[
{
"object": "item",
"id": "123123123-1232-4224-222f-234234234234",
"organizationId": null,
"folderId": null,
"type": 2,
"reprompt": 0,
"name": "SOME_SECRET",
"notes": "yyy",
"favorite": false,
"secureNote": {
"type": 0
},
"collectionIds": [],
"revisionDate": "2023-02-28T23:54:47.868Z",
"creationDate": "2022-11-07T03:16:05.828Z",
"deletedDate": null
}
]
… and extract the id
of SOME_SECRET
from the json
above and use in the erb
below.
Example .env.erb
file:
<% if (session_token=`bw unlock --raw`.strip) != "" %># Generated by kamal envify
SOME_SECRET=<%= `bw get notes 123123123-1232-4224-222f-234234234234 --session #{session_token}` %>
<% else raise ArgumentError, "session_token token missing" end %>
Then everyone deploying the app can run kamal envify
and kamal will generate .env