diff --git a/README.md b/README.md
index 7f06dc0..f38b72f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
# Overlord
@@ -8,14 +8,16 @@
Hello, I made this project for fun.
-It is written using a combination of Typescript + Node.JS for the server and GOLang for the client.
-Connections are done via encrypted websockets to connect to the server from the client.
-You need to use docker to get this to run easier/for quicker deployment.
+The server is TypeScript on Node/Bun. The client is Go. Operators talk to the server through a web panel or the Electron desktop app, and agents connect over encrypted WebSockets.
+
+Docker is the easiest way to run it.
---
- [Quick Start (Docker)](#quick-start-docker)
-- [Docker Install By OS](#docker-install-by-os)
+ - [Windows](#windows)
+ - [Linux](#linux)
+ - [macOS](#macos)
- [No Docker (.bat / .sh)](#no-docker-bat--sh)
- [Production Package Scripts](#production-package-scripts)
- [Docker Notes (TLS, reverse proxy, cache)](#docker-notes-tls-reverse-proxy-cache)
@@ -24,161 +26,95 @@ You need to use docker to get this to run easier/for quicker deployment.
## Quick Start (Docker)
-If you just want it running fast, use this.
+Pick your OS below. Each section is self-contained: install Docker, get the project, start it.
-> **⚠️ The compose file below is for Linux ONLY.** If you are on **Windows** or **macOS**, use `docker-compose.windows.yml` instead. See [Docker Install By OS](#docker-install-by-os) for the correct commands.
+> Windows and macOS use `docker-compose.windows.yml`. Linux uses the default `docker-compose.yml` (host networking).
-
+After the first start, open `https://localhost:5173`. Default login is `admin` / `admin` unless you set `OVERLORD_USER` / `OVERLORD_PASS`. First startup writes generated secrets to `data/save.json` (inside the container: `/app/data/save.json`) — keep that file private and back it up.
-Installation instructions for Linux
-
-1. Create a `docker-compose.yml` file and paste this:
-
-```yaml
-services:
- overlord-server:
- image: ${DOCKER_IMAGE:-ghcr.io/vxaboveground/overlord:latest}
- build:
- context: .
- dockerfile: Dockerfile
- cache_from:
- - type=local,src=.docker-cache/buildx
- cache_to:
- - type=local,dest=.docker-cache/buildx,mode=max
- container_name: overlord-server
- network_mode: host
- environment:
- PORT: ${PORT:-5173}
- HOST: ${HOST:-0.0.0.0}
- OVERLORD_USER: ${OVERLORD_USER:-admin}
- OVERLORD_PASS: ${OVERLORD_PASS:-}
- JWT_SECRET: ${JWT_SECRET:-}
- OVERLORD_AGENT_TOKEN: ${OVERLORD_AGENT_TOKEN:-}
- NODE_ENV: ${NODE_ENV:-production}
- OVERLORD_TLS_CERT: ${OVERLORD_TLS_CERT:-/app/certs/server.crt}
- OVERLORD_TLS_KEY: ${OVERLORD_TLS_KEY:-/app/certs/server.key}
- OVERLORD_TLS_CA: ${OVERLORD_TLS_CA:-}
- OVERLORD_TLS_OFFLOAD: ${OVERLORD_TLS_OFFLOAD:-false}
- OVERLORD_AUTH_COOKIE_SECURE: ${OVERLORD_AUTH_COOKIE_SECURE:-auto}
- OVERLORD_TLS_CERTBOT_ENABLED: ${OVERLORD_TLS_CERTBOT_ENABLED:-false}
- OVERLORD_TLS_CERTBOT_LIVE_PATH: ${OVERLORD_TLS_CERTBOT_LIVE_PATH:-/etc/letsencrypt/live}
- OVERLORD_TLS_CERTBOT_DOMAIN: ${OVERLORD_TLS_CERTBOT_DOMAIN:-}
- OVERLORD_TLS_CERTBOT_CERT_FILE: ${OVERLORD_TLS_CERTBOT_CERT_FILE:-fullchain.pem}
- OVERLORD_TLS_CERTBOT_KEY_FILE: ${OVERLORD_TLS_CERTBOT_KEY_FILE:-privkey.pem}
- OVERLORD_TLS_CERTBOT_CA_FILE: ${OVERLORD_TLS_CERTBOT_CA_FILE:-chain.pem}
- OVERLORD_CLIENT_BUILD_CACHE_DIR: ${OVERLORD_CLIENT_BUILD_CACHE_DIR:-/app/client-build-cache}
- OVERLORD_FILE_UPLOAD_INTENT_TTL_MS: ${OVERLORD_FILE_UPLOAD_INTENT_TTL_MS:-1800000}
- OVERLORD_FILE_UPLOAD_PULL_TTL_MS: ${OVERLORD_FILE_UPLOAD_PULL_TTL_MS:-1800000}
- volumes:
- - overlord-data:/app/data
- - overlord-certs:/app/certs
- - overlord-client-build-cache:/app/client-build-cache
- - overlord-plugins:/app/plugins
- restart: unless-stopped
- init: true
- security_opt:
- - no-new-privileges:true
- healthcheck:
- test: ["CMD-SHELL", "curl -f ${OVERLORD_HEALTHCHECK_URL:-https://localhost:5173/health} >/dev/null 2>&1 || exit 1"]
- interval: 30s
- timeout: 10s
- retries: 3
- start_period: 40s
-
-volumes:
- overlord-data:
- overlord-certs:
- overlord-client-build-cache:
- overlord-plugins:
-```
-
-2. Start it:
-
-```sh
-docker compose up -d
-```
-
-3. Open the panel:
-
-```text
-https://localhost:5173
-```
-
-4. Update later:
-
-```sh
-docker compose pull
-docker compose up -d
-```
-
-5. Stop:
-
-```sh
-docker compose down
-```
-
-First startup generates secrets and stores them in `data/save.json` (inside container: `/app/data/save.json`).
-Keep that file private and backed up.
-
-Default bootstrap login is `admin` / `admin` unless you set `OVERLORD_USER` and `OVERLORD_PASS`.
-
-
-
-## Docker Install By OS
+---
### Windows
- Installation instructions for Windows
-
-Install Docker Desktop (includes Docker Compose):
+Step-by-step: Windows
+
+
+**1. Install Docker Desktop**
+
+Either from the website:
- https://docs.docker.com/desktop/setup/install/windows-install/
-or with winget:
+Or with winget:
```powershell
winget install -e --id Docker.DockerDesktop
```
-After install, start Docker Desktop once, then verify:
+Start Docker Desktop once, then verify:
```powershell
docker --version
docker compose version
```
-> **Windows users:** use `docker-compose.windows.yml` instead of the default `docker-compose.yml`. The Windows compose file is pre-configured for Docker Desktop on Windows (no `network_mode: host`, correct volume paths, etc.).
+**2. Get the project**
-Clone the repo or download the files, then run:
+```powershell
+git clone https://github.com/vxaboveground/Overlord.git
+cd Overlord
+```
+
+**3. Start it**
```powershell
docker compose -f docker-compose.windows.yml up -d
```
-To rebuild after an update:
+**4. Open the panel**
-```powershell
-docker compose -f docker-compose.windows.yml up --build -d
+```text
+https://localhost:5173
```
-### Linux (Debian, official apt repo method)
+**5. Update later**
-Official docs:
+```powershell
+docker compose -f docker-compose.windows.yml down
+docker compose -f docker-compose.windows.yml pull
+docker compose -f docker-compose.windows.yml up -d
+```
-- https://docs.docker.com/engine/install/debian/
+**6. Stop**
+
+```powershell
+docker compose -f docker-compose.windows.yml down
+```
+
+
+
+---
+
+### Linux
+
+
+Step-by-step: Linux (Debian / Ubuntu / Kali)
+
+
+**1. Install Docker**
+
+Official docs: https://docs.docker.com/engine/install/debian/
Set up Docker's apt repository:
```bash
-# Add Docker's official GPG key:
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
-# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <
+---
+
### macOS
-
- Installation instructions for Mac
-
+Step-by-step: macOS
+
-Install Docker Desktop:
+**1. Install Docker Desktop**
+
+Either from the website:
- https://docs.docker.com/desktop/setup/install/mac-install/
-or with Homebrew:
+Or with Homebrew:
```bash
brew install --cask docker
@@ -256,43 +233,56 @@ docker --version
docker compose version
```
-> **macOS users:** use `docker-compose.windows.yml` instead of the default `docker-compose.yml`. The Windows/macOS compose file is pre-configured for Docker Desktop (no `network_mode: host`, correct volume paths, etc.).
+**2. Get the project**
-Clone the repo or download the files, then run:
+```bash
+git clone https://github.com/vxaboveground/Overlord.git
+cd Overlord
+```
+
+**3. Start it**
+
+macOS uses the same compose file as Windows:
```bash
docker compose -f docker-compose.windows.yml up -d
```
-To rebuild after an update:
+**4. Open the panel**
+
+```text
+https://localhost:5173
+```
+
+**5. Update later**
```bash
-docker compose -f docker-compose.windows.yml up --build -d
+docker compose -f docker-compose.windows.yml down
+docker compose -f docker-compose.windows.yml pull
+docker compose -f docker-compose.windows.yml up -d
+```
+
+**6. Stop**
+
+```bash
+docker compose -f docker-compose.windows.yml down
```
+---
+
## No Docker (.bat / .sh)
-
- If you do not want Docker, use the included scripts.
-
+If you don't want Docker, use the included scripts.
-Prerequisites for local (non-Docker) runs:
+Prerequisites:
- Bun in PATH
- Go 1.21+ in PATH
-
-
-
-
### Windows
-
- Script instructions for Windows
-
-
Development mode (starts server + client):
```bat
@@ -311,37 +301,24 @@ Build client binaries (adds client builds to the build queue):
build-clients.bat
```
-
-
-
-
### Linux / macOS
-
- Installation instructions for Linux / Mac
-
-
Make scripts executable once:
```bash
chmod +x start-dev.sh start-dev-server.sh start-dev-client.sh start-prod.sh build-prod-package.sh
```
-Development mode (starts server in background + client in foreground):
+Development mode (server in background, client in foreground):
```bash
./start-dev.sh
```
-Only server:
+Only server, or only client:
```bash
./start-dev.sh server
-```
-
-Only client:
-
-```bash
./start-dev.sh client
```
@@ -351,7 +328,7 @@ Production mode:
./start-prod.sh
```
-
+---
## Production Package Scripts
@@ -363,104 +340,75 @@ Windows:
build-prod-package.bat
```
-Linux/macOS:
+Output: `release/`
+
+Linux / macOS:
```bash
./build-prod-package.sh
```
-Package output:
+Output: `release/prod-package/`
-- Windows script: `release`
-- Linux/macOS script: `release/prod-package`
+---
## Docker Notes (TLS, reverse proxy, cache)
-Here we will store some notes for you to read depending on what it is. Configs, work arounds etc.
-
-
+Notes on configs and workarounds.
### BuildKit cache for faster rebuilds
-`docker-compose.yml` includes `build.cache_from` and `build.cache_to` using `.docker-cache/buildx`.
-
-Rebuild:
-
-```sh
-docker compose up --build -d
-```
-
-
+`docker-compose.yml` ships with `build.cache_from` and `build.cache_to` pointing at `.docker-cache/buildx`. Local builds reuse it automatically — no extra setup.
### Runtime client build cache
The compose setup uses a persistent volume for runtime client builds:
-- volume: `overlord-client-build-cache`
-- mount: `/app/client-build-cache`
-- env: `OVERLORD_CLIENT_BUILD_CACHE_DIR` (default `/app/client-build-cache`)
-
-
+- Volume: `overlord-client-build-cache`
+- Mount: `/app/client-build-cache`
+- Env: `OVERLORD_CLIENT_BUILD_CACHE_DIR` (default `/app/client-build-cache`)
### Certbot TLS
-To use certbot certificates in production Docker:
+To use Let's Encrypt certificates in production Docker:
-#### Set:
- OVERLORD_TLS_CERTBOT_ENABLED=true
-#### Set:
- OVERLORD_TLS_CERTBOT_DOMAIN=your-domain.com
-
-- Mount letsencrypt into container read-only (example: `/etc/letsencrypt:/etc/letsencrypt:ro`)
+1. Set `OVERLORD_TLS_CERTBOT_ENABLED=true`
+2. Set `OVERLORD_TLS_CERTBOT_DOMAIN=your-domain.com`
+3. Mount letsencrypt into the container read-only, e.g. `/etc/letsencrypt:/etc/letsencrypt:ro`
-#### Default cert paths:
- cert: /etc/letsencrypt/live//fullchain.pem
- key: /etc/letsencrypt/live//privkey.pem
- ca: /etc/letsencrypt/live//chain.pem
+Default cert paths:
-#### Override with:
- OVERLORD_TLS_CERTBOT_LIVE_PATH
- OVERLORD_TLS_CERTBOT_CERT_FILE
- OVERLORD_TLS_CERTBOT_KEY_FILE
- OVERLORD_TLS_CERTBOT_CA_FILE
+```
+cert: /etc/letsencrypt/live//fullchain.pem
+key: /etc/letsencrypt/live//privkey.pem
+ca: /etc/letsencrypt/live//chain.pem
+```
-
+Override with:
-### Reverse proxy TLS offload (Render, etc.)
+- `OVERLORD_TLS_CERTBOT_LIVE_PATH`
+- `OVERLORD_TLS_CERTBOT_CERT_FILE`
+- `OVERLORD_TLS_CERTBOT_KEY_FILE`
+- `OVERLORD_TLS_CERTBOT_CA_FILE`
-#### If your platform terminates TLS before traffic reaches Overlord, set:
-
- OVERLORD_TLS_OFFLOAD=true
- OVERLORD_HEALTHCHECK_URL=http://localhost:5173/health
- OVERLORD_PUBLISH_HOST=127.0.0.1
- (recommended for local proxies like ngrok)
+### Reverse proxy TLS offload
-When enabled:
+If your platform terminates TLS before traffic reaches Overlord (Render, Caddy, nginx, etc.), set:
-- container serves internal HTTP on `0.0.0.0:$PORT`
-- external URL remains `https://...` through your platform proxy
-- health checks should use `http://localhost:$PORT/health` inside the container
-- do not expose internal container HTTP port directly to the internet
-
-
-
-For ngrok/local reverse proxy use, a common setup is:
-
-```sh
+```
OVERLORD_TLS_OFFLOAD=true
OVERLORD_HEALTHCHECK_URL=http://localhost:5173/health
OVERLORD_PUBLISH_HOST=127.0.0.1
```
-Then point ngrok at local HTTP:
+When enabled:
-```sh
-ngrok http http://127.0.0.1:5173
-```
+- Container serves internal HTTP on `0.0.0.0:$PORT`
+- External URL stays `https://...` through your platform proxy
+- Health checks should use `http://localhost:$PORT/health` inside the container
+- Don't expose the internal container HTTP port directly to the internet
-
+### Notes
-Notes:
-
-- Keep `HOST=0.0.0.0` inside the container. Limiting exposure should be done with publish binding (`OVERLORD_PUBLISH_HOST`), not server bind host.
-- If your `.env` secret/password includes `$`, escape as `$$` to avoid Docker Compose variable-expansion warnings.
+- Keep `HOST=0.0.0.0` inside the container. Limit exposure with `OVERLORD_PUBLISH_HOST`, not the bind host.
+- If your `.env` secret/password contains `$`, escape it as `$$` to avoid Docker Compose variable-expansion warnings.