Self-Hosted

On-Premises Setup

One command installs everything โ€” Docker, PostgreSQL, 25+ microservices, and up to 6 branded web apps behind an auto-TLS reverse proxy. Runs on Linux, macOS, and Windows.

System Requirements

๐Ÿ–ฅ๏ธ

Server

Linux (Ubuntu, Debian, CentOS, Fedora, etc.), macOS, or Windows Server

๐Ÿ’พ

RAM

Minimum 4 GB (8 GB+ recommended)

๐Ÿ’ฟ

Disk

20 GB free space (SSD recommended)

๐ŸŒ

Network

Outbound internet access for pulling Docker images

๐Ÿ˜

Database

PostgreSQL 14+ (bundled option available, or bring your own)

๐Ÿณ

Docker

Auto-installed by the installer if not already present

Install in One Command

Run a single command on your server. The installer handles Docker, PostgreSQL, keys, secrets, and all 25+ services automatically.

DNS prerequisite: Before installation, configure DNS records for the components you select. The installer will show the exact list. The API host defaults to api.<your-domain>, and you can choose a different API subdomain during installation. Web-app hosts such as erp.<your-domain>, pos.<your-domain>, school.<your-domain>, and merchants.<your-domain> are only needed when those apps are selected.
curl -fsSL https://koroworks.com/deploy/get-koroerp.sh | KORO_DOWNLOAD_URL=https://koroworks.com/deploy bash

The command downloads the installer from this website and runs it interactively.

How Installation Works

The installer is an orchestrator. It lets you deploy the core ERP, web apps, and AI together or as separate stages.

1. Bootstrap

get-koroerp.sh or get-koroerp.ps1 downloads the versioned deployment files into a koro-erp folder and launches the root installer.

2. ERP APIs

install.sh or install.ps1 creates the environment file, keys, database connection, Caddy TLS settings, and starts the core API services. APIs are the foundation for every web app.

3. Web apps

The optional apps stage starts the selected web applications with the shared API configuration. Apps can only be installed after the APIs are available.

4. AI service

AI can run beside ERP or on a separate VM. With sibling apis and ai folders, the installer discovers available ERP connection settings and the public key. Missing settings and database addresses that are not reachable from the AI container still require input.

Choose a deployment style

All-in-one: answer yes to APIs, web apps, and AI. The root installer runs each stage in order.

Core only: install APIs and skip web apps and AI. Add either component later from the same deployment folder.

Split AI: install APIs and apps on the main server, then run the AI installer separately with the public ERP gateway URL.

AI Installation, Step by Step

Run bash ai/install.sh from your deployment folder, or .\ai\install.ps1 in PowerShell. The installer switches to its own AI directory, creates the required folders, and writes ai/.env. You do not need to change directories during an installation prompt.

  1. 1. Choose where AI runs

    On the same server, keep apis and ai as sibling deployment folders. The installer reuses available ERP URLs, configured authentication, the public key, and externally reachable database settings. Your existing AI settings and explicit overrides take precedence.

    On another server, use addresses reachable from the AI container. A Docker service name such as postgres on the ERP server, or localhost inside AI, does not automatically reach that server. Download the AI image before generating a short-lived pairing code.

    docker pull korobosta/ai:latest
  2. 2. Choose Platform authentication

    If authentication is not already configured, the installer offers three choices. A Platform internal token is for operator-owned deployments and must match Platform API. Installation ID and key are for one enrolled tenant. ERP pairing is recommended for customer-hosted AI and keeps ERP installation credentials off the AI server.

    For pairing, sign in to the ERP Business app as a tenant administrator. Open AI > Settings > Connect AI Server, select Generate Pairing Code, use its copy button, and paste the code into the waiting installer. The code lasts five minutes and works once. Generate it only when the AI server is ready to start. These controls remain available even while AI is offline.

    Pairing securely provides a dedicated relay credential and the ERP JWT public key. Shared SaaS hosts require explicit approval by the enrolled host's super administrator; an ordinary tenant code remains tenant-scoped. Do not share Platform tokens, installation keys, or pairing codes in support tickets.

  3. 3. Supply the ERP public key when needed

    Pairing supplies the public key automatically. Otherwise, the installer first looks for the sibling ERP's apis/keys/public.pem. If it cannot find it, it accepts either an absolute local file path or a pasted public PEM.

    To export the existing key, run this in a second terminal on the ERP server, from the main deployment directory:

    # Linux / macOS
    ./manage.sh export-public-key
    
    # PowerShell
    .\manage.ps1 -Command export-public-key

    The command creates erp-public.pem. Open it and copy the complete block, including -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----, into the AI installer. Alternatively, transfer the file and enter its absolute path. The installer validates it and creates ai/keys/public.pem for the read-only container mount. Never transfer private.pem, generate a replacement key pair, or use licence_public.pem for JWT verification.

  4. 4. Confirm database and storage

    Enter database credentials only if they could not be reused. Enter the real password without manually URL-encoding it: the installer generates encoded database connection values. Choose Local disk, an explicitly built or approved MinIO image, or External S3-compatible storage. Do not assume minio/minio:latest is available.

    For Google Cloud Storage, use https://storage.googleapis.com as the endpoint, koro-erp as the default bucket, and GCS HMAC access credentials. The bucket name is separate from the endpoint; do not append it to the URL. Existing custom settings remain unchanged.

  5. 5. Preserve settings and verify startup

    The installer generates the BYOK encryption key once and preserves it on reruns. Back up ai/.env securely: replacing that key makes saved provider credentials unreadable. Legacy .env.ai is copied only when .env does not exist. Local models, datasets, and pairing state use persistent volumes; do not delete them during updates.

    From the AI deployment directory, check startup and logs:

    docker compose --env-file .env -f docker-compose.yml up -d
    docker compose --env-file .env -f docker-compose.yml logs --tail 100 ai

    Add --profile minio if you selected bundled MinIO. A started container is not proof of application readiness: check the logs and AI's /health endpoint. Before recreating older containers, back up any files in /app/storage that were not already on a persistent volume.

  6. 6. Link ERP to the AI server

    For a separate AI server, configure its HTTPS address and run the link command on the main ERP server:

    ./manage.sh link-ai https://ai.your-domain.com
    
    # PowerShell
    .\manage.ps1 -Command link-ai -AiUrl https://ai.your-domain.com

    The ERP gateway forwards Business app AI requests to this server. Wallet calls use your selected direct Platform credentials or the paired ERP relay. Provider selection and managed API keys remain on Platform; they are not entered in the AI key-file prompt.

Detailed reference: AI deployment guide. Installation files: Linux installer and PowerShell installer.

Docker not an option?

Install as native binaries instead

Every Koro service also ships as a static executable โ€” no Docker, no daemon, ~20โ€“50 MB each. Ideal for low-resource VPS, Windows Server without Docker Desktop, air-gapped environments, and edge deployments.

What Gets Deployed

๐Ÿ—๏ธ Infrastructure

  • โœ“ Caddy reverse proxy (auto-TLS via Let's Encrypt)
  • โœ“ API Gateway (in-cluster rate limiting)
  • โœ“ PostgreSQL database (optional bundled)
  • โœ“ Redis cache (for lookups service)
  • โœ“ 6 branded Flutter web apps (nginx per app)
  • โœ“ RSA key management (JWT + licence)

๐Ÿ“ฆ Services (25+ modules)

โ— Auth
โ— HRM
โ— CRM
โ— Sales
โ— Accounting
โ— SCM
โ— Manufacturing
โ— POS
โ— E-Commerce
โ— Logistics
โ— Projects
โ— Marketing
โ— Compliance
โ— Documents
โ— Payments
โ— Notifications
โ— Chat
โ— LMS
โ— Healthcare
โ— Wellness
โ— Agriculture
โ— Construction
โ— NGO
โ— Service Desk
โ— BSC

Manual Installation

Prefer full control? Download the files and run the setup step by step.

Download individual files

Then run manually

# 1. Copy and edit environment variables
cp env.example .env
nano .env

# 2. Point DNS at your server
# *.acmecorp.com  A  <server-ip>

# 3. Generate RSA keys
mkdir -p keys
openssl genpkey -algorithm RSA -out keys/private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in keys/private.pem -out keys/public.pem

# 4. Start ERP core stack
docker compose -f apis/docker-compose.yml --profile db up -d

# 5. Optional companion apps
docker compose \
  -f apis/docker-compose.yml \
  -f apps/docker-compose.yml \
  --profile db --profile pos --profile shop up -d

Install stages separately

# Core APIs first
bash apis/install.sh

# Optional web apps, after APIs are running
docker compose --env-file apis/.env \
  -f apis/docker-compose.yml -f apps/docker-compose.yml \
  --profile all up -d

# Optional AI on this server or a separate VM
bash ai/install.sh

# Manage an existing deployment
bash manage.sh update
bash manage.sh status
bash manage.sh restart apis

Deployment Management Commands

Run these commands from the downloaded koro-erp deployment directory, where manage.sh, manage.ps1, and the component folders live. These scripts manage Docker deployments and require Docker Compose V2 for stack operations. The scripts resolve component paths relative to their own directory.

Linux/macOS examples use ./manage.sh; bash manage.sh also works if the script is not executable. Windows examples use PowerShell. Download the current Bash script or PowerShell script if your local version lacks a command.

Stack targets
restart, logs, and down accept apis, apps, ai, or all (the default). Bash uses a positional target; PowerShell uses -Target. The apps target combines the API and app Compose files with the all profile, so it can also affect API containers; it is not an app-only operation.
Preview changes
Append --dry-run in Bash or -DryRun in PowerShell to preview actions without downloading, writing files, or running mutating commands. Local configuration, key validation, prompts, and Docker availability checks can still apply. A dry run is not proof that a later deployment will succeed.

Interactive updates

With no command or component flags, asks which installed components to update. PowerShell also accepts -Command prompt explicitly.

Linux / macOS

./manage.sh

PowerShell

.\manage.ps1

Update installed components

Pulls the configured container images and runs Compose up -d for detected installed stacks. Uses your existing image tags; it does not change a pinned version, redownload deployment scripts, or rerun the installer. Records the update in install-manifest.json.

Linux / macOS

./manage.sh update
./manage.sh update --dry-run

PowerShell

.\manage.ps1 -Command update
.\manage.ps1 -Command update -DryRun

Legacy update alias

Backward-compatible alias for update. It performs an update; it is not a version-reporting command.

Linux / macOS

./manage.sh current

PowerShell

.\manage.ps1 -Command current

Update selected components

Use component flags without an update command to select APIs, companion apps, AI, or all three explicitly. Flags can be combined. Selected components must already be configured; --all / -All is not an installer and may fail if a component is missing. update and current instead select detected installed stacks.

Linux / macOS

./manage.sh --apis
./manage.sh --apps
./manage.sh --ai
./manage.sh --all
./manage.sh --apis --ai --dry-run

PowerShell

.\manage.ps1 -Apis
.\manage.ps1 -Apps
.\manage.ps1 -Ai
.\manage.ps1 -All
.\manage.ps1 -Apis -Ai -DryRun

Show container status

Runs Compose ps for configured installed stacks. Reports container state, not an end-to-end application health check. This command has no stack target argument.

Linux / macOS

./manage.sh status

PowerShell

.\manage.ps1 -Command status

Restart a stack

Restarts existing containers without pulling images or applying new environment values. Omit the target to restart all detected installed stacks. Use an update to recreate containers after configuration or image changes.

Linux / macOS

./manage.sh restart
./manage.sh restart apis

PowerShell

.\manage.ps1 -Command restart
.\manage.ps1 -Command restart -Target apis

Read recent logs

Prints the last 100 log lines for the selected stack. It does not follow logs continuously or accept an individual service name. Omit the target for all detected installed stacks.

Linux / macOS

./manage.sh logs
./manage.sh logs ai

PowerShell

.\manage.ps1 -Command logs
.\manage.ps1 -Command logs -Target ai

Stop and remove stack containers

Runs Compose down for the selected stack, removing its containers and Compose networks without requesting volume deletion. Causes downtime. Files stored only in a container writable layer are not preserved. Omit the target for all detected installed stacks.

Linux / macOS

./manage.sh down apis

PowerShell

.\manage.ps1 -Command down -Target apis

Remove stopped containers

Runs docker container prune and asks for Docker confirmation. This affects all stopped containers on the Docker host, including other deployments, not just KoroERP. It does not prune images or volumes. Bash also accepts clean without containers.

Linux / macOS

./manage.sh clean containers

PowerShell

.\manage.ps1 -Command clean

Enable HTTPS for AI

Run on the AI server after installing AI. Saves AI_DOMAIN and ACME_EMAIL in ai/.env and starts the AI proxy profile. Supply a hostname, not an https:// URL; PowerShell uses -AiUrl for this hostname too. Omit it to be prompted. Point DNS at the AI server and allow inbound ports 80/443. Set KORO_ACME_EMAIL to avoid the email prompt.

Linux / macOS

./manage.sh proxy-ai ai.example.com

PowerShell

.\manage.ps1 -Command proxy-ai -AiUrl ai.example.com

Export the ERP JWT public key

Validates and copies apis/keys/public.pem to erp-public.pem by default, or to the supplied output path. Refuses an existing output file. Does not rotate keys or export a licence key. Bash requires OpenSSL; PowerShell can also validate using supported .NET RSA PEM APIs. Transfer only this public key to the AI server, never private.pem.

Linux / macOS

./manage.sh export-public-key
./manage.sh export-public-key /tmp/erp-public.pem

PowerShell

.\manage.ps1 -Command export-public-key
.\manage.ps1 -Command export-public-key -OutputPath C:\Temp\erp-public.pem

Refresh deployment files

Downloads the bootstrap and refreshes deployment files in the current deployment directory without running the installer or updating running images. Preserves local environment files, keys, proxy configuration, manifests, and data. Uses KORO_DOWNLOAD_URL when set, otherwise https://koroworks.com/deploy. Requires network access; Bash requires curl or wget.

Linux / macOS

./manage.sh redownload
./manage.sh redownload --dry-run

PowerShell

.\manage.ps1 -Command redownload
.\manage.ps1 -Command redownload -DryRun

Delete deployment and reinstall

Destructive: brings stacks down with volume deletion, deletes files in the deployment directory, downloads the bootstrap, and starts installation again. Requires the exact confirmation RESET KORO ERP unless KORO_CONFIRM_RESET already contains that phrase. Back up databases, uploads, environment files, and keys first. External databases are not removed by Docker volume deletion, but do not assume reset is a safe database recovery procedure.

Linux / macOS

./manage.sh reset --dry-run
./manage.sh reset

PowerShell

.\manage.ps1 -Command reset -DryRun
.\manage.ps1 -Command reset

Inspect command syntax

Bash prints usage with --help or -h. PowerShell exposes its parameters through Get-Help; help is not a supported -Command value.

Linux / macOS

./manage.sh --help
./manage.sh -h

PowerShell

Get-Help .\manage.ps1

Verify Installation

Run these checks after deployment to confirm services are healthy and routing works.

Service health checks

# Gateway health endpoint
curl -i http://localhost:7012/health

# Platform API health endpoint
curl -i http://localhost:7080/health

# Running containers
docker compose -f docker-compose.yml ps

Smoke test URLs

# Core web app
https://erp.<your-domain>

# API gateway
https://api.<your-domain>

# Optional apps (if profiles enabled)
https://pos.<your-domain>
https://hub.<your-domain>
https://school.<your-domain>

FAQ

Deploy KoroERP today

Register, get your license, and run the installer on your server.

Koro Business

Choose how to use Koro Business

Open Business in your browser or download the app for your device.

On the login screen, click Create account to register.

Web

Use Koro Business in your browser. Nothing to install.

Mobile app

Install Koro Business on Android or iPhone.

Google Play

App Store link coming soon

Download Android APK

Windows

Install Koro Business on Windows 10 or 11.

Linux

Choose a package for your distribution.