# Installation > **Target platform**: rustguac is built and tested against **Debian 13 > (Trixie)**. The pre-built `.deb` package and the `install.sh` script > both assume FreeRDP 3.15+ (Debian 13's `freerdp3-dev`). On other Linux > distributions, the recommended path is the Docker image (Option C), > which avoids the FreeRDP ABI issue entirely. See > [Other Linux distributions](#other-linux-distributions) below. ## Option A: Debian package (recommended) Pre-built `.deb` packages are available from the [releases page](https://github.com/sol1/rustguac/releases) for Debian 13 (Trixie) and compatible distributions. ```bash sudo apt install ./rustguac_*.deb ``` Using `apt install` (not `dpkg -i`) ensures all runtime dependencies are resolved automatically. The package installs to `/opt/rustguac` and creates systemd services for both guacd and rustguac. ### Post-install 1. **Create an admin API key:** ```bash /opt/rustguac/bin/rustguac --config /opt/rustguac/config.toml add-admin --name admin ``` Save the printed API key — it is only shown once. 2. **Configure** — edit `/opt/rustguac/config.toml` as needed (see [Configuration](configuration.md)). 3. **Start the services:** ```bash sudo systemctl enable --now rustguac ``` This starts both `rustguac-guacd` (the protocol daemon) and `rustguac` (the web proxy). 4. **(Required for connections) Set up Vault or OpenBao:** The connections page is rustguac's primary user-facing feature. It stores SSH, RDP, VNC, web session, and VDI entries in [HashiCorp Vault](https://www.vaultproject.io/) or [OpenBao](https://openbao.org/) KV v2 — credentials never reach the browser. **Without one of these, the Connections UI is unavailable** and users can only run ad-hoc sessions via the Sessions page or the API. For a single-host install the fastest path is the bundled quickstart helper, which auto-detects vault or bao and provisions everything: ```bash # Against an existing Vault or OpenBao: export VAULT_ADDR=https://vault.example.com:8200 export VAULT_TOKEN=hvs.xxxxxxxx ./contrib/vault-quickstart.sh # Or install Vault locally on this box with on-disk auto-unseal: sudo ./contrib/vault-quickstart.sh --local ``` See [Vault / OpenBao Connections](integrations.md#vault--openbao-connections) for the manual walkthrough, mTLS, multi-instance setup, and the security caveat for `--local` mode. 6. **(Optional) Set up encrypted drive storage:** ```bash sudo /opt/rustguac/bin/drive-setup.sh ``` See [Drive / File Transfer](integrations.md#drive--file-transfer--luks-encryption) for details. 7. **(Optional) Enable VDI desktop containers:** If you want to use VDI sessions (ephemeral Docker desktop containers), install Docker and grant rustguac access: ```bash # Install Docker (if not already installed) curl -fsSL https://get.docker.com | sh # Allow rustguac to manage containers sudo usermod -aG docker rustguac sudo systemctl restart rustguac ``` Then add a `[vdi]` section to your config — see [VDI Desktop Containers](vdi.md) for full setup. ## Option B: Bare-metal install script For fresh Debian 13 systems, the install script builds everything from source: ```bash sudo ./install.sh ``` This performs the following steps: 1. Installs system packages (build tools, Xvnc, Chromium, cryptsetup, etc.) 2. Installs the Rust toolchain (if not present) 3. Clones and builds guacd from [guacamole-server](https://github.com/apache/guacamole-server) source, applying patches automatically 4. Builds rustguac with `cargo build --release` 5. Creates the `rustguac` system user (home: `/home/rustguac`) 6. Generates a self-signed TLS certificate 7. Installs binaries, static files, and config to `/opt/rustguac` 8. Sets up systemd services ### Install flags | Flag | Description | |------|-------------| | `--no-tls` | Skip TLS certificate generation, listen on HTTP port 8089 | | `--hostname=FQDN` | Hostname for the TLS certificate (default: system hostname) | | `--deps-only` | Only install system packages, then exit | | `--no-deps` | Skip apt package installation | ### Installed layout ``` /opt/rustguac/ bin/rustguac # Main binary bin/drive-setup.sh # LUKS drive setup script sbin/guacd # Guacamole protocol daemon lib/ # guacd shared libraries static/ # Web UI files tls/ # TLS certificates data/ # SQLite database recordings/ # Session recordings config.toml # Configuration file env # Environment variables (VAULT_SECRET_ID, etc.) ``` ### Systemd services | Service | Description | |---------|-------------| | `rustguac-guacd` | guacd protocol daemon (TLS, loopback only) | | `rustguac` | rustguac web proxy (depends on guacd) | Both services run as the `rustguac` user and restart on failure. The `rustguac` service loads environment variables from `/opt/rustguac/env` via systemd's `EnvironmentFile` directive. Use this for secrets like `VAULT_SECRET_ID` and `OIDC_CLIENT_SECRET`. ## Option C: Docker Pre-built images are available on [Docker Hub](https://hub.docker.com/r/sol1/rustguac): ```bash docker pull sol1/rustguac:latest docker run -d -p 8089:8089 sol1/rustguac:latest ``` To build from source instead: ```bash docker build -t rustguac . docker run -d -p 8089:8089 rustguac ``` The Docker image: - Uses a multi-stage build (Debian 13 trixie-slim runtime) - Builds guacd from source with patches applied - Generates a self-signed TLS certificate at build time - Enables TLS between rustguac and guacd by default - Exposes HTTP on port 8089 (put a reverse proxy in front for HTTPS) ### API key setup On first run (when no database exists), the container automatically generates an admin API key and prints it to the logs: ```bash docker logs rustguac ``` Save the printed key — it is only shown once. To generate additional keys later: ```bash docker exec rustguac /opt/rustguac/bin/rustguac \ --config /opt/rustguac/config.toml add-admin --name my-admin ``` ### Customizing the configuration To persist config changes across container restarts, bind-mount a local `config.toml` into the container: 1. **Copy the default config** from the image: ```bash docker run --rm --entrypoint cat sol1/rustguac:latest /opt/rustguac/config.toml.default > config.toml ``` 2. **Edit** `config.toml` as needed (see [Configuration](configuration.md)): ```toml # Example: allow SSH to private networks ssh_allowed_networks = ["127.0.0.0/8", "::1/128", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] ``` 3. **Mount it** in your Docker Compose file or `docker run` command (see below). If no config file is mounted, the container uses a built-in default on first start. ### Docker Compose example ```yaml services: rustguac: image: sol1/rustguac:latest ports: - "8089:8089" volumes: - ./config.toml:/opt/rustguac/config.toml - rustguac-data:/opt/rustguac/data - rustguac-recordings:/opt/rustguac/recordings environment: - RUST_LOG=info volumes: rustguac-data: rustguac-recordings: ``` ## Option D: RPM package (build from source) Pre-built RPM packages are not currently provided. An RPM spec file (`rustguac.spec`) and build script (`build-rpm.sh`) are included for Red Hat / Fedora / Rocky Linux based systems. You will need FreeRDP 3.x development headers installed. ```bash # Install build dependencies (example for Rocky/RHEL 9) sudo dnf install -y epel-release sudo dnf config-manager --set-enabled crb sudo dnf install -y gcc gcc-c++ make git autoconf automake libtool \ freerdp-devel cairo-devel libjpeg-turbo-devel libpng-devel libwebp-devel \ libssh2-devel openssl-devel libvncserver-devel pango-devel \ pulseaudio-libs-devel rpm-build # Build the RPM bash build-rpm.sh sudo rpm -i rustguac-*.rpm ``` RPM builds are untested — contributions and feedback are welcome. ## Option E: Development ```bash # Clone guacamole-server alongside rustguac git clone https://github.com/apache/guacamole-server.git ../guacamole-server # Install build deps, build guacd, build + run rustguac ./dev.sh deps ./dev.sh build-guacd ./dev.sh start ``` For development with TLS: ```bash ./dev.sh generate-cert cat > config.local.toml <input->MouseEvent()` etc. with safe FreeRDP 3.x functions 3. **NULL pointer dereference** — FreeRDP 3.x fires PubSub events before `guac_rdp_disp` is allocated 4. **Struct layout mismatch** — channel source files missing `config.h` see wrong field offsets when SSH support is enabled