feat: improve docker compose help, config strategy docs, and README
pos-docker-compose: - Rewrote usage() with full config strategy explanation, path layout, three-layer cascade, and quick-start guide - Config show now prints the config file path and inline hints - Config edit creates a commented template and confirms save - Up output clarifies deploy vs start README.md: - Restructured Docker section with compose sub-section - Added three-layer config strategy table - Added config keys reference table - Clearer quick-start flow DEV.md: - Restructured compose section with three-layer cascade diagram - Added path mutability table - Added full config keys reference
This commit is contained in:
@@ -269,39 +269,53 @@ fi
|
|||||||
|
|
||||||
## Docker Compose / ScaleTail
|
## Docker Compose / ScaleTail
|
||||||
|
|
||||||
The installer clones [ScaleTail](https://github.com/tailscale-dev/ScaleTail) templates to `/usr/local/share/linux_post_install/scale-tail/` — 119+ self-hosted services with a Tailscale sidecar pattern.
|
The installer clones [ScaleTail](https://github.com/tailscale-dev/ScaleTail) templates to `/usr/local/share/linux_post_install/scale-tail/` — 119+ self-hosted services with a Tailscale sidecar pattern. Each service gets a `tail-xxxxx.ts.net` URL via `network_mode: service:tailscale`.
|
||||||
|
|
||||||
### Deployed Layout
|
### Config Strategy — Three Layers
|
||||||
|
|
||||||
|
Values cascade from least to most specific:
|
||||||
|
|
||||||
```
|
```
|
||||||
/usr/local/share/linux_post_install/scale-tail/ # Templates (git repo)
|
Template .env (per-service defaults from ScaleTail)
|
||||||
└── services/<name>/
|
↓
|
||||||
├── compose.yaml
|
Global config (~/.config/linux_post_install/compose.env)
|
||||||
└── .env
|
↓
|
||||||
|
Per-service .env (/srv/<service>/.env) — created on first deploy, NEVER overwritten
|
||||||
~/.config/linux_post_install/compose.env # Global defaults
|
|
||||||
|
|
||||||
/srv/<service>/ # Active deployment
|
|
||||||
├── compose.yaml # Refreshed on update (preserves .env)
|
|
||||||
├── .env # Your config — preserved across updates
|
|
||||||
├── config/
|
|
||||||
└── data/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On first `pos docker compose up <service>`:
|
||||||
|
1. Template `.env` is copied to `/srv/<service>/.env`
|
||||||
|
2. Matching keys from global config are filled in
|
||||||
|
3. If `TS_AUTHKEY` is still empty, you're prompted to enter it
|
||||||
|
4. After that, the per-service `.env` is **never touched** — not even by `update`
|
||||||
|
|
||||||
|
### Layout
|
||||||
|
|
||||||
|
| Path | Purpose | Mutability |
|
||||||
|
|------|---------|------------|
|
||||||
|
| `/usr/local/share/linux_post_install/scale-tail/services/<name>/` | ScaleTail templates (git repo) | Read-only |
|
||||||
|
| `~/.config/linux_post_install/compose.env` | Your global defaults | Edit via `config set` or `config edit` |
|
||||||
|
| `/srv/<service>/` | Active deployment | Per-service `.env` preserved forever |
|
||||||
|
|
||||||
### Key Commands
|
### Key Commands
|
||||||
|
|
||||||
| Command | Behaviour |
|
| Command | Behaviour |
|
||||||
|---------|-----------|
|
|---------|-----------|
|
||||||
| `pos docker compose up <service>` | Deploys to `$SERVICES_BASE/<service>/`, creates `config/` + `data/`, generates `.env` |
|
| `pos docker compose up <service>` | Deploys to `$SERVICES_BASE/<service>/`, creates `config/` + `data/`, generates `.env` from global defaults |
|
||||||
| `pos docker compose down <service>` | Stops the stack |
|
| `pos docker compose down <service>` | Stops the stack |
|
||||||
| `pos docker compose update` | `git pull` templates + refreshes `compose.yaml` for all deployed services |
|
| `pos docker compose update` | `git pull` templates + refreshes `compose.yaml` for all deployed services (`.env` untouched) |
|
||||||
| `pos docker compose config set K=V` | Sets global default in `~/.config/linux_post_install/compose.env` |
|
| `pos docker compose config set K=V` | Sets a global default in `~/.config/linux_post_install/compose.env` |
|
||||||
|
| `pos docker compose config show` | Displays current global config and `SERVICES_BASE` |
|
||||||
|
| `pos docker compose config edit` | Opens global config in `$EDITOR` |
|
||||||
|
|
||||||
### .env Design
|
### Global Config Keys
|
||||||
|
|
||||||
- **Global config**: `~/.config/linux_post_install/compose.env` — one place for `TS_AUTHKEY`, `TZ`, `DNS_SERVER`, `SERVICES_BASE`
|
| Key | Required | Default | Purpose |
|
||||||
- **Per-service**: `<SERVICES_BASE>/<service>/.env` — generated from template, filled from global config
|
|-----|----------|---------|---------|
|
||||||
- **Updates**: `compose.yaml` refreshes from template but `.env` is never overwritten
|
| `TS_AUTHKEY` | Yes | — | Tailscale auth key for sidecar networking |
|
||||||
|
| `TZ` | No | `Europe/Amsterdam` | Timezone for services |
|
||||||
|
| `DNS_SERVER` | No | `9.9.9.9` | Custom DNS server |
|
||||||
|
| `SERVICES_BASE` | No | `/srv` | Root directory for all deployments |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -76,23 +76,63 @@ pos network scan 192.168.8.0/24 # Fast parallel ping sweep
|
|||||||
```bash
|
```bash
|
||||||
pos docker ps # List containers with health, IPs, ports
|
pos docker ps # List containers with health, IPs, ports
|
||||||
pos docker health # Health dashboard (exits 1 if unhealthy)
|
pos docker health # Health dashboard (exits 1 if unhealthy)
|
||||||
pos docker compose ls # List 119+ available services
|
|
||||||
pos docker compose up jellyfin # Deploy with Tailscale HTTPS
|
|
||||||
pos docker compose down actual-budget # Stop a stack
|
|
||||||
pos docker compose logs home-assistant -f # Tail logs
|
|
||||||
pos docker compose update # Pull latest templates
|
|
||||||
pos docker compose config set TS_AUTHKEY=x # Set global defaults
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**First run with compose:**
|
#### Compose (ScaleTail — 119+ self-hosted services)
|
||||||
|
|
||||||
|
Each service runs with a Tailscale sidecar and gets its own `tail-xxxxx.ts.net` URL.
|
||||||
|
|
||||||
|
**Quick start:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# 1. Set your Tailscale auth key (required once)
|
||||||
pos docker compose config set TS_AUTHKEY=tskey-auth-xxxxx
|
pos docker compose config set TS_AUTHKEY=tskey-auth-xxxxx
|
||||||
|
|
||||||
|
# 2. Deploy a service
|
||||||
pos docker compose up jellyfin
|
pos docker compose up jellyfin
|
||||||
# Open https://jellyfin.tail-xxxxx.ts.net
|
|
||||||
|
# 3. Open https://jellyfin.tail-xxxxx.ts.net
|
||||||
```
|
```
|
||||||
|
|
||||||
Services are deployed to `/srv/<service>/` by default.
|
**All commands:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pos docker compose ls # List available service templates
|
||||||
|
pos docker compose installed # List deployed services
|
||||||
|
pos docker compose up jellyfin # Deploy or start a service
|
||||||
|
pos docker compose down actual-budget # Stop a service
|
||||||
|
pos docker compose logs home-assistant -f # Tail logs
|
||||||
|
pos docker compose restart home-assistant # Restart a service
|
||||||
|
pos docker compose update # Pull latest templates + refresh deployed compose files
|
||||||
|
pos docker compose config # Show current configuration
|
||||||
|
pos docker compose config set TZ=Asia/Tokyo # Set a global default
|
||||||
|
pos docker compose config edit # Open config in editor
|
||||||
|
```
|
||||||
|
|
||||||
|
**Config strategy — three layers:**
|
||||||
|
|
||||||
|
| Layer | File | Purpose |
|
||||||
|
|-------|------|---------|
|
||||||
|
| Template defaults | `/usr/local/share/linux_post_install/scale-tail/services/<name>/.env` | Per-service defaults from ScaleTail |
|
||||||
|
| Global config | `~/.config/linux_post_install/compose.env` | Your defaults — applies to all services |
|
||||||
|
| Per-service | `/srv/<service>/.env` | Actual config — created on first deploy, **never overwritten** |
|
||||||
|
|
||||||
|
Set global defaults once, then every `up` fills them into the new service's `.env`.
|
||||||
|
|
||||||
|
**Paths:**
|
||||||
|
|
||||||
|
- Templates: `/usr/local/share/linux_post_install/scale-tail/services/`
|
||||||
|
- Deployments: `/srv/<service>/` (configurable via `SERVICES_BASE`)
|
||||||
|
- Global config: `~/.config/linux_post_install/compose.env`
|
||||||
|
|
||||||
|
**Config keys:**
|
||||||
|
|
||||||
|
| Key | What it does |
|
||||||
|
|-----|-------------|
|
||||||
|
| `TS_AUTHKEY` | Tailscale auth key (required for sidecar networking) |
|
||||||
|
| `TZ` | Timezone for the service |
|
||||||
|
| `DNS_SERVER` | Custom DNS server |
|
||||||
|
| `SERVICES_BASE` | Where services are deployed (default: `/srv`)
|
||||||
|
|
||||||
### VBox (disposable Docker containers)
|
### VBox (disposable Docker containers)
|
||||||
|
|
||||||
|
|||||||
+62
-20
@@ -7,24 +7,60 @@ CONFIG_ENV="${HOME}/.config/linux_post_install/compose.env"
|
|||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage:
|
Usage: pos docker compose <command> [args]
|
||||||
pos docker compose ls List available ScaleTail services
|
|
||||||
pos docker compose installed List deployed services
|
Commands:
|
||||||
pos docker compose up <service> Deploy a service
|
ls List all available ScaleTail service templates
|
||||||
pos docker compose down <service> Stop a service
|
installed List services already deployed on this machine
|
||||||
pos docker compose restart <service> Restart a service
|
up <service> Deploy or start a service
|
||||||
pos docker compose logs <service> [-f] View service logs
|
down <service> Stop and remove a deployed service
|
||||||
pos docker compose update Pull latest ScaleTail + refresh compose files
|
restart <service> Restart a running service
|
||||||
pos docker compose config Show global config
|
logs <service> [-f] View logs (use -f to follow)
|
||||||
pos docker compose config set KEY=VALUE Set a global config value
|
update Pull latest ScaleTail templates + refresh all deployed compose files
|
||||||
pos docker compose config edit Open global config in editor
|
config Show current global configuration
|
||||||
-h, --help Show this help
|
config set KEY=VALUE Set a global default (e.g. TS_AUTHKEY, TZ, SERVICES_BASE)
|
||||||
|
config edit Open global config in your editor (\$EDITOR)
|
||||||
|
|
||||||
|
─── Config Strategy ──────────────────────────────────────────
|
||||||
|
|
||||||
|
Three layers — each overrides the one above:
|
||||||
|
|
||||||
|
1. Template defaults
|
||||||
|
/usr/local/share/linux_post_install/scale-tail/services/<name>/.env
|
||||||
|
|
||||||
|
2. Global config (your defaults — set once, applies to all services)
|
||||||
|
~/.config/linux_post_install/compose.env
|
||||||
|
Keys: TS_AUTHKEY | TZ | DNS_SERVER | SERVICES_BASE
|
||||||
|
|
||||||
|
3. Per-service config (created on first deploy, preserved forever)
|
||||||
|
/srv/<service>/.env (or \$SERVICES_BASE/<service>/.env)
|
||||||
|
|
||||||
|
On first "up", the service .env is generated from the template
|
||||||
|
and filled with values from your global config. After that, the
|
||||||
|
per-service .env is never overwritten — even by "update".
|
||||||
|
|
||||||
|
─── Paths ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
Templates: /usr/local/share/linux_post_install/scale-tail/services/
|
||||||
|
Deployments: \$SERVICES_BASE/<service>/ (default: /srv/<service>/)
|
||||||
|
Global conf: ~/.config/linux_post_install/compose.env
|
||||||
|
|
||||||
|
─── Quick Start ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
1. Set your Tailscale auth key (required):
|
||||||
|
pos docker compose config set TS_AUTHKEY=tskey-auth-xxxxx
|
||||||
|
|
||||||
|
2. Deploy a service:
|
||||||
|
pos docker compose up jellyfin
|
||||||
|
|
||||||
|
3. Open https://jellyfin.tail-xxxxx.ts.net
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
pos docker compose up jellyfin
|
pos docker compose up jellyfin
|
||||||
pos docker compose down actual-budget
|
pos docker compose down actual-budget
|
||||||
pos docker compose logs home-assistant -f
|
pos docker compose logs home-assistant -f
|
||||||
pos docker compose config set TS_AUTHKEY=tskey-auth-xxxxx
|
pos docker compose config set TZ=Asia/Tokyo
|
||||||
|
pos docker compose config set SERVICES_BASE=/data
|
||||||
EOF
|
EOF
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
@@ -122,7 +158,7 @@ cmd_up() {
|
|||||||
target=$(service_dir "$svc")
|
target=$(service_dir "$svc")
|
||||||
|
|
||||||
if [ ! -d "$target" ]; then
|
if [ ! -d "$target" ]; then
|
||||||
log "Creating $svc at $target"
|
log "Deploying $svc to $target"
|
||||||
mkdir -p "$target/config" "$target/data"
|
mkdir -p "$target/config" "$target/data"
|
||||||
if [ -f "$SCALE_DIR/$svc/compose.yaml" ]; then
|
if [ -f "$SCALE_DIR/$svc/compose.yaml" ]; then
|
||||||
cp "$SCALE_DIR/$svc/compose.yaml" "$target/"
|
cp "$SCALE_DIR/$svc/compose.yaml" "$target/"
|
||||||
@@ -249,16 +285,17 @@ cmd_config() {
|
|||||||
case "$action" in
|
case "$action" in
|
||||||
show)
|
show)
|
||||||
load_global_config
|
load_global_config
|
||||||
|
echo "${CYAN}Global compose config${RESET}"
|
||||||
|
echo "${DIM}File: $CONFIG_ENV${RESET}"
|
||||||
|
echo "${BLUE}────────────────────────────────────────${RESET}"
|
||||||
if [ -f "$CONFIG_ENV" ]; then
|
if [ -f "$CONFIG_ENV" ]; then
|
||||||
echo "${CYAN}Global compose config:${RESET}"
|
|
||||||
echo "${BLUE}────────────────────────────────────────${RESET}"
|
|
||||||
cat "$CONFIG_ENV"
|
cat "$CONFIG_ENV"
|
||||||
echo "${BLUE}────────────────────────────────────────${RESET}"
|
|
||||||
echo "SERVICES_BASE=$SERVICES_BASE"
|
|
||||||
else
|
else
|
||||||
warn "No config file found at $CONFIG_ENV"
|
echo "(no global config set — using defaults)"
|
||||||
echo "Default SERVICES_BASE=/srv"
|
|
||||||
fi
|
fi
|
||||||
|
echo "${BLUE}────────────────────────────────────────${RESET}"
|
||||||
|
echo "SERVICES_BASE=$SERVICES_BASE (deployment directory)"
|
||||||
|
echo "${DIM}Set with: pos docker compose config set SERVICES_BASE=/srv${RESET}"
|
||||||
;;
|
;;
|
||||||
set)
|
set)
|
||||||
local pair="${1:-}"
|
local pair="${1:-}"
|
||||||
@@ -277,13 +314,18 @@ cmd_config() {
|
|||||||
mkdir -p "$(dirname "$CONFIG_ENV")"
|
mkdir -p "$(dirname "$CONFIG_ENV")"
|
||||||
if [ ! -f "$CONFIG_ENV" ]; then
|
if [ ! -f "$CONFIG_ENV" ]; then
|
||||||
cat > "$CONFIG_ENV" <<-EOF
|
cat > "$CONFIG_ENV" <<-EOF
|
||||||
|
# Linux_post_install — global Docker Compose config
|
||||||
|
# Each key is optional; empty values prompt on first deploy.
|
||||||
TS_AUTHKEY=
|
TS_AUTHKEY=
|
||||||
TZ=Europe/Amsterdam
|
TZ=Europe/Amsterdam
|
||||||
DNS_SERVER=9.9.9.9
|
DNS_SERVER=9.9.9.9
|
||||||
SERVICES_BASE=/srv
|
SERVICES_BASE=/srv
|
||||||
EOF
|
EOF
|
||||||
|
log "Created default config at $CONFIG_ENV"
|
||||||
fi
|
fi
|
||||||
|
log "Opening $CONFIG_ENV in ${EDITOR:-nano}..."
|
||||||
"${EDITOR:-nano}" "$CONFIG_ENV"
|
"${EDITOR:-nano}" "$CONFIG_ENV"
|
||||||
|
log "Config saved"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
usage
|
usage
|
||||||
|
|||||||
Reference in New Issue
Block a user