sidebar_position: 7
Ops Toolbox
Purpose: Reference for operational scripts in deployment/ec2/scripts/
Status: Active
Last Updated: April 2026
ops.sh is a lightweight operational toolbox for day-to-day EC2 host management. It complements the heavier install.sh (full infra install) and deploy.sh (full code deploy) by offering targeted, safe subcommands with automatic backups.
When to Use Which Script
| Task | Script |
|---|---|
| First-time server setup | provision.sh |
| Full infra install/refresh (nginx + workers) | install.sh |
| Code deployment (code + assets + migrations) | deploy.sh or ops.sh deploy |
| Resync one or more nginx configs with backup | ops.sh resync nginx |
| Provision or renew TLS certs for specific apps | ops.sh ssl |
| Rollback to a previous git ref | rollback.sh |
| Toggle maintenance mode | maintenance.sh |
| Install command aliases | install-aliases.sh |
Command Aliases (Optional)
For convenience, you can install system-wide command aliases that allow you to run ops scripts from anywhere without typing full paths:
# Install aliases (creates symlinks in /usr/local/bin)
sudo /var/www/loreax/deployment/ec2/scripts/install-aliases.sh
# Available aliases after installation:
loreax-ops <command> # ops.sh wrapper
loreax-deploy [options] # deploy.sh wrapper
loreax-rollback [options] # rollback.sh wrapper
loreax-maintenance <on|off> # maintenance.sh wrapper
Benefits:
- Run commands from any directory
- Shorter, memorable command names
- Consistent
loreax-*namespace
Uninstall:
sudo /var/www/loreax/deployment/ec2/scripts/install-aliases.sh --uninstall
Note: The provision.sh script automatically installs these aliases during first-time server setup.
Usage
# Without aliases
bash deployment/ec2/scripts/ops.sh <command> [subcommand] [options]
# With aliases installed
loreax-ops <command> [subcommand] [options]
Run with --help for a summary at any level.
Commands
deploy
Manually trigger a full deployment when CI/CD fails or for direct server deployments.
Usage:
# Deploy current branch (fast-forward to origin)
loreax-ops deploy
# Deploy specific branch, tag, or commit
loreax-ops deploy --ref=master
loreax-ops deploy --ref=v1.2.3
loreax-ops deploy --ref=abc1234
# Skip build steps (when only config changed)
loreax-ops deploy --skip-build
# Skip infrastructure sync (nginx + systemd)
loreax-ops deploy --skip-infra
# Combine options
loreax-ops deploy --ref=hotfix/payment-bug --skip-infra
What it does:
- Pulls the specified git ref (or fast-forwards current branch)
- Syncs nginx configs and systemd units (unless
--skip-infra) - Runs
composer installandbun run build(unless--skip-build) - Generates OpenAPI specification
- Runs database migrations
- Caches config, routes, events, and views
- Reloads PHP-FPM and Horizon
When to use:
- CI/CD pipeline fails but code is ready
- Emergency hotfix deployment
- Testing deployment process on staging
- Manual deployment during initial setup
resync nginx
Resyncs nginx site configs from the repo working tree into /etc/nginx/sites-available/, with an automatic timestamped backup before overwriting.
# Resync all configs
bash deployment/ec2/scripts/ops.sh resync nginx --all
# Resync specific apps (comma-separated)
bash deployment/ec2/scripts/ops.sh resync nginx --app=api
bash deployment/ec2/scripts/ops.sh resync nginx --app=dev,admin
bash deployment/ec2/scripts/ops.sh resync nginx --app=api,dev,admin
App names map to conf files by prefix match (api → api.loreax.bervant.co.ke.conf):
| App name | Conf file |
|---|---|
api |
api.loreax.bervant.co.ke.conf |
admin |
admin.loreax.bervant.co.ke.conf |
dev |
dev.loreax.bervant.co.ke.conf |
What it does for each conf:
- Backs up the current
/etc/nginx/sites-available/<conf>→<conf>.bak.<YYYYMMDD_HHMMSS> - Installs the new conf from
deployment/ec2/nginx/<conf>(mode644) - Ensures the symlink in
/etc/nginx/sites-enabled/exists - Runs
nginx -tto validate the full nginx config - If validation passes: reloads nginx (
systemctl reload nginx) - If validation fails: exits with an error — nginx is not reloaded and backups remain for manual recovery
Recovering from a bad config:
# Find the backup
ls /etc/nginx/sites-available/*.bak.*
# Restore it
sudo cp /etc/nginx/sites-available/api.loreax.bervant.co.ke.conf.bak.20260501_143022 \
/etc/nginx/sites-available/api.loreax.bervant.co.ke.conf
# Verify and reload
sudo nginx -t && sudo systemctl reload nginx
ssl
Provisions (or renews) Let's Encrypt TLS certificates via certbot's --nginx plugin. Always performs a resync nginx first so certbot operates on the latest config from the repo.
Prerequisite: certbot and the nginx plugin must be installed.
# Install certbot if not present
sudo apt-get install -y certbot python3-certbot-nginx
Usage:
# Provision certs for all three surfaces
bash deployment/ec2/scripts/ops.sh ssl --all
# Provision certs for specific apps only
bash deployment/ec2/scripts/ops.sh ssl --app=api
bash deployment/ec2/scripts/ops.sh ssl --app=api,dev,admin
# Use a custom email for the Let's Encrypt account (default: admin@loreax.bervant.co.ke)
bash deployment/ec2/scripts/ops.sh ssl --all --email=ops@yourdomain.com
What it does:
- Resolves conf files for the selected apps (same
--all/--app=logic asresync nginx) - Backs up and resyncs the selected confs from the repo working tree
- Validates with
nginx -tand reloads nginx — stops here if validation fails - Reads the
server_namedirective from each installed conf to determine the hostname - Runs
certbot --nginx --non-interactive --agree-tos -d <host1> [-d <host2> ...] - certbot patches the installed confs in-place, uncommenting the SSL
listen 443and certificate lines that are already present in the repo configs
After running:
The installed nginx confs will have their SSL blocks activated by certbot. These changes are in /etc/nginx/sites-available/ — they are not reflected back into the repo. The repo confs intentionally keep the SSL lines commented out so they work on HTTP-only environments (local, fresh provisions) without modification.
Renewal:
certbot auto-renewal runs via a system timer. Verify it is active:
sudo systemctl status certbot.timer
# Force a dry-run renewal to confirm it would succeed
sudo certbot renew --dry-run
Provisioning order matters: DNS A-records for all target hostnames must resolve to this server before running ssl. certbot performs an HTTP-01 challenge over port 80.
# Verify DNS before running ssl
dig +short api.loreax.bervant.co.ke
dig +short admin.loreax.bervant.co.ke
dig +short dev.loreax.bervant.co.ke
# All three should return 35.178.52.158
Source
deployment/ec2/scripts/ops.sh — requires bash, nginx, sudo, and (for ssl) certbot with the nginx plugin.