26 Commits
Author SHA1 Message Date
Juan Denis 652d903ae7 Normalize emails, add panel_origin & domain-aware URLs
Make email handling case-insensitive (queries + model normalization) to prevent duplicate accounts. Add SiteDomainService.panel_origin() helper and use it across services to build public URLs (Gitea, WordPress, Roundcube) and Django ALLOWED_HOSTS. Add optional custom-domain support when creating WordPress sites and propagate domain to Roundcube install. Improve environment domain fallback to prefer panel/base domains over .localhost. Small Dockerfile healthcheck tweak (use 127.0.0.1). Update install/update/build scripts to always (re)create virtualenv locally for release installs. Remove unused frontend CreateSiteModal and expose domain field in WordPress page.
2026-06-22 14:37:44 -04:00
Juan DenisandClaude Opus 4.8 a09bf0fbbe feat(security): gate panel HSTS on installer SSL mode (keep HTTPS optional)
The Flask middleware emitted HSTS with includeSubDomains+preload whenever not in
debug mode -- even on HTTP-only or Cloudflare-Flexible installs, where preload is
a hard-to-reverse commitment. HTTPS is intentionally optional, so HSTS is now
gated on the operator's recorded SSL choice.

- config._resolve_ssl_mode(): SERVERKIT_SSL_MODE env -> /etc/serverkit/ssl-mode
  file -> safe 'insecure' default. Exposed as SSL_MODE / HSTS_ENABLED.
- security middleware sends HSTS only when HSTS_ENABLED and not debug. Behind a
  proxy Flask can't distinguish real TLS from a Flexible edge via
  X-Forwarded-Proto, so we trust the installer's choice, not the request scheme.
- install.sh records SERVERKIT_SSL_MODE in .env; existing installs are covered by
  the /etc/serverkit/ssl-mode file. The nginx edge still emits HSTS in its own
  secure server block, so secure installs are unaffected.

Proving tests in tests/test_security_headers.py. Full backend suite: 342 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 16:52:40 -04:00
Juan DenisandClaude Opus 4.8 3703b47456 feat(security): server-wide TLS floor at install/update + fix HTTPS update regression
KIMI's optional-SSL commit hardened ssl_protocols/ssl_ciphers per-vhost but
left the system nginx.conf http{} defaults untouched, so the default server
and any non-ServerKit vhost could still negotiate TLS 1.0/1.1 and weak ciphers
(the scan's "insecure TLS versions" / "weak ciphers in TLS 1.2" findings).

- install.sh: harden_global_tls() rewrites (or injects) ssl_protocols and
  ssl_ciphers in /etc/nginx/nginx.conf to TLS1.2/1.3 + AEAD-only. Editing the
  line in place avoids nginx's duplicate-directive error on Debian/Ubuntu,
  which already set ssl_protocols in http{}.
- update.sh: re-applies the floor so existing installs harden on upgrade too.
- Persist the panel domain to /etc/serverkit/panel-domain; update.sh recovers
  it from there (or the live cert path) instead of the commented-out .env
  SERVERKIT_PUBLIC_URL grep, which never matched -> secure installs were
  getting the YOUR_DOMAIN placeholder re-applied and nginx -t failing on update.
- update.sh now degrades to the HTTP config when a secure cert is missing,
  rather than leaving nginx unable to reload.

Global TLS settings are inert in HTTP-only mode, so optional SSL is unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 16:26:54 -04:00
Juan Denis 02afdec9f0 feat(security): optional SSL/TLS hardening with Cloudflare-aware configs and HTTP fallback
- Add secure nginx config with TLS 1.2+, HSTS preload, CSP, and security headers
- Add insecure HTTP fallback config for users who cannot or do not want HTTPS
- Make installer best-effort SSL: try Let's Encrypt, fall back to HTTP without failing
- Preserve secure/insecure SSL choice across updates via /etc/serverkit/ssl-mode
- Support SERVERKIT_SKIP_SSL=1 to disable HTTPS entirely
- Add CAA record to default DNS zone template
- Harden generated per-app nginx configs with HSTS preload, CSP, and security headers
- Align Flask security middleware headers with nginx edge config
2026-06-19 16:13:06 -04:00
Juan Denis f9c31aec32 feat(installer): guided install/update flow with health-checked rollback
- install.sh: staged installer with pre-flight checks (disk/memory/root),
  apt/dnf lock handling, low-RAM safe mode + swap, source-or-release install
  modes, generated secrets/.env, self-signed cert bootstrap, nginx + systemd
  wiring, a post-install health probe with automatic rollback, and optional
  Let's Encrypt issuance for the panel domain.
- scripts/update.sh: in-place updater with release self-refresh, pre-update
  database + tree backups, release/source paths, health-checked rollback,
  and backup pruning.
- scripts/build-release.sh: builds a portable release tarball (pre-built
  venv + frontend) at the repo root.
- serverkit CLI: 'update' delegates to scripts/update.sh and accepts
  --release [vX.Y.Z].
- Harden the serverkit-agent unit (kernel/namespace protections, MemoryMax,
  LimitNOFILE) and ignore release tarball artifacts.
2026-06-19 01:33:17 -04:00
Juan DenisandClaude Opus 4.8 6e0db86c69 fix(install): pre-upgrade openssh+openssl together on RHEL family
On Rocky/RHEL 9.7+ the updates stream ships openssl-libs 3.5.x with a
different ABI than the 3.0.x most boxes ship with. If a later dnf install
pulls the new openssl-libs as a transitive dep, every new sshd fork dies
with "OpenSSL version mismatch" — TCP accepts then RSTs and remote installs
over SSH fail silently. Replace the blanket `dnf update -y` with
`dnf makecache --refresh` plus an upfront `dnf upgrade` of openssh*+openssl*
in one transaction so sshd restarts against a matched pair (sshd
KillMode=process keeps the live session alive). Recovered from a local
stash; this is the documented Rocky9 openssl fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 19:44:59 -04:00
Juan DenisandClaude Opus 4.7 ed68cdccb5 Support Rocky/RHEL + fix Docker install on Fedora
install.sh:
- Detect rocky/almalinux/rhel/centos as OS_FAMILY=rhel.
- The Fedora system-deps block now also runs for rhel; auto-install
  epel-release on RHEL-family.
- Docker install on Fedora/RHEL no longer pipes get.docker.com. That
  script recently added docker-model-plugin to its package list, which
  doesn't exist in docker-ce repos and aborts the install on Fedora 39.
  Replace it with explicit `dnf config-manager --add-repo` +
  `dnf install docker-ce docker-ce-cli containerd.io
  docker-compose-plugin docker-buildx-plugin`.
- Node.js and nginx installs route through dnf for rhel too.
- SELinux setsebool runs for rhel too.

scripts/test/full-stack-test.ps1:
- fedora image bumped from fedora39 (EOL Nov 2024) to fedora40 (current).
- Test-VagrantInstall + Test-VmInstall: defensive read of status file.
  Previously `(Get-Content -Raw).Trim()` crashed with InvokeMethodOnNull
  when the status file was missing/empty (which happens when the VM's
  install script crashed before producing it). Now falls back to 'FAIL'
  cleanly so the run summary still works.

Found by full 5-distro suite: Ubuntu 22/24 + Debian 12 passed; Fedora 39
failed on docker-model-plugin; Rocky 9 failed silently due to apt-vs-dnf
+ status NPE. All three fixed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:34:50 -04:00
Juan Denis e0492f54f0 Move nginx private URLs to location snippets
Generate private URL configs as location-only snippets in /etc/nginx/serverkit-locations instead of full server blocks. nginx_service.py: write location snippets (.conf) to LOCATIONS_DIR, ensure the locations directory, remove legacy separate server blocks, and add get_location_config to read these snippets (used for private URLs, Gitea, WordPress). install.sh & serverkit: only remove conflicting catch-all (server_name _) configs that are not ServerKit-managed (skip serverkit.conf and serverkit-*), strengthen the server_name regex, and create the serverkit-locations dir. cmd_doctor: add docker presence checks and avoid frontend checks when docker is missing; require root in --fix mode. Misc cleanup and minor refactors around enabling/disabling configs and reload handling.
2026-03-28 13:47:43 -04:00
Juan Denis 39ac49609e Use nginx location snippets and add doctor
Switch Gitea/WordPress to location-only snippets included into serverkit.conf and introduce /etc/nginx/serverkit-locations. NginxService now writes snippets to LOCATIONS_DIR, ensures the directory exists and removes legacy full-server configs to avoid server_name _ conflicts; validation blocks use of the reserved catch-all name. install.sh and the update path create the locations dir and remove any conflicting catch-all site configs. serverkit.conf proxy port updated (8080 -> 3847) and now includes the snippets directory. Add a new serverkit doctor command (with --fix) and help entries to run diagnostics and auto-fix common issues (nginx, docker, service health, ports, disk, DB, etc.).
2026-03-28 12:46:33 -04:00
Juan Denis e5b2a05fbc Add source fallback for Python 3.12 install
Enhance install.sh Python installation logic: for Debian-family systems, use the deadsnakes PPA on Ubuntu, and for other apt-based systems build Python 3.12 from source (installing required dev packages, downloading Python-3.12.8, configure/make/make altinstall). For Fedora, attempt dnf install first and fall back to building from source if unavailable (installing required dev packages similarly). After install, verify python3.12 is present and print success or a helpful error message on failure.
2026-03-28 10:57:00 -04:00
Juan Denis 6c41e88701 Add auth checks, logging, DNS API & UI
Enforce admin and workspace permissions, improve logging, and add DNS frontend/API support.

- Backend: added admin checks to cloud_provisioning and marketplace endpoints; added require_workspace_access helper and applied to multiple workspace endpoints to enforce membership/admin access; persist push subscription data in mobile API (commit to DB); replaced print() debugging with structured logger calls across agent_registry and added logging/exception handling in monitoring_service.
- Frontend: added a DNS API client (frontend/src/services/api/dns.js) and registered it in the API index; extended DNSZones UI to collect provider zone ID and API token, updated create payload and form reset; added optional modal footer prop to Modal component; moved rollup native binding to optionalDependencies in package.json.
- Misc: added '*.png' to .gitignore and a minor spacing change in install.sh.

These changes improve security checks, observability, and add DNS management features in the UI/API.
2026-03-24 06:10:58 -04:00
Juan Denis 6e9145495d Refactor installer and uninstaller scripts
Major refactor of install.sh and uninstall.sh to improve robustness, cross-distro support, and low-RAM VPS behavior. install.sh: add safety cd, colored helpers, Python detection with fallback to 3.12, RAM check and swap setup, noninteractive apt/dnf and needrestart handling, Docker/Docker Compose/Node installation, clone/update repo, create system dirs and install bundled templates, set up venv and dependencies, generate .env, create self-signed SSL, install systemd service, configure nginx reverse proxy, build frontend on host to avoid Docker memory issues, start services, perform health checks, and send install telemetry. uninstall.sh: formatting/consistency fixes, require root, safer docker compose teardown, remove /etc/serverkit and /var/serverkit, and send uninstall telemetry. Also add CONTRIBUTORS.md and remove the .claude code-review SKILL.md.
2026-03-15 18:05:16 -04:00
Rapeepan 600dd5325e feat: Add low RAM detection with safe mode, swap setup, and optimize post-installation steps. 2026-03-13 00:56:46 -04:00
Rapeepan 2bdc4b955a feat: Add uninstall.sh script and update install.sh to improve Python version detection and remove app template installation. 2026-03-13 00:56:46 -04:00
Rapeepan 6fc491a0d8 feat: Add Fedora support to the install script, including DNF package management and SELinux configuration. 2026-03-06 16:20:50 +07:00
Juan Denis fc02f40636 Add tracking for install, update, and uninstall events
Added calls to serverkit.ai to track successful installation, update, and uninstall events with the current version. This helps monitor usage and improve support.
2026-01-28 22:31:46 -05:00
Juan Denis 0b7dcf69cf Build frontend on host to avoid Docker memory issues
Updates the Dockerfile to expect pre-built assets and modifies install.sh to install Node.js, ensure swap space, and build the frontend on the host before packaging it into the nginx container. This approach addresses memory limitations on low-RAM VPS servers during the Vite build process.
2026-01-25 23:27:31 -05:00
Juan Denis 93eccda09c Optimize frontend Docker build and Vite config
Added .dockerignore to reduce build context size. Increased Node.js memory limit during frontend build in Dockerfile. Updated Vite config to split vendor chunks for better caching and performance. Modified install.sh to use 'docker container prune' and removed '--no-cache' from compose build for efficiency.
2026-01-25 23:15:50 -05:00
Juan Denis 06d63cbc52 Add standalone WordPress and SSL management UI
Implements backend endpoints and service logic for managing standalone WordPress via Docker, including install, uninstall, start, stop, and restart. Adds Nginx integration for WordPress at /wordpress. Introduces a new frontend page for SSL certificate management with Certbot install, obtain, renew, and revoke actions. Updates the WordPress frontend page to support one-click install, status, and lifecycle management. Updates documentation and install instructions for improved clarity.
2026-01-25 22:48:12 -05:00
Juan Denis 8cff8f98ae Set needrestart to non-interactive mode in install.sh
Configures needrestart for automated installs by setting environment variables and updating needrestart.conf if present. Also adds /.marketing to .gitignore.
2026-01-21 18:00:04 -05:00
Juan DenisandClaude Opus 4.5 2c4976e4f5 feat: Add Docker cleanup to install/update and --force flag
- Add docker network prune and docker system prune before builds
- Use --no-cache for docker compose build to ensure fresh builds
- Add --force / -f flag to skip version check during update
- Helps prevent Docker networking issues

Usage: sudo serverkit update --force

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 23:38:13 -05:00
Juan DenisandClaude Opus 4.5 b43bae9a49 Fix: Copy app templates to /etc/serverkit/templates during install
- Install script now copies bundled YAML templates to system directory
- Update command syncs templates on each update
- Creates /var/serverkit/apps directory for installed apps

Fixes 'No templates found' in Templates page.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 22:41:10 -05:00
Juan DenisandClaude Opus 4.5 736deb0832 Fix: Prevent getcwd errors by ensuring valid working directory
- install.sh now starts with cd /tmp to ensure valid directory
- uninstall command moves to /tmp before deleting install dir
- Shows reinstall command after uninstall

Prevents 'cannot access parent directories' errors when running
install from a deleted directory.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 22:33:40 -05:00
Juan DenisandClaude Opus 4.5 eebb37fd5b Add multi-site support with host nginx reverse proxy
- Host nginx routes domains to different apps
- ServerKit frontend moved to port 8080 (internal)
- New CLI commands: setup-proxy, add-site, list-sites, remove-site
- Site config templates for easy domain setup
- Install script now sets up nginx proxy automatically

Usage:
  sudo serverkit add-site test.example.com 3000
  sudo serverkit list-sites
  sudo serverkit remove-site test.example.com

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 22:04:26 -05:00
Juan Denis c95d01b2fb Refactor to run backend on host, frontend in Docker
Removed docker-compose.prod.yml and updated docker-compose.yml to only run the frontend in Docker, with the backend now running as a systemd service on the host. Updated nginx and frontend nginx.conf to proxy API requests to the backend on the host. Added serverkit-backend.service for systemd management of the backend. Refactored install.sh and serverkit CLI to support the new architecture, including improved installation, update, and management commands.
2026-01-18 21:15:31 -05:00
Juan Denis c1d60f112f Add ServerKit CLI, install script, and deployment improvements
Introduces a comprehensive Bash CLI tool (`serverkit`) for managing ServerKit services, users, and database operations. Adds a quick-install script (`install.sh`) for Ubuntu, a sample environment file (`.env.example`), and a Python CLI backend (`backend/cli.py`) for administrative tasks. Updates Docker Compose for production readiness, enhances deployment documentation, and adds Click to backend requirements. Also updates references to the correct GitHub repository.
2026-01-17 12:13:22 -05:00