Files
meshcore-analyzer/DEPLOY.md
Kpa-clawbot f59b4629b0 feat: publish Docker images to GHCR + simplified deploy (#610) (#627)
## Summary

Implements M1-M2 of the deployment simplification spec (#610). Adds
pre-built multi-arch Docker images published to GHCR, plus a simplified
deploy experience for operators.

**Spec:**
[docs/specs/deployment-simplification.md](https://github.com/Kpa-clawbot/CoreScope/blob/master/docs/specs/deployment-simplification.md)

## Files Added (no existing files modified)

### 1. `.github/workflows/publish.yml`
Multi-arch Docker publish workflow:
- Triggers on `v*` tags (releases) → produces `vX.Y.Z`, `vX.Y`, `vX`,
`latest`
- Triggers on master push → produces `edge` (unstable)
- `workflow_dispatch` for manual runs
- QEMU + buildx for `linux/amd64` + `linux/arm64`
- GHCR auth via `GITHUB_TOKEN`
- GHA layer caching for fast rebuilds

### 2. `docker-compose.example.yml`
20-line compose file that pulls from GHCR (no local build required):
- Env var overrides: `HTTP_PORT`, `DATA_DIR`, `DISABLE_CADDY`,
`DISABLE_MOSQUITTO`
- Health check included
- Volume mount for data persistence

### 3. `DEPLOY.md`
Operator documentation:
- One-line `docker run` deploy
- Tag reference (pinned vs latest vs edge)
- Environment variables table
- Update path (`docker compose pull && docker compose up -d`)
- TLS options (Caddy auto-TLS vs reverse proxy)
- **Migration guide for existing manage.sh users** — both paths
documented with command equivalency table

## Review Status

-  Self-review: Actions syntax, GHCR auth, multi-arch, tag strategy,
security — all verified
-  Torvalds: Deploy UX is clean, one-liner works, right level of
simplicity
-  BUILD_TIME fixed: uses `date` command instead of fragile
`head_commit.timestamp`
-  Migration guide added for existing manage.sh admins
- ⚠️ `DISABLE_CADDY` env var documented but not implemented in
entrypoint — pre-existing bug, filed as #629

Fixes #610

---------

Co-authored-by: you <you@example.com>
2026-04-05 14:33:57 -07:00

3.7 KiB

Deploy CoreScope

Pre-built images are published to GHCR for linux/amd64 and linux/arm64 (Raspberry Pi 4/5).

Quick Start

Docker run

docker run -d --name corescope \
  -p 80:80 \
  -v corescope-data:/app/data \
  -e DISABLE_CADDY=true \
  ghcr.io/kpa-clawbot/corescope:latest

Open http://localhost — done.

Docker Compose

curl -sL https://raw.githubusercontent.com/Kpa-clawbot/CoreScope/master/docker-compose.example.yml \
  -o docker-compose.yml
docker compose up -d

Image Tags

Tag Description
v3.4.1 Pinned release (recommended for production)
v3.4 Latest patch in v3.4.x
v3 Latest minor+patch in v3.x
latest Latest release tag
edge Built from master — unstable, for testing

Configuration

Settings can be overridden via environment variables:

Variable Default Description
DISABLE_CADDY false Skip internal Caddy (set true behind a reverse proxy)
DISABLE_MOSQUITTO false Skip internal MQTT broker (use external)
HTTP_PORT 80 Host port mapping
DATA_DIR ./data Host path for persistent data

For advanced configuration, mount a config.json into /app/data/config.json. See config.example.json in the repo.

Updating

docker compose pull
docker compose up -d

Data

All persistent data lives in /app/data:

  • meshcore.db — SQLite database (packets, nodes)
  • config.json — custom config (optional)
  • theme.json — custom theme (optional)

Backup: cp data/meshcore.db ~/backup/

TLS

Option A — External reverse proxy (recommended): Run with DISABLE_CADDY=true, put nginx/traefik/Cloudflare in front.

Option B — Built-in Caddy: Mount a custom Caddyfile at /etc/caddy/Caddyfile and expose ports 80+443.


Migrating from manage.sh (existing admins)

If you're currently deploying with manage.sh (git clone + local build), you have two options going forward:

Option A: Keep using manage.sh (no changes needed)

manage.sh update continues to work exactly as before — it fetches the latest tag, builds locally, and restarts. Nothing breaks.

./manage.sh update          # latest release
./manage.sh update v3.5.0   # specific version

Pre-built images skip the build step entirely — faster updates, no Go toolchain needed.

One-time migration:

  1. Stop the current deployment:

    ./manage.sh stop
    
  2. Your data is in ~/meshcore-data/ (or whatever PROD_DATA_DIR is set to). It's untouched — the database, config, and theme files persist.

  3. Copy docker-compose.example.yml to where you want to run from:

    cp docker-compose.example.yml ~/docker-compose.yml
    
  4. Start with the pre-built image:

    cd ~ && docker compose up -d
    
  5. Verify it picked up your existing data:

    curl http://localhost/api/stats
    

Updates after migration:

docker compose pull && docker compose up -d

What about manage.sh features?

manage.sh command Pre-built equivalent
./manage.sh update docker compose pull && docker compose up -d
./manage.sh stop docker compose down
./manage.sh start docker compose up -d
./manage.sh logs docker compose logs -f
./manage.sh status docker compose ps
./manage.sh setup Copy docker-compose.example.yml, edit env vars

manage.sh remains available for advanced use cases (building from source, custom patches, development). Pre-built images are recommended for most production deployments.