Flow Metrics

Shipcast

Forecast delivery dates with confidence. Make promises you can keep.

Shipcast is a self-hosted forecasting and analytics service that brings Monte Carlo simulations to your delivery pipeline. Stop guessing when work will be done. Start showing stakeholders probabilistic forecasts backed by your team’s actual performance data.


Why Shipcast?


Quick Start

Prerequisites

Before continuing, ensure you have completed the following from the main installation guide:

  1. Git installed and configured
  2. Docker or Podman installed and running
  3. Repository cloned via git clone

If you haven’t completed these steps, return to the main page and follow the Requirements and Getting Started sections first.

Step 1. Navigate to Shipcast Directory

cd shipcast

Step 2. Configure Environment

Run the interactive configuration wizard:

# Linux/macOS
./init_shipcast.sh

# Windows
.\init_shipcast.cmd

This guides you through all settings. Type generate when prompted for password to create a secure random one.

Alternative (manual setup): Copy .env.example to .env and edit manually.

Step 3. Start Services

# Linux/macOS
./run_shipcast.sh

# Windows
.\run_shipcast.cmd

The script authenticates with the container registry, pulls images, and starts all services.

Why .cmd and not .ps1 on Windows? Stock Windows refuses to run .ps1 files (running scripts is disabled on this system) and opens them in Notepad when double-clicked. Each .ps1 here has a .cmd launcher beside it that hands the same script to PowerShell with -ExecutionPolicy Bypass for that launch only — it changes no setting on your machine, and it forwards whatever command you pass. So you never have to touch execution policy, and the commands match the Linux and macOS ones (with one exception, --help, noted under Scripts Reference). Prefer the .ps1 directly? It works unchanged in a PowerShell window where scripts are allowed (5.1+); if yours blocks them, run powershell -ExecutionPolicy Bypass -File .\run_shipcast.ps1 [command], or ask your IT administrator to relax the policy.

Step 4. Access the Application

Open your browser to: http://localhost:3456

(Or the port you configured in FRONTEND_PORT)


Scripts Reference

Shipcast provides scripts for setup and operation:

Purpose Linux/macOS Windows
Interactive configuration wizard init_shipcast.sh init_shipcast.cmd
Service management (start, stop, logs, etc.) run_shipcast.sh run_shipcast.cmd
Run with test image and separate database run_shipcast_test.sh run_shipcast_test.cmd

Each Windows .cmd is a one-line launcher for the .ps1 of the same name, so no execution-policy change is needed and the commands are the same on every platform. The .ps1 scripts remain callable directly on PowerShell 5.1+ where policy allows it.

One spelling differs. PowerShell reads a leading -- as a parameter name, so --help and -h are rejected before the script sees them (A parameter cannot be found that matches parameter name '-help'). On Windows ask for help as run_shipcast.cmd help or run_shipcast.cmd /?. Every other command is spelled identically on both platforms. This is a property of the PowerShell runner itself, not of the .cmd launcher — calling the .ps1 directly behaves the same way.

init_shipcast - Configuration Wizard

Run once to create or update your .env configuration file.

# Linux/macOS
./init_shipcast.sh

# Windows
.\init_shipcast.cmd

The wizard guides you through:

Press Enter to keep existing values when updating configuration.

run_shipcast - Service Management

Manage the Shipcast containers after configuration.

# Linux/macOS
./run_shipcast.sh [command]

# Windows
.\run_shipcast.cmd [command]
Command Description
(none) / up Start services (or reload if already running)
down / stop Stop all services (with confirmation)
status Show status of all containers
logs View and follow service logs
pull Pull latest images without starting
tags/versions List available image versions from registry
clean Stop services and delete all data (with confirmation)
help / /? Show help message (also --help / -h on Linux and macOS only)

Examples:

./run_shipcast.sh              # Start or reload services
./run_shipcast.sh logs         # Watch live logs (Ctrl+C to exit)
./run_shipcast.sh status       # Check if services are running
./run_shipcast.sh tags         # See available versions
./run_shipcast.sh stop         # Stop services (asks for confirmation)

run_shipcast_test - Test Environment

Wrapper script that runs Shipcast with:

All other settings are loaded from your .env file.

# Linux/macOS
./run_shipcast_test.sh

# Windows
.\run_shipcast_test.cmd

Supports all the same commands as run_shipcast:

./run_shipcast_test.sh logs    # View test environment logs
./run_shipcast_test.sh stop    # Stop test environment

Architecture

                    +------------------+
    Port 3456 ----> |    Frontend      | (nginx)
                    |  /api/* proxy    |
                    +--------+---------+
                             |
                    +--------v---------+
                    |       API        | (Rust)
                    +--------+---------+
                             |
                    +--------v---------+
                    |    PostgreSQL    |
                    +------------------+

Only the frontend port is exposed to the host. All internal communication happens on an isolated Docker network.


Database Prerequisites

Shipcast does not create its database. It never issues CREATE DATABASE, CREATE ROLE, or CREATE EXTENSION — at startup it verifies its preconditions and, if any is unmet, exits with a message naming the failed precondition and the exact SQL to fix it (see Startup failures below).

With the bundled stack (the default), provisioning is handled for you: the db service creates the database named by DB_NAME when it first boots on an empty data volume. Nothing to do — but read Renaming the database before ever changing DB_NAME.

With an external or managed PostgreSQL (Amazon RDS, Azure Database, a shared corporate cluster), provisioning is your job. Shipcast requires:

Requirement Detail
PostgreSQL 13 or newer Tables default their ids to gen_random_uuid(), core-builtin from 13. Tested against 18.
The database already exists Named by DB_NAME. Shipcast will not create it.
A role that can authenticate With CONNECT on that database.
USAGE + CREATE on public See the PostgreSQL 15 note below.
Nothing else No CREATEDB, CREATEROLE, superuser, or CREATE EXTENSION. Do not hand Shipcast a superuser “to be safe”.

Minimal provisioning, as a cluster administrator:

CREATE ROLE shipcast WITH LOGIN PASSWORD 'change-me';
CREATE DATABASE shipcast OWNER shipcast;

PostgreSQL 15+ note. Since version 15, schema public no longer grants CREATE to PUBLIC. A role that owns the database (as in the recipe above) has the required privileges implicitly. A role that does not own it — common on shared clusters and some managed providers — needs an explicit grant:

GRANT USAGE, CREATE ON SCHEMA public TO "shipcast";

To point the stack at an external server, edit the DATABASE_URL value in docker-compose.yml’s api service (the shipped value is fixed to the internal db container) and remove or ignore the db service.

Shipcast’s side of the contract: it owns the schema via forward-only migrations, run automatically at startup. It is the sole writer — do not hand-edit the schema, and do not share the database with another application.

Startup failures

Startup failures name the precondition they violated:

Startup message begins with Failed precondition Remediation
Cannot reach the PostgreSQL … Server unreachable Check host/port/firewall; pg_isready -h HOST -p PORT
Authentication failed for … Bad credentials Verify DB_USER / DB_PASSWORD; check the role exists (\du)
Database "…" does not exist … Database not provisioned CREATE DATABASE dbname OWNER username; — or fix a DB_NAME typo
Role "…" lacks the privileges … Missing CREATE on schema public GRANT USAGE, CREATE ON SCHEMA public TO "role";
Migration of database "…" failed Migration state, not connectivity Contact support — do not hand-edit the schema

The authoritative version of this contract lives in the Shipcast source repository (docs/database-setup.md, access provided with your license).


Configuration Reference

All variables are required. Run ./init_shipcast.sh (or .\init_shipcast.cmd on Windows) for guided setup. You can re-run it anytime to update settings.

Variable Example Value Description
ACCESS_TOKEN glpat-xxxxxxxxxxxx GitLab registry access token (provided with license)
REGISTRY_URL registry.gitlab.com/tomasz-feliksik/flow-metrics-base Container registry URL
IMAGE_TAG latest Version tag for container images
DB_USER postgres Database username
DB_PASSWORD (your secure password) Database password (type generate in init script)
DB_NAME shipcast Database name
FRONTEND_HOST 127.0.0.1 Bind address (0.0.0.0 for network access)
FRONTEND_PORT 3456 Port to access the web UI
RUST_LOG info API log level (error/warn/info/debug/trace)
CONTAINER_RUNTIME docker Container runtime (docker or podman)

Data Persistence

Database data is stored in a Docker volume named fmb-shipcast-db-data. This persists across container restarts.

To completely reset the database (requires confirmation):

./run_shipcast.sh clean      # Linux/macOS
.\run_shipcast.cmd clean     # Windows

Warning: This permanently deletes all data.

Renaming the Database

The db service creates the database named by DB_NAME only on first boot, when the data volume is empty. Changing DB_NAME in .env after the volume exists does not create the new database — Shipcast fails fast at startup with Database "X" does not exist, plus the CREATE DATABASE statement that would fix it. (Older versions silently started a fresh empty database instead, which looked like total data loss.)

To rename, either create the new database yourself inside the running db container:

docker exec -it fmb-shipcast-db psql -U $DB_USER -c 'CREATE DATABASE "newname" OWNER "youruser";'

or start over from a clean volume with ./run_shipcast.sh clean (deletes all data).


Updating

To update to the latest version, simply restart the services:

./run_shipcast.sh up

This automatically pulls the latest images before starting.

Switching Versions

List available versions:

./run_shipcast.sh tags

To use a specific version, either:

Option A: Re-run the init script and enter the desired tag:

./init_shipcast.sh

Option B: Edit .env directly:

IMAGE_TAG=2026-01-29T12-31-53Z-071c9bc

Then restart: ./run_shipcast.sh up


Troubleshooting

Issue Solution
Cannot pull images Verify ACCESS_TOKEN in .env has read_registry scope
Services not starting Check Docker is running with docker info, then view logs with ./run_shipcast.sh logs
Port already in use Change FRONTEND_PORT in .env to an available port
Database connection issues Ensure database container is healthy with ./run_shipcast.sh status
Database "…" does not exist at startup See Database Prerequisites — likely a DB_NAME change after first boot, or an unprovisioned external database

For manual registry login troubleshooting:

docker login registry.gitlab.com

Podman Network Errors (WSL / Corporate Environments)

If you see errors like netavark: nftables error or Could not process rule: No such file or directory, this is typically caused by restricted network/firewall access in WSL or corporate environments.

Solution: Switch Podman to use pasta or slirp4netns networking:

mkdir -p ~/.config/containers
cat > ~/.config/containers/containers.conf << 'EOF'
[network]
default_rootless_network_cmd = "pasta"
EOF

podman system reset --force

If pasta is not available, try slirp4netns:

cat > ~/.config/containers/containers.conf << 'EOF'
[network]
default_rootless_network_cmd = "slirp4netns"
EOF

podman system reset --force

Alternative: Use Docker Desktop on Windows instead of Podman in WSL, as it handles networking differently and avoids these issues.