LocalLabStack is a local-first Docker Compose stack manager. It organizes local applications, a shared Caddy gateway, local HTTPS certificates, Docker networks, and hosts entries under a predictable .locallab workspace.
The CLI command is:
llstk- It does not replace Docker Compose.
- It is not a production orchestrator.
- It does not manage remote servers.
- It does not hide all generated files from users.
- It is not a Kubernetes abstraction.
- It is not a full secret manager.
From this repository:
cargo run --bin llstk -- --helpAfter building:
cargo build
./target/debug/llstk --helpFrom an empty directory:
llstk init
llstk app create gitea --template gitea-postgres
llstk gateway render
llstk hosts planThis creates:
.locallab/
docker-compose.yml
llstk.yml
gateway/
Caddyfile
data/
config/
certs/
ca/
issued/
lab-app-gitea/
docker-compose.yml
.env
llstk.yml
data/
gitea/
postgres/
config/
Root manifest:
version: 1
name: default
root: ./.locallab
network:
global: locallabstack-global
gateway:
provider: caddy
container: locallabstack-gateway
http_port: 80
https_port: 443
cert:
provider: mkcert
domains:
- locallab
hosts:
enabled: true
ip: 127.0.0.1App manifest:
version: 1
name: gitea
domain: gitea.locallab
upstreams:
web:
container: gitea
port: 3000
public: true
endpoints:
- label: web page
uri: https://gitea.locallab
type: web
- label: ssh access
uri: git@gitea.locallab:2222
type: sshllstk gateway render scans .locallab/lab-app-*/llstk.yml and writes .locallab/gateway/Caddyfile.
llstk hosts plan prints planned hosts records without writing /etc/hosts.
llstk hosts sync --dry-run previews the managed block. llstk hosts sync --yes writes only the block between:
# BEGIN LocalLabStack
# END LocalLabStack
The tool does not call sudo for you.
The first certificate provider is mkcert.
llstk cert init
llstk cert issue
llstk cert statusPrivate keys are written under .locallab/certs/issued/ and must not be committed.
llstk cert issue signs the root configured names such as locallab or *.locallab, plus the explicit domains from created app manifests such as gitea.locallab. Some browsers can reject second-level wildcard names like *.locallab, so explicit app domains are included as well.
llstk init
llstk status
llstk doctor
llstk app create <name> --template <template>
llstk app list
llstk app show <name>
llstk app up <name>
llstk app down <name>
llstk app restart <name>
llstk app logs <name>
llstk app remove <name>
llstk app import-compose <path> --name <name>
llstk app migrate-gitea
llstk stack up
llstk stack down
llstk stack restart
llstk stack logs
llstk stack status
llstk gateway up
llstk gateway down
llstk gateway restart
llstk gateway logs
llstk gateway render
llstk gateway reload
llstk gateway status
llstk cert init
llstk cert issue
llstk cert status
llstk hosts plan
llstk hosts status
llstk hosts sync
llstk template list
llstk template show <name>Docker and mkcert commands require those tools to be installed locally.
tmpdir="$(mktemp -d)"
cd "$tmpdir"
llstk init
llstk app create gitea --template gitea-postgres
llstk gateway render
llstk hosts plan
llstk doctorIf Docker is available:
llstk stack up --render
llstk stack logs --tail 50
llstk stack downFor gateway-only debugging:
llstk gateway render
llstk gateway up
llstk gateway logs --tail 50
llstk gateway downFor app-only debugging:
llstk app up gitea
llstk app logs gitea --tail 50
llstk app down giteaIf mkcert is available:
llstk cert init
llstk cert issue
llstk cert status- If
llstk doctorreports Docker errors, checkdocker compose version. - If hosts sync fails, rerun with a writable
--hosts-filefor testing or use appropriate permissions for/etc/hosts. - If Caddy cannot find certificates, run
llstk cert issueor inspect.locallab/certs/issued/. - If an app already exists, inspect
.locallab/lab-app-<name>/before using--force.