diff --git a/.env.example b/.env.example index e1ffdd0..80f39c7 100644 --- a/.env.example +++ b/.env.example @@ -11,6 +11,10 @@ API_PORT=8082 POSTGRES_PORT=5432 REDIS_PORT=6379 +# Image tag to pull from GHCR (e.g. latest, 0.1.1). Use CONTAINR_BUILD=1 +# with install.sh to build from source instead. +CONTAINR_VERSION=latest + # Database Configuration POSTGRES_DB=containr POSTGRES_USER=containr_user diff --git a/README.md b/README.md index fcf6168..172260b 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@

Quick Start • + Screenshots • Features • Architecture • Guides • @@ -34,6 +35,16 @@ The UI is inspired by Railway's project canvas: services appear as nodes, connections are inferred automatically, and everything — logs, metrics, deployments, builds — is one click away. +## Screenshots + +| Projects dashboard | Project canvas | +| --- | --- | +| ![Projects dashboard with host telemetry](docs/screenshots/dashboard.png) | ![Visual service canvas with two services](docs/screenshots/canvas.png) | + +| Service detail | Managed databases | +| --- | --- | +| ![Service view with metrics, logs and config tabs](docs/screenshots/service-detail.png) | ![Managed database list showing a running PostgreSQL](docs/screenshots/databases.png) | + ## Features - **Project canvas** — visual service topology with groups, drag/drop layout, @@ -84,8 +95,10 @@ cd Containr ``` The script creates `.env` from `.env.example`, fills in all required secrets -with random values, builds the images, and starts the stack. It keeps an -existing `.env` untouched, so it is safe to re-run. +with random values, pulls the published `:latest` images from GHCR, and +starts the stack. It keeps an existing `.env` untouched, so it is safe to +re-run. Set `CONTAINR_BUILD=1` to build from source instead, or +`CONTAINR_VERSION` in `.env` to pin a release tag (e.g. `0.1.1`). Frontend at `http://localhost:3000`, API at `http://localhost:8082`. @@ -93,11 +106,13 @@ Frontend at `http://localhost:3000`, API at `http://localhost:8082`. ```bash cp .env.example .env # fill in secrets -docker compose up -d --build +docker compose up -d # pulls ghcr.io/dvorinka/containr-*:latest ``` -Host ports can be remapped in `.env` (`HTTP_PORT`, `API_PORT`, -`POSTGRES_PORT`, `REDIS_PORT`) if the defaults collide with other services. +Compose pulls the published images by default; run `docker compose up -d +--build` to build from source. Host ports can be remapped in `.env` +(`HTTP_PORT`, `API_PORT`, `POSTGRES_PORT`, `REDIS_PORT`) if the defaults +collide with other services. ### Local development diff --git a/docker-compose.yml b/docker-compose.yml index 87f7de4..d7fb2dd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,6 +33,8 @@ services: restart: unless-stopped backend: + image: ghcr.io/dvorinka/containr-backend:${CONTAINR_VERSION:-latest} + pull_policy: missing build: context: ./app/backend dockerfile: Dockerfile @@ -94,6 +96,8 @@ services: start_period: 30s frontend: + image: ghcr.io/dvorinka/containr-frontend:${CONTAINR_VERSION:-latest} + pull_policy: missing build: context: ./app/frontend dockerfile: Dockerfile diff --git a/docs/screenshots/canvas.png b/docs/screenshots/canvas.png new file mode 100644 index 0000000..ab2e1d5 Binary files /dev/null and b/docs/screenshots/canvas.png differ diff --git a/docs/screenshots/dashboard.png b/docs/screenshots/dashboard.png new file mode 100644 index 0000000..da4e0b2 Binary files /dev/null and b/docs/screenshots/dashboard.png differ diff --git a/docs/screenshots/databases.png b/docs/screenshots/databases.png new file mode 100644 index 0000000..8365dd9 Binary files /dev/null and b/docs/screenshots/databases.png differ diff --git a/docs/screenshots/service-detail.png b/docs/screenshots/service-detail.png new file mode 100644 index 0000000..b4a3aa2 Binary files /dev/null and b/docs/screenshots/service-detail.png differ diff --git a/install.sh b/install.sh index d0b85df..b643ab2 100755 --- a/install.sh +++ b/install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash -# Containr one-shot installer: creates .env with generated secrets, builds -# images, boots the stack, and waits for the API to report healthy. +# Containr one-shot installer: creates .env with generated secrets, pulls the +# published images (or builds from source), boots the stack, and waits for +# the API to report healthy. set -euo pipefail cd "$(dirname "$0")" @@ -45,9 +46,18 @@ fi HTTP_PORT="${HTTP_PORT:-3000}" API_PORT="${API_PORT:-8082}" -# Build and boot -info "Building images and starting the stack..." -docker compose up -d --build +# Boot: pull published :latest images by default (CONTAINR_VERSION pins a +# release). Build from source instead with CONTAINR_BUILD=1, or as fallback +# when the registry is unreachable. +if [[ "${CONTAINR_BUILD:-}" == "1" ]]; then + info "CONTAINR_BUILD=1 - building images from source..." + docker compose build +elif ! docker compose pull; then + info "Image pull failed - building from source instead..." + docker compose build +fi +info "Starting the stack..." +docker compose up -d # Wait for the API info "Waiting for the API on http://localhost:${API_PORT}/health ..."