Managoat is the hosted Fountain. Fountain is the open-source engine, and its name is on the CLI, the API, the SDK and this manual. Everything here applies to Managoat unless a page says it is for a self-hosted server.

Deploy an instance

This guide shows you how to get a Fountain instance up with Docker Compose. It then shows you how to register the first account, and how to close registration behind you.

For a development environment on your own machine, read Setup. That is a different thing. This guide is for an instance that stays up.

Before you start

You must have Postgres 16 or newer, which the compose file runs for you. You must also have a sandbox provider token. Read Self-host Fountain for what each provider needs.

Bring it up

git clone https://github.com/BinaryBourbon/fountain
cd fountain
cp .env.compose.example .env
echo "SECRET_KEY_BASE=$(openssl rand -base64 48 | tr -d '\n')" >> .env
echo "MASTER_SECRETS_KEY=$(openssl rand 32 | base64 | tr '+/' '-_' | tr -d '=\n')" >> .env
# add your SPRITES_TOKEN to .env
docker compose up -d

Back MASTER_SECRETS_KEY up now, before you have data. It is not in the database, so a database backup alone does not protect you. Read Back up and restore.

These guides explain each variable that shapes a deployment as it comes up. The configuration reference holds the complete list, and it includes the deploy-level variables that the compose file never mentions.

Register the first account

Open http://localhost:4000 and register. That is the whole first login.

The compose defaults are EMAIL_DELIVERY=none and FIRST_USER_ADMIN=true. Your account then self-verifies at registration, and Fountain promotes it to admin because it is the first. The admin audit trail records the grant, like any other role change (ADR 0011).

Register before you expose the instance to a network you do not trust. While no admin exists, the first verified account takes the role.

Do you want the manual path instead? Set FIRST_USER_ADMIN=false and use a release task. Read Run a release task.

docker compose exec app bin/fountain_server eval \
'Fountain.Release.promote_admin("[email protected]")'

Point the apps at it

Fountain's own UI is a console. It covers the account, its keys, and the agents, environments and vaults that a conversation runs on. To watch a conversation turn by turn, and to message an agent as a teammate, you use separate single-page apps that talk to your /api.

Conversations Start a run, watch it, steer it, read the raw log.
Team Your agents as teammates, one thread for each.

They are static builds with no server of their own. You type your Fountain's URL in, so the hosted copies above work against your deployment as soon as it admits the origin.

echo "API_CORS_ORIGINS=https://jakegaylor.com" >> .env

To click "Sign in with Fountain" instead of a paste of an API key, register them in OAUTH_CLIENTS. Read the configuration reference.

The console links to whatever CONVERSATIONS_APP_URL and TEAM_APP_URL say. Point those at your own build of either repo and it works the same way. Set them to "" to tell the console that this deployment has neither, and the console stops the offer.

Close registration

echo "REGISTRATION_ENABLED=false" >> .env
docker compose up -d

Registration is open by default. Somebody will find an instance on the public internet that has registration open.

Verify it worked

curl -sS localhost:4000/health/ready
# {"checks":{"database":"ok"},"status":"ok"}

Then sign in and create a conversation. A run that reaches its first turn proves that the database, the secrets key and the sandbox provider are all wired up.

If it did not work

Does the app serve while a sandbox fails to start? The sandbox provider is the usual cause. Read Sandbox errors.

Does the container never open a listener? Migrations cannot reach the database. Read Pods restart or never go ready.