@avelor/vhost
v0.1.1
Published
Apache virtual host manager. Declarative sites, catch-all protection, and built-in error pages.
Maintainers
Readme
@avelor/vhost
Apache virtual host manager. Define your sites in a YAML file, run one command, and Apache is configured.

sudo vhost apply ✓ catch-all protected
✓ error pages /var/www/vhost-errors
✓ errors conf vhost-errors.conf
✓ avelor.com managed /home/avelor/avelor
✓ api.avelor.es managed :3000
✓ app.avelor.es managed :4000
✓ apache configtest
✓ apache reloadRequirements
- Node.js 18+
- Apache2 with
a2ensite,a2enconf,apache2ctl,mod_headers - Debian / Ubuntu
mod_headers is required for the X-Powered-By response header on error pages. Enable it if not already active:
sudo a2enmod headers && sudo systemctl reload apache2Install
npm install -g @avelor/vhostUsage
1. Create sites.yml:
vhost init2. Add your sites:
sites:
myblog.com:
aliases: [www.myblog.com]
mode: static
root: /var/www/myblog
api.myapp.com:
mode: proxy
port: 30003. Apply:
sudo vhost applyApache is configured, enabled, and reloaded.
Commands
| Command | Description |
|---|---|
| vhost init | Create sites.yml in the current directory |
| vhost new [domain] | Add a site interactively (or via flags) |
| sudo vhost apply [domain] | Generate configs, enable sites, reload Apache |
| sudo vhost remove <domain> | Disable and remove a site |
| vhost check | Diff sites.yml against current Apache state |
| vhost status | Show enabled sites |
Site configuration
Static site
sites:
example.com:
mode: static
root: /var/www/example.com
aliases: [www.example.com] # optionalReverse proxy
sites:
api.example.com:
mode: proxy
port: 3000
aliases: [api2.example.com] # optionalManual SSL
By default, SSL is left for Certbot to manage. To provide your own certificates:
sites:
example.com:
mode: static
root: /var/www/example.com
ssl:
cert: /etc/ssl/certs/example.pem
key: /etc/ssl/private/example.keyWhat apply does
For each site, vhost apply generates a .conf in /etc/apache2/sites-available/ containing:
- HTTP → HTTPS redirect
- HTTPS VirtualHost (static or proxy)
- SSL block (Certbot placeholder or custom cert)
- Per-site error and access logs
It also sets up two pieces of infrastructure the first time:
Catch-all — any request to an unconfigured domain returns a clean error page instead of falling through to the first VirtualHost alphabetically, which is the default Apache behavior.
Error pages — built-in pages for 400, 401, 403, 404, 405, 408, 429, 500, 502, 503, and 504. Each error code has four variants served via content negotiation:
| Accept header | Response |
|---|---|
| text/html | Styled HTML page |
| application/json | { "code": 404, "message": "Page not found.", "source": "@avelor/vhost" } |
| application/xml | <error><code>404</code><message>…</message></error> |
| text/plain | 404 Page not found. |
All responses include an X-Powered-By: avelor/vhost header. The source field in JSON and the X-Powered-By header make it easy to distinguish vhost error responses from your own API errors.
Useful when the same server hosts both web apps and APIs.
vhost new
Interactive when no flags are given:
$ vhost new
Domain: api.myapp.com
Aliases (space-separated, optional):
Mode: [1] static [2] proxy → 2
Proxy port: 3000
SSL via certbot? [Y/n]:
✓ api.myapp.com added to sites.yml
Next steps:
sudo vhost apply api.myapp.com
sudo certbot --apache -d api.myapp.comOr skip the prompts with flags:
vhost new api.myapp.com --mode proxy --port 3000
vhost new myblog.com --mode static --root /var/www/myblogPartial flags work too — only the missing fields are asked.
vhost check
Compares sites.yml against Apache's actual state and exits 1 if anything is off.
✓ catch-all
✓ vhost-errors.conf
✓ error pages /var/www/vhost-errors
✓ avelor.com managed /home/avelor/avelor
! api.avelor.es manual config → run: vhost apply api.avelor.es to migrate
✖ app.avelor.es not applied → run: vhost apply app.avelor.es
! old.avelor.es manual config not in sites.yml
✖ 3 issues found.A site is managed when its .conf was generated by vhost apply. Manual config means the file exists but was written by hand — it works, but sites.yml is not the source of truth yet.
Migrating existing configs
vhost is designed to be adopted gradually. Your existing Apache configs keep working untouched.
The typical flow:
# 1. Set up infrastructure without touching existing sites
sudo vhost apply
# 2. Add one site at a time
vhost new avelor.com --mode static --root /home/avelor/avelor
# 3. Apply only that site — overwrites the manual .conf
sudo vhost apply avelor.com
# 4. Check progress
vhost checkWhen vhost check shows no manual config warnings, the migration is complete.
License
MIT
