sitectl
v0.2.4
Published
CLI toolkit for site operations.
Downloads
1,918
Readme
sitectl
A simple CLI for bootstrapping Linux servers, nginx site configs, and TLS certificates.
It is primarily intended for admin-style management of personal or small-scale VPS/VDS hosts.

Install
npm install -g sitectl
sitectl initUse sitectl init --overwrite-bundled to refresh bundled templates without replacing
user-managed data such as config.json or per-site nginx configs.
What It Does
There are three main areas in sitectl:
Manage serversKeeps a local registry of servers, gives you quickssh/ssh-copy-idflows, and lets you sync local files to a selected server overrsync.Manage sitesManages nginx site configs, certificate issuance, and HTTP/HTTPS switching.Remote commandsRuns built-in and custom server-side commands on a selected server.
With sitectl, you can:
- manage your server list locally
- connect to servers over SSH, install your public key, and sync local files
- run built-in remote commands on servers
- add your own custom remote commands and submenus
- manage nginx site configs
- issue TLS certificates
- enable and disable HTTPS on a site
- remove site configs from a server
It is opinionated, but customizable:
- today it is biased toward Debian-like servers because the bootstrap/install
flow is written for
apt,nginx,certbot,ufw, and related packages - after
sitectl init, you can adapt the user-managed files in~/.config/sitectl/to your own setup - the main nginx customization point is
~/.config/sitectl/nginx/sites/nginx-template.conf - one of the main customization points is
Remote commands, which can be extended with your own scripts and submenus - local development and test commands require Node.js 22.17 or newer
This is a CLI-only utility for interactive local use. It is not intended for CI or hermetic automation environments.
The workflow is interactive only:
- run
sitectl initonce - start
sitectl - choose an action from the menu
- follow the prompts
Support
sitectl is intended to run on Unix-like systems.
Supported remote server operating systems:
- Debian 12+
- Ubuntu 22.04+
Supported local environments:
- Linux
- macOS
- Windows via WSL
Native Windows is not supported at the moment.
Required local dependencies:
- Node.js 22.17+
- npm
sshrsyncssh-copy-id
Platform notes:
- On macOS,
Manage sites -> Copy conf files to serverexpects a newerrsyncthan the system one. Install it with Homebrew:
brew install rsync- On Linux,
Open data dirand local config opening usexdg-open, which is typically provided by your desktop environment orxdg-utils. - On Windows, use WSL and install the Linux dependencies inside WSL.
Custom Remote Commands
One of the main features of sitectl is that Remote commands is not a hardcoded
menu. You can add your own server-side commands and submenus by dropping files
into ~/.config/sitectl/remote/.
That means you can keep using the built-in commands, but also grow your own library of deploy scripts, maintenance routines, bootstrap steps, and dangerous ops with explicit confirmation prompts.
Built-in bundled remote commands include base package setup, Docker helpers,
firewall setup, shell setup, and a Speedtest submenu for installing, running,
and removing the Ookla CLI.
You can run those commands either from the interactive menu or directly from the CLI with:
sitectl run docker/install-docker my-serverThe first argument is the command path inside ~/.config/sitectl/remote/, using
folder names plus the command basename without the file extension. The second
argument is the configured server name.
Remote Command Discovery
Remote command menus are discovered from matching metadata files:
foo.sh+foo.jsonbecomes a commandfolder/+folder.jsonbecomes a submenu- files without matching
.jsonmetadata are ignored - optional
ordersorts items inside the current menu; items withoutorderare shown after ordered items and use alphabetical order as a tie-breaker
Remote Command Metadata
Shape for remote metadata:
{
name: string;
order?: number;
hidden?: boolean;
confirmation?: string;
uploads?: Array<{
from: string;
to: string;
}>;
}When uploads is present, sitectl uploads those local paths before it starts the
remote script:
fromis a local file or directory path on the machine runningsitectlfromalso supports a glob, but it must resolve to exactly one pathtois the final destination path on the remote server- parent directories for
toare created automatically beforersyncruns - the remote script starts only after every upload succeeds
This is useful when a remote command needs a local file first, for example to restore backups, replace a database, upload a release artifact, send config files, or stage migration data before the server-side script runs.
Remote Command Example
Examples:
remote/
backups.sh
backups.json
docker/
uninstall-docker.sh
uninstall-docker.json
docker.json{
"name": "Uninstall Docker completely",
"order": 20,
"confirmation": "Are you sure you want to delete Docker containers, images, volumes, and package data?"
}Upload example:
{
"name": "Replace 3x-ui DB",
"confirmation": "This will overwrite the remote 3x-ui database. Continue?",
"uploads": [
{
"from": "~/Backups/x-ui.db",
"to": "/tmp/sitectl/3x-ui-replace-db/x-ui.db"
}
]
}That command can then use a remote shell script that moves the uploaded file into place, restarts services, or performs any other server-side steps it needs.
Menu
Manage serversAdd serverEdit serverDelete serverSync files to serverSSH copy idSSH
Manage sitesAdd siteOpen nginx.confCopy conf files to serverIssue certificateEnable httpsDisable httpsRemove site from server
Remote commandsInstall base packagesDockerInstall DockerUninstall Docker completely
SpeedtestInstall speedtestRun speedtestUninstall speedtest
Configure zshSetup ufw...your custom commands...
Open data dir
The non-interactive commands are:
sitectl initsitectl init --overwrite-bundledsitectl run <command> <server_name>sitectl sshsitectl ssh <server-name>sitectl ssh <server-name> '<full remote command string>'sitectl ssh-copy-id
For nginx site deployment, sitectl guarantees compatibility only for configs
that keep using its managed include files under /etc/nginx/sitectl-includes/
together with the user-editable
~/.config/sitectl/nginx/sites/nginx-template.conf. Other generated nginx
fragments are internal implementation details managed by sitectl.
Nginx site registry lives in:
~/.config/sitectl/nginx/sites/nginx-template.conf~/.config/sitectl/nginx/sites/<host>/nginx.conf
Manage Servers Workflow
Typical flow for a new VPS:
Add serverSSH copy idRemote commands -> Install base packagesRemote commands -> Docker -> Install Dockerif neededRemote commands -> Configure zshRemote commands -> Setup ufw
What those actions do:
Add serverCreates a server record in~/.config/sitectl/config.json.sitectl ssh-copy-idInstalls your SSH public key on the target server so the rest of the workflow can work over key-based SSH.Sync files to serverUploads a local file or directory to a chosen remote destination overrsync. Useful for one-off copies into/tmp, home-directory paths like~/uploads/, or other server-side locations before you run follow-up commands.Install base packagesRuns the opinionated bootstrap script for supported Debian and Ubuntu servers.Install dockerInstalls Docker CE and the Docker Compose plugin from Docker's apt repository.Uninstall docker completelyCompletely removes Docker packages and permanently deletes Docker data, including containers, images, networks, and volumes.Configure zshInstallszshandoh-my-zshif needed, switches the user's default shell tozsh, then applies the custom shell config bundled inside~/.config/sitectl/remote/configure-zsh.sh.Setup ufwApplies the default firewall rules for SSH, HTTP, and HTTPS.
Manage Sites Workflow
Typical flow for a new site:
Add site- edit
nginx.conf Copy conf files to serverIssue certificateEnable https
What those actions do:
Add siteCreates~/.config/sitectl/nginx/sites/<host>/and seedsnginx.conffrom~/.config/sitectl/nginx/sites/nginx-template.conf.Open nginx.confOpens the local site config for editing.Copy conf files to serverUploads:- the internal HTTP-only site config managed by
sitectl <host>.confif localnginx.confexists- managed include files in
/etc/nginx/sitectl-includes/The editable HTTPS/site config comes from your local site template and per-site config. Compatibility is guaranteed only for configs that keep using the managedsitectlinclude files.
- the internal HTTP-only site config managed by
Issue certificateUsescertbot certonly --nginx -d <host>for domain hosts. For IP hosts, uses Certbot's IP certificate flow with--webroot,--ip-address, and the requiredshortlivedprofile. If the remote system Certbot is too old for IP issuance,sitectlcan optionally install an isolated newer Certbot in/opt/certbotduring the issuance flow. This command is intended for the initial HTTP-only flow before the main HTTPS config is enabled. After issuing a certificate, the site remains on the internal HTTP-only config until you explicitly runEnable https.Enable httpsSwitchessites-enabled/<host>.confto the main HTTPS config.Disable httpsSwitchessites-enabled/<host>.confback to the internal HTTP-only config.Remove site from serverDeletes the remote nginx config, managed SSL include, and active symlink for the selected site. If the certificate lineage is clearly site-specific, it also removes the certbot certificate.
Config
Server records are stored locally in:
~/.config/sitectl/config.jsonCurrent server shape:
{
"servers": {
"prod": {
"address": "203.0.113.10",
"flag": "🌍",
"port": 22,
"user": "root"
}
}
}Run
npm run devSSH command:
npm run ssh
npm run ssh -- prod
npm run ssh -- prod 'echo "hello world!"'
npm run ssh-copy-idAfter global install:
sitectl ssh
sitectl ssh prod
sitectl ssh prod 'echo "hello world!"'
sitectl ssh-copy-idInteractive actions are available through the menu opened by sitectl.
Build
npm run buildTest
npm testThe test suite covers host detection and nginx host rendering, including the
IPv6 server_name [addr] case used for site templates.
For IP certificate issuance, the remote server needs Certbot 5.4.0 or newer.
If the system package is older, sitectl can prompt to install an isolated
newer Certbot in /opt/certbot and configure renewal for it.
Built CLI also starts without arguments:
node dist/index.js