Articles on: Custom Code & Design
This article is also available in:

πŸ”’Celestory&Voltask self-host

Complete Guide β€” Self-hosting Celestory & Voltask on CasaOS

Installation and configuration guide for Celestory & Voltask on CasaOS (the Celestory Kubb OS), designed for non-developers: every concept is explained, every setting is justified, and all common pitfalls are covered.

0. Who is this guide for?

For anyone who wants to install Celestory & Voltask "at home" (on their own server) via CasaOS, without being a developer. We explain everything: what a container is, an environment variable, a port, etc. If you already know these concepts, jump straight to section 4 (configuration).

1. The basic concepts (read once)

Before touching anything, here are the 7 notions that come up all the time. Understanding them will save you 90% of the headaches.

🧱 A "container"

Picture a small sealed box containing a program and everything it needs to run (its version of Node, its files, its settings). It's isolated from the rest of the machine. Celestory isn't one program: it's 11 containers working together (the API, the database, authentication, etc.). This is what we call a stack.

🐳 Docker

This is the engine that runs these boxes. CasaOS relies on it.

πŸ“‹ The docker-compose.yml file

This is the recipe for the stack: it lists the 11 containers, their settings, and how they talk to each other. On CasaOS, it's located here:

/var/lib/casaos/apps/big-bear-celestory-voltask/docker-compose.yml

πŸ‘‰ Everything we're going to configure in this guide is this file (either through the CasaOS interface or the command line).

πŸ”§ An "environment variable"

This is a setting passed to a container in the form NAME = value. For example ADMIN_PASSWORD = password. The program reads these variables at startup to know how to behave. This is the bulk of what we're going to modify.

πŸ”Œ A "port"

A machine can run several services at the same time; the port is the "door number" that tells which service you want to talk to. Examples: a classic website = door 80 (http) or 443 (https). Celestory exposes its interface on door 1500. Two types of ports not to confuse:

  • internal port: used inside the box (between containers);
  • published port: the door opened to the outside, the one you type into your browser.

πŸšͺ The "gateway" (reverse proxy)

One of the 11 containers is called celestory-gateway. It's the doorman of the stack: it's the only entry point. When you open the interface, you talk to the gateway, and it routes you to the right service based on the path of the URL:

  • …/celestory/api β†’ goes to the API
  • …/hub β†’ goes to the Hub (license management)
  • …/voltask β†’ goes to Voltask (the automation engine)

This is exactly why the paths in the URLs matter (see section 4.2).

πŸ›‘οΈ ORIGIN and the "CSRF" protection β€” THE critical point

The hub and auth of Celestory are built with a framework (SvelteKit) that has an anti-hacking security called CSRF protection. In short:

The server refuses any sensitive action (like login) if the address it's sent from does not exactly match the address declared in the ORIGIN variable.

"Exactly" means: same protocol (http vs https), same name (localhost vs a domain), same port (:1500). The slightest difference = error:

{"message":"Cross-site POST form submissions are forbidden"}  β† error 403

πŸ‘‰ The golden rule of this whole guide: the ORIGIN variable (and its siblings) must be identical, character for character, to the URL you type in your browser's address bar. This is the #1 cause of login failures.

2. Overview: the 11 containers

Container

Role (in plain terms)

celestory-gateway

πŸšͺ The doorman β€” sole entry point, publishes the interface on port 1500

celestory-frontend

πŸ–₯️ The web interface you see

celestory-api

βš™οΈ The application brain (cloud API)

celestory-auth

πŸ”‘ Login / accounts (OAuth, tokens)

celestory-hub

πŸ“œ License management (and admin)

celestory-voltask

πŸ€– The Voltask automation engine

celestory-orchestrator

🎬 Coordinates Voltask tasks

celestory-generator

πŸ—οΈ Generates projects / files

celestory-db

πŸ—„οΈ The PostgreSQL database (all the data)

celestory-plugins-bun

πŸ”Œ Plugins (Bun runtime)

celestory-plugins-deno

πŸ”Œ Plugins (Deno runtime)

They start in order: most wait for celestory-hub to be "healthy" before starting. If the hub doesn't start, the whole stack stays blocked (see troubleshooting).

3. Prerequisites

  • CasaOS installed and working (here: for the Celestory Kubb on WSL2 + native Docker, but it works the same on a real Linux server).
  • The "Celestory & Voltask" application (big-bear-celestory-voltask) installed from the CasaOS store.
  • Knowing how to open the CasaOS terminal (or connect via SSH).
  • A Celestory license (the offering is paid, no free version β€” see celestory.io/pricing).
  • A fal.ai API key if you want the AI generation features (see FAL_API_KEY).

4. Configuration β€” the step-by-step procedure

4.1 The principle: choose your "access address" once and for all

Before filling in anything, decide which URL you'll use to access Celestory. This URL will be reused everywhere. Two typical cases:

Situation

Your access URL ("BASE")

Local access, on the machine itself

http://localhost:1500

Access from the network, by IP

http://192.168.x.x:1500

Access by domain name behind a reverse proxy with HTTPS

https://celestory.mydomain.com (often without :1500, since the proxy handles the port)

πŸ“Œ The port :1500 is part of the address. The interface is served on the published port 1500. If you access it through this port, then the address goes all the way to the port β€” a concrete example of a real page: http://localhost:1500/hub/licenses. If your address bar shows :1500, then all your variables must contain :1500. (Remember the golden rule from section 1.)

In what follows, we write BASE for your access URL. Example: BASE = http://localhost:1500.

4.2 The variables to set

The gateway routes based on the path of the URL. So you must fill in the full paths in each variable:

Container

Variable

Value (replace BASE with your URL)

api

ORIGIN

BASE/celestory/api

auth

SELF_HOSTED_REDIRECT_URI

BASE/celestory/callback

hub

ORIGIN

BASE/hub

voltask

WEBHOOK_URL

BASE/voltask

Concrete example with BASE = http://localhost:1500:

Container

Variable

Value to enter

api

ORIGIN

http://localhost:1500/celestory/api

auth

SELF_HOSTED_REDIRECT_URI

http://localhost:1500/celestory/callback

hub

ORIGIN

http://localhost:1500/hub

voltask

WEBHOOK_URL

http://localhost:1500/voltask

⚠️ Protocol consistency. If you access via http://, everything must be http://. If you access via https://, everything must be https://. A mix = error 403 at login (the infamous CSRF protection).

4.3 πŸ†• FAL_API_KEY variable (AI generation)

What is it? fal.ai is an online service that runs AI models (image generation, etc.). Celestory uses it for its AI generation features. Without this key, those features don't work.

How to get it? Create an account on fal.ai β†’ API Keys section β†’ generate a key (it looks like a long string of characters).

Where to add it? Add an environment variable:

FAL_API_KEY = your_fal_ai_key_here

on the service that does the generation (typically generator, and/or api depending on your version). When in doubt, add it to both β€” an extra variable is harmless.

4.4 πŸ—‘οΈ The projectFiles volumes: unnecessary

Reminder: what is a volume? A container is "sealed": what it writes inside disappears if it's recreated. A volume is a folder shared between the inside of the container and the host machine's disk, to keep the files.

πŸ‘‰ In the current version, the projectFiles volumes (on the api and generator side) are not needed. If your install has them, you can remove them without breaking anything; and if you're starting from scratch, no need to add them.

4.5 βš™οΈ Check the Hub's internal port (PORT = 1402)

On some versions of the image, the hub ships with a wrong internal port that prevents the whole stack from starting (the hub stays "unhealthy", and all the other containers stay stuck in Created).

The hub must have:

PORT = 1402

(and not 1500 β€” 1500 is the port published by the gateway, not the hub's internal port). The gateway looks for the hub on HUB_PORT = 1402, and the health check also tests 1402. If you see PORT = 1500 in the hub block, fix it to 1402. (Details and symptoms in section 7.)

5. Where and how to change these settings?

Two methods. Pick one.

  1. Open CasaOS β†’ click on the Celestory & Voltask app β†’ βš™οΈ Settings.
  2. At the top, tabs: api, auth, db, frontend, gateway, generator, hub, … Click on the service you want.
  3. Scroll down to "Environment variables". Change the Value next to the right Key, or click + Add for FAL_API_KEY.
  4. To remove a volume: "Volumes" section β†’ click the βœ• on the row.
  5. Save β†’ CasaOS recreates the stack automatically.
⚠️ Two pitfalls of the CasaOS interface:After saving, check that the hub still has PORT = 1402 (the UI may sometimes re-display it) β€” otherwise fix it before saving.An "Installing NaN% / Error" banner may appear: it's purely cosmetic when the stack has also been touched via the command line. Close it with the βœ•, do not click "reinstall".

Method B β€” via the command line (faster, safer)

Open the CasaOS terminal (or SSH). First define a shortcut to the file, and make a backup:

COMPOSE=/var/lib/casaos/apps/big-bear-celestory-voltask/docker-compose.yml
sudo cp $COMPOSE ${COMPOSE}.bak.$(date +%Y%m%d_%H%M%S)
🧠 Two things you absolutely must know:The COMPOSE=… variable disappears if you close/reopen the terminal (new session). If a $COMPOSE command returns a weird error (unknown shorthand flag: 'd'), it's empty β†’ retype the COMPOSE=… line.Reading or editing this file requires sudo (otherwise: Permission denied).

Example: fix the hub's port and check the current settings:

# 1) Fix the hub's internal port (1500 β†’ 1402) β€” risk-free, 1500 only exists here
sudo sed -i 's|PORT: "1500"|PORT: "1402"|' "$COMPOSE"
​
# 2) Check the origins / paths / key
sudo grep -nE 'ORIGIN|WEBHOOK|REDIRECT|FAL_API_KEY' "$COMPOSE"

For the origins/paths, the safest is to edit the file (with sudo nano "$COMPOSE") and set the exact values from table 4.2. Locate each service block (api:, auth:, hub:, voltask:) and fix the line under environment:.

Once the changes are made, apply them by recreating the stack:

sudo docker compose -f "$COMPOSE" up -d --force-recreate

Then watch the startup (Ctrl+C to exit the watch):

watch -n3 'sudo docker ps --filter "name=celestory" --format "table {{.Names}}\t{{.Status}}"'

🎯 Goal: all 11 containers healthy. The hub should turn healthy in 30–60 s, then the others start in cascade.

6. First login & license activation

6.1 Logging into the Hub

  1. Open exactly your BASE URL in the browser (e.g. http://localhost:1500).
    • On https with a self-signed certificate: the browser shows a warning β†’ Advanced β†’ Continue, this is normal.
  1. CELESTORY HUB login page. Default credentials (set in the hub block of the compose):
    • Email: ADMIN_USERNAME (default demo@mail.com)
    • Password: ADMIN_PASSWORD (default password)
🧠 Important concept β€” the admin account is created ONLY ONCE.
The administrator account is written into the database at the very first startup, from the value ADMIN_USERNAME had at that moment. If you change ADMIN_USERNAME afterwards, it does not rename the existing account: log in with the original email. To really change the admin, you have to modify it in the database (or reset the database β€” destructive).

6.2 Activate the license

  1. Once logged in, go to the licenses page: BASE/hub/licenses

(e.g. http://localhost:1500/hub/licenses).

  1. Enter your Celestory license key (purchased on celestory.io/pricing).
  2. The hub validates the license β†’ the Voltask/Celestory features unlock.

7. Troubleshooting β€” common pitfalls

Table of real symptoms encountered during an actual install, with the solution.

Symptom

Cause

Solution

Login impossible, error {"message":"Cross-site POST form submissions are forbidden"} 403

The access URL β‰  the ORIGIN variable (different protocol, name or port)

Align ORIGIN/REDIRECT/WEBHOOK exactly with the address bar URL (cf. 4.1). http≠https, and :1500 counts!

The stack won't start: hub unhealthy, and api/frontend/generator/voltask/gateway frozen in Created

The hub has PORT = 1500 instead of 1402 β†’ its health check fails in a loop β†’ blocks all the services waiting on it

`sudo sed -i 's\

PORT: "1500"\

PORT: "1402"\

' "$COMPOSE"` then recreate (cf. 4.5)

dependency failed to start: container celestory-hub is unhealthy

Same cause as above

Same

unknown shorthand flag: 'd' in -d

The $COMPOSE variable is empty (new terminal session)

Retype the COMPOSE=/var/lib/... line then rerun

Permission denied when reading the compose

You need root rights

Prefix the command with sudo

CasaOS "Installing NaN% / Error" banner

CasaOS UI desync after a command-line recreation

Cosmetic: close with βœ•. Do not reinstall (it would overwrite your fixes)

Login OK but an AI generation feature doesn't work

FAL_API_KEY missing or invalid

Add the fal.ai key (cf. 4.3)

Login with an admin email refused even though it works on another machine

The admin was seeded with a different email at first startup

Log in with this machine's original email

Useful diagnostic commands

# State of all containers
sudo docker ps -a --filter "name=celestory" --format "table {{.Names}}\t{{.Status}}"

# Which port the hub actually listens on (should show 1402)
sudo docker logs --tail 20 celestory-hub

# Check the configured origins/paths/key
sudo grep -nE 'ORIGIN|WEBHOOK|REDIRECT|FAL_API_KEY|PORT: "14' "$COMPOSE"

# Auth logs (useful if login fails on the server side)
sudo docker logs --tail 40 celestory-auth

8. Reference β€” example final values (BASE = http://localhost:1500)

# --- api ---
ORIGIN = http://localhost:1500/celestory/api
SELF_HOSTED = true
FAL_API_KEY = <your_fal_ai_key> # depending on version

# --- auth ---
SELF_HOSTED_REDIRECT_URI = http://localhost:1500/celestory/callback
USE_SELF_HOSTED_CLIENT = true

# --- hub ---
ORIGIN = http://localhost:1500/hub
PORT = 1402 # ⚠️ definitely not 1500
ADMIN_USERNAME = demo@mail.com # or your admin email
ADMIN_PASSWORD = password # change in production!

# --- voltask ---
WEBHOOK_URL = http://localhost:1500/voltask

# --- generator ---
FAL_API_KEY = <your_fal_ai_key> # depending on version

# --- gateway ---
# publishes the interface on port 1500 (do not change HUB_PORT = 1402)
πŸ” In production, you must change ADMIN_PASSWORD, the PostgreSQL password, and do not expose the interface over http on the Internet without a reverse proxy + HTTPS.


Updated on: 11/06/2026

Was this article helpful?

Share your feedback

Cancel

Thank you!