NigFossil Simple tools for lasting software

NigFossil / Documentation Tool / Carnelian

Documentation Tool / Carnelian

Unified Platform for Document & Fossil Repository Management

Files in the top-level directory from the latest check-in


Carnelian

Personal Fossil repository manager, documentation site, and blog publisher.

Stack: Crystal 1.21.0, Amber 2.0.0-beta.5, SQLite3.

Development

shards install
./script/ci
AMBER_ENV=development ./bin/carnelian

script/ci installs frozen shards, then runs format check, Ameba, specs, and a compile. Any step failure exits non-zero. Individual steps: ./script/ci format, ./script/ci ameba, ./script/ci spec, ./script/ci build.

Health check: GET /health/live

shards build carnelian
./bin/carnelian migrate
AMBER_ENV=development ./bin/carnelian web

Development uses config/environments/development.yml. Specs set AMBER_ENV=test. Production reads host, port, secret, and database URL from environment variables (AMBER_SERVER_*, DATABASE_URL).

docker compose up --build

Only the gateway service publishes a host port (8080). Web, worker, and fossil stay on the internal compose network. The current Fossil supervisor is a process placeholder until the dedicated supervisor task.

Master key (64 hex characters, 32 bytes) is loaded from CARNELIAN_MASTER_KEY, CARNELIAN_MASTER_KEY_FILE, or /run/secrets/carnelian_master_key. Credentials are stored with AES-256-GCM. Logs must pass through Carnelian::LogRedactor so passwords, tokens, and credential URLs are not written.

Application layout follows docs/architecture.md: controllers, views, pipes, models, repositories, services, jobs, integrations, infrastructure, and CLI.

Production Docker deployment

Build the image with the pinned Crystal/Amber inputs and explicit Fossil/Git labels, then create four host-only secret files (mode 0600): a 64-character hex master key, an Amber server secret, a one-time setup token, and an internal health token. Copy docker/compose.prod.env.example to a private env file and change the *_SOURCE paths. Start the production overlay with:

docker compose --env-file docker/compose.prod.env \
  -f docker-compose.yml -f docker-compose.prod.yml up -d

The web container runs carnelian migrate before serving traffic; the worker waits for the web health check. The named carnelian-data volume contains the SQLite database, Fossil repositories, Git mirrors, rendered assets, uploads, and SSH material. Do not remove it during upgrades. Pull a new image, run the same command to recreate services, and keep the master key unchanged so stored credentials remain decryptable. The container creates the volume directories and assigns them to UID/GID 1001 (carnelian); a pre-existing bind mount must be writable by that user.

On first start, open /setup and provide the setup token. Subsequent restarts reuse the volume and skip initialization. To reset the administrator password, run docker compose exec web carnelian admin reset-password; the command reads the new password from the terminal and revokes existing sessions.

Clone

Clone this repository with Fossil:

fossil clone https://1wt.in/dot/carnelian carnelian.fossil