Marreta reads its runtime configuration (the server port, provider hosts,
credentials, feature flags) from MARRETA_* environment variables. Locally you keep
them in a marreta.env file. In production you set real environment variables. This
page explains how the two relate and how to keep secrets out of git.
Prerequisites
- A scaffolded project (
marreta init hello). - The Quickstart finished.
marreta.env and marreta.env.example
marreta init writes two files:
marreta.envholds the real values your machine uses, including secrets. It is gitignored, so it never leaves your machine.marreta.env.exampleis a committed template. It lists the same keys with placeholder values, so a teammate knows what to set without ever seeing a secret.
The difference is only the secret values. For a database, marreta.env has the real
password:
MARRETA_DB_PROVIDER=postgres
MARRETA_DB_HOST=127.0.0.1
MARRETA_DB_PORT=5432
MARRETA_DB_NAME=marreta
MARRETA_DB_USER=marreta
MARRETA_DB_PASSWORD=marretawhile marreta.env.example has a placeholder:
MARRETA_DB_PASSWORD=change-meA new contributor copies the example to marreta.env and fills in the real values.
How a value is resolved
When more than one source sets the same key, Marreta uses this order, highest to lowest:
- A CLI flag, such as
--port. - A process environment variable.
- The
marreta.envfile. - The built-in default.
A process environment variable always wins over marreta.env. For example, with
MARRETA_PORT=8080 in marreta.env:
MARRETA_PORT=9091 marreta serve
# the server starts on port 9091, not 8080This is exactly how production works: you do not ship a marreta.env file, you set
the real environment variables in your platform, and they take effect because they
outrank the file.
Read a value in your code
Configuration is also available to your code through the env namespace. env.NAME
returns the value of an environment variable, read from marreta.env with process
variables overriding it, as a string:
route GET "/config/region"
region = env.APP_REGION or "us-east-1"
reply 200, { region: region }A variable that is not set reads as null, so or supplies a default and require can
demand one before the route runs:
require env.STRIPE_KEY else fail 500, "STRIPE_KEY is not configured"Values always come back as strings. Auth providers in Secure your API
read their secrets with the same env.NAME form, which is how secrets stay out of the
source and in your environment.
Local services versus external providers
In a fresh project, marreta.env points at the local Docker providers on
127.0.0.1 (see Persist data with local services). To use
a managed or remote provider instead, set the same keys to the real endpoint:
MARRETA_DB_HOST=db.internal.example.com
MARRETA_DB_PORT=5432
MARRETA_DB_NAME=catalog_prod
MARRETA_DB_USER=catalog
MARRETA_DB_PASSWORD=...Locally you can put these in marreta.env. In production, set them as real
environment variables through your platform’s secret management, so no credentials
are written to a file at all.
Keep secrets out of git
- Never commit
marreta.env. The scaffold already gitignores it. - Commit
marreta.env.examplewith placeholders, so the required keys are documented without exposing values. - In production, prefer real environment variables over a file, so secrets live in your platform’s secret store.
Use it in CI and CD
A pipeline has no marreta.env (it is gitignored and never checked out with
secrets). Set the MARRETA_* values as environment variables in the pipeline
instead, reading secrets from the platform’s secret store. Because process
environment variables outrank the file, the project runs unchanged.
A deploy or test step looks like this:
export MARRETA_DB_HOST=db.internal.example.com
export MARRETA_DB_USER=catalog
export MARRETA_DB_PASSWORD="$DB_PASSWORD" # injected from the CI secret store
marreta migrate apply
marreta testReference secrets as pipeline variables (for example $DB_PASSWORD above), never
as literals in the workflow file, and never echo them to the log.
Try it
# marreta.env sets MARRETA_PORT=8080, but the process env var wins:
MARRETA_PORT=9091 marreta serveThe startup line reports http://0.0.0.0:9091.
Result checkpoint
You should now understand that marreta.env holds local values (and is gitignored),
marreta.env.example is the committed template, and real environment variables
override the file, which is how you configure a deployed app.
Common pitfalls
- A committed secret. If
marreta.envis tracked, your credentials are in git history. Keep it ignored and usemarreta.env.examplefor sharing keys. - A change to
marreta.envdoes not take effect. A process environment variable with the same name overrides the file. Unset it, or change it instead. - A provider is configured but unreachable. Run
marreta doctorto see whether the host and port actually resolve.
Next steps
- Providers: what the
MARRETA_<concern>_PROVIDERvariables select. - Configuration reference: every
MARRETA_*variable and what it controls. - Persist data with local services: the provider variables in context.