Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/soker90/finper/llms.txt

Use this file to discover all available pages before exploring further.

Finper ships with two Docker Compose files that start the API server in a container and persist the SQLite database in a named Docker volume. You do not need to install Node.js or pnpm on the host — the container bundles the entire runtime.

What Docker Compose provides

docker-compose.yml (development)

Builds the API image locally from packages/api/Dockerfile. Use this when you want to run the container from your local source code. Maps port 3008 on the host.

docker-compose.prod.yml (production)

Pulls the pre-built published image soker90/finper-api:daily from Docker Hub. No local build step required. Identical port and volume configuration.
In both configurations:
  • SQLite data is persisted in the finperdb named volume, mounted inside the container at /home/node/app/data.
  • The default database file path inside the container is /home/node/app/data/finper.db.
  • The API is exposed on port 3008.
Docker Compose only starts the API. The React frontend is not included in the Compose setup. You must serve the client separately — for example with make start-client during development, or via Nginx / Vercel in production.

Required environment variables

Create a .env file at the project root before running Compose. Both Compose files load it automatically via env_file: .env.
VariableRequiredDescription
DATABASE_FILENoPath to the SQLite file inside the container. Defaults to /home/node/app/data/finper.db.
JWT_SECRETSecret used to sign JWT tokens. Use a long random string in production.
SALT_ROUNDSbcrypt salt rounds for password hashing (e.g. 10).
LOKI_USERNoGrafana Loki logging user. Leave empty to disable remote logging.
LOKI_PASSWORDNoGrafana Loki logging password.
TICKET_BOT_URLNoBase URL of the external finper-bot service.
TICKET_BOT_API_KEYNoAPI key for finper-bot.

Starting with Docker

1

Copy and configure the environment file

cp .env.example .env
Open .env and set at minimum JWT_SECRET and SALT_ROUNDS. All other variables are optional.
2

Start in development mode (local build)

docker compose up --build
This builds the API image from your local Dockerfile and starts the container. The --build flag is only required the first time or after source changes.
3

Or start in production mode (pre-built image)

docker compose -f docker-compose.prod.yml up
This pulls soker90/finper-api:daily from Docker Hub and starts the container immediately — no local build required.
4

Verify the API is running

curl http://localhost:3008/api/monit/health
A 200 OK response confirms the API is up and the SQLite migrations have been applied.

Persistent data

The SQLite database lives in the finperdb Docker named volume. This volume is managed by Docker and survives container restarts and image upgrades. Backing up the database:
# Copy the SQLite file out of the volume to your local machine
docker run --rm \
  -v finperdb:/data \
  -v "$(pwd)":/backup \
  alpine \
  cp /data/finper.db /backup/finper-backup.db
Changing the database file path: Override DATABASE_FILE in .env to use a different filename inside the volume:
DATABASE_FILE=/home/node/app/data/myfinance.db
The volume mount point (/home/node/app/data) must remain the same so the volume mapping in Compose still applies.

Creating a user in Docker

After the container is running, seed the first user by passing credentials as environment variables:
docker compose exec \
  -e INIT_USERNAME=admin \
  -e INIT_PASSWORD=securepass \
  api pnpm seed-user
Alternatively, use make seed-user if you also have the project checked out locally and the .env is configured (this runs outside Docker but targets the same SQLite file if DATABASE_FILE points to the volume path).
Always use a strong, randomly generated value for JWT_SECRET in production. Tokens are signed with this secret; a weak or default value allows anyone who obtains the secret to forge authentication tokens.

Build docs developers (and LLMs) love