Skip to content

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.

Prereqs

  • Docker and Docker Compose
  • A terminal on Linux/macOS/WSL

1) Create a folder and add these two files

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.

2) Start Invio

docker compose up -d

Once started:

3) First steps in the app

  • 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

4) Update to the latest version

docker compose pull
docker compose up -d

Troubleshooting

  • 401/403 at login: use the UI login form (or POST to /api/v1/auth/login with JSON credentials) so you receive a JWT. Also confirm ADMIN_USER/ADMIN_PASS in .env and 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.

Clone this wiki locally