Skip to Content
MySagra 1.4.0 is released πŸŽ‰

Quick Start

Deploy MySagra on your server in three steps β€” no prior configuration needed.

0

Prerequisites

Make sure the following tools are installed on the machine that will run MySagra.

🐳

Docker (with Compose v2)

MySagra runs entirely inside Docker containers. Install Docker Desktop (Windows / macOS) or Docker Engine + Docker Compose (Linux) from the official site:

docs.docker.com/get-docker β†’
1

Configure your stack

Select the services you need. Copy each generated file (docker-compose.yml, .env, and nginx.conf if using Nginx) into a new folder on your server.

Choosing the right SERVER_IP

  • Private / local deployment β€” use your server's LAN IP address (e.g. 192.168.1.100). The self-signed certificate generated by mkcert in Step 2 will be valid exactly for that address.
  • Public / internet-exposed deployment β€” point a real domain name to your server and use a certificate issued by a trusted CA such as Cloudflare, Let's Encrypt, or similar. This way browsers will trust the certificate automatically β€” no need to install a root CA on every device.

Before copying the generated files, open the .env tab and set SERVER_IP to your server's actual IP address or hostname. This value is used both by the services at runtime and by mkcert in Step 2 to generate a certificate valid for that address.

Core (required)
Always included in the stack
Services
Select the services to include
Utilities
Select the services to include
* Secrets (JWT_SECRET, PEPPER, AUTH_SECRET, DB_USER_PASSWORD, ROOT_PASSWORD) are randomly generated client-side on each page load. Click "Regenerate" to get new values.
3 services selected β€” viewing docker-compose.yml
name: mysagra

services:
  mysagra-backend:
    image: ghcr.io/mysagra/mysagra-backend:latest
    container_name: mysagra-api
    env_file: .env
    ports:
      - "4300:4300"
    environment:
      - NODE_ENV=${NODE_ENV:-production}
      - DATABASE_URL=mysql://${DB_USER:-mysagra}:${DB_USER_PASSWORD:-mysagra}@db:3306/${MYSQL_DATABASE:-mysagra}
      - JWT_SECRET=${JWT_SECRET}
      - PEPPER=${PEPPER}
      - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}
      - MIGRATE_ON_START=true
      - TRUST_PROXY_LEVEL=${TRUST_PROXY_LEVEL:-2}
    depends_on:
      db:
        condition: service_healthy
    restart: always
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4300/health"]
      interval: 30s
      timeout: 3s
      retries: 3
    volumes:
      - api_logs:/app/logs
      - api_public:/app/public
    tmpfs:
      - /tmp
      - /run
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - mysagra-network

  db:
    image: mysql:latest
    container_name: db
    env_file: .env
    environment:
      MYSQL_ROOT_PASSWORD: ${ROOT_PASSWORD:-rootpassword}
      MYSQL_DATABASE: "${MYSQL_DATABASE:-mysagra}"
      MYSQL_USER: "${DB_USER:-mysagra}"
      MYSQL_PASSWORD: ${DB_USER_PASSWORD:-mysagra}
    volumes:
      - mysql_data:/var/lib/mysql:delegated
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    ports:
      - "3306:3306"
    restart: always
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
      - DAC_OVERRIDE
      - NET_BIND_SERVICE
    security_opt:
      - seccomp=unconfined
    user: mysql
    networks:
      - mysagra-network

  nginx:
    image: nginx:alpine
    container_name: mysagra-nginx
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    networks:
      - mysagra-network
    depends_on:
      - mysagra-backend

volumes:
  api_logs:
    driver: local
  api_public:
    driver: local
  mysql_data:
    driver: local
  nginx_certs:
    driver: local

networks:
  mysagra-network:
    driver: bridge

Expected folder structure after this step:

your-server:~/mysagra/
mysagra/ β”œβ”€β”€ docker-compose.yml β”œβ”€β”€ .env β”œβ”€β”€ nginx.conf ← only if Nginx is selected β”œβ”€β”€ certs/ ← created in Step 2 β”‚ β”œβ”€β”€ cert.pem β”‚ └── key.pem └── rootCA.pem ← created in Step 2
2

Generate TLS certificates

Use mkcert to create a locally-trusted certificate for your server IP or domain and copy the root CA so the containers trust it.

1 β€” Install mkcert

Linux (apt)

bash
sudo apt install mkcert

Linux / macOS (Homebrew)

bash
brew install mkcert

Windows (winget)

PowerShell
winget install FiloSottile.mkcert

Windows (Scoop)

PowerShell
scoop install mkcert

2 β€” Install the local CA

This makes your OS and browsers trust the certificate. Run once per machine.

bash / PowerShell
mkcert -install

3 β€” Create the certs folder and generate the certificate

Run from inside your mysagra/ folder. Replace YOUR_SERVER_IP with your actual IP or domain.

Linux / macOS

bash
mkdir -p certs mkcert -key-file certs/key.pem -cert-file certs/cert.pem localhost 127.0.0.1 YOUR_SERVER_IP

Windows (PowerShell)

PowerShell
New-Item -ItemType Directory -Force -Path certs mkcert -key-file certs\key.pem -cert-file certs\cert.pem localhost 127.0.0.1 YOUR_SERVER_IP

4 β€” Copy rootCA.pem into the project folder

The containers need this file to trust the self-signed certificate internally.

Linux / macOS

bash
cp "$(mkcert -CAROOT)/rootCA.pem" ./rootCA.pem

Windows (PowerShell)

PowerShell
Copy-Item "$(mkcert -CAROOT)\rootCA.pem" .\rootCA.pem
3

Start the stack

From your mysagra/ folder, bring all services up in detached mode.

bash / PowerShell
docker compose up -d

On first boot MySagra will run database migrations automatically. Check the logs with docker compose logs -f mysagra-backend.

Where to find the services

Once the stack is running, replace SERVER_IP with your actual IP or domain:

ServiceURL
MyCassahttps://SERVER_IP (port 443)
Admin panelhttps://SERVER_IP:81
Print servicehttps://SERVER_IP:1234

Trust the certificate on local devices

For a private LAN deployment using a self-signed certificate, every device that needs to access MySagra must trust the rootCA.pem you generated in Step 2. Copy rootCA.pem from your server to the target machine, then install it:

Windows

PowerShell (run as Administrator)
Import-Certificate -FilePath .\rootCA.pem -CertStoreLocation Cert:\LocalMachine\Root

Alternatively, double-click rootCA.pem, choose Install Certificate β†’ Local Machine β†’ Trusted Root Certification Authorities.

macOS

bash
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain rootCA.pem

Linux (Debian / Ubuntu)

bash
sudo cp rootCA.pem /usr/local/share/ca-certificates/mysagra-rootCA.crt sudo update-ca-certificates

On Android go to Settings β†’ Security β†’ Install a certificate β†’ CA certificate and select rootCA.pem. On iOS / iPadOS AirDrop or email yourself the file, tap it to install, then go to Settings β†’ General β†’ VPN & Device Management β†’ Certificate Trust Settings and enable full trust.