- Path:
docs/setup/ubuntu/app.md - Template Version:
20260508
This document describes how to deploy and configure github-flows-app under a dedicated Ubuntu runtime user referenced as user.
The document covers application directory creation, repository cloning, .env configuration, production dependency installation, systemd service registration, application logging, and log rotation.
This document assumes that the operating system runtime user, Docker access, nvm, and Node.js are already configured.
The runtime user is referenced as user.
The application is deployed into:
/home/user/app/github-flows/
The application listens on localhost:
127.0.0.1:5020
The runtime workspace is located under the application directory:
/home/user/app/github-flows/var/work/
The deployment-specific service name is referenced as flows-user.
Switch to the runtime user:
sudo -iu userCreate the application base directory:
mkdir -p ~/app
cd ~/appClone github-flows-app into ~/app/github-flows:
git clone https://github.com/flancer32/github-flows-app.git github-flows
cd ~/app/github-flowsThe resulting application directory is:
/home/user/app/github-flows/
The application is configured through a local .env file.
Create it from the example:
cp .env.example .env
nano .envSet the runtime values:
HOST=127.0.0.1
PORT=5020
WORKSPACE_ROOT=./var/work
WEBHOOK_SECRET=replace-with-shared-secretRestrict access to the configuration file:
chmod 600 .envCreate the runtime workspace directories:
cd /home/user/app/github-flows
mkdir -p ./var/work
mkdir -p ./var/work/log
mkdir -p ./var/work/cfgCreate the application log file under the runtime user:
touch ./var/work/app.log
chmod 640 ./var/work/app.logThe public web/ directory may contain symbolic links to runtime log and configuration directories.
Create or update the links manually:
cd /home/user/app/github-flows
ln -sfn ../var/work/log ./web/log
ln -sfn ../var/work/cfg ./web/cfgCheck the links:
readlink -f ./web/log
readlink -f ./web/cfgExpected targets:
/home/user/app/github-flows/var/work/log
/home/user/app/github-flows/var/work/cfg
The repository contains package-lock.json, and no build step is required.
Install only production dependencies:
cd /home/user/app/github-flows
npm ci --omit=devShow available npm scripts:
npm runTest the application manually:
npm run startCheck local HTTP access:
curl -I http://127.0.0.1:5020/Stop the manual process before registering the application as a service.
Create the service file:
sudo nano /etc/systemd/system/flows-user.serviceUse this configuration:
[Unit]
Description=GitHub Flows App
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
User=user
Group=user
WorkingDirectory=/home/user/app/github-flows
ExecStart=/bin/bash -lc 'source /home/user/.nvm/nvm.sh && exec npm run start >> /home/user/app/github-flows/var/work/app.log 2>&1'
Restart=always
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.targetThe service does not use EnvironmentFile. Runtime configuration is loaded by the application from its local .env file.
The log redirection is placed inside ExecStart so that the log file is opened by the process running under user. This avoids creating the log file as root, which can happen when StandardOutput=append: is used by systemd.
Reload systemd:
sudo systemctl daemon-reloadEnable the service:
sudo systemctl enable flows-userStart the service:
sudo systemctl start flows-userCheck the service status:
systemctl status flows-userCheck the application log:
tail -f /home/user/app/github-flows/var/work/app.logCheck that the application listens on the configured local port:
ss -ltnp | grep 5020Check HTTP access through the local application port:
curl -I http://127.0.0.1:5020/The application log is written to:
/home/user/app/github-flows/var/work/app.log
Create the logrotate configuration:
sudo nano /etc/logrotate.d/flows-userUse this configuration:
/home/user/app/github-flows/var/work/app.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
copytruncate
create 0640 user user
su user user
}
Check the configuration:
sudo logrotate -d /etc/logrotate.d/flows-userForce a test rotation if needed:
sudo logrotate -f /etc/logrotate.d/flows-userAfter forced rotation, check the log files:
ls -lh /home/user/app/github-flows/var/work/app.log*The active log file must remain writable by user.
After the setup:
- the application repository is cloned to
/home/user/app/github-flows/; - the
.envfile is created from.env.example; - the
.envfile is readable only by the runtime user; - runtime directories exist under
/home/user/app/github-flows/var/work/; web/logpoints to/home/user/app/github-flows/var/work/log;web/cfgpoints to/home/user/app/github-flows/var/work/cfg;app.logexists and is owned byuser;- production npm dependencies are installed;
- the application starts manually with
npm run start; - the
flows-usersystemd service is enabled; - the service runs under the
useraccount; - the service starts the application through
nvmandnpm run start; - the service restarts automatically on failure;
- stdout and stderr are written to
/home/user/app/github-flows/var/work/app.log; - log rotation is configured through
/etc/logrotate.d/flows-user; - the application is available locally at
http://127.0.0.1:5020/.