Interactive updates
With no command or component flags, asks which installed components to update. PowerShell also accepts -Command prompt explicitly.
Linux / macOS
./manage.shPowerShell
.\manage.ps1One 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.
Linux (Ubuntu, Debian, CentOS, Fedora, etc.), macOS, or Windows Server
Minimum 4 GB (8 GB+ recommended)
20 GB free space (SSD recommended)
Outbound internet access for pulling Docker images
PostgreSQL 14+ (bundled option available, or bring your own)
Auto-installed by the installer if not already present
Run a single command on your server. The installer handles Docker, PostgreSQL, keys, secrets, and all 25+ services automatically.
curl -fsSL https://koroworks.com/deploy/get-koroerp.sh | KORO_DOWNLOAD_URL=https://koroworks.com/deploy bashThe command downloads the installer from this website and runs it interactively.
Prefer downloading scripts first? Use the files below.
The installer is an orchestrator. It lets you deploy the core ERP, web apps, and AI together or as separate stages.
get-koroerp.sh or get-koroerp.ps1 downloads the versioned deployment files into a koro-erp folder and launches the root installer.
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.
The optional apps stage starts the selected web applications with the shared API configuration. Apps can only be installed after the APIs are available.
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.
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.
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.
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:latestIf 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.
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-keyThe 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.
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.
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 aiAdd --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.
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.comThe 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.
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.
Prefer full control? Download the files and run the setup step by step.
# 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# 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 apisRun 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.
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.--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.With no command or component flags, asks which installed components to update. PowerShell also accepts -Command prompt explicitly.
./manage.sh.\manage.ps1Pulls 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.
./manage.sh update
./manage.sh update --dry-run.\manage.ps1 -Command update
.\manage.ps1 -Command update -DryRunBackward-compatible alias for update. It performs an update; it is not a version-reporting command.
./manage.sh current.\manage.ps1 -Command currentUse 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.
./manage.sh --apis
./manage.sh --apps
./manage.sh --ai
./manage.sh --all
./manage.sh --apis --ai --dry-run.\manage.ps1 -Apis
.\manage.ps1 -Apps
.\manage.ps1 -Ai
.\manage.ps1 -All
.\manage.ps1 -Apis -Ai -DryRunRuns Compose ps for configured installed stacks. Reports container state, not an end-to-end application health check. This command has no stack target argument.
./manage.sh status.\manage.ps1 -Command statusRestarts 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.
./manage.sh restart
./manage.sh restart apis.\manage.ps1 -Command restart
.\manage.ps1 -Command restart -Target apisPrints 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.
./manage.sh logs
./manage.sh logs ai.\manage.ps1 -Command logs
.\manage.ps1 -Command logs -Target aiRuns 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.
./manage.sh down apis.\manage.ps1 -Command down -Target apisRuns 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.
./manage.sh clean containers.\manage.ps1 -Command cleanRun on the ERP server after installing APIs. Delegates to ai/link.sh or ai/link.ps1 to configure the AI endpoint. Omit the URL to be prompted. Requires the complete deployment package with the AI link script.
./manage.sh link-ai https://ai.example.com.\manage.ps1 -Command link-ai -AiUrl https://ai.example.comRun 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.
./manage.sh proxy-ai ai.example.com.\manage.ps1 -Command proxy-ai -AiUrl ai.example.comValidates 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.
./manage.sh export-public-key
./manage.sh export-public-key /tmp/erp-public.pem.\manage.ps1 -Command export-public-key
.\manage.ps1 -Command export-public-key -OutputPath C:\Temp\erp-public.pemDownloads 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.
./manage.sh redownload
./manage.sh redownload --dry-run.\manage.ps1 -Command redownload
.\manage.ps1 -Command redownload -DryRunDestructive: 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.
./manage.sh reset --dry-run
./manage.sh reset.\manage.ps1 -Command reset -DryRun
.\manage.ps1 -Command resetBash prints usage with --help or -h. PowerShell exposes its parameters through Get-Help; help is not a supported -Command value.
./manage.sh --help
./manage.sh -hGet-Help .\manage.ps1Run these checks after deployment to confirm services are healthy and routing works.
# 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# 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>Register, get your license, and run the installer on your server.