Last active
May 11, 2025 20:46
-
-
Save glektarssza/c39b4d34ca893108fa1f29742c3e3e27 to your computer and use it in GitHub Desktop.
Factorio Systemd Service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-- Put your environment variable overrides here! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
#-- Unit metadata | |
Description=Factorio Server (%i) | |
#-- Dependencies | |
After=network-online.target | |
Wants=network-online.target | |
[Service] | |
#-- Service type | |
Type=simple | |
#-- Restart on failure | |
Restart=on-failure | |
#-- Wait 3 seconds before restarting | |
RestartSec=3s | |
#-- Limit to a maximum of 3 restarts per day | |
StartLimitInterval=1d | |
StartLimitBurst=3 | |
#-- User and group | |
User=factorio | |
Group=factorio | |
#-- Define I/O | |
[email protected] | |
StandardInput=socket | |
StandardOutput=journal | |
StandardError=journal | |
#-- Directories | |
RuntimeDirectory=factorio | |
RuntimeDirectoryMode=0775 | |
RuntimeDirectoryPreserve=no | |
WorkingDirectory=/<YOUR_FACTORIO_ROOT>/ | |
#-- Protect various system parameters | |
ProtectSystem=full | |
ProtectHome=true | |
ProtectKernelTunables=true | |
ProtectKernelModules=true | |
ProtectControlGroups=true | |
#-- Timeout settings | |
TimeoutStopSec=30 | |
#-- Default environment variables | |
Environment=FACTORIO_STOP_BEFORE_SAVE_DELAY=10 | |
Environment=FACTORIO_STOP_AFTER_SAVE_DELAY=5 | |
Environment=FACTORIO_FINAL_STOP_DELAY=3 | |
#-- Environment file | |
EnvironmentFile=-/<YOUR_FACTORIO_ROOT>/config/%i/.envrc | |
#-- Startup command(s) | |
ExecStart=/<YOUR_FACTORIO_ROOT>/startFactorioServer.sh "%i" | |
#-- Stop command(s) | |
ExecStop=/bin/sh -c 'echo "Server is preparing to shut down!" > /run/factorio/%i.stdin' | |
ExecStop=/bin/sh -c 'echo "Saving the world in ${FACTORIO_STOP_BEFORE_SAVE_DELAY} seconds..." > /run/factorio/%i.stdin' | |
ExecStop=sleep ${FACTORIO_STOP_BEFORE_SAVE_DELAY} | |
ExecStop=/bin/sh -c 'echo "Saving the world!" > /run/factorio/%i.stdin' | |
ExecStop=/bin/sh -c 'echo "/save" > /run/factorio/%i.stdin' | |
ExecStop=/bin/sh -c 'echo "World saved! Shutting down in ${FACTORIO_STOP_AFTER_SAVE_DELAY} seconds..." > /run/factorio/%i.stdin' | |
ExecStop=sleep ${FACTORIO_STOP_AFTER_SAVE_DELAY} | |
ExecStop=/bin/sh -c 'echo "Shutting down! Good bye!" > /run/factorio/%i.stdin' | |
ExecStop=sleep ${FACTORIO_FINAL_STOP_DELAY} | |
ExecStop=/bin/sh -c 'echo "/quit" > /run/factorio/%i.stdin' | |
[Install] | |
WantedBy=multi-user.target |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
[email protected] | |
[Socket] | |
#-- User and group | |
SocketUser=factorio | |
SocketGroup=factorio | |
#-- The mode to create the FIFO node in | |
SocketMode=0665 | |
#-- Define standard input socket | |
ListenFIFO=%t/factorio/%i.stdin | |
#-- Remove when the parent service stops | |
RemoveOnStop=true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
#-- Unit metadata | |
Description=Restart the %i Factorio server daily. | |
#-- Dependencies | |
Requisite=factorio@%i.service | |
[Service] | |
#-- Service type | |
Type=oneshot | |
#-- Timeout settings | |
TimeoutStartSec=30 | |
#-- Startup command(s) | |
ExecStart=/usr/bin/systemctl try-restart factorio@%i.service |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
#-- Unit metadata | |
Description=Restart the %i Factorio server daily. | |
[Timer] | |
#-- The calendar time to restart at (optionally add a time zone) | |
OnCalendar=*-*-* 00:00:00 | |
#-- Persist next restart time to disk | |
Persistent=true | |
[Install] | |
WantedBy=timers.target |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
#-- Resolve script directory | |
SCRIPT_SOURCE="${BASH_SOURCE[0]}"; | |
while [[ -L "${SCRIPT_SOURCE}" ]]; do | |
SCRIPT_DIR="$(cd -P "$(dirname "${SCRIPT_SOURCE}")" > /dev/null 2>&1 && pwd)"; | |
SCRIPT_SOURCE="$(readlink "${SCRIPT_SOURCE}")"; | |
[[ ${SCRIPT_SOURCE} != /* ]] && SOURCE="${SCRIPT_DIR}/${SCRIPT_SOURCE}"; | |
done | |
SCRIPT_DIR="$(cd -P "$(dirname "${SCRIPT_SOURCE}")" > /dev/null 2>&1 && pwd)"; | |
if [[ -z "$1" ]]; then | |
printf "[\x1b[91mFATAL\x1b[0m] A save name/configuration to start is required!\n"; | |
exit 1; | |
fi | |
#-- Start server | |
exec "${SCRIPT_DIR}/bin/x64/factorio" --start-server "$1" --server-adminlist "${SCRIPT_DIR}/config/$1/server-adminlist.json" --server-settings "${SCRIPT_DIR}/config/$1/server-settings.json" $([[ -n "${FACTORIO_USE_WHITELIST}" ]] && echo --use-server-whitelist --server-whitelist "${SCRIPT_DIR}/config/$1/server-whitelist.json" || echo "") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
#-- Resolve script directory | |
SCRIPT_SOURCE="${BASH_SOURCE[0]}"; | |
while [[ -L "${SCRIPT_SOURCE}" ]]; do | |
SCRIPT_DIR="$(cd -P "$(dirname "${SCRIPT_SOURCE}")" > /dev/null 2>&1 && pwd)"; | |
SCRIPT_SOURCE="$(readlink "${SCRIPT_SOURCE}")"; | |
[[ ${SCRIPT_SOURCE} != /* ]] && SOURCE="${SCRIPT_DIR}/${SCRIPT_SOURCE}"; | |
done | |
SCRIPT_DIR="$(cd -P "$(dirname "${SCRIPT_SOURCE}")" > /dev/null 2>&1 && pwd)"; | |
#-- Parse CLI arguments | |
while [[ -n "$1" ]]; do | |
case "$1" in | |
--help|-h) | |
printf "updateFactorioServer.sh [--help|-h] [stable|experimental]\n"; | |
exit 0; | |
;; | |
*) | |
if [[ -z "${CHANNEL}" ]]; then | |
CHANNEL="$1" | |
else | |
printf "[\x1b[33mWARN\x1b[0m] Factorio channel already set to '\x1b[96m${CHANNEL}\x1b[0m', ignoring CLI argument '\x1b[95m$1\x1b[0m'!\n"; | |
fi | |
;; | |
esac | |
shift 1; | |
done | |
#-- Default to stable update channel | |
if [[ -z "${CHANNEL}" ]]; then | |
printf "[\x1b[33mWARN\x1b[0m] No Factorio channel selected, assuming '\x1b[96mstable\x1b[0m'!\n"; | |
CHANNEL="stable" | |
else | |
printf "[\x1b[94mINFO\x1b[0m] Factorio channel '\x1b[96m${CHANNEL}\x1b[0m' selected!\n"; | |
fi | |
#-- Check update channel is valid | |
if [[ "${CHANNEL}" != "stable" && "${CHANNEL}" != "experimental" ]]; then | |
printf "[\x1b[91mFATAL\x1b[0m] Unknown Factorio channel '\x1b[96m${CHANNEL}\x1b[0m' selected!\n"; | |
exit 1; | |
fi | |
#-- Make sure we're in Factorio root directory | |
pushd "${SCRIPT_DIR}"; | |
#-- Create temporary directory | |
mkdir -p "${SCRIPT_DIR}/tmp/"; | |
#-- Enter temporary directory | |
pushd "${SCRIPT_DIR}/tmp/"; | |
#-- Get latest update | |
wget -O "${SCRIPT_DIR}/tmp/factorio-headless-latest.tar.xz" "https://factorio.com/get-download/${CHANNEL}/headless/linux64"; | |
#-- Unpack latest | |
tar xvf "${SCRIPT_DIR}/tmp/factorio-headless-latest.tar.xz"; | |
#-- Return to Factorio root | |
popd; | |
#-- Remove executable and data directories | |
rm -r "${SCRIPT_DIR}/bin/" "${SCRIPT_DIR}/data/"; | |
#-- Apply update | |
mv "${SCRIPT_DIR}/tmp/factorio/bin/" "${SCRIPT_DIR}/tmp/factorio/data/" "${SCRIPT_DIR}"; | |
#-- Remove temporary directory | |
rm -r "${SCRIPT_DIR}/tmp/"; | |
#-- Return to original directory | |
popd; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment