serman is a local infrastructure manager for development stacks built on Docker Compose. It gives you two interfaces over the same service set:
- a web UI for fast day-to-day service control
- a terminal UI for keyboard-driven workflows
The project manages common local dependencies such as Redis, MySQL, MongoDB, and PostgreSQL, including separate testing variants where needed.
- Starts, stops, restarts, and recreates local services
- Shows live service state, health, and published ports
- Edits service config from the project
.env - Supports both a web UI and a TUI
- Runs the web UI in the background with
start,stop, andstatus - Uses Compose fragments from
services/
Current built-in services:
redismysqlmysql_testingmongopostgrespostgres_testing
Service definitions are declared in internal/serman/services.go.
- cmd/web/main.go: web server and web command entrypoint
- cmd/serman/main.go: terminal UI
- services/: Docker Compose fragments
- web/: Vue frontend
- .env.example: starter environment values
You need:
- Docker
- Docker Compose v2
- Go 1.24+
- Node.js and npm for building the web frontend
- Copy the environment file:
cp .env.example .env- Build the web frontend:
cd web
npm install
npm run build
cd ..- Build the binaries:
GOCACHE=/tmp/go-build-web go build -o serman-web ./cmd/web
GOCACHE=/tmp/go-build-tui go build -o serman-tui ./cmd/serman- Start the web UI in the background:
./serman-web start- Open the UI:
http://localhost:8080
Build the web binary:
GOCACHE=/tmp/go-build-web go build -o serman-web ./cmd/webBuild the TUI binary:
GOCACHE=/tmp/go-build-tui go build -o serman-tui ./cmd/sermanserman-web supports command-style usage:
./serman-web start
./serman-web stop
./serman-web status
./serman-web helpBehavior:
start: runs the web UI in the backgroundstop: stops the running background serverstatus: shows whether it is runninghelp: prints command usage
Runtime files:
- PID file: .serman/serman-web.pid
- Log file: .serman/serman-web.log
If browser auto-open works in your desktop environment, serman-web will try to open http://localhost:8080 automatically.
Run the terminal UI:
./serman-tuiKeyboard shortcuts:
Enter: edit selected service confige: edit selected service configs: start servicet: stop servicer: restart servicef: fresh recreate serviceR: refresh statusq: quit
The web UI currently includes:
- dependency checks for Docker and Compose
- services table with state, health, and ports
- action buttons with state-aware disabling
- search across service name, state, health, and ports
- inline config editor backed by
.env
Configuration lives in .env. If it does not exist, create it from .env.example.
Example:
NAMESPACE=services
REDIS_PORT=6379
REDIS_PASSWORD=password
MYSQL_PORT=3306
MYSQL_DATABASE="${NAMESPACE}-db"
MYSQL_USER="${NAMESPACE}-user"
MYSQL_PASSWORD=password
MYSQL_ROOT_PASSWORD=password
MONGODB_PORT=27017
MONGODB_DATABASE="${NAMESPACE}-db"
MONGODB_USERNAME="${NAMESPACE}-user"
MONGODB_PASSWORD=password
POSTGRES_PORT=5432
POSTGRES_DB="${NAMESPACE}-db"
POSTGRES_USER="${NAMESPACE}-user"
POSTGRES_PASSWORD=passwordImportant:
NAMESPACEmust be set, or Compose names will be invalid- service actions load
.envexplicitly from the repo root - config edits in the web UI and TUI both write back to
.env
This project uses multiple Compose fragments from services/ instead of a single large file.
Examples:
- services/00-base.yaml
- services/redis.yaml
- services/mysql.yaml
- services/mongo.yaml
- services/postgres.yaml
The web and TUI layers assemble these fragments dynamically when calling Docker Compose.
If you want to add extra services without committing them, put additional Compose fragments in services/local/.
- files in
services/remain tracked project defaults - files in
services/local/are loaded automatically byserman services/local/is ignored by git
Example:
services/
00-base.yaml
redis.yaml
local/
mailhog.yaml
Any *.yaml file in services/local/ can define extra services, volumes, or other Compose fragments for your machine only.
fresh is intended for resetting a service and recreating it cleanly.
Behavior:
- stops the service
- removes the service container
- removes declared persistent volumes when relevant
- starts the service again
Testing services are designed to be ephemeral and use tmpfs where appropriate.
Run the web frontend in dev mode:
cd web
npm install
npm run devRun the web backend directly in foreground mode:
go run ./cmd/web serveRun the TUI directly:
go run ./cmd/sermanPostgreSQL 18 images expect data under /var/lib/postgresql, not the old /var/lib/postgresql/data mount layout.
This repo has already been updated for that layout, but if you created volumes with an older version of the service definition, you may need to remove and recreate the old PostgreSQL volume if you do not need the data.
The web binary tries several Linux launchers:
xdg-opengio opensensible-browser
If none of them work in your session, open the URL manually.
If :8080 cannot be bound, the web server will fail to start. This is usually an environment restriction, not an application bug.
Symptom:
Invalid container name (-postgres)
Cause:
.envis missingNAMESPACEis blank
Fix:
cp .env.example .envThen confirm:
grep '^NAMESPACE=' .envSymptom:
data in /var/lib/postgresql/data (unused mount/volume)
Cause:
- old volume layout with newer PostgreSQL image
Fix:
- migrate the data correctly, or
- remove the old volume and recreate the container if the data is disposable
Check:
./serman-web status
cat .serman/serman-web.logThen open:
http://localhost:8080
This project is licensed under the MIT License. See LICENSE.

