๐ Configuration
Startup options live in a .env file: ports, the data folder, logging, login sessions and a few
optional features. It sits at the root of the project, or next to docker-compose.yml with
Docker. The options you change from inside the app are Global Settings instead.
๐ง Create the .env File
In the project folder, copy the sample file, then edit the values you need:
With the pre-built Docker image, the Docker installation guide downloads
the same sample as .env.
- LibreFolio reads
.envwhen it starts: restart it after a change. With Docker Compose, rundocker compose up -d, becausedocker compose restartkeeps the old values. - Names are case-sensitive. In the main options and the risk settings below, a value of the wrong type or out of range stops the server at startup with an error.
โ๏ธ Main Options
| Variable | Default | What it does |
|---|---|---|
PORT |
6040 |
Port of the web server. With Docker Compose, the port opened on the host (the container always listens on 6040). |
TEST_PORT |
6041 |
Port of the test server (./dev.py server --test). |
LIBREFOLIO_DATA_DIR |
./backend/data/prod |
Folder of the database, uploads, broker reports and logs; a relative path starts from the project folder. Docker fixes it to /app/backend/data/prod-docker: to move the data on the host, change the left side of the ./LibreFolio-data volume in docker-compose.yml. |
LOG_LEVEL |
INFO |
How much the server logs: TRACE, DEBUG, INFO, WARNING, ERROR or CRITICAL. |
JWT_SECRET |
not set | Key that signs login sessions. Not set: a new key at every start, so everyone logs in again after a restart. See Keep users signed in. |
SESSION_COOKIE_SECURE |
auto |
When the login session cookie is sent over HTTPS only: auto (if the browser uses HTTPS), always or never. See HTTPS and reverse proxies. |
PREVIEW_CACHE_MAX_MB |
50 |
Memory, in MB, of the image-preview cache in each server process. |
Older .env files may still contain PORTFOLIO_BASE_CURRENCY: LibreFolio ignores it, and new
users start from the Default Currency in Global Settings.
๐ HTTPS and reverse proxies โ the session cookie
auto(default):Securewhen the browser reached LibreFolio over HTTPS. LibreFolio itself serves plain HTTP, so HTTPS comes from a reverse proxy in front of it, which says so with theX-Forwarded-Proto: httpsheader; only its first value counts. There is no list of trusted proxies to set up: the header can only turnSecureon, never off. Over plain HTTP, such ashttp://localhost:6040, a LAN IP or the Tailscale IP of Levels 1 and 2 in Exposing Securely, the cookie is notSecure, so signing in keeps working.always: alwaysSecure, for an install reached over HTTPS only. Over plain HTTP the browser drops the cookie, so the sign-in does not stick: the next page sends the user back to the login page.never: neverSecure. It is the way out when a proxy sendsX-Forwarded-Proto: httpsto a browser that actually uses plain HTTP, such as Nginx with a hard-codedproxy_set_header X-Forwarded-Proto https;in a plain-HTTPserverblock: inauto, that browser would be sent back to the login page after every sign-in. Fixing the proxy is better ($schemeinstead ofhttps);neveris the fallback.
Behind an HTTPS reverse proxy, auto relies on its X-Forwarded-Proto header:
- Tailscale Serve and Funnel (Levels 3 and 4 in Exposing Securely), Caddy and Traefik send it on their own: nothing to configure.
- Nginx does not: add
proxy_set_header X-Forwarded-Proto $scheme;to thelocationthat proxies LibreFolio. - Any other proxy: make it send the header or, if LibreFolio is reachable only through it,
set
SESSION_COOKIE_SECURE=always.
To check in your browser whether the session cookie is marked Secure, see
Checking Connection Security.
๐งฎ Risk engine workers โ advanced tuning
Risk simulations and portfolio optimizations run in separate worker processes, started on
first use. The defaults suit most installs: add a variable to .env only to change it.
| Variable | Default | What it does |
|---|---|---|
RISK_SIMULATION_WORKERS, RISK_OPTIMIZATION_WORKERS |
1 (1โ8) |
Worker processes per kind of job: more run more jobs at once. |
RISK_SIMULATION_QUEUE_CAPACITY, RISK_OPTIMIZATION_QUEUE_CAPACITY |
2 (0โ64) |
Jobs that can wait for a worker; beyond that, new requests are turned away. |
RISK_SIMULATION_TIMEOUT_SECONDS, RISK_OPTIMIZATION_TIMEOUT_SECONDS |
120 / 60 |
Time limit of one job, in seconds. |
RISK_SIMULATION_IDLE_TIMEOUT_SECONDS, RISK_OPTIMIZATION_IDLE_TIMEOUT_SECONDS |
600 |
Idle workers stop after this many seconds and restart with the next job; 0 keeps them running. |
๐ป Parameters Set by the Tools
./dev.py and Docker Compose set these for you: change them only if you know why.
| Variable | Default | What it does |
|---|---|---|
HOST |
0.0.0.0 |
Address ./dev.py server listens on; 127.0.0.1 accepts local connections only. Docker Compose always uses 0.0.0.0. |
LIBREFOLIO_LOG_LEVEL |
โ | Replaces LOG_LEVEL when set; ./dev.py server --debug sets it to DEBUG. |
LIBREFOLIO_TEST_MODE |
โ | 1, true or yes switches to the test data folder. Set by ./dev.py server --test and the test runners. |
LIBREFOLIO_TEST_DATA_DIR |
./backend/data/test |
Folder of the test data; it may not overlap the production one. |
๐ Optional: Web Search for New Assets
When you create an asset, also from the broker import wizard, and a provider's own search finds
nothing, LibreFolio can find the asset's page with a web search through the
ddgs library. It is on by default and never used for price
updates. All these variables are optional: uncomment a line of .env.example to change one.
| Variable | Default | What it does |
|---|---|---|
LIBREFOLIO_WEB_LINK_FINDER_ENABLED |
1 |
0 turns the web search off; the providers' own search keeps working. |
LIBREFOLIO_WEB_LINK_FINDER_ENGINE |
ddgs |
ddgs needs no setup. apikey is reserved for a paid search service and returns no results yet. |
LIBREFOLIO_WEB_LINK_FINDER_DDGS_REGION |
wt-wt |
Search region. wt-wt (worldwide) keeps national sites such as Borsa Italiana from being pushed down. Examples: it-it, us-en. |
LIBREFOLIO_WEB_LINK_FINDER_DDGS_BACKEND |
auto |
Engines that ddgs queries: auto rotates them for the widest coverage; a list such as google,bing,duckduckgo gives steadier results. |
LIBREFOLIO_WEB_LINK_FINDER_TIMEOUT |
6 |
Time limit of one search, in seconds. |
LIBREFOLIO_WEB_LINK_FINDER_MAX |
5 |
Most links returned by one search. |
LIBREFOLIO_WEB_LINK_FINDER_API_KEY |
empty | Key for the apikey engine. |
๐ Results change between attempts โ when a known asset is sometimes not found
With auto, each search may reach different engines, so the same query can do better or worse
from one try to the next. Retry once, or set
LIBREFOLIO_WEB_LINK_FINDER_DDGS_BACKEND=google,bing,duckduckgo.
๐ Which Value Wins
From the highest priority to the lowest:
- The
--host,--portand--data-diroptions of./dev.py server. - Variables set in the shell.
- The
.envfile. - The defaults listed on this page.
With Docker Compose, the environment: block of docker-compose.yml wins over .env: it fixes
HOST and LIBREFOLIO_DATA_DIR. See Advanced Docker.
๐ Where the Data Goes
- Production:
backend/data/prod/, orLIBREFOLIO_DATA_DIR. It holds the database (sqlite/app.db),custom-uploads/,broker_reports/andlogs/. - Test:
backend/data/test/, orLIBREFOLIO_TEST_DATA_DIR. Same layout, kept apart.
Filesystem Structure details each folder and how to back it up.
๐ Related
- โ๏ธ Global Settings โ Options changed from inside the app
- ๐ณ Advanced Docker โ Compose file, volumes, user and group IDs
- ๐งโ๐ป For developers: Settings System โ How these values are loaded