Deployment
Deploy Nanosync as a single binary, Docker container, Kubernetes Helm chart, or via Terraform.
Single binary
Nanosync is a single statically-linked binary with no runtime dependencies. State is persisted in an embedded SQLite database.
nanosync start dev --config nanosync.yaml --api-addr :7600 --db-data-dir ./dataDevelopment mode uses embedded SQLite, writes a dev context so CLI commands auto-connect, and colourises logs on TTY. Config is optional.
nanosync start server --config nanosync.yaml --api-addr :7600 --db-data-dir /var/lib/nanosyncProduction mode requires a config file and outputs JSON logs by default.
systemd unit file
[Unit]
Description=Nanosync Data Replication
After=network.target
[Service]
Type=simple
User=nanosync
WorkingDirectory=/opt/nanosync
ExecStart=/usr/local/bin/nanosync start server \
--config /etc/nanosync/nanosync.yaml \
--db-data-dir /var/lib/nanosync
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
systemctl reload nanosync # sends SIGHUP — reloads config without restart
Docker
docker run -d \
--name nanosync \
-p 7600:7600 \
-v /etc/nanosync/nanosync.yaml:/etc/nanosync/nanosync.yaml:ro \
-v /var/lib/nanosync:/var/lib/nanosync \
-e PG_PASSWORD=secret \
ghcr.io/nanosyncorg/nanosync:latest \
start server --config /etc/nanosync/nanosync.yaml --db-data-dir /var/lib/nanosync
Docker Compose
services:
nanosync:
image: ghcr.io/nanosyncorg/nanosync:latest
ports:
- "7600:7600"
volumes:
- ./nanosync.yaml:/etc/nanosync/nanosync.yaml:ro
- nanosync-data:/var/lib/nanosync
environment:
PG_PASSWORD: secret
command: start server --config /etc/nanosync/nanosync.yaml --db-data-dir /var/lib/nanosync
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
command: postgres -c wal_level=logical
healthcheck:
test: pg_isready -U postgres
interval: 5s
retries: 5
volumes:
nanosync-data:
Kubernetes (Helm)
helm install nanosync deploy/helm/nanosync/ \
--namespace nanosync \
--create-namespace \
--set image.tag=v0.1.0 \
--set persistence.enabled=true \
--set config.existingSecret=nanosync-config
Key Helm values
| Value | Default | Description |
|---|---|---|
mode | single | single (one replica) or ha (leader-elected multi-replica) |
image.repository | ghcr.io/nanosyncorg/nanosync | Container image |
image.tag | latest | Image tag |
replicaCount | 1 | Replicas (clamped to 1 in single mode) |
persistence.enabled | true | Create a PVC for the SQLite state store |
persistence.size | 10Gi | PVC size |
config.existingSecret | "" | Kubernetes Secret name containing nanosync.yaml |
ingress.enabled | false | Expose the API via Ingress |
serviceMonitor.enabled | false | Create a Prometheus ServiceMonitor |
Config as a Kubernetes Secret
kubectl create secret generic nanosync-config \
--from-file=nanosync.yaml=./nanosync.yaml \
--namespace nanosync
Terraform
GCP — Cloud Run
module "nanosync" {
source = "./deploy/terraform/gcp/cloud-run"
project = "my-gcp-project"
region = "us-central1"
image = "ghcr.io/nanosyncorg/nanosync:v0.1.0"
config_secret_id = google_secret_manager_secret.nanosync_config.secret_id
}
AWS — ECS Fargate
module "nanosync" {
source = "./deploy/terraform/aws/ecs"
cluster_arn = aws_ecs_cluster.main.arn
image = "ghcr.io/nanosyncorg/nanosync:v0.1.0"
config_secret_arn = aws_secretsmanager_secret.nanosync_config.arn
}
Data directory layout
/var/lib/nanosync/
nanosync.db # SQLite: checkpoints, schema history, FSM, run history
nanosync.db-wal # SQLite WAL file (normal during operation)
nanosync.db-shm # SQLite shared memory file
Back up nanosync.db before upgrading. Nanosync runs schema migrations automatically on startup, but a backup lets you roll back if needed.
Upgrading
# Binary
nanosync stop
curl -fsSL https://nanosync.dev/install.sh | sh
nanosync start server --config nanosync.yaml
# Docker
docker pull ghcr.io/nanosyncorg/nanosync:v0.2.0
docker restart nanosync
# Helm
helm upgrade nanosync deploy/helm/nanosync/ --set image.tag=v0.2.0
Schema migrations run automatically on startup.