mirror of
https://github.com/factoriotools/factorio-docker.git
synced 2025-07-04 07:58:13 +02:00
Compare commits
1 Commits
master
...
feature/ro
Author | SHA1 | Date | |
---|---|---|---|
7e59315e3d |
136
README-ROOTLESS.md
Normal file
136
README-ROOTLESS.md
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
# Rootless Docker Support
|
||||||
|
|
||||||
|
This document describes the rootless Docker images for Factorio, which are designed to work better with rootless Docker installations and avoid permission issues.
|
||||||
|
|
||||||
|
## What is Rootless Docker?
|
||||||
|
|
||||||
|
Rootless Docker allows running the Docker daemon and containers as a non-root user, which improves security by eliminating the need for root privileges. However, it introduces complexity with UID/GID mapping that can cause permission issues with volumes.
|
||||||
|
|
||||||
|
## Rootless Image Tags
|
||||||
|
|
||||||
|
For each regular Factorio image tag, there's a corresponding rootless tag with the `-rootless` suffix:
|
||||||
|
|
||||||
|
- `latest` → `latest-rootless`
|
||||||
|
- `stable` → `stable-rootless`
|
||||||
|
- `2.0.55` → `2.0.55-rootless`
|
||||||
|
- etc.
|
||||||
|
|
||||||
|
## Key Differences from Regular Images
|
||||||
|
|
||||||
|
1. **No dynamic UID/GID mapping**: The rootless images run as UID 1000 by default and don't support PUID/PGID environment variables
|
||||||
|
2. **No runtime chown operations**: Eliminates the recursive chown that can cause race conditions
|
||||||
|
3. **Simplified permissions**: All directories are created with open permissions (777) during build
|
||||||
|
4. **USER directive**: The container runs as non-root from the start
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
-p 34197:34197/udp \
|
||||||
|
-p 27015:27015/tcp \
|
||||||
|
-v /opt/factorio:/factorio \
|
||||||
|
--name factorio \
|
||||||
|
factoriotools/factorio:stable-rootless
|
||||||
|
```
|
||||||
|
|
||||||
|
### With Rootless Docker
|
||||||
|
|
||||||
|
If you're running rootless Docker, the container will work out of the box:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# As your regular user (not root)
|
||||||
|
docker run -d \
|
||||||
|
-p 34197:34197/udp \
|
||||||
|
-p 27015:27015/tcp \
|
||||||
|
-v ~/factorio:/factorio \
|
||||||
|
--name factorio \
|
||||||
|
factoriotools/factorio:stable-rootless
|
||||||
|
```
|
||||||
|
|
||||||
|
### With Regular Docker
|
||||||
|
|
||||||
|
If you're running regular Docker but want to avoid permission issues:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pre-create the volume directory with your user's permissions
|
||||||
|
mkdir -p /opt/factorio
|
||||||
|
sudo chown -R $(id -u):$(id -g) /opt/factorio
|
||||||
|
|
||||||
|
# Run the container
|
||||||
|
docker run -d \
|
||||||
|
--user $(id -u):$(id -g) \
|
||||||
|
-p 34197:34197/udp \
|
||||||
|
-p 27015:27015/tcp \
|
||||||
|
-v /opt/factorio:/factorio \
|
||||||
|
--name factorio \
|
||||||
|
factoriotools/factorio:stable-rootless
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
All the same environment variables from the regular image are supported, except:
|
||||||
|
- `PUID` - Not supported (container runs as UID 1000)
|
||||||
|
- `PGID` - Not supported (container runs as GID 1000)
|
||||||
|
|
||||||
|
## Migrating from Regular Images
|
||||||
|
|
||||||
|
If you're switching from a regular image to a rootless image:
|
||||||
|
|
||||||
|
1. Stop your existing container
|
||||||
|
2. Fix permissions on your volume (one time only):
|
||||||
|
```bash
|
||||||
|
sudo chown -R 1000:1000 /opt/factorio
|
||||||
|
# Or if you want to match your user:
|
||||||
|
sudo chown -R $(id -u):$(id -g) /opt/factorio
|
||||||
|
```
|
||||||
|
3. Start the new rootless container
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Permission Denied Errors
|
||||||
|
|
||||||
|
If you get permission errors, ensure your volume directory is writable by UID 1000 or your user:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check current ownership
|
||||||
|
ls -la /opt/factorio
|
||||||
|
|
||||||
|
# Fix ownership for UID 1000 (default)
|
||||||
|
sudo chown -R 1000:1000 /opt/factorio
|
||||||
|
|
||||||
|
# Or fix for your current user
|
||||||
|
sudo chown -R $(id -u):$(id -g) /opt/factorio
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running as a Different User
|
||||||
|
|
||||||
|
If you need to run as a different UID, override it at runtime:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--user 2000:2000 \
|
||||||
|
-v /opt/factorio:/factorio \
|
||||||
|
factoriotools/factorio:stable-rootless
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building Rootless Images
|
||||||
|
|
||||||
|
To build rootless images locally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build for current architecture
|
||||||
|
python3 build-rootless.py
|
||||||
|
|
||||||
|
# Build and push multi-arch images
|
||||||
|
python3 build-rootless.py --multiarch --push-tags
|
||||||
|
```
|
||||||
|
|
||||||
|
## Why Use Rootless Images?
|
||||||
|
|
||||||
|
1. **Avoid permission issues**: No more files with unexpected ownership
|
||||||
|
2. **Better security**: Runs as non-root by default
|
||||||
|
3. **Simpler**: No complex permission logic at startup
|
||||||
|
4. **Faster startup**: No recursive chown operations
|
||||||
|
5. **Rootless Docker compatible**: Works seamlessly with rootless Docker installations
|
31
README.md
31
README.md
@ -439,6 +439,37 @@ stream {
|
|||||||
|
|
||||||
If your factorio host uses multiple IP addresses (very common with IPv6), you might additionally need to bind Factorio to a single IP (otherwise the UDP proxy might get confused with IP mismatches). To do that pass the `BIND` envvar to the container: `docker run --network=host -e BIND=2a02:1234::5678 ...`
|
If your factorio host uses multiple IP addresses (very common with IPv6), you might additionally need to bind Factorio to a single IP (otherwise the UDP proxy might get confused with IP mismatches). To do that pass the `BIND` envvar to the container: `docker run --network=host -e BIND=2a02:1234::5678 ...`
|
||||||
|
|
||||||
|
## Rootless Docker Support
|
||||||
|
|
||||||
|
If you're experiencing permission issues or want better security, consider using the rootless images. These images are designed to work seamlessly with rootless Docker installations and avoid common permission problems.
|
||||||
|
|
||||||
|
### Rootless Image Tags
|
||||||
|
|
||||||
|
Each regular tag has a corresponding rootless version with the `-rootless` suffix:
|
||||||
|
- `latest-rootless`
|
||||||
|
- `stable-rootless`
|
||||||
|
- `2.0.55-rootless`
|
||||||
|
|
||||||
|
### Quick Start with Rootless
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run -d \
|
||||||
|
-p 34197:34197/udp \
|
||||||
|
-p 27015:27015/tcp \
|
||||||
|
-v ~/factorio:/factorio \
|
||||||
|
--name factorio \
|
||||||
|
--restart=unless-stopped \
|
||||||
|
factoriotools/factorio:stable-rootless
|
||||||
|
```
|
||||||
|
|
||||||
|
Key differences:
|
||||||
|
- No `chown` command needed
|
||||||
|
- No PUID/PGID environment variables
|
||||||
|
- Runs as UID 1000 by default
|
||||||
|
- No permission issues with volumes
|
||||||
|
|
||||||
|
For more information, see the [Rootless Docker documentation](README-ROOTLESS.md).
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### My server is listed in the server browser, but nobody can connect
|
### My server is listed in the server browser, but nobody can connect
|
||||||
|
128
build-rootless.py
Executable file
128
build-rootless.py
Executable file
@ -0,0 +1,128 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
|
PLATFORMS = [
|
||||||
|
"linux/arm64",
|
||||||
|
"linux/amd64",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def create_builder(build_dir, builder_name, platform):
|
||||||
|
check_exists_command = ["docker", "buildx", "inspect", builder_name]
|
||||||
|
if subprocess.run(check_exists_command, stderr=subprocess.DEVNULL).returncode != 0:
|
||||||
|
create_command = ["docker", "buildx", "create", "--platform", platform, "--name", builder_name]
|
||||||
|
try:
|
||||||
|
subprocess.run(create_command, cwd=build_dir, check=True)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print("Creating builder failed")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def build_and_push_multiarch(build_dir, build_args, push):
|
||||||
|
builder_name = "factoriotools-rootless-multiarch"
|
||||||
|
platform=",".join(PLATFORMS)
|
||||||
|
create_builder(build_dir, builder_name, platform)
|
||||||
|
build_command = ["docker", "buildx", "build", "--platform", platform, "--builder", builder_name] + build_args
|
||||||
|
if push:
|
||||||
|
build_command.append("--push")
|
||||||
|
try:
|
||||||
|
subprocess.run(build_command, cwd=build_dir, check=True)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print("Build and push of rootless image failed")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def build_singlearch(build_dir, build_args):
|
||||||
|
build_command = ["docker", "build"] + build_args
|
||||||
|
try:
|
||||||
|
subprocess.run(build_command, cwd=build_dir, check=True)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print("Build of rootless image failed")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def push_singlearch(tags):
|
||||||
|
for tag in tags:
|
||||||
|
try:
|
||||||
|
subprocess.run(["docker", "push", f"factoriotools/factorio:{tag}"],
|
||||||
|
check=True)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print("Docker push failed")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def build_and_push(sha256, version, tags, push, multiarch):
|
||||||
|
build_dir = tempfile.mktemp()
|
||||||
|
shutil.copytree("docker", build_dir)
|
||||||
|
# Use the rootless Dockerfile
|
||||||
|
build_args = ["-f", "Dockerfile.rootless", "--build-arg", f"VERSION={version}", "--build-arg", f"SHA256={sha256}", "."]
|
||||||
|
for tag in tags:
|
||||||
|
build_args.extend(["-t", f"factoriotools/factorio:{tag}"])
|
||||||
|
if multiarch:
|
||||||
|
build_and_push_multiarch(build_dir, build_args, push)
|
||||||
|
else:
|
||||||
|
build_singlearch(build_dir, build_args)
|
||||||
|
if push:
|
||||||
|
push_singlearch(tags)
|
||||||
|
|
||||||
|
|
||||||
|
def login():
|
||||||
|
try:
|
||||||
|
username = os.environ["DOCKER_USERNAME"]
|
||||||
|
password = os.environ["DOCKER_PASSWORD"]
|
||||||
|
subprocess.run(["docker", "login", "-u", username, "-p", password], check=True)
|
||||||
|
except KeyError:
|
||||||
|
print("Username and password need to be given")
|
||||||
|
exit(1)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print("Docker login failed")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_rootless_tags(original_tags):
|
||||||
|
"""Generate rootless-specific tags from original tags"""
|
||||||
|
rootless_tags = []
|
||||||
|
for tag in original_tags:
|
||||||
|
# Add -rootless suffix to each tag
|
||||||
|
rootless_tags.append(f"{tag}-rootless")
|
||||||
|
return rootless_tags
|
||||||
|
|
||||||
|
|
||||||
|
def main(push_tags=False, multiarch=False):
|
||||||
|
with open(os.path.join(os.path.dirname(__file__), "buildinfo.json")) as file_handle:
|
||||||
|
builddata = json.load(file_handle)
|
||||||
|
|
||||||
|
if push_tags:
|
||||||
|
login()
|
||||||
|
|
||||||
|
# Build only the latest stable and experimental versions for rootless
|
||||||
|
versions_to_build = []
|
||||||
|
|
||||||
|
# Find latest stable and experimental versions
|
||||||
|
for version, buildinfo in builddata.items():
|
||||||
|
if "stable" in buildinfo["tags"] or "latest" in buildinfo["tags"]:
|
||||||
|
versions_to_build.append((version, buildinfo))
|
||||||
|
|
||||||
|
for version, buildinfo in versions_to_build:
|
||||||
|
sha256 = buildinfo["sha256"]
|
||||||
|
original_tags = buildinfo["tags"]
|
||||||
|
rootless_tags = generate_rootless_tags(original_tags)
|
||||||
|
build_and_push(sha256, version, rootless_tags, push_tags, multiarch)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
push_tags = False
|
||||||
|
multiarch = False
|
||||||
|
for arg in sys.argv[1:]:
|
||||||
|
if arg == "--push-tags":
|
||||||
|
push_tags = True
|
||||||
|
elif arg == "--multiarch":
|
||||||
|
multiarch = True
|
||||||
|
main(push_tags, multiarch)
|
93
docker/Dockerfile.rootless
Normal file
93
docker/Dockerfile.rootless
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# build rcon client
|
||||||
|
FROM debian:stable-slim AS rcon-builder
|
||||||
|
RUN apt-get -q update \
|
||||||
|
&& DEBIAN_FRONTEND=noninteractive apt-get -qy install build-essential
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
COPY rcon/ /src
|
||||||
|
RUN make
|
||||||
|
|
||||||
|
# build factorio image
|
||||||
|
FROM debian:stable-slim
|
||||||
|
LABEL maintainer="https://github.com/factoriotools/factorio-docker"
|
||||||
|
|
||||||
|
ARG BOX64_VERSION=v0.2.4
|
||||||
|
|
||||||
|
# optionally utilize a built-in map-gen-preset (see data/base/prototypes/map-gen-presets
|
||||||
|
ARG PRESET
|
||||||
|
|
||||||
|
# number of retries that curl will use when pulling the headless server tarball
|
||||||
|
ARG CURL_RETRIES=8
|
||||||
|
|
||||||
|
ENV PORT=34197 \
|
||||||
|
RCON_PORT=27015 \
|
||||||
|
SAVES=/factorio/saves \
|
||||||
|
PRESET="$PRESET" \
|
||||||
|
CONFIG=/factorio/config \
|
||||||
|
MODS=/factorio/mods \
|
||||||
|
SCENARIOS=/factorio/scenarios \
|
||||||
|
SCRIPTOUTPUT=/factorio/script-output \
|
||||||
|
DLC_SPACE_AGE="true"
|
||||||
|
|
||||||
|
SHELL ["/bin/bash", "-eo", "pipefail", "-c"]
|
||||||
|
|
||||||
|
RUN apt-get -q update \
|
||||||
|
&& DEBIAN_FRONTEND=noninteractive apt-get -qy install ca-certificates curl jq pwgen xz-utils procps gettext-base --no-install-recommends \
|
||||||
|
&& if [[ "$(uname -m)" == "aarch64" ]]; then \
|
||||||
|
echo "installing ARM compatability layer" \
|
||||||
|
&& DEBIAN_FRONTEND=noninteractive apt-get -qy install unzip --no-install-recommends \
|
||||||
|
&& curl -LO https://github.com/ptitSeb/box64/releases/download/${BOX64_VERSION}/box64-GENERIC_ARM-RelWithDebInfo.zip \
|
||||||
|
&& unzip box64-GENERIC_ARM-RelWithDebInfo.zip -d /bin \
|
||||||
|
&& rm -f box64-GENERIC_ARM-RelWithDebInfo.zip \
|
||||||
|
&& chmod +x /bin/box64; \
|
||||||
|
fi \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# version checksum of the archive to download
|
||||||
|
ARG VERSION
|
||||||
|
ARG SHA256
|
||||||
|
|
||||||
|
LABEL factorio.version=${VERSION}
|
||||||
|
|
||||||
|
ENV VERSION=${VERSION} \
|
||||||
|
SHA256=${SHA256}
|
||||||
|
|
||||||
|
RUN set -ox pipefail \
|
||||||
|
&& if [[ "${VERSION}" == "" ]]; then \
|
||||||
|
echo "build-arg VERSION is required" \
|
||||||
|
&& exit 1; \
|
||||||
|
fi \
|
||||||
|
&& if [[ "${SHA256}" == "" ]]; then \
|
||||||
|
echo "build-arg SHA256 is required" \
|
||||||
|
&& exit 1; \
|
||||||
|
fi \
|
||||||
|
&& archive="/tmp/factorio_headless_x64_$VERSION.tar.xz" \
|
||||||
|
&& mkdir -p /opt /factorio \
|
||||||
|
&& curl -sSL "https://www.factorio.com/get-download/$VERSION/headless/linux64" -o "$archive" --retry $CURL_RETRIES \
|
||||||
|
&& echo "$SHA256 $archive" | sha256sum -c \
|
||||||
|
|| (sha256sum "$archive" && file "$archive" && exit 1) \
|
||||||
|
&& tar xf "$archive" --directory /opt \
|
||||||
|
&& chmod ugo=rwx /opt/factorio \
|
||||||
|
&& rm "$archive" \
|
||||||
|
&& ln -s "$SCENARIOS" /opt/factorio/scenarios \
|
||||||
|
&& ln -s "$SAVES" /opt/factorio/saves \
|
||||||
|
&& mkdir -p /opt/factorio/config/
|
||||||
|
|
||||||
|
COPY files/*.sh /
|
||||||
|
COPY files/docker-entrypoint-rootless.sh /docker-entrypoint.sh
|
||||||
|
COPY files/config.ini /opt/factorio/config/config.ini
|
||||||
|
COPY --from=rcon-builder /src/rcon /bin/rcon
|
||||||
|
|
||||||
|
# Make all scripts executable
|
||||||
|
RUN chmod +x /*.sh
|
||||||
|
|
||||||
|
# Set proper permissions for the factorio directory
|
||||||
|
RUN chmod -R 777 /opt/factorio /factorio
|
||||||
|
|
||||||
|
VOLUME /factorio
|
||||||
|
EXPOSE $PORT/udp $RCON_PORT/tcp
|
||||||
|
|
||||||
|
# Run as non-root user (UID 1000 is common for the first user in rootless containers)
|
||||||
|
USER 1000:1000
|
||||||
|
|
||||||
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
124
docker/files/docker-entrypoint-rootless.sh
Executable file
124
docker/files/docker-entrypoint-rootless.sh
Executable file
@ -0,0 +1,124 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -eoux pipefail
|
||||||
|
INSTALLED_DIRECTORY=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
|
||||||
|
FACTORIO_VOL=/factorio
|
||||||
|
LOAD_LATEST_SAVE="${LOAD_LATEST_SAVE:-true}"
|
||||||
|
GENERATE_NEW_SAVE="${GENERATE_NEW_SAVE:-false}"
|
||||||
|
PRESET="${PRESET:-""}"
|
||||||
|
SAVE_NAME="${SAVE_NAME:-""}"
|
||||||
|
BIND="${BIND:-""}"
|
||||||
|
CONSOLE_LOG_LOCATION="${CONSOLE_LOG_LOCATION:-""}"
|
||||||
|
|
||||||
|
# Create directories if they don't exist
|
||||||
|
# In rootless mode, these should be writable by the container user
|
||||||
|
mkdir -p "$FACTORIO_VOL"
|
||||||
|
mkdir -p "$SAVES"
|
||||||
|
mkdir -p "$CONFIG"
|
||||||
|
mkdir -p "$MODS"
|
||||||
|
mkdir -p "$SCENARIOS"
|
||||||
|
mkdir -p "$SCRIPTOUTPUT"
|
||||||
|
|
||||||
|
# Generate RCON password if needed
|
||||||
|
if [[ ! -f $CONFIG/rconpw ]]; then
|
||||||
|
pwgen 15 1 >"$CONFIG/rconpw"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy default configs if they don't exist
|
||||||
|
if [[ ! -f $CONFIG/server-settings.json ]]; then
|
||||||
|
cp /opt/factorio/data/server-settings.example.json "$CONFIG/server-settings.json"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f $CONFIG/map-gen-settings.json ]]; then
|
||||||
|
cp /opt/factorio/data/map-gen-settings.example.json "$CONFIG/map-gen-settings.json"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f $CONFIG/map-settings.json ]]; then
|
||||||
|
cp /opt/factorio/data/map-settings.example.json "$CONFIG/map-settings.json"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up incomplete saves
|
||||||
|
NRTMPSAVES=$( find -L "$SAVES" -iname \*.tmp.zip -mindepth 1 | wc -l )
|
||||||
|
if [[ $NRTMPSAVES -gt 0 ]]; then
|
||||||
|
rm -f "$SAVES"/*.tmp.zip
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update mods if requested
|
||||||
|
if [[ ${UPDATE_MODS_ON_START:-} == "true" ]]; then
|
||||||
|
${INSTALLED_DIRECTORY}/docker-update-mods.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Handle DLC
|
||||||
|
${INSTALLED_DIRECTORY}/docker-dlc.sh
|
||||||
|
|
||||||
|
# In rootless mode, we don't need to handle user switching or chown
|
||||||
|
# The container runs as the specified user from the start
|
||||||
|
EXEC=""
|
||||||
|
if [[ -f /bin/box64 ]]; then
|
||||||
|
# Use emulator for ARM hosts
|
||||||
|
EXEC="/bin/box64"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update config path
|
||||||
|
sed -i '/write-data=/c\write-data=\/factorio/' /opt/factorio/config/config.ini
|
||||||
|
|
||||||
|
# Generate new save if needed
|
||||||
|
NRSAVES=$(find -L "$SAVES" -iname \*.zip -mindepth 1 | wc -l)
|
||||||
|
if [[ $GENERATE_NEW_SAVE != true && $NRSAVES == 0 ]]; then
|
||||||
|
GENERATE_NEW_SAVE=true
|
||||||
|
SAVE_NAME=_autosave1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $GENERATE_NEW_SAVE == true ]]; then
|
||||||
|
if [[ -z "$SAVE_NAME" ]]; then
|
||||||
|
echo "If \$GENERATE_NEW_SAVE is true, you must specify \$SAVE_NAME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -f "$SAVES/$SAVE_NAME.zip" ]]; then
|
||||||
|
echo "Map $SAVES/$SAVE_NAME.zip already exists, skipping map generation"
|
||||||
|
else
|
||||||
|
if [[ ! -z "$PRESET" ]]; then
|
||||||
|
$EXEC /opt/factorio/bin/x64/factorio \
|
||||||
|
--create "$SAVES/$SAVE_NAME.zip" \
|
||||||
|
--preset "$PRESET" \
|
||||||
|
--map-gen-settings "$CONFIG/map-gen-settings.json" \
|
||||||
|
--map-settings "$CONFIG/map-settings.json"
|
||||||
|
else
|
||||||
|
$EXEC /opt/factorio/bin/x64/factorio \
|
||||||
|
--create "$SAVES/$SAVE_NAME.zip" \
|
||||||
|
--map-gen-settings "$CONFIG/map-gen-settings.json" \
|
||||||
|
--map-settings "$CONFIG/map-settings.json"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build command flags
|
||||||
|
FLAGS=(\
|
||||||
|
--port "$PORT" \
|
||||||
|
--server-settings "$CONFIG/server-settings.json" \
|
||||||
|
--server-banlist "$CONFIG/server-banlist.json" \
|
||||||
|
--rcon-port "$RCON_PORT" \
|
||||||
|
--server-whitelist "$CONFIG/server-whitelist.json" \
|
||||||
|
--use-server-whitelist \
|
||||||
|
--server-adminlist "$CONFIG/server-adminlist.json" \
|
||||||
|
--rcon-password "$(cat "$CONFIG/rconpw")" \
|
||||||
|
--server-id /factorio/config/server-id.json \
|
||||||
|
--mod-directory "$MODS" \
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ -n "$CONSOLE_LOG_LOCATION" ]; then
|
||||||
|
FLAGS+=( --console-log "$CONSOLE_LOG_LOCATION" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$BIND" ]; then
|
||||||
|
FLAGS+=( --bind "$BIND" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $LOAD_LATEST_SAVE == true ]]; then
|
||||||
|
FLAGS+=( --start-server-load-latest )
|
||||||
|
else
|
||||||
|
FLAGS+=( --start-server "$SAVE_NAME" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute factorio
|
||||||
|
# In rootless mode, we run directly without user switching
|
||||||
|
exec $EXEC /opt/factorio/bin/x64/factorio "${FLAGS[@]}" "$@"
|
Reference in New Issue
Block a user