Skip to main content

Box services

A Slothbox environment template can declare services — databases, caches, and other supporting containers that run alongside your projects on the box. Each service is a Docker image. When a box is baked, Slothbox assembles the template's services into a generated docker-compose.yml and brings them up with docker compose, so a Postgres, a Redis, and your app all start together on the same instance.

info

Services used to be installed from hand-written apt scripts. They are now Docker images assembled into a per-box docker-compose.yml. The service keys you pick (postgres, redis, and so on) are unchanged, but each one now maps to an image and tag, and you can bring your own image or import an existing compose file. Existing templates are rebaked onto the Docker model on their next bake — there's nothing to migrate by hand. Language runtimes (Node, Python, and so on) are not affected: they are still installed natively on the box, not run as containers.

Where services are configured

Services belong to an environment template, which describes how a box is built. You add them in the web app's template builder ("Add service"), and the same shape is available over the API on the template body — see the API reference for the template schemas.

A service comes from one of two sources:

  • A curated catalog image — a small, vetted set we maintain (see below).
  • A custom image — any image from any registry, including private registries.

You can also import an existing docker-compose.yml as a starting point: the web app reads your compose file and turns each service into a template service you can then tweak. This is the quickest way to bring an existing local stack onto a box — see importing a compose file for exactly what carries over.

A template can declare up to 20 services, and each service up to 20 published ports and 20 volumes.

The curated catalog

The catalog is a maintained allowlist of common services, each pinned to an official image. The full, live list is available from GET /catalog/services (it populates the "Add service" picker), and currently covers:

ServiceImageTagsDefault port
PostgreSQLpostgres16, 155432
Redisredis76379
MySQLmysql83306
DynamoDB Localamazon/dynamodb-local2.58000

Catalog services are trusted: each image is curated and vetted by Slothbox. They are pulled from their official upstream registry at bake time.

To add one, you pick the service and a tag. Catalog images are pinned to a digest when you save the template, so a template bakes the exact image it was built against (see pinning). Pinning is best-effort: in the rare case the registry can't be reached at save time, the image is left on its tag.

Networking and persistence

Catalog services are configured to behave well on a single-tenant box out of the box:

  • Loopback only. Service ports are published on 127.0.0.1, never on a public interface — the database is reachable from your project on the box, but not from the internet. The defaults also mirror the old single-tenant auth setup (for example, Postgres uses trust auth on loopback), so connecting from the box just works.
  • Persistent by default. Stateful services keep their data in a named Docker volume (<service>-data), so it survives container restarts and the box being stopped and started. DynamoDB Local defaults to in-memory; to make it persist, set its command to -jar DynamoDBLocal.jar -sharedDb -dbPath /home/dynamodblocal/data — the path must be exactly /home/dynamodblocal/data, which is where its data volume is mounted.

Configuring a service

Every service — catalog or custom — accepts the same config block to tailor how it runs:

FieldWhat it does
envNon-secret environment variables, merged over the catalog defaults.
commandOverride the container's command (a string or array).
portsPorts to publish (on loopback). Replaces the default port list.
volumesExtra mounts: a named volume (cache:/data) or a bind mount (/host:/path).
resourcesOptional cpus and mem_limit caps for the container.

Because ports replaces the defaults rather than adding to them, include the default port explicitly if you still want it — for Postgres, "ports": [5432, 5433] publishes both, while "ports": [5433] would drop 5432.

warning

Service env values are literals, written into the box's service configuration as-is — there is no secret injection for service environment variables yet, so keep passwords and API tokens out of service env. For your application code, use project-level environment variables and secrets, which do support referencing your organization's secrets by name.

On box launch, services are brought up before your projects' setup runs, so setup scripts can reach a database or cache straight away. There is no health-gated ordering beyond that: a service may still be finishing its own internal startup when setup begins, so a script that needs it ready should retry its first connection.

Importing a compose file

The compose importer turns each service in a docker-compose.yml into a template service. It keeps the fields that map onto the template model and warns about anything it drops, so review the import before saving:

Compose inputWhat the importer does
imageKept. A missing tag defaults to latest.
container_nameKept.
portsKept (published on loopback).
environmentKept, as literal values.
volumes — named, short syntax (data:/var/lib/x)Kept.
commandKept (string or array).
build:Service skipped — only prebuilt images can be imported.
depends_onDropped, with a warning.
Bind mounts (./local:/path)Dropped, with a warning.
Long-syntax volumes entriesDropped, with a warning.
YAML anchors and aliasesDropped, with a warning.
Block-scalar command valuesDropped, with a warning.
Environment interpolation (${VAR})Dropped, with a warning.
Top-level networks, volumes, secrets, configsDropped, with a warning.

Every imported service becomes an unverified custom image — even a stock postgres:16 imported this way is treated as a custom image rather than being mapped back to the curated catalog entry.

On the box

A few useful facts when you're troubleshooting a service on a running box:

  • The generated compose file is at /etc/slothbox/docker-compose.yml, and each service's environment file is at /etc/slothbox/services/<name>.env.
  • The usual compose commands work against it: docker compose -f /etc/slothbox/docker-compose.yml ps and docker compose -f /etc/slothbox/docker-compose.yml logs <service>.
  • Container logs use the json-file driver and rotate at 10 MB across 3 files per container, so they won't fill the disk.
  • Container health is reported on the box's health heartbeat, so you can see a failing service from the box page without SSHing in.

Next steps

  • Custom images — bring your own image from any registry, and how image pinning works.
  • Private registries — pull private images with org-level registry credentials (Docker Hub, GHCR, or ECR).