-
Notifications
You must be signed in to change notification settings - Fork 15
Quick Start
VoodooLikesCoding edited this page Nov 17, 2025
·
8 revisions
Spin up Invio fast with Docker Compose — no need to clone the repo or build anything locally.
- Docker and Docker Compose
- A terminal on Linux/macOS/WSL
Create an empty folder (e.g., invio/) on your server or workstation and add the following files.
You can also use the tag :main if you always want the latest version, however using the :latest tag will ensure you are running a stable version.
docker-compose.yml
name: invio
services:
backend:
image: ghcr.io/kittendevv/invio-backend:latest
env_file:
- .env
environment:
ADMIN_USER: ${ADMIN_USER:-admin}
ADMIN_PASS: ${ADMIN_PASS:-supersecret}
JWT_SECRET: ${JWT_SECRET:-change-me-in-prod}
DATABASE_PATH: ${DATABASE_PATH:-/app/data/invio.db}
volumes:
- invio_data:/app/data
ports:
- "${BACKEND_PORT:-3000}:3000"
restart: unless-stopped
frontend:
image: ghcr.io/kittendevv/invio-frontend:latest
env_file:
- .env
environment:
PORT: ${FRONTEND_PORT_INTERNAL:-8000}
BACKEND_URL: ${BACKEND_URL:-http://backend:3000}
depends_on:
- backend
ports:
- "${FRONTEND_PORT:-8000}:${FRONTEND_PORT_INTERNAL:-8000}"
restart: unless-stopped
volumes:
invio_data:
driver: local.env (you can copy/paste and adjust)
# ======================
# Backend configuration
# ======================
ADMIN_USER=admin
ADMIN_PASS=supersecret
JWT_SECRET=change-me-in-production
SESSION_TTL_SECONDS=3600
# SQLite database path (inside the backend container)
DATABASE_PATH=/app/data/invio.db
# Optional Demo Mode (allows writes, auto-resets from DEMO_DB_PATH)
# DEMO_MODE=false
# DEMO_DB_PATH=/app/data/invio-demo.db
# DEMO_RESET_HOURS=0.5
# DEMO_RESET_ON_START=true
# ======================
# Networking / Ports
# ======================
BACKEND_PORT=3000
FRONTEND_PORT=8000
# Frontend internal container port (matches app PORT)
FRONTEND_PORT_INTERNAL=8000
# ======================
# Frontend -> Backend URL
# ======================
# Compose service name resolves on the network
BACKEND_URL=http://backend:3000
# ======================
# Security headers
# ======================
# Leave these defaults for production-strength headers. Override only for local debugging.
COOKIE_SECURE=true # if login fails try setting this to false
SECURE_HEADERS_DISABLED=false
FRONTEND_SECURE_HEADERS_DISABLED=false
ENABLE_HSTS=false # shared toggle for backend and frontend HSTS headers
# CONTENT_SECURITY_POLICY=...
# FRONTEND_CONTENT_SECURITY_POLICY=...Notes
- The images are published, so you don’t need the source code to deploy.
- Data persists in the named Docker volume
invio_data.
docker compose up -dOnce started:
- Frontend: http://localhost:8000
- Backend API: http://localhost:3000
- Login with the ADMIN_USER/ADMIN_PASS you set in
.env; the UI exchanges them for a short-lived JWT and stores it in a secure cookie.
- Go to Settings → Company and fill in your details
- Optionally set a logo URL or data URI in Settings → Branding
- Create a Customer
- Create an Invoice, add items, and save
- Publish the invoice to generate a share link
- Open the public link or download PDF/XML
docker compose pull
docker compose up -d- 401/403 at login: use the UI login form (or POST to
/api/v1/auth/loginwith JSON credentials) so you receive a JWT. Also confirm ADMIN_USER/ADMIN_PASS in.envand that clocks are roughly in sync. - PDFs look basic: the system falls back to a pure-PDF renderer if browser rendering fails. Ensure the images are current (
docker compose pull). - Database path: the compose file mounts a persistent volume at
/app/data; your DB lives there across restarts.