# Single-server Coolify deployment

This page describes the simplest **production-shaped** Crown deployment that still keeps the platform understandable: one Ubuntu host, one Coolify installation, one proxy layer, and one single-node SurrealDB runtime.

It is grounded in the official platform guidance:

- Coolify documents support for **single servers**, deployment to **any server via SSH**, and a built-in reverse proxy with automatic TLS handling.
- Coolify also documents that everything runs as **Docker containers**, and that it can either **build from Dockerfiles / Compose** or **pull prebuilt images** from a registry.
- Forgejo documents that it can be **self-hosted on your own server**, including installation with Docker.
- Forgejo also documents an **OCI-compliant container registry** with `docker login`, `docker push`, and `docker pull` flows using the Forgejo instance domain as the registry hostname.
- SurrealDB documents a **single-node, on-disk RocksDB server** as a good fit for getting started quickly and for **small deployments**.

Official references:

- [Coolify introduction](https://coolify.io/docs/get-started/introduction)
- [Coolify concepts](https://coolify.io/docs/get-started/concepts)
- [Forgejo installation overview](https://forgejo.org/docs/latest/admin/installation/)
- [Forgejo installation with Docker](https://forgejo.org/docs/latest/admin/installation/docker/)
- [Forgejo container registry](https://forgejo.org/docs/latest/user/packages/container/)
- [SurrealDB single-node RocksDB deployment](https://surrealdb.com/docs/surrealdb/installation/running/rocksdb)

## Reference topology

![Single-server Coolify deployment](../diagrams/generated/single-server-coolify-deployment.svg)

Source: [`single-server-coolify-deployment.mmd`](../diagrams/generated/single-server-coolify-deployment.mmd)

## What lives on the single host

In this reference shape, one Ubuntu server carries:

- Coolify control plane
- the Coolify-managed proxy layer
- a self-hosted **Forgejo** instance for source control and webhook-driven delivery
- a self-hosted **OCI registry** for private image storage
- frontend containers
- backend service containers
- the `database-migrations` job
- a single-node SurrealDB instance
- persistent volumes for database state, uploaded attachments, Git repositories, and registry blobs

That makes the infrastructure compact and easy to reason about. One box, one blast radius, one set of operational dashboards. Simple is a feature.

## Why this pattern exists

This is the right starting point when you want:

- the fewest moving parts
- the fastest path from repo to production
- one place to inspect logs, volumes, and container state
- lower operational cost than a multi-node footprint

For early production, pilots, or smaller teams, this can be the most sensible place to begin.

## Build modes supported by the docs

According to Coolify's concepts docs, there are two broad ways to get containers onto the host:

### Build on the same host from Forgejo source

Coolify can build directly from the source repository exposed by a self-hosted Forgejo instance.

Pros:

- minimal moving pieces
- easy to set up quickly
- no separate build runner required

Trade-offs:

- build workloads compete with production workloads for CPU, RAM, and disk
- rollouts become slower as the repo and image set grows
- the host needs enough headroom for both serving traffic and compiling containers

### Pull prebuilt images from a self-hosted registry

Coolify can also deploy containers from images that were built elsewhere and pushed to a private self-hosted OCI registry.

Pros:

- cleaner production host
- faster rollouts
- easier rollback to immutable image tags
- less chance that build-tool drift leaks into production

If you use Forgejo's own container registry, the registry endpoint follows the Forgejo instance domain and OCI naming rules. If you run a separate private registry, the delivery shape stays the same: source in Forgejo, images in the registry, deploys pulled by Coolify.

For Crown, this is usually the better steady-state option even if you begin with a single host.

## What changes when Forgejo and the registry are also self-hosted

If you colocate Forgejo and the registry on the same machine as Crown, the host is no longer only an application runtime. It also becomes the **delivery plane**.

That adds a few very practical concerns:

- repository data and registry blobs now compete with Crown for disk space
- developer HTTPS / SSH traffic for Forgejo now shares the same host as production runtime traffic
- image retention and Git retention policies matter because stale artifacts can eat the box alive
- outages on the single machine affect both the deployed app and the software delivery path

This is still a workable pattern for smaller environments, but it raises the importance of:

- volume monitoring
- storage cleanup rules
- host backups that cover both runtime data and delivery data
- clear domain routing for app traffic vs Forgejo vs registry traffic

## Database shape

The SurrealDB guidance for a single-node RocksDB deployment maps neatly onto this topology:

- one SurrealDB server
- one mounted on-disk data path
- authentication enabled
- Docker-internal networking rather than public database exposure

That means the single-host deployment should generally keep the database **internal only**, with traffic flowing from Crown services to SurrealDB over the container network.

## When to choose this pattern

Choose the single-server pattern when:

- workload is modest
- the team is small
- the priority is operational simplicity
- there is no immediate need to spread workloads across multiple machines
- you are still validating traffic levels and resource envelopes

## When to move beyond it

Move past the single-server pattern when one or more of these become true:

- builds noticeably interfere with production performance
- frontend, API, and database workloads need separate scaling behaviour
- maintenance on one machine creates too much risk
- database durability or throughput needs justify a clustered data tier

At that point, the next reference to read is [Multi-node Coolify + SurrealDB deployment](./multi-node-coolify-surrealdb-deployment.md).

## Crown recommendation

For Crown specifically, the single-server deployment is a strong **initial production baseline** when you want the smallest possible platform footprint.

The most practical default is:

- use Coolify on the runtime host
- if Forgejo is self-hosted on the same box, keep its storage and routing explicit
- if the registry is self-hosted too, prefer immutable tags and retention rules
- keep SurrealDB internal and volume-backed
- run the migration job before service rollout
- prefer prebuilt images as soon as builds start becoming expensive
- back up the database and attachment volumes aggressively
