Deployment Guide - digitalunconciousness/shiftledger GitHub Wiki
ShiftLedger is designed to run as a lightweight service on a Linux server, Proxmox LXC container, or any system with Node.js and systemd.
In the Proxmox web UI:
- Template: Debian 12 (Bookworm) standard
- CPU: 1 core
- RAM: 512 MB
- Disk: 4 GB (plenty for the app + years of data)
- Network: DHCP or static IP on your LAN
SSH into the container and run:
apt-get update && apt-get install -y git
git clone https://github.com/digitalunconciousness/shiftledger.git
cd shiftledger
chmod +x install.sh
./install.shThe installer handles everything — see Getting Started for details.
systemctl status shiftledger
curl http://localhost:3000/api/auth/statusThe installer creates /etc/systemd/system/shiftledger.service:
[Unit]
Description=ShiftLedger Earnings Tracker
After=network.target
[Service]
Type=simple
User=shiftledger
WorkingDirectory=/opt/shiftledger
Environment=NODE_ENV=production
Environment=PORT=3000
Environment=DB_PATH=/opt/shiftledger/shifts.db
Environment=SESSION_SECRET=<generated>
ExecStart=/usr/bin/node /opt/shiftledger/server.js
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=shiftledger
[Install]
WantedBy=multi-user.target-
Dedicated user (
shiftledger) — non-root, no login shell - Auto-restart — if the process crashes, systemd restarts it after 5 seconds
- Journal logging — stdout/stderr go to journald
sudo systemctl start shiftledger # start
sudo systemctl stop shiftledger # stop
sudo systemctl restart shiftledger # restart
sudo systemctl status shiftledger # check status
sudo systemctl enable shiftledger # start on boot
sudo systemctl disable shiftledger # don't start on boot
journalctl -u shiftledger -f # follow live logs
journalctl -u shiftledger --since "1 hour ago" # recent logsThe installer optionally configures nginx on port 80. To set it up manually:
sudo apt-get install -y nginxCreate /etc/nginx/sites-available/shiftledger:
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection '';
proxy_buffering off;
}
}sudo ln -sf /etc/nginx/sites-available/shiftledger /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl restart nginxIf exposing directly to the internet (without a tunnel):
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.comTo update to a new version:
# On your development machine or wherever the repo lives
cd /path/to/shiftledger
git pull
# Copy files to the deployment directory
sudo cp server.js /opt/shiftledger/
sudo cp -r public/ /opt/shiftledger/
sudo cp package.json /opt/shiftledger/
# Install any new dependencies
cd /opt/shiftledger
sudo -u shiftledger npm install --omit=dev
# Restart
sudo systemctl restart shiftledgerDatabase migrations run automatically on startup — no manual steps needed.
For development or non-systemd systems:
cd /path/to/shiftledger
npm install
PORT=3000 SESSION_SECRET=$(openssl rand -hex 32) node server.jsShiftLedger doesn't ship a Dockerfile, but creating one is straightforward:
FROM node:20-slim
WORKDIR /app
COPY package.json ./
RUN npm install --omit=dev
COPY . .
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE 3000
VOLUME ["/app/data"]
CMD ["node", "server.js"]Run with:
docker run -d -p 3000:3000 \
-e SESSION_SECRET=$(openssl rand -hex 32) \
-e DB_PATH=/app/data/shifts.db \
-v shiftledger-data:/app/data \
shiftledgerTypical resource consumption:
- Memory: ~30–50 MB RSS
- CPU: Negligible (SQLite queries are fast)
- Disk: Database grows ~1 KB per shift. 10,000 shifts ≈ 10 MB.
- Network: Minimal — only serves the SPA and JSON API responses