mas
Open sourceMIT licensed · v0.1 beta

Your server,
mapped and deployed.

Mas is a self-hosted dashboard that adopts what already runs on your Debian + nginx box, PHP sites, PM2 apps, systemd units, Docker containers, then deploys from GitHub on every push. Nothing gets reinstalled.

Debian 12+ · nginx · runs on the box you already have

Mas overview: every service detected on the server, with status, domains, manager, port and SSL expiryMas app page: production deployment and live build log

Adopts what you already run

nginxsystemdPM2DockerPHP-FPMNext.jsNodePythonStaticLet's Encrypt
Discovery

Point it at a server that has run for years.

Mas reads nginx vhosts, listening ports, /proc, systemd, PM2 and the Docker socket, then tells you what runs, where, for which domain, under which user and from which git repository. Every detection is deterministic parsing. No AI model, no agent to install elsewhere, and the scan never writes a byte.

How a vhost becomes a service

Each hop is a file or a syscall you could check by hand.

nginx vhostproxy_pass:3000ssPID 4127
/proc cgroup pm2 · user web
/proc cwd/srv/web · nextjs · gh:acme/web
nginx vhostfastcgi_passPHP-FPM site
nginx vhostroot onlystatic site
port / unit / containerno vhost“no domain” service
root@prod-01: ~
$ sudo mas scan
14 services
ServiceTypeManagerPortSSLGit
●api.example.compythonsystemd800086dgh:acme/api@main
●app.example.comnextjspm2300086dgh:acme/web@main
●blog.example.comphpphp-fpm-9dgh:acme/blog@main
●grafana.example.comunknowndocker300161d-
●shop.example.comunknownunknown400072d-
●docs.example.comstaticnginx-static-44d-
…
$ sudo mas doctor
! blog.example.com: certificate expires in 9 days, certbot.timer is inactive
fix: systemctl enable --now certbot.timer
$
Features

From inventory to push-to-deploy.

Start by seeing what you have. Then hand Mas the parts you want it to manage, one service at a time.

Deploy from GitHub on every push

Vercel-style, on your own machine. Atomic releases, a generated systemd unit and nginx vhost, Let's Encrypt, a health check and automatic rollback when it fails.

Readymain · c19e8aanextjs5 releases kept

Health checks that explain

Broken certbot lineages, expiring certificates, standalone renewals that stop nginx, vhosts pointing to missing certs, domains resolving elsewhere. Each comes with the fix; Mas never applies it for you.

Domains from your registrar

Connect OVH, Cloudflare, Gandi, Hetzner, DigitalOcean or Porkbun. Mas creates the A/AAAA record, waits for it to resolve, then issues the certificate. It never deletes a record.

Self-hosted Supabase

One click installs the official stack. Ports bound to 127.0.0.1, only the public API published over HTTPS, Studio kept private, daily pg_dump.

Adopt in place

A detected service that is already a GitHub checkout gets Connect to GitHub. Mas deploys it where it lives, through its current manager, and resets to the previous commit if the health check fails.

CLI and dashboard

Everything from mas scan to mas rollback in the terminal, or from a web dashboard with password + 2FA, light and dark themes, and ⌘K to jump anywhere.

Why another one?

Built for the server you already have.

Coolify, Dokploy and CapRover are great, but they want a clean server: everything in their containers, behind their proxy. Mas starts from the other end.

Coolify / Dokploy / CapRover Mas
Starting pointFresh server✓Your existing server
Reverse proxyTraefik / Caddy (theirs)✓Your nginx, your vhosts
RuntimesDocker only✓PHP-FPM, systemd, PM2, Docker, static
Existing appsRe-deploy them✓Detected and adopted in place
Detectionn/a✓Deterministic parsing, no AI
Deploy from GitHub

git push, and it's live.

Create a GitHub App in one click from the dashboard (manifest flow, minimal read-only permissions), pick a repository and a branch, and every push goes through the same seven steps.

  1. Clone the pushed commit into its own release folder; the token goes through the environment, never on the command line.
  2. Build as a dedicated mas-<app> user: npm, a Python venv, composer, or your own command.
  3. Switch the current symlink atomically.
  4. Restart a generated, sandboxed systemd unit listening on 127.0.0.1.
  5. Route through an nginx vhost from a template: backup, nginx -t, reload.
  6. Secure with certbot if the domain has no certificate yet.
  7. Verify with an HTTP health check. If it fails, the previous release is put back.

The last 5 releases are kept. mas rollback <app> puts any of them back.

build #3 · c19e8aaBuilding
Security model

It runs as root, so it behaves.

Mas has to read /proc for every user and restart services. So the agent is sandboxed by systemd, writes only where it must, and treats every change as reversible.

Read-only discovery

Scans never write. The test suite hashes the whole fixture tree before and after a scan and allow-lists every command.

Allow-listed actions

A strict (manager, action) → argv table, executed without a shell. Every action and its output lands in the audit log.

nginx -t, always

Generated files are backed up first and nginx only reloads after a successful nginx -t.

Password + 2FA

TOTP with any authenticator app, __Host- session cookie, rate-limited checks. The dashboard can stay behind an SSH tunnel.

Sandboxed apps

Each app runs as its own non-root user with NoNewPrivileges, ProtectSystem, no capabilities, on loopback.

Secrets stay secret

Encrypted at rest, 0600 files. Credentials found in git remotes or PM2 env are neither stored nor shown.

Full details in the security model and SECURITY.md.

Install

Three commands. One server.

On Debian 12+, as root. The installer is idempotent: it asks for an admin password, shows a QR code for 2FA, and optionally serves the dashboard on your domain with a Let's Encrypt certificate. Leave the domain out to keep it private behind an SSH tunnel.

root@prod-01: ~
$ git clone https://github.com/SyanCode/Mas.git /opt/mas-install
$ cd /opt/mas-install
$ sudo ./deploy/install.sh --domain mas.example.com --email you@example.com
Update
sudo mas self-update
Private dashboard
ssh -L 7070:127.0.0.1:7070 you@server
Beta. Mas edits nginx, systemd and DNS. Every change is backed up and validated, and discovery is read-only, but try it first on a server you can restore.
Roadmap

Built in the open, phase by phase.

Phase 1Shipped

Detection

Collectors, correlation, type detection, mas scan --json.

Phase 2Shipped

Dashboard & management

API, 2FA, background scan, logs, allow-listed actions, audit log, installer.

Phase 2.5Shipped

Health checks

Certificates, certbot renewal, nginx, DNS: mas doctor.

Phase 3Shipped

Deploy from GitHub

GitHub App, signed webhooks, atomic releases, rollback, live build logs, adoption.

LaterPlanned

Next

Preview deployments per pull request, 2FA recovery codes, notifications.

Open source, MIT, and waiting for your server.

Read the code, try it on a box you can restore, and open an issue with what it found. Feedback shapes the next phase.