Configuration
Everything is configured in two places, and it is worth knowing which is which:
- The backend
.env— what the system needs in order to start: database, secrets, keys for outside services. You edit it in a text editor and it requires a restart. - The panel — what changes day to day: store name, tax details, payment methods, AI provider. Requires no restart at all.
The rule is simple: if it is a secret, it goes in the .env. Everything
else goes in the panel. API keys are never stored in the database and never
travel to the browser.
The full list of variables, generated from the code, is in reference/environment-variables.md. What follows is what you need to understand in order to decide.
The minimum to start
Section titled “The minimum to start”Only one variable is required:
DATABASE_URL=postgres://user:password@localhost:5432/my_storeWith nothing else, the system starts and works. Everything else turns things on.
Redis: no longer needed
Section titled “Redis: no longer needed”The notification queue, workflows and scheduled tasks live in Postgres and
survive a restart just the same. If REDIS_URL is set, the setup wizard shows
it as optional; if not, it says nothing. It used to be one more piece to set up
and a false warning on the first screen of the wizard.
Session secrets
Section titled “Session secrets”JWT_SECRET=COOKIE_SECRET=With the example values in place, anyone who knows them can sign their own tokens and walk into your panel. Change them before you go live.
Under Docker you can leave them empty: the container generates a set on first run. Set them by hand only if you are going to run several backend replicas — each one would generate its own, and a session would stop being valid the moment a request landed on a different replica.
CORS: who is allowed to talk to the store
Section titled “CORS: who is allowed to talk to the store”STORE_CORS=https://mystore.com # the storefrontADMIN_CORS=https://panel.mystore.com # the panelAUTH_CORS=https://panel.mystore.comThese are comma-separated lists. If an address is missing, the browser blocks
the request and the error does not tell you this is why: it says “CORS”, and
you lose half an afternoon looking in the wrong place. When you stand up a new
theme on another port, remember to add it to STORE_CORS.
What each thing turns on
Section titled “What each thing turns on”Everything below is optional. Without the variable, the feature simply is not there — it does not fail, it does not warn, it does not get in the way.
SMTP_HOST=SMTP_PORT=587SMTP_USER=SMTP_PASS=SMTP_FROM=CONTACT_TO= # where the contact form landsWithout this there are no order confirmations and no password resets.
Artificial intelligence
Section titled “Artificial intelligence”ANTHROPIC_API_KEY=OPENAI_API_KEY=GOOGLE_API_KEY=MISTRAL_API_KEY=OPENROUTER_API_KEY=VOYAGE_API_KEY= # for meaning-based search onlyCOHERE_API_KEY=OLLAMA_URL=http://localhost:11434 # on your own machine, at no costSet the key for the provider you want to use, not all of them. The provider itself is chosen afterwards in the panel, under AI.
The key is yours and so is the bill: the system ships with the brakes on (a daily cap and a per-visitor limit), but you are the one paying for the calls. How it works and what it costs: AI.
With no key at all the store works exactly the same — keyword search, product pages, alerts. What needs a key is what writes or reasons.
Crypto payments
Section titled “Crypto payments”BTCPAY_URL=BTCPAY_API_KEY=BTCPAY_STORE_ID=Without BTCPAY_URL the payment provider does not even register itself: it does
not appear at checkout.
Shipping with Sendcloud
Section titled “Shipping with Sendcloud”SENDCLOUD_PUBLIC_KEY=SENDCLOUD_SECRET_KEY=SENDCLOUD_WEBHOOK_SECRET= # signature on their notificationsSENDCLOUD_FROM_... # origin address, see the .env.exampleSENDCLOUD_FALLBACK_EUR=4.95Without SENDCLOUD_PUBLIC_KEY you are left with the manual provider: flat rates
that you configure yourself in the panel.
Themes and extensions
Section titled “Themes and extensions”THEMES_DIR= # where the themes live. Default: themes/PLUGINS_DIR= # where the plugins live. Default: plugins/PLUGINS_DISABLED=one,another # turn one off without uninstalling itLICENSE_PUBLIC_KEY= # verify licences for paid pluginsLICENSE_PUBLIC_KEY is public on purpose: it can only verify signatures,
never create them.
Links back to the store
Section titled “Links back to the store”STOREFRONT_URL=https://mystore.comSTOREFRONT_RUTA_PRODUCTO=producto # /producto/<handle>These produce the links the AI and your emails send to customers. If your theme
uses a different path — /p/, /item/ — change it here or the links will 404.
The storefront is configured separately
Section titled “The storefront is configured separately”The theme does not read the backend .env: it is a different application, very
often on a different server. It needs two values of its own:
COMMERCE_URL=https://mystore.com # the store's addressCOMMERCE_KEY=pk_... # publishable key for the sales channelEach stack exposes them its own way: Vite wants VITE_, Next wants
NEXT_PUBLIC_ for anything that reaches the browser. Check the theme’s
.env.example.
The publishable key decides which products that storefront can see. It is what lets two different stores live on the same backend without their catalogues mixing, so it is worth giving each theme its own.
You create one with npm run preparar on the backend, or from Settings in the
panel.
What is configured in the panel
Section titled “What is configured in the panel”No files, no restart:
| Where | What |
|---|---|
| Settings | Store name and branding, tax details for invoices, payment methods |
| AI | Provider and model, daily spending cap, what may be written unattended |
| Themes | Which theme is active and its demo content |
| Extensions | Installed plugins and their settings |
| Users | Who gets into the panel |
Tax details live in the store, not in the code: changing a tax ID should not require rebuilding anything.