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?
Data-Driven Forecasts - Generate delivery predictions using Monte Carlo simulations based on your team’s historical throughput. Know the probability of hitting any given date.
Self-Hosted Privacy - Your delivery data stays on your infrastructure. The entire stack runs in Docker containers on your own servers.
Modern Web Interface - Access forecasts and analytics through an intuitive browser-based dashboard. No desktop software to install.
Production-Ready Architecture - Built with a robust Rust backend, PostgreSQL database, and nginx frontend. Designed for reliability.
Quick Start
Prerequisites
Before continuing, ensure you have completed the following from the main installation guide:
- Git installed and configured
- Docker or Podman installed and running
- 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 shipcastStep 2. Configure Environment
Run the interactive configuration wizard:
# Linux/macOS
./init_shipcast.sh
# Windows
.\init_shipcast.cmdThis 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.cmdThe script authenticates with the container registry, pulls images, and starts all services.
Why
.cmdand not.ps1on Windows? Stock Windows refuses to run.ps1files (running scripts is disabled on this system) and opens them in Notepad when double-clicked. Each.ps1here has a.cmdlauncher beside it that hands the same script to PowerShell with-ExecutionPolicy Bypassfor 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.ps1directly? It works unchanged in a PowerShell window where scripts are allowed (5.1+); if yours blocks them, runpowershell -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--helpand-hare rejected before the script sees them (A parameter cannot be found that matches parameter name '-help'). On Windows ask for help asrun_shipcast.cmd helporrun_shipcast.cmd /?. Every other command is spelled identically on both platforms. This is a property of the PowerShell runner itself, not of the.cmdlauncher — calling the.ps1directly 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.cmdThe wizard guides you through:
- Registry authentication - Enter your GitLab access token
- Container images - Set registry URL and version tag
- Database - Configure credentials (type
generatefor a random password) - Frontend access - Set host binding and port
- Application settings - Configure log level
- Container runtime - Choose Docker or Podman
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:
IMAGE_TAG=test- Uses the test image versionDB_NAME=shipcast_test- Uses a separate database
All other settings are loaded from your .env file.
# Linux/macOS
./run_shipcast_test.sh
# Windows
.\run_shipcast_test.cmdSupports all the same commands as run_shipcast:
./run_shipcast_test.sh logs # View test environment logs
./run_shipcast_test.sh stop # Stop test environmentArchitecture
+------------------+
Port 3456 ----> | Frontend | (nginx)
| /api/* proxy |
+--------+---------+
|
+--------v---------+
| API | (Rust)
+--------+---------+
|
+--------v---------+
| PostgreSQL |
+------------------+
- Frontend - nginx serving the web UI, proxies API requests to the backend
- API - High-performance Rust backend service
- Database - PostgreSQL for persistent storage
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
publicno longer grantsCREATEtoPUBLIC. 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 # WindowsWarning: 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 upThis automatically pulls the latest images before starting.
Switching Versions
List available versions:
./run_shipcast.sh tagsTo use a specific version, either:
Option A: Re-run the init script and enter the desired tag:
./init_shipcast.shOption B: Edit .env directly:
IMAGE_TAG=2026-01-29T12-31-53Z-071c9bcThen 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.comPodman 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 --forceIf pasta is not available, try
slirp4netns:
cat > ~/.config/containers/containers.conf << 'EOF'
[network]
default_rootless_network_cmd = "slirp4netns"
EOF
podman system reset --forceAlternative: Use Docker Desktop on Windows instead of Podman in WSL, as it handles networking differently and avoids these issues.