A lightweight, self-hosted PaaS — deploy your apps from Git with automatic SSL, health checks, and webhooks. Built with Rust + SvelteKit, targeting <50MB RAM idle.
Think Coolify, but leaner.
- One-command deploy — push to Git, Ployer builds and deploys automatically
- Automatic SSL — via Caddy + Let's Encrypt, zero config
- Webhooks — GitHub and GitLab push events trigger auto-deploys
- Health checks — HTTP polling with auto-restart on failure
- Container stats — CPU, memory, and network I/O monitoring
- Real-time logs — WebSocket streaming for build and runtime logs
- Multi-server — manage apps across multiple servers
- Encrypted secrets — environment variables encrypted at rest (AES-256-GCM)
| Minimum | Recommended | |
|---|---|---|
| OS | Ubuntu 22.04 / Debian 12 | Ubuntu 24.04 LTS |
| RAM | 1 GB | 2 GB+ |
| CPU | 1 vCPU | 2 vCPU |
| Disk | 20 GB | 40 GB+ |
| Arch | x86_64 | x86_64 / arm64 |
Important: Install on a fresh, dedicated server. Ployer owns ports 80 and 443 via Caddy. It will conflict with Nginx, Apache, Coolify, or any other reverse proxy already running on those ports.
Point your domain's DNS A record to your server IP first, then run:
curl -fsSL https://raw.githubusercontent.com/nusendra/ployer/main/install.sh | sudo bashNote:
curl | bashruns in non-interactive mode and will auto-detect your server IP. To use a custom domain with HTTPS, download and run the script directly instead:curl -fsSL https://raw.githubusercontent.com/nusendra/ployer/main/install.sh -o install.sh sudo bash install.sh
The installer will:
- Detect your OS and install Docker if needed
- Ask for your domain (or use server IP for quick testing)
- Generate a secure JWT secret automatically
- Build and start all services
- Print the dashboard URL when ready
That's it. HTTPS is provisioned automatically when you use a domain.
If you prefer to set things up yourself:
curl -fsSL https://get.docker.com | bashgit clone https://github.com/nusendra/ployer.git /data/ployer
cd /data/ployercp .env.example .env
nano .envSet at minimum:
PLOYER_JWT_SECRET=your-long-random-secret-here
PLOYER_BASE_DOMAIN=ployer.yourdomain.com
PLOYER_PUBLIC_URL=https://ployer.yourdomain.com
PLOYER_ALLOWED_ORIGINS=https://ployer.yourdomain.comEdit Caddyfile and replace your-staging-domain.com with your actual domain:
ployer.yourdomain.com {
reverse_proxy ployer:3001
}
docker compose up -d --buildNavigate to https://ployer.yourdomain.com — you'll be prompted to create the first admin account.
Re-run the install script — it detects an existing installation, pulls the latest code, and restarts:
curl -fsSL https://raw.githubusercontent.com/nusendra/ployer/main/install.sh | sudo bashOr manually:
cd /data/ployer
git pull
docker compose up -d --buildAll configuration is via environment variables in /data/ployer/.env:
| Variable | Default | Description |
|---|---|---|
PLOYER_JWT_SECRET |
(required) | Secret key for signing JWT tokens. Use a long random string. |
PLOYER_BASE_DOMAIN |
localhost |
Base domain for auto-generated app subdomains |
PLOYER_PUBLIC_URL |
http://localhost |
Full public URL of the Ployer dashboard |
PLOYER_ALLOWED_ORIGINS |
* |
CORS allowed origins. Lock down in production. |
PLOYER_DATABASE_URL |
sqlite:///data/ployer.db |
SQLite database path |
PLOYER_PORT |
3001 |
Internal API port |
PLOYER_CADDY_URL |
http://caddy:2019 |
Caddy Admin API URL |
PLOYER_DOCKER_SOCKET |
/var/run/docker.sock |
Docker socket path |
LOG_FORMAT |
(plain text) | Set to json for structured JSON logging |
After editing .env, restart:
docker compose -f /data/ployer/docker-compose.yml up -dIf you get locked out:
docker compose -f /data/ployer/docker-compose.yml exec ployer \
./ployer reset-password --email you@example.com --password newpassword123# View live logs
docker compose -f /data/ployer/docker-compose.yml logs -f
# View only API logs
docker compose -f /data/ployer/docker-compose.yml logs -f ployer
# Stop Ployer
docker compose -f /data/ployer/docker-compose.yml down
# Restart Ployer
docker compose -f /data/ployer/docker-compose.yml restart ployer
# Open a shell inside the container
docker compose -f /data/ployer/docker-compose.yml exec ployer sh- Add a server — Ployer auto-registers the local server on first start
- Create an application — provide a Git URL, branch, and build strategy
- Add the deploy key — copy the public key from Ployer into your repository's deploy keys
- Deploy — click Deploy or push to the configured branch via webhook
| Strategy | Description |
|---|---|
| Dockerfile | Builds using a Dockerfile in your repo root |
| Nixpacks | Auto-detects language and builds without a Dockerfile |
| Docker Compose | Deploys using a docker-compose.yml in your repo |
- Go to your application → Webhooks → Configure
- Select your Git provider (GitHub or GitLab)
- Copy the webhook URL and secret
- Add it to your repository's webhook settings
- Push to your configured branch — Ployer deploys automatically
Internet
│
▼
Caddy (80/443) ← TLS termination, auto SSL
│
▼
Ployer (3001) ← Rust/Axum API + SvelteKit frontend
│
├── SQLite (/data) ← Persistent database
├── Docker socket ← Container management
└── Caddy Admin API ← Dynamic reverse proxy routes
- Backend — Rust (Axum), SQLite via sqlx, bollard for Docker
- Frontend — SvelteKit (static build, served by the Rust binary)
- Proxy — Caddy 2 (automatic HTTPS, dynamic routing)
- Database — SQLite with WAL mode (no separate database server needed)
Dashboard not loading after install
docker compose -f /data/ployer/docker-compose.yml logs caddy
docker compose -f /data/ployer/docker-compose.yml logs ployerSSL certificate not issued
- Make sure your domain's DNS A record points to the server before running the installer
- Port 80 must be open on your firewall (
ufw allow 80andufw allow 443)
Cannot connect to Docker
ls -la /var/run/docker.sock # should exist
systemctl status docker # should be activeDatabase errors on startup
- The
/datavolume is created automatically. If permissions are wrong:
docker compose -f /data/ployer/docker-compose.yml down
docker volume rm ployer_ployer-data
docker compose -f /data/ployer/docker-compose.yml up -dMIT — see LICENSE