# rustbox-package-builder Linux-only package builder and signed repository publisher for RustBox. It watches the RustBox source repository, builds release binaries, produces distribution-specific packages, signs repository metadata, and serves a small read-only repository dashboard. ## Supported Linux families A single RustBox source commit is published for `amd64/x86_64` in three equal Linux families: - Debian / Ubuntu: DEB package and signed APT repository - RHEL / AlmaLinux / Rocky Linux: RPM package and signed DNF/YUM repository - SUSE / openSUSE: RPM package and signed Zypper repository The dashboard and API use these three families directly. There is no separate generic `Linux` channel. ## Repository dashboard The repository UI is English-only and intentionally text-only. It has no logo, favicon, decorative icons, or letter badge. The default public HTTP port is `18965`. The dashboard provides: - latest RustBox package version - status for Debian / Ubuntu, RHEL / AlmaLinux / Rocky Linux, and SUSE / openSUSE - downloadable package list - installation commands for each Linux family - repository metadata and build information - JSON API at `GET /api/v1/packages` ## RustBox source requirement RustBox must support native file logging through `log_dir`. The package configuration uses: ```toml log_dir = "/var/log/rustbox" ``` The builder rejects RustBox sources that do not contain this setting. Application logs are written to `/var/log/rustbox/rustbox.log` instead of normal systemd stdout logging. ## Quick start ```bash cp .env.example .env nano .env ./start.sh ``` Minimum configuration: ```env SOURCE_REPO=https://git.example.com/rustbox/RustBox.git SOURCE_BRANCH=master REPOSITORY_URL=http://127.0.0.1:18965 HTTP_PORT=18965 ``` For a public installation, set `REPOSITORY_URL` to the externally reachable URL. If a reverse proxy terminates HTTPS, it can forward traffic to local port `18965`. `start.sh` creates a persistent GPG signing key in `gpg/`, builds the containers, and starts: - `rustbox-package-builder`: source watcher, build, package and publication process - `repository-dashboard`: read-only dashboard and API - `repository-http`: Nginx serving the dashboard and package repositories on port `18965` by default Persistent builder state is stored in `data/`. ## Default build settings ```env POLL_INTERVAL=300 REPO_DISTRIBUTION=stable REPO_COMPONENT=main PACKAGE_RELEASE=auto RUN_LINUX_TESTS=compile MAX_GLIBC_VERSION=2.34 RELEASE_RETENTION=10 ``` `RUN_LINUX_TESTS=compile` runs `cargo test --release --locked --no-run`. Use `full` to run the test suite or `0` to skip Rust tests. All three supported Linux package families are built on every successful release. SUSE is not treated as a separate non-Linux target. ## Installed RustBox layout The generated packages install: ```text /usr/local/bin/rustbox /usr/lib/systemd/system/rustbox.service /etc/rustbox/rustbox.toml /etc/logrotate.d/rustbox ``` They create and maintain: ```text /var/lib/rustbox rustbox:rustbox 0700 /var/log/rustbox rustbox:rustbox 0750 /etc/rustbox rustbox:rustbox 0750 ``` `/etc/rustbox/rustbox.toml` is owned by `rustbox:rustbox`, mode `0640`, and packaged as a non-replacing configuration file so package upgrades preserve local changes. ## systemd The service uses the dedicated `rustbox` user and hardened systemd settings: ```ini User=rustbox Group=rustbox Environment=RUSTBOX_CONFIG=/etc/rustbox/rustbox.toml WorkingDirectory=/var/lib/rustbox ExecStart=/usr/local/bin/rustbox StateDirectory=rustbox LogsDirectory=rustbox ProtectSystem=strict ProtectHome=true NoNewPrivileges=true ``` RustBox tracing logs are written to `/var/log/rustbox/rustbox.log`. `StandardOutput=null` is used for normal output. `StandardError=journal` remains available for startup failures that happen before the application logger is initialized. ## logrotate `/etc/logrotate.d/rustbox` rotates `/var/log/rustbox/rustbox.log` daily, keeps 7 rotations, compresses old files, and recreates the active log with `rustbox:rustbox` ownership. ## Default RustBox configuration ```toml host = "0.0.0.0" port = 3001 environment = "production" data_dir = "/var/lib/rustbox" log_dir = "/var/log/rustbox" session_timeout_hours = 72 remember_me_enabled = true remember_me_days = 30 imap_host = "localhost" imap_port = 993 smtp_host = "localhost" smtp_port = 587 tls_enabled = true tls_verify = false max_attachment_size_mb = 50 max_message_size_mb = 100 sieve_port = 4190 sieve_tls_mode = "none" sieve_allow_insecure_auth = true sieve_timeout_secs = 10 default_junk_folder = "Spam" default_theme = "system" default_interface_skin = "apple-mail" trusted_proxies = "127.0.0.1,::1" outgoing_headers = [] pgp_wkd_enabled = true pgp_hkp_enabled = false pgp_hkp_url = "https://keys.openpgp.org" pgp_network_timeout_secs = 10 pgp_max_key_bytes = 1048576 pgp_allow_private_export = true ``` ## Debian / Ubuntu ```bash curl -fsSL http://repo.example.com:18965/repo-key.gpg \ | sudo gpg --dearmor -o /usr/share/keyrings/rustbox.gpg echo "deb [signed-by=/usr/share/keyrings/rustbox.gpg] http://repo.example.com:18965/apt stable main" \ | sudo tee /etc/apt/sources.list.d/rustbox.list sudo apt update sudo apt install rustbox ``` ## RHEL / AlmaLinux / Rocky Linux ```bash sudo rpm --import http://repo.example.com:18965/repo-key.gpg sudo tee /etc/yum.repos.d/rustbox.repo >/dev/null <<'REPO' [rustbox] name=RustBox Package Repository baseurl=http://repo.example.com:18965/rpm/$basearch enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=http://repo.example.com:18965/repo-key.gpg REPO sudo dnf install rustbox ``` ## SUSE / openSUSE ```bash sudo rpm --import http://repo.example.com:18965/repo-key.gpg sudo zypper addrepo --refresh --gpgcheck http://repo.example.com:18965/suse/x86_64/ rustbox sudo zypper refresh rustbox sudo zypper install rustbox ``` ## Repository paths ```text /apt/ Debian / Ubuntu APT repository /rpm/x86_64/ RHEL / AlmaLinux / Rocky Linux RPM repository /suse/x86_64/ SUSE / openSUSE RPM repository /repo-key.gpg public package signing key /DEBIAN-BUILD-INFO.txt Debian / Ubuntu build metadata /RHEL-BUILD-INFO.txt RHEL-family build metadata /SUSE-BUILD-INFO.txt SUSE-family build metadata /api/v1/packages repository JSON API ``` ## Builder logs ```bash docker compose --env-file .env logs -f rustbox-package-builder docker compose --env-file .env logs -f repository-http docker compose --env-file .env logs -f repository-dashboard ``` ## Runtime package dependencies Generated packages declare the system OpenSSL and GnuPG dependencies used by RustBox: - Debian / Ubuntu: `libssl3` or `libssl3t64`, plus `gnupg` - RHEL / AlmaLinux / Rocky Linux: `openssl-libs` and `gnupg2` - SUSE / openSUSE: `libopenssl3` and `gpg2` ## Package license metadata The supplied RustBox source archive does not contain an authoritative `LICENSE` file. The builder therefore keeps package license metadata as `UNKNOWN` instead of guessing. Set the correct license in `scripts/prepare-package.sh` before public redistribution once the upstream license has been confirmed.