diff --git a/README.md b/README.md index 5c56e06..957b06c 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,4 @@ See [src/gmux/README.md](src/gmux/README.md) for options and configuration. ## Publishing -Features are published automatically to `ghcr.io/gmuxapp/features/` on push to `main` via the [release workflow](.github/workflows/release.yaml). +Features are published automatically to `ghcr.io/gmuxapp/features/` via the [release workflow](.github/workflows/release.yaml). Trigger it manually from the Actions tab after merging changes to `main`. diff --git a/src/gmux/README.md b/src/gmux/README.md index 2a1e699..244cc8d 100644 --- a/src/gmux/README.md +++ b/src/gmux/README.md @@ -1,6 +1,6 @@ # gmux (ghcr.io/gmuxapp/features/gmux) -Installs [gmux](https://gmux.app) and gmuxd into a dev container. gmuxd starts automatically with a [network listener](https://gmux.app/develop/network-listener) so it's accessible from the host via port forwarding. +Installs [gmux](https://gmux.app) and gmuxd into a dev container. gmuxd starts automatically and listens on all interfaces so it's accessible via port forwarding. ## Usage @@ -13,15 +13,15 @@ Installs [gmux](https://gmux.app) and gmuxd into a dev container. gmuxd starts a } ``` -Port 8791 is automatically forwarded to the host. Open the forwarded URL and authenticate with the bearer token. +Port 8790 is automatically forwarded to the host. Open the forwarded URL and authenticate with the bearer token. ### Finding the auth token ```bash -docker exec gmuxd auth-link +docker exec gmuxd auth ``` -Prints a ready-to-use URL with the token. Open it in a browser to authenticate. +Prints the listen address, auth token, and a ready-to-use login URL. ## Options @@ -29,14 +29,36 @@ Prints a ready-to-use URL with the token. Open it in a browser to authenticate. |--------|------|---------|-------------| | `version` | string | `latest` | gmux version to install (e.g. `0.8.0` or `latest`) | +## Pre-provisioned auth token + +If you need a known token (for scripting, health checks, or future host-side peer discovery), set `GMUXD_TOKEN` in your `devcontainer.json`: + +```json +{ + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ghcr.io/gmuxapp/features/gmux:1": {} + }, + "containerEnv": { + "GMUXD_TOKEN": "output-of-openssl-rand-hex-32" + } +} +``` + +The token must be at least 64 hex characters. On first start, gmuxd writes it to disk. On subsequent starts, the file is verified against the env var. See [Environment variables](https://gmux.app/reference/environment/#auth-token) for details. + ## Security -The network listener uses bearer token authentication. The token is auto-generated on first start and stored inside the container at `~/.local/state/gmux/auth-token`. +The network listener requires bearer token authentication on every request. The token is auto-generated on first start and stored inside the container at `~/.local/state/gmux/auth-token`. Devcontainer-aware tooling (VS Code, Codespaces) forwards the port to `localhost` on the host, so only local processes can reach it. The bearer token provides a second layer of protection on the Docker bridge network. -See [Network Listener](https://gmux.app/develop/network-listener) for the full security model. +See [Security](https://gmux.app/security/) for the full security model. + +## How it works + +The feature sets `GMUXD_LISTEN=0.0.0.0` via `containerEnv` so gmuxd accepts connections from outside the container (required for port forwarding and Docker bridge access). The entrypoint starts gmuxd in the background before running the container's main process. ## Peer discovery -A host gmuxd can automatically discover gmuxd instances running inside dev containers. No additional configuration is needed; the feature's presence in the container's `devcontainer.metadata` label is the discovery signal. See [Peer Discovery & Aggregation](https://gmux.app/planned/peer-discovery-aggregation) for details. +A host gmuxd will be able to automatically discover gmuxd instances running inside dev containers. The feature's presence in the container's `devcontainer.metadata` label is the discovery signal. See [Peer Discovery & Aggregation](https://gmux.app/planned/peer-discovery-aggregation/) for the planned design. diff --git a/src/gmux/devcontainer-feature.json b/src/gmux/devcontainer-feature.json index b5f3248..05120cd 100644 --- a/src/gmux/devcontainer-feature.json +++ b/src/gmux/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gmux", - "version": "1.0.0", + "version": "1.1.0", "name": "gmux", "documentationURL": "https://gmux.app/running-in-docker", "description": "Installs gmux and gmuxd for managing terminal sessions from a browser dashboard.", @@ -11,9 +11,12 @@ "description": "gmux version to install (e.g. '0.8.0' or 'latest')" } }, - "forwardPorts": [8791], + "containerEnv": { + "GMUXD_LISTEN": "0.0.0.0" + }, + "forwardPorts": [8790], "portsAttributes": { - "8791": { + "8790": { "label": "gmux", "onAutoForward": "silent" } diff --git a/src/gmux/install.sh b/src/gmux/install.sh index bd90756..5499d1c 100755 --- a/src/gmux/install.sh +++ b/src/gmux/install.sh @@ -36,24 +36,11 @@ fi echo "gmux ${VERSION} installed successfully" -# Generate config for the network listener. -# Tailscale is intentionally disabled; container gmuxd is accessed -# via port forwarding (browser) or Docker network (peer discovery). -mkdir -p /usr/local/share/gmux -cat > /usr/local/share/gmux/config.toml << EOF -[network] -listen = "0.0.0.0:8791" -EOF - -# Entrypoint: copies config if user hasn't provided their own, starts gmuxd. +# Entrypoint: starts gmuxd in the background if not already running. +# GMUXD_LISTEN is set via containerEnv in devcontainer-feature.json. +# GMUXD_TOKEN can be set via containerEnv in the user's devcontainer.json. cat > /usr/local/bin/gmuxd-start.sh << 'SCRIPT' #!/bin/bash -GMUX_CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/gmux" -if [ ! -f "$GMUX_CONFIG_DIR/config.toml" ]; then - mkdir -p "$GMUX_CONFIG_DIR" - cp /usr/local/share/gmux/config.toml "$GMUX_CONFIG_DIR/config.toml" -fi - if ! curl -fsS http://localhost:8790/ >/dev/null 2>&1; then gmuxd start >/tmp/gmuxd.log 2>&1 & for i in $(seq 1 30); do diff --git a/test/gmux/test.sh b/test/gmux/test.sh index 3972524..c237f65 100755 --- a/test/gmux/test.sh +++ b/test/gmux/test.sh @@ -7,12 +7,11 @@ echo "Testing gmux installation..." command -v gmux || { echo "FAIL: gmux not found"; exit 1; } command -v gmuxd || { echo "FAIL: gmuxd not found"; exit 1; } -# Entrypoint script exists -test -x /usr/local/bin/gmuxd-start.sh || { echo "FAIL: gmuxd-start.sh not found"; exit 1; } +# Entrypoint script exists and is executable +test -x /usr/local/bin/gmuxd-start.sh || { echo "FAIL: gmuxd-start.sh not found or not executable"; exit 1; } -# Default config was generated with network listener -grep -q 'listen = "0.0.0.0:8791"' /usr/local/share/gmux/config.toml \ - || { echo "FAIL: default config missing or wrong"; exit 1; } +# GMUXD_LISTEN is set via containerEnv +test "$GMUXD_LISTEN" = "0.0.0.0" || { echo "FAIL: GMUXD_LISTEN not set (got: '$GMUXD_LISTEN')"; exit 1; } # gmuxd can report its version gmuxd version || { echo "FAIL: gmuxd version failed"; exit 1; }