Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions prod-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ INDEX_FILE="$PROJECT_DIR/index.js"
ENV_FILE="$PROJECT_DIR/.env"
LOG_DIR="$PROJECT_DIR/logs"
BOT_LOG="$LOG_DIR/runewager.log"
LEGACY_BOT_LOG="$PROJECT_DIR/runewager.log"
CRASH_LOG="$LOG_DIR/crash.log"
SYSTEMD_STDOUT_LOG="$LOG_DIR/runewager-1.log"
SERVICE_FILE="/etc/systemd/system/runewager.service"
LOGROTATE_FILE="/etc/logrotate.d/runewager"
CRON_LINE='0 3 * * * /usr/sbin/logrotate -f /etc/logrotate.d/runewager'
Expand All @@ -31,6 +34,17 @@ ensure_file() {
[ -f "$1" ] || : > "$1"
}

ensure_log_paths() {
ensure_dir "$LOG_DIR"
ensure_file "$BOT_LOG"
ensure_file "$CRASH_LOG"
ensure_file "$SYSTEMD_STDOUT_LOG"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Pre-creating the systemd stdout log file in ensure_log_paths() can cause permission errors when the script is run as a different user than the systemd service user: if prod-run.sh is ever run manually as root, it will create $SYSTEMD_STDOUT_LOG as a root-owned file, and later when systemd starts the service as the runewager user with StandardOutput=append:$SYSTEMD_STDOUT_LOG, systemd will fail to append to this file with "permission denied", preventing the service from starting correctly. Letting systemd create and own its own stdout log file avoids this mismatch. [logic error]

Severity Level: Critical 🚨
- ❌ Systemd runewager service fails to start on production VPS.
- ❌ Telegram bot offline; /health and /metrics endpoints unavailable.
- ⚠️ Manual prod-run.sh diagnostics can silently break systemd logging.
Suggested change
ensure_file "$SYSTEMD_STDOUT_LOG"
Steps of Reproduction ✅
1. Set up the production deployment under `/var/www/html/Runewager` following
`README.md:102-155`, which creates the `runewager` system user and the app directory and
installs the provided unit file `/var/www/html/Runewager/runewager.service`.

2. Inspect the unit file `/var/www/html/Runewager/runewager.service` (lines 8-12 and 18 in
that file): it runs `ExecStart=/var/www/html/Runewager/prod-run.sh` as `User=runewager`
and `Group=runewager`, with
`StandardOutput=append:/var/www/html/Runewager/logs/runewager-1.log`.

3. As `root` (or any user different from `runewager`), run the startup script manually in
the app directory: `cd /var/www/html/Runewager && ./prod-run.sh`. In
`prod-run.sh:454-466`, `main()` calls `ensure_log_paths`, which in turn calls `ensure_file
"$SYSTEMD_STDOUT_LOG"` at `prod-run.sh:41`, creating or truncating
`/var/www/html/Runewager/logs/runewager-1.log` owned by `root` (typically mode `0644
root:root`).

4. Restart the systemd service: `sudo systemctl restart runewager`. Systemd now starts
`prod-run.sh` as `User=runewager` (unit lines 8-12) and tries to append to
`/var/www/html/Runewager/logs/runewager-1.log` per
`StandardOutput=append:/var/www/html/Runewager/logs/runewager-1.log` (unit line 18), but
the file is owned by `root` and not writable by `runewager`, so systemd fails to open the
stdout log with a permission denied error and the `runewager` service fails to start.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** prod-run.sh
**Line:** 41:41
**Comment:**
	*Logic Error: Pre-creating the systemd stdout log file in `ensure_log_paths()` can cause permission errors when the script is run as a different user than the systemd service user: if `prod-run.sh` is ever run manually as root, it will create `$SYSTEMD_STDOUT_LOG` as a root-owned file, and later when systemd starts the service as the `runewager` user with `StandardOutput=append:$SYSTEMD_STDOUT_LOG`, systemd will fail to append to this file with "permission denied", preventing the service from starting correctly. Letting systemd create and own its own stdout log file avoids this mismatch.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎


if [ ! -f "$LEGACY_BOT_LOG" ]; then
: > "$LEGACY_BOT_LOG"
fi
}

fix_working_directory() {
if [ "$(pwd)" != "$PROJECT_DIR" ]; then
say "Switching working directory to $PROJECT_DIR"
Expand Down Expand Up @@ -324,7 +338,7 @@ Restart=always
RestartSec=5
KillSignal=SIGTERM
TimeoutStopSec=20
StandardOutput=append:$LOG_DIR/runewager-1.log
StandardOutput=append:$SYSTEMD_STDOUT_LOG
StandardError=inherit

[Install]
Expand All @@ -347,7 +361,7 @@ CONF
"WorkingDirectory=$PROJECT_DIR"
"ExecStart=$PROJECT_DIR/prod-run.sh"
"EnvironmentFile=$PROJECT_DIR/.env"
"StandardOutput=append:$LOG_DIR/runewager-1.log"
"StandardOutput=append:$SYSTEMD_STDOUT_LOG"
'Environment=NODE_ENV=production'
'Restart=always'
'RestartSec=5'
Expand Down Expand Up @@ -380,6 +394,9 @@ print_human_errors() {

local blob
blob="$(tail -n 200 "$BOT_LOG" 2>/dev/null || true)"
if [ -z "$blob" ] && [ -f "$LEGACY_BOT_LOG" ]; then
blob="$(tail -n 200 "$LEGACY_BOT_LOG" 2>/dev/null || true)"
fi

say "Human-readable diagnosis"
printf '%s\n' "$blob" | grep -qi 'Cannot find module' && say "Root cause: A Node module is missing or a require path is wrong. Run npm ci and verify relative import paths."
Expand Down Expand Up @@ -446,10 +463,9 @@ main() {
exit 1
fi

ensure_dir "$LOG_DIR"
ensure_log_paths
ensure_dir "$PROJECT_DIR/data"
ensure_dir "$PROJECT_DIR/data/backups"
ensure_file "$BOT_LOG"

fix_merge_conflicts
fix_lockfiles
Expand Down