Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Factorio [![Docker Version](https://img.shields.io/docker/v/factoriotools/factorio?sort=semver)](https://hub.docker.com/r/factoriotools/factorio/) [![Docker Pulls](https://img.shields.io/docker/pulls/factoriotools/factorio.svg?maxAge=600)](https://hub.docker.com/r/factoriotools/factorio/) [![Docker Stars](https://img.shields.io/docker/stars/factoriotools/factorio.svg?maxAge=600)](https://hub.docker.com/r/factoriotools/factorio/)

> [!NOTE]
> Support for ARM is experimental. Expect crashes and lag if you try to run this on a raspberry pi.
> ARM64 images for Factorio 2.1 and newer run the native `linux-arm64` headless build. Older versions have no native build and run the x64 build under box64 emulation, which is experimental: expect crashes and lag if you try to run those on a raspberry pi.

[中文](./README_zh_CN.md)

Expand Down
15 changes: 11 additions & 4 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,15 @@ def push_singlearch(tags):
exit(1)


def build_and_push(sha256, version, tags, push, multiarch, dockerfile="Dockerfile", builder_suffix=""):
def build_and_push(sha256, version, tags, push, multiarch, dockerfile="Dockerfile", builder_suffix="",
sha256_arm64=None):
build_dir = tempfile.mktemp()
shutil.copytree("docker", build_dir)
build_args = ["-f", dockerfile, "--build-arg", f"VERSION={version}", "--build-arg", f"SHA256={sha256}", "."]
build_args = ["-f", dockerfile, "--build-arg", f"VERSION={version}", "--build-arg", f"SHA256={sha256}"]
if sha256_arm64:
# Native ARM64 archive available: the arm64 image runs it instead of the x64 build under box64
build_args.extend(["--build-arg", f"SHA256_ARM64={sha256_arm64}"])
build_args.append(".")
for tag in tags:
build_args.extend(["-t", f"factoriotools/factorio:{tag}"])

Expand Down Expand Up @@ -131,7 +136,8 @@ def main():
for version, buildinfo in versions_to_build:
sha256 = buildinfo["sha256"]
tags = buildinfo["tags"]
build_and_push(sha256, version, tags, args.push_tags, args.multiarch)
build_and_push(sha256, version, tags, args.push_tags, args.multiarch,
sha256_arm64=buildinfo.get("sha256_arm64"))

# Build rootless images
if build_rootless:
Expand All @@ -150,7 +156,8 @@ def main():
original_tags = buildinfo["tags"]
rootless_tags = generate_rootless_tags(original_tags)
build_and_push(sha256, version, rootless_tags, args.push_tags, args.multiarch,
dockerfile="Dockerfile.rootless", builder_suffix="-rootless")
dockerfile="Dockerfile.rootless", builder_suffix="-rootless",
sha256_arm64=buildinfo.get("sha256_arm64"))


if __name__ == '__main__':
Expand Down
1 change: 1 addition & 0 deletions buildinfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"2.1.19": {
"sha256": "e6b607da1d68aee85d1796dbc20e57360a70a66e4d997437ce25534c4ced2ab3",
"sha256_arm64": "6f051154b7d48bc7ae1cc2ad9e1aa05eae5724020fd9876e11d7ebba70de1be1",
"tags": [
"latest",
"2",
Expand Down
17 changes: 13 additions & 4 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ ARG GROUP=factorio
ARG PUID=845
ARG PGID=845
ARG BOX64_VERSION=v0.2.4
# sha256 of the native linux-arm64 archive (2.1+); empty means x64 build under box64
ARG SHA256_ARM64

# optionally utilize a built-in map-gen-preset (see data/base/prototypes/map-gen-presets
# if this is used, the preset will be used over any .json files supplied
Expand Down Expand Up @@ -44,7 +46,7 @@ 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 file --no-install-recommends \
&& if [[ "$(uname -m)" == "aarch64" ]]; then \
&& if [[ "$(uname -m)" == "aarch64" && -z "${SHA256_ARM64}" ]]; 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 \
Expand Down Expand Up @@ -75,14 +77,21 @@ RUN set -ox pipefail \
echo "build-arg SHA256 is required" \
&& exit 1; \
fi \
&& archive="/tmp/factorio_headless_x64_$VERSION.tar.xz" \
&& if [[ "$(uname -m)" == "aarch64" && -n "${SHA256_ARM64}" ]]; then \
platform="linux-arm64" && sha256="${SHA256_ARM64}"; \
else \
platform="linux64" && sha256="${SHA256}"; \
fi \
&& archive="/tmp/factorio_headless_${platform}_$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 \
&& curl -sSL "https://www.factorio.com/get-download/$VERSION/headless/$platform" -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" \
# the native arm64 archive ships bin/arm64; keep the bin/x64 path the scripts use
&& if [[ -d /opt/factorio/bin/arm64 && ! -e /opt/factorio/bin/x64 ]]; then ln -s arm64 /opt/factorio/bin/x64; fi \
&& ln -s "$SCENARIOS" /opt/factorio/scenarios \
&& ln -s "$SAVES" /opt/factorio/saves \
&& mkdir -p /opt/factorio/config/ \
Expand Down
17 changes: 13 additions & 4 deletions docker/Dockerfile.rootless
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ FROM debian:stable-slim
LABEL maintainer="https://github.com/factoriotools/factorio-docker"

ARG BOX64_VERSION=v0.2.4
# sha256 of the native linux-arm64 archive (2.1+); empty means x64 build under box64
ARG SHA256_ARM64

# optionally utilize a built-in map-gen-preset (see data/base/prototypes/map-gen-presets
ARG PRESET
Expand All @@ -33,7 +35,7 @@ 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 \
&& if [[ "$(uname -m)" == "aarch64" && -z "${SHA256_ARM64}" ]]; 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 \
Expand Down Expand Up @@ -61,14 +63,21 @@ RUN set -ox pipefail \
echo "build-arg SHA256 is required" \
&& exit 1; \
fi \
&& archive="/tmp/factorio_headless_x64_$VERSION.tar.xz" \
&& if [[ "$(uname -m)" == "aarch64" && -n "${SHA256_ARM64}" ]]; then \
platform="linux-arm64" && sha256="${SHA256_ARM64}"; \
else \
platform="linux64" && sha256="${SHA256}"; \
fi \
&& archive="/tmp/factorio_headless_${platform}_$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 \
&& curl -sSL "https://www.factorio.com/get-download/$VERSION/headless/$platform" -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" \
# the native arm64 archive ships bin/arm64; keep the bin/x64 path the scripts use
&& if [[ -d /opt/factorio/bin/arm64 && ! -e /opt/factorio/bin/x64 ]]; then ln -s arm64 /opt/factorio/bin/x64; fi \
&& ln -s "$SCENARIOS" /opt/factorio/scenarios \
&& ln -s "$SAVES" /opt/factorio/saves \
&& mkdir -p /opt/factorio/config/
Expand Down
19 changes: 11 additions & 8 deletions update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ experimental_online_version=$(curl 'https://factorio.com/api/latest-releases' |

stable_sha256=$(curl "https://factorio.com/download/sha256sums/" | grep -E "(factorio_headless_x64_|factorio-headless_linux_)${stable_online_version}.tar.xz" | awk '{print $1}')
experimental_sha256=$(curl "https://factorio.com/download/sha256sums/" | grep -E "(factorio_headless_x64_|factorio-headless_linux_)${experimental_online_version}.tar.xz" | awk '{print $1}')
# Native ARM64 headless builds exist from 2.1 on; older versions have no arm64 archive and the value stays empty.
stable_sha256_arm64=$(curl "https://factorio.com/download/sha256sums/" | grep -E "factorio-headless_linux-arm64_${stable_online_version}.tar.xz" | awk '{print $1}')
experimental_sha256_arm64=$(curl "https://factorio.com/download/sha256sums/" | grep -E "factorio-headless_linux-arm64_${experimental_online_version}.tar.xz" | awk '{print $1}')

stable_current_version=$(jq 'with_entries(select(.value.tags | index("stable"))) | keys | .[0]' buildinfo.json -r)
latest_current_version=$(jq 'with_entries(select(.value.tags | index("latest"))) | keys | .[0]' buildinfo.json -r)
Expand Down Expand Up @@ -68,22 +71,22 @@ echo '{}' > "$tmpfile"
# Add stable version
if [[ "$stable_online_version" == "$experimental_online_version" ]]; then
# Stable and experimental are the same version
jq --arg stable_online_version "$stable_online_version" --arg sha256 "$stable_sha256" --arg stableOnlineVersionShort "$stableOnlineVersionShort" --arg stableOnlineVersionMajor "$stableOnlineVersionMajor" \
'. + {($stable_online_version): {sha256: $sha256, tags: ["latest", "stable", ("stable-" + $stable_online_version), $stableOnlineVersionMajor, $stableOnlineVersionShort, $stable_online_version]}}' "$tmpfile" > buildinfo.json
jq --arg stable_online_version "$stable_online_version" --arg sha256 "$stable_sha256" --arg sha256_arm64 "$stable_sha256_arm64" --arg stableOnlineVersionShort "$stableOnlineVersionShort" --arg stableOnlineVersionMajor "$stableOnlineVersionMajor" \
'. + {($stable_online_version): {sha256: $sha256} + (if $sha256_arm64 != "" then {sha256_arm64: $sha256_arm64} else {} end) + {tags: ["latest", "stable", ("stable-" + $stable_online_version), $stableOnlineVersionMajor, $stableOnlineVersionShort, $stable_online_version]}}' "$tmpfile" > buildinfo.json
else
# Different stable and experimental versions
# First add stable
jq --arg stable_online_version "$stable_online_version" --arg sha256 "$stable_sha256" --arg stableOnlineVersionShort "$stableOnlineVersionShort" --arg stableOnlineVersionMajor "$stableOnlineVersionMajor" \
'. + {($stable_online_version): {sha256: $sha256, tags: ["stable", ("stable-" + $stable_online_version), $stableOnlineVersionMajor, $stableOnlineVersionShort, $stable_online_version]}}' "$tmpfile" > buildinfo.json.tmp
jq --arg stable_online_version "$stable_online_version" --arg sha256 "$stable_sha256" --arg sha256_arm64 "$stable_sha256_arm64" --arg stableOnlineVersionShort "$stableOnlineVersionShort" --arg stableOnlineVersionMajor "$stableOnlineVersionMajor" \
'. + {($stable_online_version): {sha256: $sha256} + (if $sha256_arm64 != "" then {sha256_arm64: $sha256_arm64} else {} end) + {tags: ["stable", ("stable-" + $stable_online_version), $stableOnlineVersionMajor, $stableOnlineVersionShort, $stable_online_version]}}' "$tmpfile" > buildinfo.json.tmp
mv buildinfo.json.tmp "$tmpfile"

# Then add experimental
if [[ $stableOnlineVersionShort == "$experimentalOnlineVersionShort" ]]; then
jq --arg experimental_online_version "$experimental_online_version" --arg sha256 "$experimental_sha256" \
'. + {($experimental_online_version): {sha256: $sha256, tags: ["latest", $experimental_online_version]}}' "$tmpfile" > buildinfo.json
jq --arg experimental_online_version "$experimental_online_version" --arg sha256 "$experimental_sha256" --arg sha256_arm64 "$experimental_sha256_arm64" \
'. + {($experimental_online_version): {sha256: $sha256} + (if $sha256_arm64 != "" then {sha256_arm64: $sha256_arm64} else {} end) + {tags: ["latest", $experimental_online_version]}}' "$tmpfile" > buildinfo.json
else
jq --arg experimental_online_version "$experimental_online_version" --arg sha256 "$experimental_sha256" --arg experimentalOnlineVersionShort "$experimentalOnlineVersionShort" --arg experimentalOnlineVersionMajor "$experimentalOnlineVersionMajor" \
'. + {($experimental_online_version): {sha256: $sha256, tags: ["latest", $experimentalOnlineVersionMajor, $experimentalOnlineVersionShort, $experimental_online_version]}}' "$tmpfile" > buildinfo.json
jq --arg experimental_online_version "$experimental_online_version" --arg sha256 "$experimental_sha256" --arg sha256_arm64 "$experimental_sha256_arm64" --arg experimentalOnlineVersionShort "$experimentalOnlineVersionShort" --arg experimentalOnlineVersionMajor "$experimentalOnlineVersionMajor" \
'. + {($experimental_online_version): {sha256: $sha256} + (if $sha256_arm64 != "" then {sha256_arm64: $sha256_arm64} else {} end) + {tags: ["latest", $experimentalOnlineVersionMajor, $experimentalOnlineVersionShort, $experimental_online_version]}}' "$tmpfile" > buildinfo.json
fi
fi

Expand Down