Skip to main content

Services

Every Swisblade project is composed of one or more services. A service is either an application you build from source code (type: "app") or a pre-built Docker image (type: "custom").

App services

App services are built from your Git repository. Swisblade clones the repo, builds a Docker image, and runs it.

{
"api": {
"source": { "repo": "github.com/you/api.git", "ref": "main" },
"type": "app",
"runtime": "node",
"port": 3000,
"public": true,
"needs": ["postgres"]
}
}

Build process

  1. Swisblade clones your repository at the specified ref (branch, tag, or commit SHA).
  2. If a Dockerfile exists at the repo root, it's used to build the image.
  3. If there's no Dockerfile, Swisblade uses Nixpacks to auto-detect your tech stack and generate one.

Supported runtimes

Runtimeruntime valueAuto-instrumentation
Node.js"node"OpenTelemetry for Express, Fastify, Hono, etc.
Python"python"OpenTelemetry for Flask, FastAPI, Django, etc.
Java"java"OpenTelemetry Java agent

The runtime field enables automatic observability instrumentation. Your application sends traces and metrics without any code changes.

Monorepo / local source

If all your services live in a single repository, use source.path instead of source.repo:

{
"api": {
"source": { "path": "packages/api" },
"type": "app",
"runtime": "java",
"port": 3000
}
}

The path is relative to the project root. With local source, Swisblade skips the git clone step and builds directly from the specified directory. Each directory must contain its own Dockerfile or be auto-detectable by Nixpacks.

Versioning with ref

The ref field controls which version of your code gets deployed:

"source": { "repo": "github.com/you/api.git", "ref": "main" }

You can use:

  • Branch names: "main", "develop" — deploys the latest commit on that branch.
  • Tags: "v1.2.0", "release-2024-01" — pins to a specific release.
  • Commit SHAs: "a1b2c3d" — pins to an exact commit.
Pin versions in production

Use tags or commit SHAs for production deployments. Branch names deploy the latest commit, which may change between deploys.

Custom services

Custom services run pre-built Docker images. Use them for third-party tools, databases, or any service you don't build yourself.

{
"search": {
"type": "custom",
"image": "elasticsearch:8.12.0",
"port": 9200
}
}
FieldDescription
imageDocker Hub image and tag (e.g., rabbitmq:3-management)
portThe port the service listens on inside the container
protocolProtocol for generated URLs (default: "http", use "amqp" for message queues, etc.)

Examples

RabbitMQ with management UI:

{
"mq": {
"type": "custom",
"image": "rabbitmq:3-management",
"protocol": "amqp",
"port": 5672
}
}

MongoDB:

{
"mongo": {
"type": "custom",
"image": "mongo:7",
"port": 27017
}
}

Database services

Database services declare named databases on the shared platform. They don't run containers — they provision a dedicated database and user on the existing PostgreSQL or MySQL instance.

{
"analytics-db": {
"type": "database",
"engine": "mysql"
}
}

App services connect to them via connects_to, which injects a DATABASE_URL_{NAME} environment variable with dedicated credentials. See Databases for details.

In the dashboard, database services show a Shared status badge (green) and appear in the network topology map with their own node.

Service connections

connects_to

When one service needs to talk to another, declare it in connects_to:

{
"api": {
"type": "app",
"connects_to": ["worker", "search"]
},
"worker": { "type": "app", "port": 8080 },
"search": { "type": "custom", "image": "elasticsearch:8.12.0", "port": 9200 }
}

The API service receives:

  • WORKER_URL=http://worker:8080
  • SEARCH_URL=http://search:9200

needs

For managed databases and infrastructure, use needs instead. See Databases.

{
"api": {
"needs": ["postgres", "redis"]
}
}

The API service receives:

  • DATABASE_URL=postgresql://proj_xxx:password@platform-postgres:5432/proj_xxx
  • REDIS_URL=redis://proj_xxx:password@platform-redis:6379/0
  • REDIS_KEY_PREFIX=proj_xxx:

Networking

Services within the same project can communicate using their service names as hostnames (e.g., http://worker:8080). This works via Docker's internal DNS.

Services from different projects are isolated from each other — they cannot communicate directly.