Skip to content

Latest commit

 

History

History
120 lines (81 loc) · 5.67 KB

File metadata and controls

120 lines (81 loc) · 5.67 KB

Auto-deploy

Server-side hourly rebuild + rsync to webroot. Triggered by a systemd timer; no CI, no webhooks, no secrets to manage.

What runs

Component Purpose
deploy.sh Idempotent pipeline: fetch umstutorial → npm ci (only if lockfile moved) → sync umsme → sync gdrive → build → rsync dist/ to webroot. Skips build+rsync when nothing changed.
umstutorial-deploy.service Oneshot systemd unit that runs deploy.sh as the deploy user.
umstutorial-deploy.timer Fires OnCalendar=hourly with Persistent=true so a missed run catches up after reboot.
bootstrap.sh One-time setup: installs the units, enables the timer, triggers a first deploy.

Default paths (override with env vars when calling bootstrap.sh / deploy.sh):

  • Clone: /srv/umstutorial
  • Webroot: /var/www/tutorial.uppsalamakerspace.se

One-time setup on a fresh server

Prerequisites: git, node ≥ 18, npm, rsync, systemd. The deploy user must own both the clone and the webroot.

# 1. Create a low-privilege deploy user (skip if you already have one).
sudo useradd -r -m -d /srv/umstutorial -s /usr/sbin/nologin deploy

# 2. Clone the repo into /srv/umstutorial (as the deploy user, via HTTPS so
#    no SSH key is needed).
sudo -u deploy git clone https://github.com/uppsala-makerspace/umstutorial.git /srv/umstutorial

# 3. Run the bootstrap. This installs the systemd units, enables the timer,
#    and kicks off a first deploy synchronously so failures surface here.
cd /srv/umstutorial
sudo DEPLOY_USER=deploy ./deploy/bootstrap.sh

The first deploy populates /var/www/tutorial.uppsalamakerspace.se. Point your existing nginx vhost at that directory if it isn't already.

Node and the deploy user

bootstrap.sh probes two things separately:

  • login shell — what sudo -iu deploy sees. Sources .bashrc/.profile, so any nvm initialisation there runs.
  • service env — the bare environment systemd will give the unit: a clean PATH, no shell init, no nvm.

The systemd timer fails if the service env probe finds no node (or one older than 18), even if the login shell looks fine. This is the most common nvm trap: node lives under ~/.nvm/versions/node/v…/bin, which only ends up on PATH when a shell init script runs.

Three fixes, in order of preference:

  1. Install node ≥ 18 system-wide (recommended). Puts node in /usr/bin or /usr/local/bin, which is on the service PATH out of the box. On Debian/Ubuntu:

    curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
    sudo apt-get install -y nodejs

    If the install fails with a dpkg file-conflict on /usr/include/node/common.gypi (or similar), purge Ubuntu's split libnode-dev / libnode* packages first — NodeSource's nodejs deb is self-contained and collides with them:

    sudo apt-get purge -y libnode-dev 'libnode[0-9]*'
    sudo apt-get autoremove -y
    sudo apt-get install -y nodejs

    Then re-run sudo DEPLOY_USER=deploy ./deploy/bootstrap.sh.

  2. Use nvm under the deploy user and point the service at the nvm bin directory. After installing nvm + node 22 as the deploy user, edit /etc/systemd/system/umstutorial-deploy.service and change the Environment=PATH=… line to prepend the nvm bin path:

    Environment=PATH=/home/deploy/.nvm/versions/node/v22.21.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

    Then sudo systemctl daemon-reload && sudo systemctl start umstutorial-deploy.service. The version directory will change when you bump node, so prefer fix 1 if you can.

  3. Symlink the root-installed nvm node into a system path. Quick and dirty; brittle when node is upgraded. Only as a stopgap:

    sudo ln -sf "$(readlink -f /root/.nvm/versions/node/v22.21.0/bin/node)" /usr/local/bin/node
    sudo ln -sf "$(readlink -f /root/.nvm/versions/node/v22.21.0/bin/npm)"  /usr/local/bin/npm

Operator commands

systemctl status umstutorial-deploy.timer         # next run + last result
journalctl -u umstutorial-deploy.service -n 50    # recent deploy logs
journalctl -fu umstutorial-deploy.service         # follow live
sudo systemctl start umstutorial-deploy.service   # force a deploy now

A run that found no changes logs one line (no changes (umstutorial=…, umsme=…, gdrive=…)); a real deploy logs deployed umstutorial=… umsme=… gdrive=…. Everything from the build pipeline goes to the journal.

Upgrading

To pull in changes to the deploy artifacts themselves (this directory):

sudo -u deploy git -C /srv/umstutorial pull
sudo ./deploy/bootstrap.sh    # re-runs systemd install + daemon-reload

Day-to-day code changes don't need this — the hourly timer picks them up automatically.

Removing

sudo systemctl disable --now umstutorial-deploy.timer
sudo rm /etc/systemd/system/umstutorial-deploy.{service,timer}
sudo systemctl daemon-reload

The clone and webroot stay; remove them by hand if you also want those gone.

Adapting for other repos

Copy deploy/ to a sibling repo and change three values:

  1. The clone path and webroot in deploy.sh (CLONE, WEBROOT defaults).
  2. The sync command line — replace scripts/sync-umsme.sh --https with whatever pulls that repo's inputs (delete it if there are none).
  3. The service / timer names (rename umstutorial-deploy throughout).