Configuration settings
Every setting in your .env file, what it does and which ones the app won't start without. Plus the shop file that provision:site reads.
How settings work
The app reads its settings from environment variables, usually an .env file passed to docker run --env-file. They're checked when it starts. If a required one is missing or malformed, it stops and names it. An empty value counts as not set. Change a setting, then restart the container.
Write each value without quotes, as KEY=value. docker run --env-file keeps quote marks as part of the value, so KEY="value" fails validation.
NEXT_PUBLIC_IMAGE_PROXY_PATH is the exception: it's set when you build the image, not when you start it.
Required
The app won't start in production without these.
DATABASE_URLYour PostgreSQL database.
postgres://shop:…@db:5432/shopDIRECT_URLThe same as DATABASE_URL, unless you put a connection pooler in front of PostgreSQL. Needed to prepare the database.
postgres://shop:…@db:5432/shopAUTH_SECRETSigns sign-in sessions.
a long random stringAUTH_SECRETS_KEYEncrypts two-factor and webhook secrets. Keep a copy: without it, staff two-factor can't be read.
at least 32 charactersEMAIL_WORKER_SECRETThe password your scheduler sends to run the email queue.
at least 16 charactersCRON_SECRETThe password your scheduler sends to run every other job.
at least 16 charactersSES_SNS_WEBHOOK_SECRETChecks delivery and bounce reports from Amazon SES.
at least 16 charactersSES_SNS_ALLOWED_TOPIC_ARNThe SNS topic those reports come from.
arn:aws:sns:…Your shop and sign-in
SINGLE_STORE_SLUGTies this server to your shop. provision:site tells you the value.
your-shopAUTH_URLYour shop's address. Needed in production.
https://shop.example.comAUTH_TRUST_HOSTSet to true behind a reverse proxy.
trueAPP_ENVOnly production lets search engines index the shop. Use staging for a
test copy.
productionSearch
MEILISEARCH_HOSTYour Meilisearch server. Without it, search falls back to the database.
http://search:7700MEILISEARCH_API_KEYA key that can manage documents and settings. Leave the line out rather than empty.
a long random stringMEILISEARCH_INDEX_PREFIXPut in front of index names, if several shops share one Meilisearch.
shop_Storage and images
S3_ENDPOINTYour S3-compatible storage.
https://s3.example.comS3_BUCKETThe bucket for photos and uploads. Created on first start if it's missing.
shop-mediaS3_ACCESS_KEY, S3_SECRET_KEYKeys for that bucket.
from your storage providerMEDIA_CDN_BASE_URLThe public address photos are read from, ending in the bucket name. imgproxy
is reached at /img on the same host.
https://media.example.com/shop-mediaS3_REGIONThe bucket's region. Defaults to us-east-1.
us-east-1S3_FORCE_PATH_STYLEPath-style bucket addresses. On by default.
trueMEDIA_MAX_UPLOAD_BYTESLargest upload, in bytes. Defaults to 10 MB.
10485760NEXT_PUBLIC_IMAGE_PROXY_PATHSet when you build the image. Defaults to imgproxy at /img. Build with it
empty to serve photos as they are.
/img/insecureEMAIL_FROMWho emails come from, unless you set a sender in Settings › Email. Just the address: emails use your shop's name as the sender name.
[email protected]AWS_REGIONThe Amazon SES region. A new shop sends through SES.
eu-west-2AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYKeys that can send with SES. Not needed if the server has an IAM role.
from AWSEMAIL_SERVERAn SMTP server, used once you choose SMTP in Settings › Email.
smtp://user:…@mail.example.com:587MARKETING_EMAIL_SERVER, MARKETING_EMAIL_FROMA separate account for newsletters and other marketing emails. Without it, marketing emails are refused. The FROM is just an address, like EMAIL_FROM.
smtp://…Payments
STRIPE_SECRET_KEY, STRIPE_PUBLISHABLE_KEYYour Stripe keys.
sk_live_…, pk_live_…STRIPE_WEBHOOK_SECRETChecks the payment updates Stripe sends.
whsec_…APPLE_PAY_DOMAIN_ASSOCIATIONThe domain file Apple Pay needs.
from StripePAYMENTS_ALLOW_TEST_KEYSLeave at 0 in production. Set 1 only on a test copy, to try checkout with test keys.
0Optional extras
OPENAI_API_KEYFor the AI helper.
sk-…ANTHROPIC_API_KEYOptional, for AI-drafted descriptions.
sk-ant-…WORLDPRICE_API_KEYLive exchange rates, for multiple currencies.
from the providerSHIPPING_CREDENTIALS_KEYEncrypts carrier account details. Needed before you save a carrier account.
at least 32 charactersVEXON_UPDATE_MANIFEST_URLWhere Settings › Updates checks for new versions. Unset means no checks.
https://…APP_VERSIONThe version shown in the admin. Set it when you build from a release.
1.2.0SENTRY_DSNSends errors to Sentry, if you use it.
https://…Leave the SEED_* and DEFAULT_STORE_SLUG settings out in production. They're for development.
Your shop's file
npm run provision:site -- your-shop.json creates your shop from a JSON file. Unknown keys are refused, and every problem is listed at once.
nameYour shop's name.
Your ShopslugA short name in lowercase with hyphens.
your-shopdefaultLocaleThe shop's language and region.
en-GBbaseCurrencyPrices are stored in this currency.
GBPcountryCodeWhere the shop is based.
GBtimezoneThe shop's time zone.
Europe/LondontaxModeWhether prices include tax: INCLUSIVE or EXCLUSIVE.
INCLUSIVEdomainsYour shop's addresses, without https://. Exactly one is primary.
[{"host": "shop.example.com", "isPrimary": true}]settings.legalNameShown on invoices and legal pages.
Your Shop Ltdshipping.flatRateMinorA first flat shipping rate, in pence or cents.
499tax.domesticRateBpsYour tax rate in hundredths of a percent: 2000 is 20%. Write 0 if you don't charge tax.
2000featureFlagsSwitches to set when the shop is created. The only place to set the seven deployment-only ones.
{"checkout": false}Optional keys include ownerName, enabledLocales, enabledCurrencies, more settings (such as supportEmail, vatNumber, registeredAddress and lowStockThreshold, which defaults to 5), shipping (freeOverMinor, delivery days, cutoffTime), tax.appliesToShipping and theme. The example file in the code's config/sites folder shows them all.