We've finally reached our first beta. Please ensure you are using our DNS server.

Concepts

Town OS is built around a set of core ideas. Understanding these concepts will help you make sense of how everything fits together — from defining a package to managing a running service.

Packages

A package is a self-contained YAML definition of a service, pulled from a git repository. Each package specifies its networking port mappings, storage volumes, environment variables, and interactive questions — everything needed to run the service. Packages can run as containers (the default), QEMU-based virtual machines, or Windows applications via Valve's Proton compatibility layer. File templates (Go text/template files) can be rendered into volumes at install time for dynamic configuration. Packages declare supplies tags (like http, database, cache) to describe their capabilities. The default repository ships with curated packages covering git hosting, video conferencing, media streaming, team messaging, and databases — with more being added regularly.

Questions

When you install a package, Town OS may present interactive prompts called questions. Your responses fill @variable@ template placeholders throughout the package definition — setting hostnames, ports, credentials, and other options. Each question has a typed validator (hostname, port, bytes, volume, archive, duration, secret, or free-form text) and an optional default value, so configuration errors are caught before the service ever starts. Several types auto-generate values when left empty: ports are assigned randomly in the 10000–60000 range, hostnames are generated as package-name-4hex, and secrets produce a 64-character hex string.

Services

Once a package is installed, it becomes a service — a running container managed by a systemd unit. Town OS gives you start, stop, and restart control, live log streaming via Server-Sent Events, cursor-based journal pagination, and the ability to enable or disable services. Services are isolated from each other and from the host system.

Networking

Town OS includes rolodex, a DNS server that manages authoritative zones for your packages and forwards upstream queries. Each package declares its own port mappings — external ports exposed to the host and internal ports available only between containers. Port values support @variable@ templates so users can choose ports at install time. Packages that declare dependencies share a network, allowing containers in the same dependency tree to communicate directly. Parent packages can reference dependencies using @dep_KEY_host@ and @dep_KEY_port_N@ template variables in their environment, or via runtime environment variables (TOWNOS_DEP_{KEY}_HOST and TOWNOS_DEP_{KEY}_PORT_{port}). UPnP forwarding is handled automatically.

Storage

All data is stored on btrfs subvolumes with per-package isolation. Each volume has a mountpoint inside the container, a configurable quota (e.g. 512mb, 2gb), and optional uid/gid ownership. Volumes can be pre-populated from container images using the archives feature, or seeded by cloning a git repository into an empty volume at install time. Users can also create their own standalone volumes. VM disk images are cached in a dedicated subvolume so subsequent installs reuse them. Btrfs snapshots are supported for point-in-time backups. Data persists across package reinstalls and upgrades — your files are never lost when you update a service.

Repositories

Packages are organized into repositories — git repos containing a packages/ directory with versioned YAML definitions. Every Town OS installation includes the default repository, but anyone can create and share custom repositories. Repositories are ordered — later entries override earlier ones when package names collide. A featured.json file can highlight selected packages in the UI.

Templates & Notes

The @variable@ template system connects user responses from questions to environment variables, port mappings, volume quotas, and more. Built-in variables like @LOCAL_EXTERNAL_HOST@ and @LOCAL_INTERNAL_HOST@ are always available. After installation, notes display key metadata like connection URLs, credentials, or contact information — with optional type validation for url, phone, and email.

Pages

Town OS can host static websites. Each page has three possible source types: upload a tar archive, extract files from a container image, or clone a git repository. Every page gets its own domain and is served through Caddy. Archive pages can be updated by re-uploading; git and container image pages can be rebuilt on demand.

Monitoring

A built-in observability stack runs out of the box with no configuration required. Prometheus collects metrics and Node Exporter reports host statistics (CPU, memory, disk, network). Two monitoring backends are available: a lightweight built-in UI (default) or Grafana with auto-provisioned dashboards. The entire stack runs as system services and restarts automatically on failure.

Internationalization

All user-facing strings are routed through a message catalog keyed by BCP 47 locale codes. 21 common languages are presented in their native scripts, with 87+ country-specific codes available. Only English (en-US) is fully translated today — the infrastructure is ready for community translations.

Accounts & Sessions

Town OS supports administrator and normal user accounts. Passwords require a minimum of 8 characters. Authentication uses JWT tokens with a 7-day inactivity expiration. Sessions are ephemeral — signing keys are regenerated on every reboot, which clears all active sessions automatically.

Audit Logging

Every administrative action is recorded with the account name, action, request path, detail, success flag, and timestamp. Read-only endpoints are excluded. The audit log supports pagination, filtering by account, and full-text search.

Settings

System-wide configuration is managed through key-value settings in the UI. Configurable values include the default volume quota (50 GB), max archive upload size (1 GB), archive unpack timeout (600s), locale, Proton runner image, and the DNS top-level domain.

Package Upgrades

Town OS automatically detects when newer package versions are available in your configured repositories. A badge on the dashboard shows the number of pending upgrades. You can dismiss versions you do not want — dismissals are tracked by a SHA256 hash so they reappear only when the upgrade set changes.

System Services

Infrastructure containers — monitoring, DNS, and the web UI — are managed separately from user-installed packages. They use a distinct systemd prefix (town-os-system--), always restart on failure, and cannot be disabled by users.