mirror of
https://github.com/factoriotools/factorio-docker.git
synced 2025-07-02 06:58:16 +02:00
Compare commits
97 Commits
Author | SHA1 | Date | |
---|---|---|---|
68e8a5f25c | |||
b658982c93 | |||
1d3fc75d20 | |||
a4a482ee91 | |||
eafe7c08be | |||
9acfe47d16 | |||
b47b20e834 | |||
7e0718a332 | |||
ae327add0b | |||
efb5eb7afc | |||
ec1c4f9455 | |||
edf8035ae3 | |||
25b41c9f22 | |||
228339ec31 | |||
755c106b7b | |||
f1f76e9ae0 | |||
26f053451c | |||
c439634ef1 | |||
cc33c84d86 | |||
8806ca2160 | |||
83bf5c4a11 | |||
30859d57b8 | |||
3e9f74eaac | |||
14bbd68a3b | |||
d4052bc790 | |||
2fc2b7656d | |||
199f6c7f59 | |||
d614babc54 | |||
257e1751c2 | |||
e8e5047490 | |||
d089b02941 | |||
6fe77c30da | |||
a97763a0e1 | |||
602881a0d9 | |||
b56ab27e52 | |||
5edbcd9055 | |||
059a77574e | |||
c1488c61be | |||
fb0d7d955b | |||
a34b260d15 | |||
5d5cb71a90 | |||
ad9c5c37dc | |||
63a9eb14d2 | |||
76eddb14f8 | |||
24bd934d98 | |||
9c873ac907 | |||
c44a3d1faf | |||
926a377146 | |||
52bb117a2b | |||
04c4a6b577 | |||
39c27944be | |||
ba9faac10e | |||
c987fe8769 | |||
606b537b13 | |||
9473de8934 | |||
6b00a3fc32 | |||
34a99ec43e | |||
2caf5345c2 | |||
8a68a162fe | |||
96a6f66445 | |||
e5c351dd14 | |||
eedff789a5 | |||
20fcec5783 | |||
2bfa89fea1 | |||
ee99e7d469 | |||
817844352d | |||
abd518de79 | |||
98337ac18f | |||
2bd0d475eb | |||
2d9d8e17b8 | |||
48c22aa707 | |||
97feb7acb5 | |||
5ee0f8d06a | |||
7230263559 | |||
6f65ae8acc | |||
2fae0bdb22 | |||
4f10d32d7b | |||
61e3941a5a | |||
777cac4849 | |||
9a35472d8a | |||
5b3d17117f | |||
234eea09f0 | |||
c5e0b6b3b5 | |||
df19b88ba0 | |||
0a39c756a5 | |||
0cab74d578 | |||
23c26f83ae | |||
3de6931817 | |||
7a370c11e0 | |||
1a09531600 | |||
ea57f58c3b | |||
5eb71608de | |||
51398ca509 | |||
16dc9c9da2 | |||
e30bf8d656 | |||
3cd89b6870 | |||
f33bfadd47 |
11
.github/dependabot.yml
vendored
11
.github/dependabot.yml
vendored
@ -1,11 +0,0 @@
|
|||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
||||||
|
|
||||||
- package-ecosystem: docker
|
|
||||||
directory: "/docker"
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
29
.github/workflows/docker-build.yml
vendored
29
.github/workflows/docker-build.yml
vendored
@ -1,29 +0,0 @@
|
|||||||
name: Docker build & push
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths:
|
|
||||||
- buildinfo.json
|
|
||||||
# workaround for #526
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v3
|
|
||||||
|
|
||||||
- name: build and push
|
|
||||||
if: ${{ env.DOCKER_USERNAME != '' && env.DOCKER_PASSWORD != '' }}
|
|
||||||
env:
|
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
run: |
|
|
||||||
./build.py --push-tags --multiarch
|
|
28
.github/workflows/docker-description.yml
vendored
28
.github/workflows/docker-description.yml
vendored
@ -1,28 +0,0 @@
|
|||||||
name: Docker Hub Description
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths:
|
|
||||||
- README.md
|
|
||||||
# workaround for #526
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
docker-description:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Docker Hub Description
|
|
||||||
uses: peter-evans/dockerhub-description@v4.0.2
|
|
||||||
if: ${{ env.DOCKER_USERNAME != '' && env.DOCKER_PASSWORD != '' }}
|
|
||||||
env:
|
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
repository: factoriotools/factorio
|
|
32
.github/workflows/lint.yml
vendored
32
.github/workflows/lint.yml
vendored
@ -1,32 +0,0 @@
|
|||||||
name: 'Linter'
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
shellcheck:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: shellcheck
|
|
||||||
uses: reviewdog/action-shellcheck@v1
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.github_token }}
|
|
||||||
reporter: github-pr-review
|
|
||||||
|
|
||||||
hadolint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: hadolint
|
|
||||||
uses: reviewdog/action-hadolint@v1
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.github_token }}
|
|
||||||
reporter: github-pr-review
|
|
21
.github/workflows/update.yml
vendored
21
.github/workflows/update.yml
vendored
@ -1,21 +0,0 @@
|
|||||||
name: Check Update
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 * * * *"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository == 'factoriotools/factorio-docker')
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.REPO_TOKEN }}
|
|
||||||
|
|
||||||
- name: Run update script
|
|
||||||
run: ./update.sh
|
|
||||||
shell: bash
|
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
# IDE
|
|
||||||
.idea
|
|
@ -1,14 +0,0 @@
|
|||||||
ignored:
|
|
||||||
# ignore apt version pinning
|
|
||||||
- DL3008
|
|
||||||
# ignore pip version pinning
|
|
||||||
- DL3013
|
|
||||||
# ignore apk version pinning
|
|
||||||
- DL3018
|
|
||||||
# ignore pipefail cause Balena/resin.io images do not work with it
|
|
||||||
- DL4006
|
|
||||||
# ignore false positive regex
|
|
||||||
- SC1083
|
|
||||||
- SC2086
|
|
||||||
# ignore as need for debug
|
|
||||||
- SC2005
|
|
28
Dockerfile
Normal file
28
Dockerfile
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
FROM frolvlad/alpine-glibc:alpine-3.3_glibc-2.23
|
||||||
|
|
||||||
|
MAINTAINER zopanix <zopanix@gmail.com>
|
||||||
|
|
||||||
|
WORKDIR /opt
|
||||||
|
|
||||||
|
COPY ./smart_launch.sh /opt
|
||||||
|
COPY ./factorio.crt /opt
|
||||||
|
|
||||||
|
VOLUME /opt/factorio/saves /opt/factorio/mods
|
||||||
|
|
||||||
|
ENV FACTORIO_AUTOSAVE_INTERVAL=2 \
|
||||||
|
FACTORIO_AUTOSAVE_SLOTS=3 \
|
||||||
|
FACTORIO_DISSALOW_COMMANDS=true \
|
||||||
|
FACTORIO_NO_AUTO_PAUSE=false \
|
||||||
|
VERSION=0.12.31 \
|
||||||
|
FACTORIO_SHA1=2b225302bcea95d541da9057f05acc3d27b0fe79
|
||||||
|
|
||||||
|
RUN apk --update add bash curl && \
|
||||||
|
curl -sSL --cacert /opt/factorio.crt https://www.factorio.com/get-download/$VERSION/headless/linux64 -o /tmp/factorio_headless_x64_$VERSION.tar.gz && \
|
||||||
|
echo "$FACTORIO_SHA1 /tmp/factorio_headless_x64_$VERSION.tar.gz" | sha1sum -c && \
|
||||||
|
tar xzf /tmp/factorio_headless_x64_$VERSION.tar.gz && \
|
||||||
|
rm /tmp/factorio_headless_x64_$VERSION.tar.gz
|
||||||
|
|
||||||
|
EXPOSE 34197/udp
|
||||||
|
|
||||||
|
CMD ["./smart_launch.sh"]
|
||||||
|
|
564
README.md
564
README.md
@ -1,74 +1,11 @@
|
|||||||
# Factorio [](https://hub.docker.com/r/factoriotools/factorio/) [](https://hub.docker.com/r/factoriotools/factorio/) [](https://hub.docker.com/r/factoriotools/factorio/)
|
# Supported tags and respective `Dockerfile` links
|
||||||
|
|
||||||
> [!NOTE]
|
* `0.12.31`, `latest` [(0.12.31/Dockerfile)](https://github.com/dtandersen/docker_factorio_server/blob/dt_0.12.31/Dockerfile)
|
||||||
> Support for ARM is experimental. Expect crashes and lag if you try to run this on a raspberry pi.
|
* `0.12.30` [(0.12.30/Dockerfile)](https://github.com/dtandersen/docker_factorio_server/blob/dt_0.12.30/Dockerfile)
|
||||||
|
|
||||||
[中文](./README_zh_CN.md)
|
[](https://imagelayers.io/?images=dtandersen/factorio:latest 'Get your own badge on imagelayers.io')
|
||||||
|
|
||||||
<!-- start autogeneration tags -->
|
# What is Factorio?
|
||||||
* `2.0.58`, `latest`
|
|
||||||
* `2.0.57`
|
|
||||||
* `2`, `2.0`, `2.0.55`, `stable`, `stable-2.0.55`
|
|
||||||
* `2.0.54`
|
|
||||||
* `2.0.53`
|
|
||||||
* `2.0.52`
|
|
||||||
* `2.0.51`
|
|
||||||
* `2.0.50`
|
|
||||||
* `2.0.49`
|
|
||||||
* `2.0.48`
|
|
||||||
* `2.0`, `2.0.47`, `stable-2.0.47`
|
|
||||||
* `2.0.46`
|
|
||||||
* `2.0.45`
|
|
||||||
* `2.0.44`
|
|
||||||
* `2.0`, `2.0.43`, `stable-2.0.43`
|
|
||||||
* `2.0`, `2.0.42`, `stable-2.0.42`
|
|
||||||
* `2.0`, `2.0.41`, `stable-2.0.41`
|
|
||||||
* `2.0.40`
|
|
||||||
* `2.0`, `2.0.39`, `stable-2.0.39`
|
|
||||||
* `2.0.38`
|
|
||||||
* `2.0.37`
|
|
||||||
* `2.0.36`
|
|
||||||
* `2.0.35`
|
|
||||||
* `2.0.34`
|
|
||||||
* `2.0.33`
|
|
||||||
* `2.0`, `2.0.32`, `stable-2.0.32`
|
|
||||||
* `2.0.31`
|
|
||||||
* `2.0`, `2.0.30`, `stable-2.0.30`
|
|
||||||
* `2.0.29`
|
|
||||||
* `2.0`, `2.0.28`, `stable-2.0.28`
|
|
||||||
* `2.0.27`
|
|
||||||
* `2.0.26`
|
|
||||||
* `2.0.25`
|
|
||||||
* `2.0.24`
|
|
||||||
* `2.0`, `2.0.23`, `stable-2.0.23`
|
|
||||||
* `2.0.22`
|
|
||||||
* `2.0`, `2.0.21`, `stable-2.0.21`
|
|
||||||
* `2.0`, `2.0.20`, `stable-2.0.20`
|
|
||||||
* `2.0.19`
|
|
||||||
* `2.0.18`
|
|
||||||
* `2.0.17`
|
|
||||||
* `2.0.16`
|
|
||||||
* `2.0`, `2.0.15`, `stable-2.0.15`
|
|
||||||
* `2.0`, `2.0.14`, `stable-2.0.14`
|
|
||||||
* `2.0`, `2.0.13`, `stable-2.0.13`
|
|
||||||
* `1`, `1.1`, `1.1.110`, `stable-1.1.110`
|
|
||||||
* `1.0`, `1.0.0`
|
|
||||||
* `0.17`, `0.17.79`
|
|
||||||
* `0.16`, `0.16.51`
|
|
||||||
* `0.15`, `0.15.40`
|
|
||||||
* `0.14`, `0.14.23`
|
|
||||||
* `0.13`, `0.13.20`
|
|
||||||
* `0.12`, `0.12.35`<!-- end autogeneration tags -->
|
|
||||||
|
|
||||||
## Tag descriptions
|
|
||||||
|
|
||||||
* `latest` - most up-to-date version (may be experimental).
|
|
||||||
* `stable` - version declared stable on [factorio.com](https://www.factorio.com) ([FFF-435 Since 2.0 versions gets released as experimental first, once stable it will be marked as stable](https://factorio.com/blog/post/fff-435)).
|
|
||||||
* `0.x` - latest version in a branch.
|
|
||||||
* `0.x.y` - a specific version.
|
|
||||||
* `0.x-z` - incremental fix for that version.
|
|
||||||
|
|
||||||
## What is Factorio?
|
|
||||||
|
|
||||||
[Factorio](https://www.factorio.com) is a game in which you build and maintain factories.
|
[Factorio](https://www.factorio.com) is a game in which you build and maintain factories.
|
||||||
|
|
||||||
@ -76,416 +13,137 @@ You will be mining resources, researching technologies, building infrastructure,
|
|||||||
|
|
||||||
The game is very stable and optimized for building massive factories. You can create your own maps, write mods in Lua or play with friends via Multiplayer.
|
The game is very stable and optimized for building massive factories. You can create your own maps, write mods in Lua or play with friends via Multiplayer.
|
||||||
|
|
||||||
NOTE: This is only the server. The full game is available at [Factorio.com](https://www.factorio.com), [Steam](https://store.steampowered.com/app/427520/), [GOG.com](https://www.gog.com/game/factorio) and [Humble Bundle](https://www.humblebundle.com/store/factorio).
|
NOTE: This is only the server. The game is available on [Steam](http://store.steampowered.com/app/427520/).
|
||||||
|
|
||||||
## Usage
|
# Features
|
||||||
|
|
||||||
### Quick Start
|
* Automatically takes latest save or autosave when restarting the container.
|
||||||
|
* Volumes for saves and mods
|
||||||
|
* Set autosave interval and number of saves.
|
||||||
|
* Enable/disable the no-auto-pause option.
|
||||||
|
* Enable/disable console commands in game.
|
||||||
|
* Based on Alpine Linux.
|
||||||
|
|
||||||
Run the server to create the necessary folder structure and configuration files. For this example data is stored in `/opt/factorio`.
|
# How to use this image?
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
This runs factorio with default settings, and your save will be kept:
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo mkdir -p /opt/factorio
|
|
||||||
sudo chown 845:845 /opt/factorio
|
|
||||||
sudo docker run -d \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
factoriotools/factorio
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For those new to Docker, here is an explanation of the options:
|
|
||||||
|
|
||||||
* `-d` - Run as a daemon ("detached").
|
|
||||||
* `-p` - Expose ports.
|
|
||||||
* `-v` - Mount `/opt/factorio` on the local file system to `/factorio` in the container.
|
|
||||||
* `--restart` - Restart the server if it crashes and at system start
|
|
||||||
* `--name` - Name the container "factorio" (otherwise it has a funny random name).
|
|
||||||
|
|
||||||
The `chown` command is needed because in 0.16+, we no longer run the game server as root for security reasons, but rather as a 'factorio' user with user id 845. The host must therefore allow these files to be written by that user.
|
|
||||||
|
|
||||||
Check the logs to see what happened:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker logs factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
Stop the server:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker stop factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
Now there's a `server-settings.json` file in the folder `/opt/factorio/config`. Modify this to your liking and restart the server:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker start factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
Try to connect to the server. Check the logs if it isn't working.
|
|
||||||
|
|
||||||
### Console
|
|
||||||
|
|
||||||
To issue console commands to the server, start the server in interactive mode with `-it`. Open the console with `docker attach` and then type commands.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker run -d -it \
|
|
||||||
--name factorio \
|
|
||||||
factoriotools/factorio
|
|
||||||
docker attach factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
### RCON (2.0.18+)
|
|
||||||
|
|
||||||
Alternativly (e.g. for scripting) the RCON connection can be used to send commands to the running factorio server.
|
|
||||||
This does not require the RCON connection to be exposed.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker exec factorio rcon /h
|
|
||||||
```
|
|
||||||
|
|
||||||
### Upgrading
|
|
||||||
|
|
||||||
Before upgrading backup the save. It's easy to make a save in the client.
|
|
||||||
|
|
||||||
Ensure `-v` was used to run the server so the save is outside of the Docker container. The `docker rm` command completely destroys the container, which includes the save if it isn't stored in a data volume.
|
|
||||||
|
|
||||||
Delete the container and refresh the image:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker stop factorio
|
|
||||||
docker rm factorio
|
|
||||||
docker pull factoriotools/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
Now run the server as before. In about a minute the new version of Factorio should be up and running, complete with saves and config!
|
|
||||||
|
|
||||||
### Saves
|
|
||||||
|
|
||||||
A new map named `_autosave1.zip` is generated the first time the server is started. The `map-gen-settings.json` and `map-settings.json` files in `/opt/factorio/config` are used for the map settings. On subsequent runs the newest save is used.
|
|
||||||
|
|
||||||
To load an old save stop the server and run the command `touch oldsave.zip`. This resets the date. Then restart the server. Another option is to delete all saves except one.
|
|
||||||
|
|
||||||
To generate a new map stop the server, delete all of the saves and restart the server.
|
|
||||||
|
|
||||||
#### Specify a save directly (0.17.79-2+)
|
|
||||||
|
|
||||||
You can specify a specific save to load by configuring the server through a set of environment variables:
|
|
||||||
|
|
||||||
To load an existing save set `SAVE_NAME` to the name of your existing save file located within the `saves` directory, without the `.zip` extension:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo docker run -d \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
-e LOAD_LATEST_SAVE=false \
|
|
||||||
-e SAVE_NAME=replaceme \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
factoriotools/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
To generate a new map set `GENERATE_NEW_SAVE=true` and specify `SAVE_NAME`:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo docker run -d \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
-e LOAD_LATEST_SAVE=false \
|
|
||||||
-e GENERATE_NEW_SAVE=true \
|
|
||||||
-e SAVE_NAME=replaceme \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
factoriotools/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mods
|
|
||||||
|
|
||||||
Copy mods into the mods folder and restart the server.
|
|
||||||
|
|
||||||
As of 0.17 a new environment variable was added ``UPDATE_MODS_ON_START`` which if set to ``true`` will cause the mods get to updated on server start. If set a valid [Factorio Username and Token](https://www.factorio.com/profile) must be supplied or else the server will not start. They can either be set as docker secrets, environment variables, or pulled from the server-settings.json file.
|
|
||||||
|
|
||||||
### Scenarios
|
|
||||||
|
|
||||||
If you want to launch a scenario from a clean start (not from a saved map) you'll need to start the docker image from an alternate entrypoint. To do this, use the example entrypoint file stored in the /factorio/entrypoints directory in the volume, and launch the image with the following syntax. Note that this is the normal syntax with the addition of the --entrypoint setting AND the additional argument at the end, which is the name of the Scenario in the Scenarios folder.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker run -d \
|
docker run -d \
|
||||||
-p 34197:34197/udp \
|
-v [PATH]:/opt/factorio/saves \
|
||||||
-p 27015:27015/tcp \
|
-p [PORT]:34197/udp \
|
||||||
-v /opt/factorio:/factorio \
|
dtandersen/factorio
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
--entrypoint "/scenario.sh" \
|
|
||||||
factoriotools/factorio \
|
|
||||||
MyScenarioName
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Converting Scenarios to Regular Maps
|
* Where [PATH] is a folder where you'll put your saves, if there already is a save in it with the string "save", that one will be taken by default, otherwize, a new one will be made.
|
||||||
|
* Where [PORT] is the port number you choose, if you're going to launch it on your local machine, don't use the port 34197, take another one at random.
|
||||||
|
|
||||||
If you would like to export your scenario to a saved map, you can use the example entrypoint similar to the Scenario usage above. Factorio will run once, converting the Scenario to a saved Map in your saves directory. A restart of the docker image using the standard options will then load that map, just as if the scenario were just started by the Scenarios example noted above.
|
## Advanced usage
|
||||||
|
|
||||||
```shell
|
### Without map persistence
|
||||||
|
|
||||||
|
This will generate a new random map with default settings.
|
||||||
|
|
||||||
|
```
|
||||||
docker run -d \
|
docker run -d \
|
||||||
-p 34197:34197/udp \
|
-p [PORT]:34197/udp \
|
||||||
-p 27015:27015/tcp \
|
dtandersen/factorio
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
--entrypoint "/scenario2map.sh" \
|
|
||||||
factoriotools/factorio
|
|
||||||
MyScenarioName
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### RCON
|
### With map persistence
|
||||||
|
|
||||||
Set the RCON password in the `rconpw` file. A random password is generated if `rconpw` doesn't exist.
|
This will generate a new random map with default settings and save it onto the volume.
|
||||||
|
Replace [PATH] with a path to a folder on the host where the map will be saved.
|
||||||
To change the password, stop the server, modify `rconpw`, and restart the server.
|
|
||||||
|
|
||||||
To "disable" RCON don't expose port 27015, i.e. start the server without `-p 27015:27015/tcp`. RCON is still running, but nobody can to connect to it.
|
|
||||||
|
|
||||||
### Whitelisting (0.15.3+)
|
|
||||||
|
|
||||||
Create file `config/server-whitelist.json` and add the whitelisted users.
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
"you",
|
|
||||||
"friend"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Banlisting (0.17.1+)
|
|
||||||
|
|
||||||
Create file `config/server-banlist.json` and add the banlisted users.
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
"bad_person",
|
|
||||||
"other_bad_person"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Adminlisting (0.17.1+)
|
|
||||||
|
|
||||||
Create file `config/server-adminlist.json` and add the adminlisted users.
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
"you",
|
|
||||||
"friend"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Customize configuration files (0.17.x+)
|
|
||||||
|
|
||||||
Out-of-the box, factorio does not support environment variables inside the configuration files. A workaround is the usage of `envsubst` which generates the configuration files dynamically during startup from environment variables set in docker-compose:
|
|
||||||
|
|
||||||
Example which replaces the server-settings.json:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
factorio_1:
|
|
||||||
image: factoriotools/factorio
|
|
||||||
ports:
|
|
||||||
- "34197:34197/udp"
|
|
||||||
volumes:
|
|
||||||
- /opt/factorio:/factorio
|
|
||||||
- ./server-settings.json:/server-settings.json
|
|
||||||
environment:
|
|
||||||
- INSTANCE_NAME=Your Instance's Name
|
|
||||||
- INSTANCE_DESC=Your Instance's Description
|
|
||||||
entrypoint: /bin/sh -c "mkdir -p /factorio/config && envsubst < /server-settings.json > /factorio/config/server-settings.json && exec /docker-entrypoint.sh"
|
|
||||||
```
|
|
||||||
|
|
||||||
The `server-settings.json` file may then contain the variable references like this:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"name": "${INSTANCE_NAME}",
|
|
||||||
"description": "${INSTANCE_DESC}",
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
These are the environment variables which can be specified at container run time.
|
|
||||||
|
|
||||||
| Variable Name | Description | Default | Available in |
|
|
||||||
|----------------------|----------------------------------------------------------------------|----------------|--------------|
|
|
||||||
| GENERATE_NEW_SAVE | Generate a new save if one does not exist before starting the server | false | 0.17+ |
|
|
||||||
| LOAD_LATEST_SAVE | Load latest when true. Otherwise load SAVE_NAME | true | 0.17+ |
|
|
||||||
| PORT | UDP port the server listens on | 34197 | 0.15+ |
|
|
||||||
| BIND | IP address (v4 or v6) the server listens on (IP\[:PORT]) | | 0.15+ |
|
|
||||||
| RCON_PORT | TCP port the rcon server listens on | 27015 | 0.15+ |
|
|
||||||
| SAVE_NAME | Name to use for the save file | _autosave1 | 0.17+ |
|
|
||||||
| TOKEN | factorio.com token | | 0.17+ |
|
|
||||||
| UPDATE_MODS_ON_START | If mods should be updated before starting the server | | 0.17+ |
|
|
||||||
| USERNAME | factorio.com username | | 0.17+ |
|
|
||||||
| CONSOLE_LOG_LOCATION | Saves the console log to the specifies location | | |
|
|
||||||
| DLC_SPACE_AGE | Enables or disables the mods for DLC Space Age in mod-list.json[^1] | true | 2.0.8+ |
|
|
||||||
| MODS | Mod directory to use | /factorio/mods | 2.0.8+ |
|
|
||||||
|
|
||||||
**Note:** All environment variables are compared as strings
|
|
||||||
|
|
||||||
## Container Details
|
|
||||||
|
|
||||||
The philosophy is to [keep it simple](http://wiki.c2.com/?KeepItSimple).
|
|
||||||
|
|
||||||
* The server should bootstrap itself.
|
|
||||||
* Prefer configuration files over environment variables.
|
|
||||||
* Use one volume for data.
|
|
||||||
|
|
||||||
### Volumes
|
|
||||||
|
|
||||||
To keep things simple, the container uses a single volume mounted at `/factorio`. This volume stores configuration, mods, and saves.
|
|
||||||
|
|
||||||
The files in this volume should be owned by the factorio user, uid 845.
|
|
||||||
|
|
||||||
```text
|
|
||||||
factorio
|
|
||||||
|-- config
|
|
||||||
| |-- map-gen-settings.json
|
|
||||||
| |-- map-settings.json
|
|
||||||
| |-- rconpw
|
|
||||||
| |-- server-adminlist.json
|
|
||||||
| |-- server-banlist.json
|
|
||||||
| |-- server-settings.json
|
|
||||||
| `-- server-whitelist.json
|
|
||||||
|-- mods
|
|
||||||
| `-- fancymod.zip
|
|
||||||
`-- saves
|
|
||||||
`-- _autosave1.zip
|
|
||||||
```
|
|
||||||
|
|
||||||
## Docker Compose
|
|
||||||
|
|
||||||
[Docker Compose](https://docs.docker.com/compose/install/) is an easy way to run Docker containers.
|
|
||||||
|
|
||||||
* docker-engine >= 1.10.0 is required
|
|
||||||
* docker-compose >=1.6.0 is required
|
|
||||||
|
|
||||||
First get a [docker-compose.yml](https://github.com/factoriotools/factorio-docker/blob/master/docker/docker-compose.yml) file. To get it from this repository:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git clone https://github.com/factoriotools/factorio-docker.git
|
|
||||||
cd factorio-docker/docker
|
|
||||||
```
|
|
||||||
|
|
||||||
Or make your own:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
services:
|
|
||||||
factorio:
|
|
||||||
image: factoriotools/factorio
|
|
||||||
ports:
|
|
||||||
- "34197:34197/udp"
|
|
||||||
- "27015:27015/tcp"
|
|
||||||
volumes:
|
|
||||||
- /opt/factorio:/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
Now cd to the directory with docker-compose.yml and run:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo mkdir -p /opt/factorio
|
|
||||||
sudo chown 845:845 /opt/factorio
|
|
||||||
sudo docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ports
|
|
||||||
|
|
||||||
* `34197/udp` - Game server (required). This can be changed with the `PORT` environment variable.
|
|
||||||
* `27015/tcp` - RCON (optional).
|
|
||||||
|
|
||||||
## LAN Games
|
|
||||||
|
|
||||||
Ensure the `lan` setting in server-settings.json is `true`.
|
|
||||||
|
|
||||||
```json
|
|
||||||
"visibility":
|
|
||||||
{
|
|
||||||
"public": false,
|
|
||||||
"lan": true
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
Start the container with the `--network=host` option so clients can automatically find LAN games. Refer to the Quick Start to create the `/opt/factorio` directory.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo docker run -d \
|
|
||||||
--network=host \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
factoriotools/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deploy to other plaforms
|
|
||||||
|
|
||||||
### Vagrant
|
|
||||||
|
|
||||||
[Vagrant](https://www.vagrantup.com/) is a easy way to setup a virtual machine (VM) to run Docker. The [Factorio Vagrant box repository](https://github.com/dtandersen/factorio-lan-vagrant) contains a sample Vagrantfile.
|
|
||||||
|
|
||||||
For LAN games the VM needs an internal IP in order for clients to connect. One way to do this is with a public network. The VM uses DHCP to acquire an IP address. The VM must also forward port 34197.
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
config.vm.network "public_network"
|
|
||||||
config.vm.network "forwarded_port", guest: 34197, host: 34197
|
|
||||||
```
|
|
||||||
|
|
||||||
### Amazon Web Services (AWS) Deployment
|
|
||||||
|
|
||||||
If you're looking for a simple way to deploy this to the Amazon Web Services Cloud, check out the [Factorio Server Deployment (CloudFormation) repository](https://github.com/m-chandler/factorio-spot-pricing). This repository contains a CloudFormation template that will get you up and running in AWS in a matter of minutes. Optionally it uses Spot Pricing so the server is very cheap, and you can easily turn it off when not in use.
|
|
||||||
|
|
||||||
## Using a reverse proxy
|
|
||||||
|
|
||||||
If you need to use a reverse proxy you can use the following nginx snippet:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
stream {
|
docker run -d \
|
||||||
server {
|
-v [PATH]:/opt/factorio/saves \
|
||||||
listen 34197 udp reuseport;
|
-p [PORT]:34197/udp \
|
||||||
proxy_pass my.upstream.host:34197;
|
dtandersen/factorio
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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 ...`
|
### With existing map
|
||||||
|
|
||||||
## Troubleshooting
|
It's the same as above, it takes the last modified file which contains the word save in the filename as current save when booting the server. This allows when upgrading the container to take the last save, you don't have to rename the last autosave as save.zip
|
||||||
|
|
||||||
### My server is listed in the server browser, but nobody can connect
|
```
|
||||||
|
docker run -d \
|
||||||
|
-v [PATH]:/opt/factorio/saves \
|
||||||
|
-p [PORT]:34197/udp \
|
||||||
|
dtandersen/factorio
|
||||||
|
```
|
||||||
|
|
||||||
Check the logs. If there is the line `Own address is RIGHT IP:WRONG PORT`, then this could be caused by the Docker proxy. If the the IP and port is correct it's probably a port forwarding or firewall issue instead.
|
### Autosave interval
|
||||||
|
|
||||||
By default, Docker routes traffic through a proxy. The proxy changes the source UDP port, so the wrong port is detected. See the forum post *[Incorrect port detected for docker hosted server](https://forums.factorio.com/viewtopic.php?f=49&t=35255)* for details.
|
You can set the autosave interval. By default it is set at 2 minutes bud you can change it by launching the container with the `FACTORIO_AUTOSAVE_INTERVAL` variable to whatever suits you best.
|
||||||
|
|
||||||
To fix the incorrect port, start the Docker service with the `--userland-proxy=false` switch. Docker will route traffic with iptables rules instead of a proxy. Add the switch to the `DOCKER_OPTS` environment variable or `ExecStart` in the Docker systemd service definition. The specifics vary by operating system.
|
```
|
||||||
|
docker run -d \
|
||||||
|
--env FACTORIO_AUTOSAVE_INTERVAL=[NUMBER] \
|
||||||
|
-p [PORT]:34197/udp \
|
||||||
|
dtandersen/factorio
|
||||||
|
```
|
||||||
|
|
||||||
### When I run a server on a port besides 34197 nobody can connect from the server browser
|
Where [NUMBER] is the number of minutes between autosaves.
|
||||||
|
|
||||||
Use the `PORT` environment variable to start the server on the a different port, .e.g. `docker run -e "PORT=34198"`. This changes the source port on the packets used for port detection. `-p 34198:34197` works fine for private servers, but the server browser detects the wrong port.
|
### Autosave slots
|
||||||
|
|
||||||
## Contributors
|
You can set the number of autosave slots. By default it is set at 3 slots bud you can change it by launching the container with the `FACTORIO_AUTOSAVE_SLOTS` variable to whatever suits you best.
|
||||||
|
|
||||||
* [dtandersen](https://github.com/dtandersen) - Maintainer
|
```
|
||||||
* [Fank](https://github.com/Fankserver) - Programmer of the Factorio watchdog that keeps the version up-to-date.
|
docker run -d \
|
||||||
* [SuperSandro2000](https://github.com/supersandro2000) - CI Guy, Maintainer and runner of the Factorio watchdog. Contributed version updates and wrote the Travis scripts.
|
--env FACTORIO_AUTOSAVE_SLOTS=[NUMBER] \
|
||||||
* [DBendit](https://github.com/DBendit/docker_factorio_server) - Coded admin list, ban list support and contributed version updates
|
-p [PORT]:34197/udp \
|
||||||
* [Zopanix](https://github.com/zopanix/docker_factorio_server) - Original Author
|
dtandersen/factorio
|
||||||
* [Rfvgyhn](https://github.com/Rfvgyhn/docker-factorio) - Coded randomly generated RCON password
|
```
|
||||||
* [gnomus](https://github.com/gnomus/docker_factorio_server) - Coded white listing support
|
|
||||||
* [bplein](https://github.com/bplein/docker_factorio_server) - Coded scenario support
|
|
||||||
* [jaredledvina](https://github.com/jaredledvina/docker_factorio_server) - Contributed version updates
|
|
||||||
* [carlbennett](https://github.com/carlbennett) - Contributed version updates and bugfixes
|
|
||||||
|
|
||||||
[^1]: Space Age mods can also be individually enabled by using their name separated by space.
|
Where [NUMBER] is the number of autosave slots.
|
||||||
Example 1: Enable all by using `true`
|
|
||||||
Example 2: Enable all by listing the mod names `space-age elevated-rails quality`
|
### Mounting mod volume
|
||||||
Example 3: Enable only Elevated rails `elevated-rails`
|
|
||||||
|
As everybody knows about factorio is you can add mods to it. Now you can also do it in this docker image by mounting a volume.
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -d \
|
||||||
|
-v [PATH]:/opt/factorio/mods \
|
||||||
|
-p [PORT]:34197/udp \
|
||||||
|
dtandersen/factorio
|
||||||
|
```
|
||||||
|
|
||||||
|
Where [PATH] is the path to the folder with your mods.
|
||||||
|
|
||||||
|
### Allowing in-game commands
|
||||||
|
|
||||||
|
I've always disabled in-game commands because I think it is like cheating, however, you can enable them by setting the the `FACTORIO_DISSALOW_COMMANDS` variable to "false".
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -d \
|
||||||
|
--env FACTORIO_DISSALOW_COMMANDS=false \
|
||||||
|
-p [PORT]:34197/udp \
|
||||||
|
dtandersen/factorio
|
||||||
|
```
|
||||||
|
|
||||||
|
### Activating no-auto-pause in the game when no one is on the server
|
||||||
|
|
||||||
|
I do not recommend this feature, bud it can make the game more difficult if you're up for a challenge :-). Just set the `FACTORIO_NO_AUTO_PAUSE` variable to "true".
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -d \
|
||||||
|
--env FACTORIO_NO_AUTO_PAUSE=true \
|
||||||
|
-p [PORT]:34197/udp \
|
||||||
|
dtandersen/factorio
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
Sometimes it's useful to see the logs of a running container:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker exec -it [CONTAINER] tail -f /opt/factorio/factorio-current.log
|
||||||
|
```
|
||||||
|
|
||||||
|
# Credits
|
||||||
|
|
||||||
|
Based on [Zopanix' Factorio Server](https://github.com/zopanix/docker_factorio_server).
|
||||||
|
490
README_zh_CN.md
490
README_zh_CN.md
@ -1,490 +0,0 @@
|
|||||||
# Factorio [](https://hub.docker.com/r/factoriotools/factorio/) [](https://hub.docker.com/r/factoriotools/factorio/) [](https://hub.docker.com/r/factoriotools/factorio/)
|
|
||||||
|
|
||||||
> [!注意]
|
|
||||||
> ARM 架构支持是实验性的。如果你尝试在 Raspberry Pi 上运行,可能会遇到崩溃和延迟问题。
|
|
||||||
|
|
||||||
[English](./README.md)
|
|
||||||
|
|
||||||
<!-- start autogeneration tags -->
|
|
||||||
* `2`, `2.0`, `2.0.55`, `latest`, `stable`, `stable-2.0.55`
|
|
||||||
* `2.0.54`
|
|
||||||
* `2.0.53`
|
|
||||||
* `2.0.52`
|
|
||||||
* `2.0.51`
|
|
||||||
* `2.0.50`
|
|
||||||
* `2.0.49`
|
|
||||||
* `2.0.48`
|
|
||||||
* `2.0`, `2.0.47`, `stable-2.0.47`
|
|
||||||
* `2.0.46`
|
|
||||||
* `2.0.45`
|
|
||||||
* `2.0.44`
|
|
||||||
* `2.0`, `2.0.43`, `stable-2.0.43`
|
|
||||||
* `2.0`, `2.0.42`, `stable-2.0.42`
|
|
||||||
* `2.0`, `2.0.41`, `stable-2.0.41`
|
|
||||||
* `2.0.40`
|
|
||||||
* `2.0`, `2.0.39`, `stable-2.0.39`
|
|
||||||
* `2.0.38`
|
|
||||||
* `2.0.37`
|
|
||||||
* `2.0.36`
|
|
||||||
* `2.0.35`
|
|
||||||
* `2.0.34`
|
|
||||||
* `2.0.33`
|
|
||||||
* `2.0`, `2.0.32`, `stable-2.0.32`
|
|
||||||
* `2.0.31`
|
|
||||||
* `2.0`, `2.0.30`, `stable-2.0.30`
|
|
||||||
* `2.0.29`
|
|
||||||
* `2.0`, `2.0.28`, `stable-2.0.28`
|
|
||||||
* `2.0.27`
|
|
||||||
* `2.0.26`
|
|
||||||
* `2.0.25`
|
|
||||||
* `2.0.24`
|
|
||||||
* `2.0`, `2.0.23`, `stable-2.0.23`
|
|
||||||
* `2.0.22`
|
|
||||||
* `2.0`, `2.0.21`, `stable-2.0.21`
|
|
||||||
* `2.0`, `2.0.20`, `stable-2.0.20`
|
|
||||||
* `2.0.19`
|
|
||||||
* `2.0.18`
|
|
||||||
* `2.0.17`
|
|
||||||
* `2.0.16`
|
|
||||||
* `2.0`, `2.0.15`, `stable-2.0.15`
|
|
||||||
* `2.0`, `2.0.14`, `stable-2.0.14`
|
|
||||||
* `2.0`, `2.0.13`, `stable-2.0.13`
|
|
||||||
* `1`, `1.1`, `1.1.110`, `stable-1.1.110`
|
|
||||||
* `1.0`, `1.0.0`
|
|
||||||
* `0.17`, `0.17.79`
|
|
||||||
* `0.16`, `0.16.51`
|
|
||||||
* `0.15`, `0.15.40`
|
|
||||||
* `0.14`, `0.14.23`
|
|
||||||
* `0.13`, `0.13.20`
|
|
||||||
* `0.12`, `0.12.35`<!-- end autogeneration tags -->
|
|
||||||
|
|
||||||
## 标签描述
|
|
||||||
|
|
||||||
* `latest` - 最新版本(可能含有实验性功能)。
|
|
||||||
* `stable` - 在 [factorio.com](https://www.factorio.com) 上声明为稳定的版本([FFF-435 自 2.0 版本起,版本首先作为实验版发布,一旦稳定就会被标记为稳定版](https://factorio.com/blog/post/fff-435))。
|
|
||||||
* `0.x` - 某个分支上的最新版本。
|
|
||||||
* `0.x.y` - 具体的版本。
|
|
||||||
* `0.x-z` - 该版本的增量修复。
|
|
||||||
|
|
||||||
## 什么是 Factorio?
|
|
||||||
|
|
||||||
[Factorio](https://www.factorio.com) 是一款建造和维护工厂的游戏。
|
|
||||||
|
|
||||||
在游戏中,你将挖掘资源、研发科技、建设基础设施、自动化生产并与敌人战斗。发挥你的想象力来设计工厂,将简单的元素组合成巧妙的结构,运用管理技能保持其正常运转,最后保护它不受那些不太喜欢你的生物的侵害。
|
|
||||||
|
|
||||||
游戏非常稳定,并为建造大规模工厂进行了优化。你可以创建自己的地图,用 Lua 编写模组,或通过多人游戏与朋友一起游戏。
|
|
||||||
|
|
||||||
**注意**:这仅仅是服务端。完整游戏可在 [Factorio.com](https://www.factorio.com)、[Steam](https://store.steampowered.com/app/427520/)、[GOG.com](https://www.gog.com/game/factorio) 和 [Humble Bundle](https://www.humblebundle.com/store/factorio) 获得。
|
|
||||||
|
|
||||||
## 使用方法
|
|
||||||
|
|
||||||
### 快速开始
|
|
||||||
|
|
||||||
运行服务端以创建必要的文件夹结构和配置文件。在这个例子中,数据存储在 `/opt/factorio`。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo mkdir -p /opt/factorio
|
|
||||||
sudo chown 845:845 /opt/factorio
|
|
||||||
sudo docker run -d \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
factoriotools/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
对于 Docker 新手,这里解释一下选项:
|
|
||||||
|
|
||||||
* `-d` - 以守护进程方式运行("分离"模式)。
|
|
||||||
* `-p` - 暴露端口。
|
|
||||||
* `-v` - 将本地文件系统的 `/opt/factorio` 挂载到容器中的 `/factorio`。
|
|
||||||
* `--restart` - 如果服务端崩溃或系统启动时重启服务端。
|
|
||||||
* `--name` - 将容器命名为 "factorio"(否则它会有一个有趣的随机名称)。
|
|
||||||
|
|
||||||
需要 `chown` 命令是因为在 0.16+ 版本中,出于安全原因,我们不再以 root 身份运行游戏服务端,而是以用户 ID 为 845 的 'factorio' 用户身份运行。因此主机必须允许该用户写入这些文件。
|
|
||||||
|
|
||||||
检查日志以查看发生了什么:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker logs factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
停止服务端:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker stop factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
现在在 `/opt/factorio/config` 文件夹中有一个 `server-settings.json` 文件。根据你的喜好修改它并重启服务端:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker start factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
尝试连接到服务端。如果无法正常工作,请检查日志。
|
|
||||||
|
|
||||||
### 控制台
|
|
||||||
|
|
||||||
要向服务端发出控制台命令,请使用 `-it` 以交互模式启动服务端。使用 `docker attach` 打开控制台,然后输入命令。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker run -d -it \
|
|
||||||
--name factorio \
|
|
||||||
factoriotools/factorio
|
|
||||||
docker attach factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
### RCON (2.0.18+)
|
|
||||||
|
|
||||||
或者(例如用于脚本),可以使用 RCON 连接向正在运行的 factorio 服务端发送命令。
|
|
||||||
这不需要暴露 RCON 连接。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker exec factorio rcon /h
|
|
||||||
```
|
|
||||||
|
|
||||||
### 更新
|
|
||||||
|
|
||||||
在升级服务端之前,请备份存档。在客户端中制作存档很容易。
|
|
||||||
|
|
||||||
确保在运行服务端时使用了 `-v` 参数,这样存档就在 Docker 容器外部。`docker rm` 命令会完全销毁容器,如果存档没有存储在数据卷中,也会包括存档。
|
|
||||||
|
|
||||||
删除容器并刷新镜像:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker stop factorio
|
|
||||||
docker rm factorio
|
|
||||||
docker pull factoriotools/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
现在像之前一样运行服务端。大约一分钟后,新版本的 Factorio 应该就会运行起来,完整保留存档和配置!
|
|
||||||
|
|
||||||
### 存档
|
|
||||||
|
|
||||||
服务端首次启动时会生成一个名为 `_autosave1.zip` 的新地图。使用 `/opt/factorio/config` 中的 `map-gen-settings.json` 和 `map-settings.json` 文件作为地图设置。在后续运行中使用最新的存档。
|
|
||||||
|
|
||||||
要加载旧存档,请停止服务端并运行命令 `touch oldsave.zip`。这会重置日期。然后重启服务端。另一个选择是删除除一个存档外的所有存档。
|
|
||||||
|
|
||||||
要生成新地图,请停止服务端,删除所有存档并重启服务端。
|
|
||||||
|
|
||||||
#### 直接指定存档(0.17.79-2+)
|
|
||||||
|
|
||||||
你可以通过一组环境变量配置服务端来指定要加载的特定存档:
|
|
||||||
|
|
||||||
要加载现有存档,请将 `SAVE_NAME` 设置为位于 `saves` 目录中的现有存档文件名,不包含 `.zip` 扩展名:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo docker run -d \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
-e LOAD_LATEST_SAVE=false \
|
|
||||||
-e SAVE_NAME=replaceme \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
factoriotools/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
要生成新地图,请设置 `GENERATE_NEW_SAVE=true` 并指定 `SAVE_NAME`:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo docker run -d \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
-e LOAD_LATEST_SAVE=false \
|
|
||||||
-e GENERATE_NEW_SAVE=true \
|
|
||||||
-e SAVE_NAME=replaceme \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
factoriotools/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mods-模组
|
|
||||||
|
|
||||||
将模组复制到 mods 文件夹中并重启服务端。
|
|
||||||
|
|
||||||
从 0.17 版本开始,添加了一个新的环境变量 `UPDATE_MODS_ON_START`,如果设置为 `true`,将在服务端启动时更新模组。如果设置了此选项,必须提供有效的 [Factorio 用户名和令牌](https://www.factorio.com/profile),否则服务端将不会启动。它们可以设置为 docker secrets、环境变量,或从 server-settings.json 文件中获取。
|
|
||||||
|
|
||||||
### Scenarios-场景
|
|
||||||
|
|
||||||
如果你想从全新开始启动场景(而不是从保存的地图),你需要从备用入口点启动 docker 镜像。为此,请使用存储在卷中 /factorio/entrypoints 目录中的示例入口点文件,并使用以下语法启动镜像。请注意,这是正常语法,添加了 --entrypoint 设置和末尾的附加参数,这是 Scenarios 文件夹中场景的名称。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker run -d \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
--entrypoint "/scenario.sh" \
|
|
||||||
factoriotools/factorio \
|
|
||||||
MyScenarioName
|
|
||||||
```
|
|
||||||
|
|
||||||
### 将场景转换为常规地图
|
|
||||||
|
|
||||||
如果你想将场景导出为保存的地图,可以使用类似于上述场景用法的示例入口点。Factorio 将运行一次,将场景转换为 saves 目录中的保存地图。然后使用标准选项重启 docker 镜像将加载该地图,就像上述场景示例刚启动的场景一样。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker run -d \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
--entrypoint "/scenario2map.sh" \
|
|
||||||
factoriotools/factorio
|
|
||||||
MyScenarioName
|
|
||||||
```
|
|
||||||
|
|
||||||
### RCON
|
|
||||||
|
|
||||||
在 `rconpw` 文件中设置 RCON 密码。如果 `rconpw` 不存在,将生成随机密码。
|
|
||||||
|
|
||||||
要更改密码,请停止服务端,修改 `rconpw`,然后重启服务端。
|
|
||||||
|
|
||||||
要"禁用" RCON,请不要暴露端口 27015,即不使用 `-p 27015:27015/tcp` 启动服务端。RCON 仍在运行,但没有人可以连接到它。
|
|
||||||
|
|
||||||
|
|
||||||
### 白名单 (0.15.3+)
|
|
||||||
|
|
||||||
创建文件 `config/server-whitelist.json` 并添加白名单用户。
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
"you",
|
|
||||||
"friend"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 黑名单 (0.17.1+)
|
|
||||||
|
|
||||||
创建文件 `config/server-banlist.json` 并添加黑名单用户。
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
"bad_person",
|
|
||||||
"other_bad_person"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 管理员列表 (0.17.1+)
|
|
||||||
|
|
||||||
创建文件 `config/server-adminlist.json` 并添加管理员用户。
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
"you",
|
|
||||||
"friend"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 自定义配置文件 (0.17.x+)
|
|
||||||
|
|
||||||
开箱即用的 factorio 不支持配置文件中的环境变量。一个解决方法是使用 `envsubst`,它在启动期间从 docker-compose 中设置的环境变量动态生成配置文件:
|
|
||||||
|
|
||||||
替换 server-settings.json 的示例:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
factorio_1:
|
|
||||||
image: factoriotools/factorio
|
|
||||||
ports:
|
|
||||||
- "34197:34197/udp"
|
|
||||||
volumes:
|
|
||||||
- /opt/factorio:/factorio
|
|
||||||
- ./server-settings.json:/server-settings.json
|
|
||||||
environment:
|
|
||||||
- INSTANCE_NAME=Your Instance's Name
|
|
||||||
- INSTANCE_DESC=Your Instance's Description
|
|
||||||
entrypoint: /bin/sh -c "mkdir -p /factorio/config && envsubst < /server-settings.json > /factorio/config/server-settings.json && exec /docker-entrypoint.sh"
|
|
||||||
```
|
|
||||||
|
|
||||||
然后 `server-settings.json` 文件可能包含这样的变量引用:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"name": "${INSTANCE_NAME}",
|
|
||||||
"description": "${INSTANCE_DESC}",
|
|
||||||
```
|
|
||||||
|
|
||||||
### 环境变量
|
|
||||||
|
|
||||||
这些是可以在容器运行时指定的环境变量。
|
|
||||||
|
|
||||||
| 变量名 | 描述 | 默认值 | 可用版本 |
|
|
||||||
|---------------------|----------------------------------------------------------------|----------------|--------------|
|
|
||||||
| GENERATE_NEW_SAVE | 如果在启动服务端之前不存在存档,则生成新存档 | false | 0.17+ |
|
|
||||||
| LOAD_LATEST_SAVE | 为 true 时加载最新存档。否则加载 SAVE_NAME | true | 0.17+ |
|
|
||||||
| PORT | 服务端监听的 UDP 端口 | 34197 | 0.15+ |
|
|
||||||
| BIND | 服务端监听的 IP 地址(v4 或 v6)(IP\[:PORT]) | | 0.15+ |
|
|
||||||
| RCON_PORT | rcon 服务端监听的 TCP 端口 | 27015 | 0.15+ |
|
|
||||||
| SAVE_NAME | 存档文件使用的名称 | _autosave1 | 0.17+ |
|
|
||||||
| TOKEN | factorio.com 令牌 | | 0.17+ |
|
|
||||||
| UPDATE_MODS_ON_START| 是否在启动服务端之前更新模组 | | 0.17+ |
|
|
||||||
| USERNAME | factorio.com 用户名 | | 0.17+ |
|
|
||||||
| CONSOLE_LOG_LOCATION| 将控制台日志保存到指定位置 | | |
|
|
||||||
| DLC_SPACE_AGE | 在 mod-list.json 中启用或禁用 DLC Space Age 的模组[^1] | true | 2.0.8+ |
|
|
||||||
| MODS | 要使用的模组目录 | /factorio/mods | 2.0.8+ |
|
|
||||||
|
|
||||||
**注意**:所有环境变量都作为字符串进行比较
|
|
||||||
|
|
||||||
## 容器细节
|
|
||||||
|
|
||||||
理念是[保持简单](http://wiki.c2.com/?KeepItSimple)。
|
|
||||||
|
|
||||||
* 服务端应该自启动。
|
|
||||||
* 优先使用配置文件而不是环境变量。
|
|
||||||
* 使用一个数据卷。
|
|
||||||
|
|
||||||
### 数据卷
|
|
||||||
|
|
||||||
为了保持简单,容器使用挂载在 `/factorio` 的单个卷。此卷存储配置、模组和存档。
|
|
||||||
|
|
||||||
此卷中的文件应该由 factorio 用户拥有,uid 845。
|
|
||||||
|
|
||||||
```text
|
|
||||||
factorio
|
|
||||||
|-- config
|
|
||||||
| |-- map-gen-settings.json
|
|
||||||
| |-- map-settings.json
|
|
||||||
| |-- rconpw
|
|
||||||
| |-- server-adminlist.json
|
|
||||||
| |-- server-banlist.json
|
|
||||||
| |-- server-settings.json
|
|
||||||
| `-- server-whitelist.json
|
|
||||||
|-- mods
|
|
||||||
| `-- fancymod.zip
|
|
||||||
`-- saves
|
|
||||||
`-- _autosave1.zip
|
|
||||||
```
|
|
||||||
|
|
||||||
## Docker Compose
|
|
||||||
|
|
||||||
[Docker Compose](https://docs.docker.com/compose/install/) 是运行 Docker 容器的简便方法。
|
|
||||||
|
|
||||||
* 需要 docker-engine >= 1.10.0
|
|
||||||
* 需要 docker-compose >=1.6.0
|
|
||||||
|
|
||||||
首先获取一个 [docker-compose.yml](https://github.com/factoriotools/factorio-docker/blob/master/docker/docker-compose.yml) 文件。从此仓库获取:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git clone https://github.com/factoriotools/factorio-docker.git
|
|
||||||
cd factorio-docker/docker
|
|
||||||
```
|
|
||||||
|
|
||||||
或者创建你自己的:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
services:
|
|
||||||
factorio:
|
|
||||||
image: factoriotools/factorio
|
|
||||||
ports:
|
|
||||||
- "34197:34197/udp"
|
|
||||||
- "27015:27015/tcp"
|
|
||||||
volumes:
|
|
||||||
- /opt/factorio:/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
现在 cd 到包含 docker-compose.yml 的目录并运行:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo mkdir -p /opt/factorio
|
|
||||||
sudo chown 845:845 /opt/factorio
|
|
||||||
sudo docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### 端口
|
|
||||||
|
|
||||||
* `34197/udp` - 游戏服务端(必需)。可以通过 `PORT` 环境变量更改。
|
|
||||||
* `27015/tcp` - RCON(可选)。
|
|
||||||
|
|
||||||
## 局域网游戏
|
|
||||||
|
|
||||||
确保 server-settings.json 中的 `lan` 设置为 `true`。
|
|
||||||
|
|
||||||
```json
|
|
||||||
"visibility":
|
|
||||||
{
|
|
||||||
"public": false,
|
|
||||||
"lan": true
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
使用 `--network=host` 选项启动容器,以便客户端可以自动找到局域网游戏。参考快速入门来创建 `/opt/factorio` 目录。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo docker run -d \
|
|
||||||
--network=host \
|
|
||||||
-p 34197:34197/udp \
|
|
||||||
-p 27015:27015/tcp \
|
|
||||||
-v /opt/factorio:/factorio \
|
|
||||||
--name factorio \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
factoriotools/factorio
|
|
||||||
```
|
|
||||||
|
|
||||||
## 部署到其他平台
|
|
||||||
|
|
||||||
### Vagrant
|
|
||||||
|
|
||||||
[Vagrant](https://www.vagrantup.com/) 是设置虚拟机(VM)运行 Docker 的简便方法。[Factorio Vagrant box 仓库](https://github.com/dtandersen/factorio-lan-vagrant)包含一个示例 Vagrantfile。
|
|
||||||
|
|
||||||
对于局域网游戏,VM 需要内部 IP 以便客户端连接。一种方法是使用公共网络。VM 使用 DHCP 获取 IP 地址。VM 还必须转发端口 34197。
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
config.vm.network "public_network"
|
|
||||||
config.vm.network "forwarded_port", guest: 34197, host: 34197
|
|
||||||
```
|
|
||||||
|
|
||||||
### Amazon Web Services (AWS) 部署
|
|
||||||
|
|
||||||
如果你正在寻找一种简单的方法将此部署到 Amazon Web Services 云,请查看 [Factorio Server Deployment (CloudFormation) 仓库](https://github.com/m-chandler/factorio-spot-pricing)。此仓库包含一个 CloudFormation 模板,可以让你在几分钟内在 AWS 上运行起来。它可选择使用 Spot Pricing,因此服务端非常便宜,你可以在不使用时轻松关闭它。
|
|
||||||
|
|
||||||
## 使用反向代理
|
|
||||||
|
|
||||||
如果你需要使用反向代理,可以使用以下 nginx 片段:
|
|
||||||
|
|
||||||
```
|
|
||||||
stream {
|
|
||||||
server {
|
|
||||||
listen 34197 udp reuseport;
|
|
||||||
proxy_pass my.upstream.host:34197;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
如果你的 factorio 主机使用多个 IP 地址(IPv6 非常常见),你可能还需要将 Factorio 绑定到单个 IP(否则 UDP 代理可能会因 IP 不匹配而混乱)。要做到这一点,将 `BIND` 环境变量传递给容器:`docker run --network=host -e BIND=2a02:1234::5678 ...`
|
|
||||||
|
|
||||||
## 疑难解答
|
|
||||||
|
|
||||||
### 我的服务端在服务端浏览器中列出,但没有人可以连接
|
|
||||||
|
|
||||||
检查日志。如果有一行显示 `Own address is RIGHT IP:WRONG PORT`,那么这可能是由 Docker 代理引起的。如果 IP 和端口是正确的,可能是端口转发或防火墙问题。
|
|
||||||
|
|
||||||
默认情况下,Docker 通过代理路由流量。代理更改源 UDP 端口,因此检测到错误的端口。有关详细信息,请参阅论坛帖子 *[docker 托管服务端检测到错误端口](https://forums.factorio.com/viewtopic.php?f=49&t=35255)*。
|
|
||||||
|
|
||||||
为了修复错误端口,使用 `--userland-proxy=false` 开关启动 Docker 服务。Docker 将使用 iptables 规则而不是代理路由流量。将开关添加到 `DOCKER_OPTS` 环境变量或 Docker systemd 服务定义中的 `ExecStart`。具体情况因操作系统而异。
|
|
||||||
|
|
||||||
### 当我在 34197 之外的端口上运行服务端时,没有人可以从服务端浏览器连接
|
|
||||||
|
|
||||||
使用 `PORT` 环境变量在不同端口上启动服务端,例如 `docker run -e "PORT=34198"`。这会更改用于端口检测的数据包的源端口。`-p 34198:34197` 对于私人服务端工作正常,但服务端浏览器检测到错误的端口。
|
|
||||||
|
|
||||||
## 贡献者
|
|
||||||
|
|
||||||
* [dtandersen](https://github.com/dtandersen) - 维护者
|
|
||||||
* [Fank](https://github.com/Fankserver) - Factorio 监视程序的程序员,保持版本更新。
|
|
||||||
* [SuperSandro2000](https://github.com/supersandro2000) - CI 负责人,维护者和 Factorio 监视程序的运行者。贡献版本更新并编写了 Travis 脚本。
|
|
||||||
* [DBendit](https://github.com/DBendit/docker_factorio_server) - 编写了管理员列表、禁止列表支持并贡献版本更新
|
|
||||||
* [Zopanix](https://github.com/zopanix/docker_factorio_server) - 原作者
|
|
||||||
* [Rfvgyhn](https://github.com/Rfvgyhn/docker-factorio) - 编写了随机生成的 RCON 密码
|
|
||||||
* [gnomus](https://github.com/gnomus/docker_factorio_server) - 编写了白名单支持
|
|
||||||
* [bplein](https://github.com/bplein/docker_factorio_server) - 编写了场景支持
|
|
||||||
* [jaredledvina](https://github.com/jaredledvina/docker_factorio_server) - 贡献版本更新
|
|
||||||
* [carlbennett](https://github.com/carlbennett) - 贡献版本更新和错误修复
|
|
||||||
|
|
||||||
[^1]: Space Age 模组也可以通过使用它们的名称(用空格分隔)来单独启用。
|
|
||||||
示例 1:使用 `true` 启用所有
|
|
||||||
示例 2:通过列出模组名称启用所有 `space-age elevated-rails quality`
|
|
||||||
示例 3:仅启用 Elevated rails `elevated-rails`
|
|
109
build.py
109
build.py
@ -1,109 +0,0 @@
|
|||||||
#!/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-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 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 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)
|
|
||||||
build_args = ["--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 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()
|
|
||||||
|
|
||||||
for version, buildinfo in sorted(builddata.items(), key=lambda item: item[0], reverse=True):
|
|
||||||
sha256 = buildinfo["sha256"]
|
|
||||||
tags = buildinfo["tags"]
|
|
||||||
build_and_push(sha256, version, 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)
|
|
104
build_legacy.sh
104
build_legacy.sh
@ -1,104 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -eoux pipefail
|
|
||||||
|
|
||||||
if [[ -z ${1:-} && -n ${CI:-} ]]; then
|
|
||||||
echo 'Usage: ./build.sh VERSION_SHORT'
|
|
||||||
exit 1
|
|
||||||
elif [[ ${CI:-} == true || -n ${1:-} ]]; then
|
|
||||||
VERSION_SHORT="$1"
|
|
||||||
else
|
|
||||||
VERSION_SHORT=$(find . -maxdepth 1 -type d | sort | tail -1 | grep -o "[[0-9]].[[0-9]]*")
|
|
||||||
EXTRA_TAG=latest
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "$VERSION_SHORT" || exit 1
|
|
||||||
|
|
||||||
VERSION=$(grep -oP '[0-9]+\.[0-9]+\.[0-9]+' Dockerfile | head -1)
|
|
||||||
DOCKER_REPO=factoriotools/factorio
|
|
||||||
|
|
||||||
BRANCH=${GITHUB_REF#refs/*/}
|
|
||||||
|
|
||||||
if [[ -n ${GITHUB_BASE_REF:-} ]]; then
|
|
||||||
TAGS="-t $DOCKER_REPO:$GITHUB_BASE_REF"
|
|
||||||
else
|
|
||||||
if [[ -n ${CI:-} ]]; then
|
|
||||||
# we are either on master or on a tag build
|
|
||||||
if [[ ${BRANCH:-} == master || ${BRANCH:-} == "$VERSION" ]]; then
|
|
||||||
TAGS="-t $DOCKER_REPO:$VERSION -t $DOCKER_REPO:$VERSION_SHORT"
|
|
||||||
# we are on an incremental build of a tag
|
|
||||||
elif [[ $VERSION == "${BRANCH%-*}" ]]; then
|
|
||||||
TAGS="-t $DOCKER_REPO:$BRANCH -t $DOCKER_REPO:$VERSION -t $DOCKER_REPO:$VERSION_SHORT"
|
|
||||||
# we build a other branch than master and exclude dependabot branches from tags cause the / is not supported by docker
|
|
||||||
elif [[ -n ${BRANCH:-} && ! $BRANCH =~ "/" ]]; then
|
|
||||||
TAGS="-t $DOCKER_REPO:$BRANCH"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# we are not in CI and tag version and version short
|
|
||||||
TAGS="-t $DOCKER_REPO:$VERSION -t $DOCKER_REPO:$VERSION_SHORT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n ${EXTRA_TAG:-} ]]; then
|
|
||||||
IFS=","
|
|
||||||
for TAG in $EXTRA_TAG; do
|
|
||||||
TAGS+=" -t $DOCKER_REPO:$TAG"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ${STABLE:-} == "$VERSION" ]]; then
|
|
||||||
TAGS+=" -t $DOCKER_REPO:stable"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Travis gets rate limited by Docker HUB.
|
|
||||||
if [[ ${CI:-} == true && -n ${DOCKER_PASSWORD:-} && -n ${DOCKER_USERNAME:-} ]]; then
|
|
||||||
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
|
|
||||||
fi
|
|
||||||
|
|
||||||
# shellcheck disable=SC2068
|
|
||||||
eval docker build . ${TAGS[@]:-}
|
|
||||||
docker images
|
|
||||||
|
|
||||||
# remove -1 from incremental tag
|
|
||||||
# eg before: 0.18.24-1, after 0.18.24
|
|
||||||
if [[ ${BRANCH:-} ]]; then
|
|
||||||
BRANCH_VERSION=${BRANCH%-*}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# only push when:
|
|
||||||
# or we build a tag and we don't build a PR
|
|
||||||
if [[ $VERSION == "${BRANCH_VERSION:-}" && ${GITHUB_BASE_REF:-} == "" ]] ||
|
|
||||||
# or we are not in CI
|
|
||||||
[[ -z ${CI:-} ]]; then
|
|
||||||
|
|
||||||
if [[ ${CI:-} == true ]]; then
|
|
||||||
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
|
|
||||||
fi
|
|
||||||
|
|
||||||
# push a tag on a branch other than master except dependabot branches cause docker does not support /
|
|
||||||
if [[ -n ${BRANCH:-} && $VERSION != "${BRANCH_VERSION:-}" && ${BRANCH:-} != "master" && ! ${BRANCH:-} =~ "/" ]]; then
|
|
||||||
docker push "$DOCKER_REPO:$BRANCH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# push an incremental tag
|
|
||||||
# eg 0.18.24-1
|
|
||||||
if [[ $VERSION == "${BRANCH_VERSION:-}" ]]; then
|
|
||||||
docker push "$DOCKER_REPO:$BRANCH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# only push on tags or when manually running the script
|
|
||||||
if [[ -n ${BRANCH_VERSION:-} || -z ${CI:-} ]]; then
|
|
||||||
docker push "$DOCKER_REPO:$VERSION"
|
|
||||||
docker push "$DOCKER_REPO:$VERSION_SHORT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n ${EXTRA_TAG:-} ]]; then
|
|
||||||
IFS=","
|
|
||||||
for TAG in $EXTRA_TAG; do
|
|
||||||
docker push "$DOCKER_REPO:$TAG"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ${STABLE:-} == "$VERSION" ]]; then
|
|
||||||
docker push "$DOCKER_REPO:stable"
|
|
||||||
fi
|
|
||||||
fi
|
|
363
buildinfo.json
363
buildinfo.json
@ -1,363 +0,0 @@
|
|||||||
{
|
|
||||||
"0.12.35": {
|
|
||||||
"sha256": "ab9cf01a56dde3073aaaa5152c628bbf9a5bb85638b87dc3d7fdb77fb169aedd",
|
|
||||||
"tags": [
|
|
||||||
"0.12.35",
|
|
||||||
"0.12"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"0.13.20": {
|
|
||||||
"sha256": "cbf5481e4b7e0efcc07c7b6a1fc3ff1404ad5597f3c9d37914a52ffb58d7c159",
|
|
||||||
"tags": [
|
|
||||||
"0.13.20",
|
|
||||||
"0.13"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"0.14.23": {
|
|
||||||
"sha256": "96c3e7acd4e0f066a499baba01823cac7c1caf0e50dbddcea5793f57bd60dc8c",
|
|
||||||
"tags": [
|
|
||||||
"0.14.23",
|
|
||||||
"0.14"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"0.15.40": {
|
|
||||||
"sha256": "1041ef61ea4aecd1f425e6030a909f0c349a9c01d1b3324d84a61b1cfef5ba6c",
|
|
||||||
"tags": [
|
|
||||||
"0.15.40",
|
|
||||||
"0.15"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"0.16.51": {
|
|
||||||
"sha256": "6cb09f5ac87f16f8d5b43cef26c0ae26cc46a57a0382e253dfda032dc5bb367f",
|
|
||||||
"tags": [
|
|
||||||
"0.16.51",
|
|
||||||
"0.16"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"0.17.79": {
|
|
||||||
"sha256": "9ace12fa986df028dc1851bf4de2cb038044d743e98823bc1c48ba21aa4d23df",
|
|
||||||
"tags": [
|
|
||||||
"0.17.79",
|
|
||||||
"0.17"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"1.0.0": {
|
|
||||||
"sha256": "81d9e1aa94435aeec4131c8869fa6e9331726bea1ea31db750b65ba42dbd1464",
|
|
||||||
"tags": [
|
|
||||||
"1.0.0",
|
|
||||||
"1.0"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"1.1.110": {
|
|
||||||
"sha256": "485fe6db36e5decd7dd0d70e7c97e61f818100fa3e48d87884b287027c7a646a",
|
|
||||||
"tags": [
|
|
||||||
"stable-1.1.110",
|
|
||||||
"1",
|
|
||||||
"1.1",
|
|
||||||
"1.1.110"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.13": {
|
|
||||||
"sha256": "27b36901a39e593adf28418c0286142c6c7a9f83d156963c7369bd405a25c7d1",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.13",
|
|
||||||
"2.0",
|
|
||||||
"2.0.13"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.14": {
|
|
||||||
"sha256": "5a4bc4c3b2a97ed1fc58eb796321e848dcc64435bd91013dd9c78a14a8ce8815",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.14",
|
|
||||||
"2.0",
|
|
||||||
"2.0.14"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.15": {
|
|
||||||
"sha256": "70b441cb807811a60586c01107248c1d8d7ae043bd1f23675fc924fbaaa538d8",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.15",
|
|
||||||
"2.0",
|
|
||||||
"2.0.15"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.16": {
|
|
||||||
"sha256": "f2069b4b746500d945eeb67ef7eda5e7aebe7fd0294c2af4e117af22a3bbaea3",
|
|
||||||
"tags": [
|
|
||||||
"2.0.16"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.17": {
|
|
||||||
"sha256": "183407f2fb21e05152442ffb5f15ffb283994339ca6a51b3559a257c30505e5e",
|
|
||||||
"tags": [
|
|
||||||
"2.0.17"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.18": {
|
|
||||||
"sha256": "f378a1dc8a545c13d8ca616cbe72d245aa3ce93e3f219d8d60d3c06c7df82dc0",
|
|
||||||
"tags": [
|
|
||||||
"2.0.18"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.19": {
|
|
||||||
"sha256": "2e27aca3a7f65b50916d14a62203b6861cbe657e8d2dbd8f813e0a606efce9c7",
|
|
||||||
"tags": [
|
|
||||||
"2.0.19"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.20": {
|
|
||||||
"sha256": "c4a901f2f1dbedbb41654560db4c6fab683a30c20334e805d4ef740c0416515a",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.20",
|
|
||||||
"2.0",
|
|
||||||
"2.0.20"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.21": {
|
|
||||||
"sha256": "1d6d2785006d6a8d9d5fdcdaa7097a189ec35ba95f3521025dc4e046f7a1398e",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.21",
|
|
||||||
"2.0",
|
|
||||||
"2.0.21"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.22": {
|
|
||||||
"sha256": "14c3eea7600fbe7f35bca52fe4c277e8f5e23b34c35ebebaa46c6752c750cb85",
|
|
||||||
"tags": [
|
|
||||||
"2.0.22"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.23": {
|
|
||||||
"sha256": "e819fc9ad6df061bf9d4bffc91988dd18d0e3982c8b1c22c0525d78bda3ef216",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.23",
|
|
||||||
"2.0",
|
|
||||||
"2.0.23"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.24": {
|
|
||||||
"sha256": "4644acc4195391fe19a7468c546d10a494ce1a188964c79f20cb0fa050b67120",
|
|
||||||
"tags": [
|
|
||||||
"2.0.24"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.25": {
|
|
||||||
"sha256": "0d1698f1f29759ff27faa6a5d9c3804377cb1767f2692003a8e9d4c294845e5a",
|
|
||||||
"tags": [
|
|
||||||
"2.0.25"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.26": {
|
|
||||||
"sha256": "a401024039372a53b9a29b7deb4ac279cd9a34abe69426a109a13a9a1c599f1f",
|
|
||||||
"tags": [
|
|
||||||
"2.0.26"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.27": {
|
|
||||||
"sha256": "63c75ce74cd9d1e4b65ae9f98e9865abdbe3d600fb3259dcda5ea69a512b2993",
|
|
||||||
"tags": [
|
|
||||||
"2.0.27"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.28": {
|
|
||||||
"sha256": "ea9937b6adc7a18e17a4e1e64992ec389407497b36e68280bb14fcdd4c884dd3",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.28",
|
|
||||||
"2.0",
|
|
||||||
"2.0.28"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.29": {
|
|
||||||
"sha256": "54088c9cacfddbce2e7bf90604fea095ff723e70d9bb056e1fb469b900a50f09",
|
|
||||||
"tags": [
|
|
||||||
"2.0.29"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.30": {
|
|
||||||
"sha256": "4137824a20e1f3298410432c85e62d0eb46b0dab1a8411c233699f890d4c1668",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.30",
|
|
||||||
"2.0",
|
|
||||||
"2.0.30"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.31": {
|
|
||||||
"sha256": "0ee39ff6181ef41b606b7ba1ab5c04d8f81579ef56ec4947e4d74ce5d192b5d5",
|
|
||||||
"tags": [
|
|
||||||
"2.0.31"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.32": {
|
|
||||||
"sha256": "2a6102ae42dcc5e8fe923bd68bcd326a569e35912acde121301e5d4d2d856417",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.32",
|
|
||||||
"2.0",
|
|
||||||
"2.0.32"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.33": {
|
|
||||||
"sha256": "9365a34d1724e5c9f592cc9da511485e2fa7da1c12df08029bce478586ba4b7b",
|
|
||||||
"tags": [
|
|
||||||
"2.0.33"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.34": {
|
|
||||||
"sha256": "9511462203ebb2763f9f8623bb17f3070041ae3cbd7d80284c1e9bb38c09fc40",
|
|
||||||
"tags": [
|
|
||||||
"2.0.34"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.35": {
|
|
||||||
"sha256": "31cd58eaf4b06cc0dc5d82640f7adf2366aa9da64133d2c228f1308f1060a990",
|
|
||||||
"tags": [
|
|
||||||
"2.0.35"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.36": {
|
|
||||||
"sha256": "e94567b986654f1f7c3ec5c8bd151e3768b4ab9ab9cc389f6b9fd8e0dab32ce2",
|
|
||||||
"tags": [
|
|
||||||
"2.0.36"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.37": {
|
|
||||||
"sha256": "5f105131fe4f48d47fd813f57b6bd275840a47b21e39b30d22bf5da30075a786",
|
|
||||||
"tags": [
|
|
||||||
"2.0.37"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.38": {
|
|
||||||
"sha256": "ad9650f7456aecc8adb5369eedb418507c7643bede0da60fc1a239878d4902de",
|
|
||||||
"tags": [
|
|
||||||
"2.0.38"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.39": {
|
|
||||||
"sha256": "0f8a3d0e43797b5ff4d8b85d7c334b095a3f07d9aa7f80b1e87f94939a93df34",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.39",
|
|
||||||
"2.0",
|
|
||||||
"2.0.39"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.40": {
|
|
||||||
"sha256": "eac1f24afb68acbfcf1d72d2ad142e8584d77f2d100a3af743f106e50ac176d3",
|
|
||||||
"tags": [
|
|
||||||
"2.0.40"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.41": {
|
|
||||||
"sha256": "77ebccae8167fc1a9fc4da8c11e8410f6017b92b1a0913eb58ac5285c9eec399",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.41",
|
|
||||||
"2.0",
|
|
||||||
"2.0.41"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.42": {
|
|
||||||
"sha256": "b5b8b8bdc915e67dbc1710cd3d6aa6802d397b7c0f47db07da8acf39d5bd6376",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.42",
|
|
||||||
"2.0",
|
|
||||||
"2.0.42"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.43": {
|
|
||||||
"sha256": "bde6e167330c4439ce7df3ac519ea445120258ef676f1f6ad31d0c2816d3aee3",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.43",
|
|
||||||
"2.0",
|
|
||||||
"2.0.43"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.44": {
|
|
||||||
"sha256": "9468c5e07080c01eb7a734036160bf806d62cafc11465a23150cfbd210e1036d",
|
|
||||||
"tags": [
|
|
||||||
"2.0.44"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.45": {
|
|
||||||
"sha256": "4fd7e04bb3ea7d12da8e1c3befc6b53b3c0064775c960a5a9db6a943f2259fc2",
|
|
||||||
"tags": [
|
|
||||||
"2.0.45"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.46": {
|
|
||||||
"sha256": "fc611b6d4078b5d9448284c2890f7e0b6b1f203d52f622c655d3600982489c3e",
|
|
||||||
"tags": [
|
|
||||||
"2.0.46"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.47": {
|
|
||||||
"sha256": "f0f320c77616a4794227eb637a70b557108f3141a4633276593220a768f49a26",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.47",
|
|
||||||
"2.0",
|
|
||||||
"2.0.47"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.48": {
|
|
||||||
"sha256": "f0038835e96bbacc19d52d22d47469882d9ebe41a4e5213c0471020647a1ee2d",
|
|
||||||
"tags": [
|
|
||||||
"2.0.48"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.49": {
|
|
||||||
"sha256": "ef0648ca1ba44c145a3a3e4c174ccd276eb4a335155a20df1ae0e47156fa34ff",
|
|
||||||
"tags": [
|
|
||||||
"2.0.49"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.50": {
|
|
||||||
"sha256": "81d4aec735473c5bd2c87f09abcd793c31cb9a07d9fdf3c3d7275c78ebe4bc18",
|
|
||||||
"tags": [
|
|
||||||
"2.0.50"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.51": {
|
|
||||||
"sha256": "fc940dea67d25d3fd403531520e8afda2779ff1fa8050f535ac1351b7873a070",
|
|
||||||
"tags": [
|
|
||||||
"2.0.51"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.52": {
|
|
||||||
"sha256": "be8d6216890089890693d6d94f141f745d35c53e52c6b942f6c944f5c00c8c26",
|
|
||||||
"tags": [
|
|
||||||
"2.0.52"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.53": {
|
|
||||||
"sha256": "40a57076f80dbee0238dab62f16585def06f7d7e5b41f6b677be41b4d2cae811",
|
|
||||||
"tags": [
|
|
||||||
"2.0.53"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.54": {
|
|
||||||
"sha256": "ad47c541b70763552bcf597202ee84aaac727d0ba158873134dc163a3a0506f0",
|
|
||||||
"tags": [
|
|
||||||
"2.0.54"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.55": {
|
|
||||||
"sha256": "ef12a54d1556ae1f84ff99edc23706d13b7ad41f1c02d74ca1dfadf9448fcbae",
|
|
||||||
"tags": [
|
|
||||||
"stable-2.0.55",
|
|
||||||
"2",
|
|
||||||
"2.0",
|
|
||||||
"2.0.55",
|
|
||||||
"stable"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.57": {
|
|
||||||
"sha256": "22b232afb77067c68a3afe087be6a0ee760479262598a12a709e1b03ea9508a6",
|
|
||||||
"tags": [
|
|
||||||
"2.0.57"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"2.0.58": {
|
|
||||||
"sha256": "be82e1aeba4169420e1b00c12a3e00ec2309a41327f9d6c335feec27bbc885e6",
|
|
||||||
"tags": [
|
|
||||||
"latest",
|
|
||||||
"2.0.58"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
version: "2"
|
|
||||||
services:
|
|
||||||
factorio:
|
|
||||||
container_name: factorio
|
|
||||||
image: factoriotools/factorio:stable
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "34197:34197/udp"
|
|
||||||
- "27015:27015/tcp"
|
|
||||||
volumes:
|
|
||||||
- ./data:/factorio
|
|
||||||
environment:
|
|
||||||
- UPDATE_MODS_ON_START=true
|
|
||||||
|
|
||||||
# Uncomment to enable autoupdate via watchtower
|
|
||||||
#labels:
|
|
||||||
# # Labels to allow watchtower autoupdate only if no players are online
|
|
||||||
# - com.centurylinklabs.watchtower.enable=true
|
|
||||||
# - com.centurylinklabs.watchtower.scope=factorio
|
|
||||||
# - com.centurylinklabs.watchtower.lifecycle.pre-update="/players-online.sh"
|
|
||||||
|
|
||||||
# Uncomment the following files to use watchtower for updating the factorio container
|
|
||||||
# Full documentation of watchtower: https://github.com/containrrr/watchtower
|
|
||||||
#watchtower:
|
|
||||||
# container_name: watchtower_factorio
|
|
||||||
# image: containrrr/watchtower
|
|
||||||
# restart: unless-stopped
|
|
||||||
# volumes:
|
|
||||||
# - /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
# environment:
|
|
||||||
# # Only update containers which have the option 'watchtower.enable=true' set
|
|
||||||
# - WATCHTOWER_TIMEOUT=30s
|
|
||||||
# - WATCHTOWER_LABEL_ENABLE=true
|
|
||||||
# - WATCHTOWER_POLL_INTERVAL=3600
|
|
||||||
# - WATCHTOWER_LIFECYCLE_HOOKS=true
|
|
||||||
# - WATCHTOWER_SCOPE=factorio
|
|
||||||
# labels:
|
|
||||||
# - com.centurylinklabs.watchtower.scope=factorio
|
|
@ -1,97 +0,0 @@
|
|||||||
# 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 USER=factorio
|
|
||||||
ARG GROUP=factorio
|
|
||||||
ARG PUID=845
|
|
||||||
ARG PGID=845
|
|
||||||
ARG BOX64_VERSION=v0.2.4
|
|
||||||
|
|
||||||
# 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
|
|
||||||
# vanilla factorio provides the following presets:
|
|
||||||
# rich-resources, marathon, death-world, death-world-marathon, rail-world, ribbon-world, island
|
|
||||||
# a modded factorio example for using this:
|
|
||||||
# space-exploration
|
|
||||||
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 \
|
|
||||||
PUID="$PUID" \
|
|
||||||
PGID="$PGID" \
|
|
||||||
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/*
|
|
||||||
|
|
||||||
RUN addgroup --system --gid "$PGID" "$GROUP" \
|
|
||||||
&& adduser --system --uid "$PUID" --gid "$PGID" --no-create-home --disabled-password --shell /bin/sh "$USER"
|
|
||||||
|
|
||||||
# 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/ \
|
|
||||||
&& chown -R "$USER":"$GROUP" /opt/factorio /factorio
|
|
||||||
|
|
||||||
COPY files/*.sh /
|
|
||||||
COPY files/config.ini /opt/factorio/config/config.ini
|
|
||||||
COPY --from=rcon-builder /src/rcon /bin/rcon
|
|
||||||
|
|
||||||
VOLUME /factorio
|
|
||||||
EXPOSE $PORT/udp $RCON_PORT/tcp
|
|
||||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
|
@ -1,28 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
services:
|
|
||||||
factorio:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
args:
|
|
||||||
# Check buildinfo.json for supported versions and SHAs
|
|
||||||
# https://github.com/factoriotools/factorio-docker/blob/master/buildinfo.json
|
|
||||||
- VERSION=2.0.55
|
|
||||||
- SHA256=ef12a54d1556ae1f84ff99edc23706d13b7ad41f1c02d74ca1dfadf9448fcbae
|
|
||||||
ports:
|
|
||||||
- "34197:34197/udp"
|
|
||||||
- "27015:27015/tcp"
|
|
||||||
volumes:
|
|
||||||
- /opt/factorio:/factorio
|
|
||||||
# environment:
|
|
||||||
# - PUID=1000
|
|
||||||
# - PGID=1000
|
|
||||||
# - UPDATE_MODS_ON_START=true
|
|
||||||
# - USERNAME=FactorioUsername
|
|
||||||
# - TOKEN=FactorioToken
|
|
||||||
# - PORT=34198
|
|
||||||
# - PRESET=deathworld
|
|
||||||
# - ADDR=::1
|
|
||||||
# # Uncomment the following line to enable the use of the host's network stack,
|
|
||||||
# # which may be necessary for some setups like NAS or when using some proxy service like firewall rules.
|
|
||||||
# extra_hosts:
|
|
||||||
# - "host.docker.internal:host-gateway"
|
|
@ -1,755 +0,0 @@
|
|||||||
; version=8
|
|
||||||
; This is INI file : https://en.wikipedia.org/wiki/INI_file#Format
|
|
||||||
; Semicolons (;) at the beginning of the line indicate a comment. Comment lines are ignored.
|
|
||||||
[path]
|
|
||||||
read-data=__PATH__executable__/../../data
|
|
||||||
write-data=__PATH__executable__/../..
|
|
||||||
|
|
||||||
[general]
|
|
||||||
locale=
|
|
||||||
|
|
||||||
[other]
|
|
||||||
; Options: true, false
|
|
||||||
; verbose-logging=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; log-saving-statistics=false
|
|
||||||
|
|
||||||
; autosave-interval=5
|
|
||||||
|
|
||||||
; autosave-slots=3
|
|
||||||
|
|
||||||
; In ticks
|
|
||||||
; minimum-latency-in-multiplayer=0
|
|
||||||
|
|
||||||
; In seconds
|
|
||||||
; multiplayer-initial-connection-timeout=10
|
|
||||||
|
|
||||||
; port=34197
|
|
||||||
|
|
||||||
; max-map-preview-chunk-side=64
|
|
||||||
|
|
||||||
; max-map-preview-threads=7
|
|
||||||
|
|
||||||
; In bytes
|
|
||||||
; max-multiplayer-script-reload-size=1048576
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-steam-networking=true
|
|
||||||
|
|
||||||
; proxy=
|
|
||||||
|
|
||||||
; proxy-username=
|
|
||||||
|
|
||||||
; proxy-password=
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; check-updates=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-experimental-updates=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-new-mods=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; use-mod-settings-per-save=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; disable-minimal-mode=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; disable-blueprint-storage=false
|
|
||||||
|
|
||||||
; Disables tracking which mod created/changed what prototype. Mainly for faster startup during development.
|
|
||||||
;
|
|
||||||
; Options: true, false
|
|
||||||
; disable-prototype-history=false
|
|
||||||
|
|
||||||
; Print a warning for all prototype values that were not accessed.
|
|
||||||
;
|
|
||||||
; Options: true, false
|
|
||||||
; check-unused-prototype-data=false
|
|
||||||
|
|
||||||
; Cache data stage prototype data for faster startup. Experimental.
|
|
||||||
;
|
|
||||||
; Options: true, false
|
|
||||||
; cache-prototype-data=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-razer-chroma-support=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-logitech-led-support=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-crash-log-uploading=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-heap-validation=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-threaded-message-pump=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-taskbar-animation=true
|
|
||||||
|
|
||||||
; Does nothing on Windows
|
|
||||||
;
|
|
||||||
; Options: true, false
|
|
||||||
; non-blocking-saving=false
|
|
||||||
|
|
||||||
; Related to MacOS
|
|
||||||
;
|
|
||||||
; Options: true, false
|
|
||||||
; discard-mouse-events-when-accessibility-zoomed=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-blueprint-storage-cloud-sync=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; force-enable-factorio-version-check=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; bring-window-to-top-on-click=true
|
|
||||||
|
|
||||||
; Options: fast, maximum
|
|
||||||
; multiplayer-compression-level=fast
|
|
||||||
|
|
||||||
; Options: none, fast, maximum
|
|
||||||
; autosave-compression-level=fast
|
|
||||||
|
|
||||||
; Socket to host RCON on when lauching MP server from the menu.
|
|
||||||
; local-rcon-socket=0.0.0.0:0
|
|
||||||
|
|
||||||
; Password for RCON when launching MP server from the menu.
|
|
||||||
; local-rcon-password=
|
|
||||||
|
|
||||||
|
|
||||||
[interface]
|
|
||||||
; Options: true, false
|
|
||||||
; automatic-ui-scale=true
|
|
||||||
|
|
||||||
; custom-ui-scale=1.000000
|
|
||||||
|
|
||||||
; tooltip-delay=0.040000
|
|
||||||
|
|
||||||
; entity-tooltip-delay=0.000000
|
|
||||||
|
|
||||||
; tooltip-offset=20
|
|
||||||
|
|
||||||
; output-console-delay=1200
|
|
||||||
|
|
||||||
; train-stop-label-angle=0.085526
|
|
||||||
|
|
||||||
; active-quick-bars=2
|
|
||||||
|
|
||||||
; shortcut-bar-rows=2
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; autosort-inventory=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; research-finished-stops-game=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; use-item-groups=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; use-item-subgroups=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; use-version-filter-in-browse-games-gui=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; use-version-filter-in-install-mods-gui=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; play-sound-for-chat-messages=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; fuzzy-search-enabled=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; pick-ghost-cursor=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-minimap=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-tips-and-tricks=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-tutorial-notifications=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-turret-radius-when-blueprinting=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-item-labels-in-cursor=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-rail-block-visualization=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-missing-logistic-network-icon=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-interaction-indications=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-grid-when-paused=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-inserter-arrows-when-selected=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-inserter-arrows-when-detailed-info-is-on=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-pump-arrows-when-detailed-info-is-on=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-mining-drill-arrows-when-detailed-info-is-on=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-combinator-settings-when-detailed-info-is-on=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; entity-tooltip-on-the-side=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-mod-owners-in-tooltips=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-descriptions-in-tooltips=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-total-raw-in-recipe-tooltips=true
|
|
||||||
|
|
||||||
; debug-font-size=18
|
|
||||||
|
|
||||||
; train-visualization-length=5
|
|
||||||
|
|
||||||
|
|
||||||
[sound]
|
|
||||||
; master-volume=0.800000
|
|
||||||
|
|
||||||
; music-volume=0.500000
|
|
||||||
|
|
||||||
; game-effects-volume=0.700000
|
|
||||||
|
|
||||||
; gui-effects-volume=0.600000
|
|
||||||
|
|
||||||
; walking-sound-volume=0.250000
|
|
||||||
|
|
||||||
; environment-sounds-volume=0.550000
|
|
||||||
|
|
||||||
; alerts-volume=0.500000
|
|
||||||
|
|
||||||
; wind-volume=0.350000
|
|
||||||
|
|
||||||
; audible-distance=40.000000
|
|
||||||
|
|
||||||
; environment-audible-distance=30.000000
|
|
||||||
|
|
||||||
; maximum-environment-sounds=50
|
|
||||||
|
|
||||||
; active-gui-volume-modifier=0.800000
|
|
||||||
|
|
||||||
; active-gui-environment-volume-modifier=0.400000
|
|
||||||
|
|
||||||
; The maximum volume allowed for any sound.
|
|
||||||
; maximum-volume=2.000000
|
|
||||||
|
|
||||||
; ambient-music-pause-mean-seconds=45.000000
|
|
||||||
|
|
||||||
; ambient-music-pause-variance-seconds=30.000000
|
|
||||||
|
|
||||||
; Options: main-tracks-only, interleave-main-tracks-with-interludes, randomize-all
|
|
||||||
; ambient-music-mode=interleave-main-tracks-with-interludes
|
|
||||||
|
|
||||||
; zoom-audible-distance-coefficient=0.500000
|
|
||||||
|
|
||||||
; zoom-volume-coefficient=0.750000
|
|
||||||
|
|
||||||
|
|
||||||
[map-view]
|
|
||||||
; Options: true, false
|
|
||||||
; show-logistic-network=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-electric-network=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-turret-range=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-pollution=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-networkless-logistic-members=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-train-station-names=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-player-names=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-non-standard-map-info=false
|
|
||||||
|
|
||||||
|
|
||||||
[debug]
|
|
||||||
; force=enemy
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; capture-perf-statistics=false
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-fps=debug
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-detailed-info=debug
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-time-usage=debug
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-gpu-time-usage=debug
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-sprite-counts=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-lua-object-statistics=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-heat-buffer-info=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-multiplayer-waiting-icon=debug
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-multiplayer-statistics=debug
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-multiplayer-selection-rectangles=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-debug-info-in-tooltips=debug
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; hide-mod-guis=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-tile-grid=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-collision-rectangles=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-selection-rectangles=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-render-rectangles=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-entity-positions=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-entity-velocities=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-selected-entity-advanced-tiles=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-selected-input-transport-belts=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-paths=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-path-requests=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-next-waypoint-bb=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-target=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-unit-group-info=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-unit-behavior-info=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-pathfinder-fringe=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-path-cache=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-path-cache-paths=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-rail-paths=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-rolling-stock-count=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-rail-connections=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-rail-joints=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-rail-signal-states=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-rail-segment-collision-boxes=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-train-stop-point=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-train-braking-distance=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-train-signals=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-train-repathing=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-network-connected-entities=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-circuit-network-numbers=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-energy-sources-networks=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-active-state=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-wakeup-lists=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-transport-lines=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-transport-line-gaps=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-pollution-values=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-active-entities-on-chunk-counts=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-active-chunks=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-polluted-chunks=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; hide-chart-tags=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-enemy-expansion-candidate-chunks=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-enemy-expansion-candidate-chunk-values=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-bad-attack-chunks=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-tile-variations=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-raw-tile-transitions=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-fluid-box-fluid-info=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-environment-sound-info=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-environment-sound-area=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-selected-entity-audible-range=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-recently-played-sound-info=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-logistic-robot-targets=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-logistic-robots-on-map=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-recipe-icons-on-map=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-player-robots=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-fire-info=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-sticker-info=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-decorative-names=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-decorative-collision-rectangles=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; allow-increased-zoom=never
|
|
||||||
|
|
||||||
; Options: always, debug, never
|
|
||||||
; show-chunk-components=never
|
|
||||||
|
|
||||||
|
|
||||||
[multiplayer-lobby]
|
|
||||||
; name=
|
|
||||||
|
|
||||||
; description=
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; visibility-public=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; visibility-steam=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; visibility-lan=true
|
|
||||||
|
|
||||||
; max-players=0
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; ignore-player-limit-when-returning=false
|
|
||||||
|
|
||||||
; max-upload-in-kilobytes-per-second=0
|
|
||||||
|
|
||||||
; max-upload-slots=5
|
|
||||||
|
|
||||||
; password=
|
|
||||||
|
|
||||||
; tag-list=
|
|
||||||
|
|
||||||
; afk-auto-kick=0
|
|
||||||
|
|
||||||
; Options: true, false, admins-only
|
|
||||||
; allowed-commands=admins-only
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; only-admins-can-pause=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; autosave-only-on-server=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; non-blocking-saving=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; verify-user-identity=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; enable-whitelist=false
|
|
||||||
|
|
||||||
|
|
||||||
[graphics]
|
|
||||||
; lights-render-quality=0.250000
|
|
||||||
|
|
||||||
; Default preferred display index should force finding primary monitor
|
|
||||||
; preferred-display-index=255
|
|
||||||
|
|
||||||
; screenshots-threads-count=8
|
|
||||||
|
|
||||||
; cache-sprite-atlas-count=1
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; cache-sprite-atlas=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; compress-sprite-atlas-cache=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; texture-streaming=true
|
|
||||||
|
|
||||||
; streamed-atlas-physical-vram-size=0
|
|
||||||
|
|
||||||
; sprite-vertex-buffer-size=1048576
|
|
||||||
|
|
||||||
; max-texture-size=0
|
|
||||||
|
|
||||||
; max-threads=8
|
|
||||||
|
|
||||||
; 'low' and 'very-low' options are deprecated and will be migrated to 'normal'
|
|
||||||
;
|
|
||||||
; Options: high, normal, low, very-low
|
|
||||||
; graphics-quality=normal
|
|
||||||
|
|
||||||
; brightness=0
|
|
||||||
|
|
||||||
; contrast=0
|
|
||||||
|
|
||||||
; saturation=100
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; full-screen=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; minimize-on-focus-loss=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-smoke=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-clouds=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-decoratives=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-particles=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-item-shadows=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-inserter-shadows=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-animated-water=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; show-tree-distortion=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; force-opengl=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; v-sync=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; high-quality-animations=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; high-quality-shadows=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; high-quality-terrain=true
|
|
||||||
|
|
||||||
; Minimum number of turrets required to turn on the turret range overdraw optimization
|
|
||||||
; turret-overdraw-minimum-count=4
|
|
||||||
|
|
||||||
; Scale at which the turret range overdraw optimization will start being applied
|
|
||||||
; turret-overdraw-scale-threshold=0.200000
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; skip-vram-detection=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; halt-rendering-when-minimized=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; runtime-sprite-reload=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; full-color-depth=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; render-in-native-resolution=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; use-flip-presentation-model=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; debug-api=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; discard-buffers-on-begin-frame=true
|
|
||||||
|
|
||||||
; Options: all, high, medium, low
|
|
||||||
; video-memory-usage=high
|
|
||||||
|
|
||||||
; Options: none, high-quality, low-quality
|
|
||||||
; texture-compression-level=high-quality
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; compress-virtual-atlas=true
|
|
||||||
|
|
||||||
; Options: copy, copy-sequential, flip, flip-discard
|
|
||||||
; dxgi-presentation-model=copy
|
|
||||||
|
|
||||||
; Options: none, flush, wait-for-vblank, flush-and-wait-for-vblank
|
|
||||||
; dxgi-action-before-present=none
|
|
||||||
|
|
||||||
; relevant only for flip presentation models
|
|
||||||
;
|
|
||||||
; Options: true, false
|
|
||||||
; dxgi-allow-tearing=false
|
|
||||||
|
|
||||||
; Options: false, true, auto
|
|
||||||
; dxgi-flip-do-not-wait=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; dxgi-present-restart=false
|
|
||||||
|
|
||||||
; dxgi-swap-chain-buffer-count=0
|
|
||||||
|
|
||||||
; dxgi-max-frame-latency=0
|
|
||||||
|
|
||||||
; dxgi-adapter-index=-1
|
|
||||||
|
|
||||||
; max-sprite-loading-threads=32
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; gpu-accelerated-compression=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; gpu-accelerated-mipmap-compression=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; wait-until-mipmap-generation-finished=true
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; check-for-unused-pixels=false
|
|
||||||
|
|
||||||
; ogl-depth-buffer-bit-depth=0
|
|
||||||
|
|
||||||
; Options: false, true, auto
|
|
||||||
; ogl-accelerated-renderer=auto
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; ogl-double-buffered=true
|
|
||||||
|
|
||||||
; Set to true if mipmapped sprites render very blurry on your GPU. Limited support.
|
|
||||||
;
|
|
||||||
; Options: true, false
|
|
||||||
; legacy-gpu-no-mipmaps=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; force-linear-magnification=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; custom-mipmap-workaround=false
|
|
||||||
|
|
||||||
; Options: true, false
|
|
||||||
; buffer-rename-workaround=false
|
|
||||||
|
|
||||||
; Comma separated list of OpenGL extensions that should not be used (for example: ARB_copy_image,KHR_debug)
|
|
||||||
; disabled-opengl-extensions=
|
|
||||||
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -eou pipefail
|
|
||||||
|
|
||||||
# Path to the mod-list.json file
|
|
||||||
MOD_LIST_FILE="$MODS/mod-list.json"
|
|
||||||
|
|
||||||
ALL_SPACE_AGE_MODS=("elevated-rails" "quality" "space-age")
|
|
||||||
|
|
||||||
if [[ ! -f "$MOD_LIST_FILE" ]]; then
|
|
||||||
# Create the mod-list.json file if it doesn't exist
|
|
||||||
echo '{"mods":[{"name":"base","enabled":true}]}' > "$MOD_LIST_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
enable_mod()
|
|
||||||
{
|
|
||||||
echo "Enable mod $1 for DLC"
|
|
||||||
jq --arg mod_name "$1" 'if .mods | map(.name) | index($mod_name) then .mods |= map(if .name == $mod_name and .enabled == false then .enabled = true else . end) else . end' "$MOD_LIST_FILE" > "$MOD_LIST_FILE.tmp"
|
|
||||||
mv "$MOD_LIST_FILE.tmp" "$MOD_LIST_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
disable_mod()
|
|
||||||
{
|
|
||||||
echo "Disable mod $1 for DLC"
|
|
||||||
jq --arg mod_name "$1" 'if .mods | map(.name) | index($mod_name) then .mods |= map(if .name == $mod_name and .enabled == true then .enabled = false else . end) else .mods += [{"name": $mod_name, "enabled": false}] end' "$MOD_LIST_FILE" > "$MOD_LIST_FILE.tmp"
|
|
||||||
mv "$MOD_LIST_FILE.tmp" "$MOD_LIST_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Enable or disable DLCs if configured
|
|
||||||
if [[ ${DLC_SPACE_AGE:-} == "true" ]]; then
|
|
||||||
# Define the DLC mods
|
|
||||||
ENABLE_MODS=(${ALL_SPACE_AGE_MODS[@]})
|
|
||||||
elif [[ ${DLC_SPACE_AGE:-} == "false" ]]; then
|
|
||||||
# Define the DLC mods
|
|
||||||
DISABLE_MODS=(${ALL_SPACE_AGE_MODS[@]})
|
|
||||||
else
|
|
||||||
ENABLE_MODS=()
|
|
||||||
DISABLE_MODS=()
|
|
||||||
|
|
||||||
for SPACE_AGE_MOD in "${ALL_SPACE_AGE_MODS[@]}"; do
|
|
||||||
REGEX="(^|\s)$SPACE_AGE_MOD($|\s)"
|
|
||||||
if [[ "$DLC_SPACE_AGE" =~ $REGEX ]]; then
|
|
||||||
ENABLE_MODS+=($SPACE_AGE_MOD)
|
|
||||||
else
|
|
||||||
DISABLE_MODS+=($SPACE_AGE_MOD)
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Iterate over each DLC mod to enable
|
|
||||||
for MOD in "${ENABLE_MODS[@]}"; do
|
|
||||||
enable_mod "$MOD"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Iterate over each DLC mod to disable
|
|
||||||
for MOD in "${DISABLE_MODS[@]}"; do
|
|
||||||
disable_mod "$MOD"
|
|
||||||
done
|
|
@ -1,124 +0,0 @@
|
|||||||
#!/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:-""}"
|
|
||||||
|
|
||||||
mkdir -p "$FACTORIO_VOL"
|
|
||||||
mkdir -p "$SAVES"
|
|
||||||
mkdir -p "$CONFIG"
|
|
||||||
mkdir -p "$MODS"
|
|
||||||
mkdir -p "$SCENARIOS"
|
|
||||||
mkdir -p "$SCRIPTOUTPUT"
|
|
||||||
|
|
||||||
if [[ ! -f $CONFIG/rconpw ]]; then
|
|
||||||
# Generate a new RCON password if none exists
|
|
||||||
pwgen 15 1 >"$CONFIG/rconpw"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f $CONFIG/server-settings.json ]]; then
|
|
||||||
# Copy default settings if server-settings.json doesn't exist
|
|
||||||
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
|
|
||||||
|
|
||||||
NRTMPSAVES=$( find -L "$SAVES" -iname \*.tmp.zip -mindepth 1 | wc -l )
|
|
||||||
if [[ $NRTMPSAVES -gt 0 ]]; then
|
|
||||||
# Delete incomplete saves (such as after a forced exit)
|
|
||||||
rm -f "$SAVES"/*.tmp.zip
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ${UPDATE_MODS_ON_START:-} == "true" ]]; then
|
|
||||||
${INSTALLED_DIRECTORY}/docker-update-mods.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
${INSTALLED_DIRECTORY}/docker-dlc.sh
|
|
||||||
|
|
||||||
EXEC=""
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
|
||||||
# Update the User and Group ID based on the PUID/PGID variables
|
|
||||||
usermod -o -u "$PUID" factorio
|
|
||||||
groupmod -o -g "$PGID" factorio
|
|
||||||
# Take ownership of factorio data if running as root
|
|
||||||
chown -R factorio:factorio "$FACTORIO_VOL"
|
|
||||||
# Drop to the factorio user
|
|
||||||
EXEC="runuser -u factorio -g factorio --"
|
|
||||||
fi
|
|
||||||
if [[ -f /bin/box64 ]]; then
|
|
||||||
# Use an emulator to run on ARM hosts
|
|
||||||
# this only gets installed when the target docker platform is linux/arm64
|
|
||||||
EXEC="$EXEC /bin/box64"
|
|
||||||
fi
|
|
||||||
|
|
||||||
sed -i '/write-data=/c\write-data=\/factorio/' /opt/factorio/config/config.ini
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
exec $EXEC /opt/factorio/bin/x64/factorio "${FLAGS[@]}" "$@"
|
|
@ -1,28 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -eou pipefail
|
|
||||||
|
|
||||||
if [[ -f /run/secrets/username ]]; then
|
|
||||||
USERNAME=$(cat /run/secrets/username)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -f /run/secrets/token ]]; then
|
|
||||||
TOKEN=$(cat /run/secrets/token)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z ${USERNAME:-} ]]; then
|
|
||||||
USERNAME="$(jq -j ".username" "$CONFIG/server-settings.json")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z ${TOKEN:-} ]]; then
|
|
||||||
TOKEN="$(jq -j ".token" "$CONFIG/server-settings.json")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z ${USERNAME:-} ]]; then
|
|
||||||
echo "You need to provide your Factorio username to update mods."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z ${TOKEN:-} ]]; then
|
|
||||||
echo "You need to provide your Factorio token to update mods."
|
|
||||||
fi
|
|
||||||
|
|
||||||
./update-mods.sh "$VERSION" "$MODS" "$USERNAME" "$TOKEN"
|
|
@ -1,11 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
PLAYERS=$(rcon /players)
|
|
||||||
ONLINE_COUNT=$(echo "$PLAYERS" | grep -c " (online)$")
|
|
||||||
|
|
||||||
if [[ "$ONLINE_COUNT" -gt "0" ]]; then
|
|
||||||
echo "$PLAYERS"
|
|
||||||
# exit with 75 (EX_TEMPFAIL) so watchtower skips the update
|
|
||||||
# https://containrrr.dev/watchtower/lifecycle-hooks/
|
|
||||||
exit 75
|
|
||||||
fi
|
|
@ -1,47 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -eoux pipefail
|
|
||||||
|
|
||||||
if [[ -z ${1:-} ]]; then
|
|
||||||
echo "No argument supplied"
|
|
||||||
fi
|
|
||||||
|
|
||||||
SERVER_SCENARIO="$1"
|
|
||||||
PRESET="${PRESET:-""}"
|
|
||||||
|
|
||||||
mkdir -p "$SAVES"
|
|
||||||
mkdir -p "$CONFIG"
|
|
||||||
mkdir -p "$MODS"
|
|
||||||
mkdir -p "$SCENARIOS"
|
|
||||||
|
|
||||||
#chown -R factorio /factorio
|
|
||||||
|
|
||||||
if [[ ! -f $CONFIG/rconpw ]]; then
|
|
||||||
pwgen 15 1 >"$CONFIG/rconpw"
|
|
||||||
fi
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
exec /opt/factorio/bin/x64/factorio \
|
|
||||||
--port "$PORT" \
|
|
||||||
--start-server-load-scenario "$SERVER_SCENARIO" \
|
|
||||||
--preset "$PRESET" \
|
|
||||||
--map-gen-settings "$CONFIG/map-gen-settings.json" \
|
|
||||||
--map-settings "$CONFIG/map-settings.json" \
|
|
||||||
--server-settings "$CONFIG/server-settings.json" \
|
|
||||||
--server-banlist "$CONFIG/server-banlist.json" \
|
|
||||||
--server-whitelist "$CONFIG/server-whitelist.json" \
|
|
||||||
--use-server-whitelist \
|
|
||||||
--server-adminlist "$CONFIG/server-adminlist.json" \
|
|
||||||
--rcon-port "$RCON_PORT" \
|
|
||||||
--rcon-password "$(cat "$CONFIG/rconpw")" \
|
|
||||||
--server-id /factorio/config/server-id.json
|
|
@ -1,27 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -eoux pipefail
|
|
||||||
|
|
||||||
if [[ -z ${1:-} ]]; then
|
|
||||||
echo "No argument supplied"
|
|
||||||
fi
|
|
||||||
|
|
||||||
SERVER_SCENARIO="$1"
|
|
||||||
mkdir -p "$SAVES"
|
|
||||||
mkdir -p "$CONFIG"
|
|
||||||
mkdir -p "$MODS"
|
|
||||||
mkdir -p "$SCENARIOS"
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
exec /opt/factorio/bin/x64/factorio \
|
|
||||||
--scenario2map "$SERVER_SCENARIO"
|
|
@ -1,96 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -eou pipefail
|
|
||||||
|
|
||||||
FACTORIO_VERSION=$1
|
|
||||||
MOD_DIR=$2
|
|
||||||
USERNAME=$3
|
|
||||||
TOKEN=$4
|
|
||||||
|
|
||||||
MOD_BASE_URL="https://mods.factorio.com"
|
|
||||||
|
|
||||||
print_step()
|
|
||||||
{
|
|
||||||
echo "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_success()
|
|
||||||
{
|
|
||||||
echo "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_failure()
|
|
||||||
{
|
|
||||||
echo "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
update_mod()
|
|
||||||
{
|
|
||||||
MOD_NAME="$1"
|
|
||||||
MOD_NAME_ENCODED="${1// /%20}"
|
|
||||||
|
|
||||||
print_step "Checking for update of mod $MOD_NAME for factorio $FACTORIO_VERSION ..."
|
|
||||||
|
|
||||||
MOD_INFO_URL="$MOD_BASE_URL/api/mods/$MOD_NAME_ENCODED"
|
|
||||||
MOD_INFO_JSON=$(curl --silent "$MOD_INFO_URL")
|
|
||||||
|
|
||||||
if ! echo "$MOD_INFO_JSON" | jq -e .name >/dev/null; then
|
|
||||||
print_success " Custom mod not on $MOD_BASE_URL, skipped."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
MOD_INFO=$(echo "$MOD_INFO_JSON" | jq -j --arg version "$FACTORIO_VERSION" ".releases|reverse|map(select(.info_json.factorio_version as \$mod_version | \$version | startswith(\$mod_version)))[0]|.file_name, \";\", .download_url, \";\", .sha1")
|
|
||||||
|
|
||||||
MOD_FILENAME=$(echo "$MOD_INFO" | cut -f1 -d";")
|
|
||||||
MOD_URL=$(echo "$MOD_INFO" | cut -f2 -d";")
|
|
||||||
MOD_SHA1=$(echo "$MOD_INFO" | cut -f3 -d";")
|
|
||||||
|
|
||||||
if [[ $MOD_FILENAME == null ]]; then
|
|
||||||
print_failure " Not compatible with version"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -f $MOD_DIR/$MOD_FILENAME ]]; then
|
|
||||||
print_success " Already up-to-date."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_step " Downloading $MOD_FILENAME"
|
|
||||||
FULL_URL="$MOD_BASE_URL$MOD_URL?username=$USERNAME&token=$TOKEN"
|
|
||||||
HTTP_STATUS=$(curl --silent -L -w "%{http_code}" -o "$MOD_DIR/$MOD_FILENAME" "$FULL_URL")
|
|
||||||
|
|
||||||
if [[ $HTTP_STATUS != 200 ]]; then
|
|
||||||
print_failure " Download failed: Code $HTTP_STATUS."
|
|
||||||
rm -f "$MOD_DIR/$MOD_FILENAME"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f $MOD_DIR/$MOD_FILENAME ]]; then
|
|
||||||
print_failure " Downloaded file missing!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! [[ $(sha1sum "$MOD_DIR/$MOD_FILENAME") =~ $MOD_SHA1 ]]; then
|
|
||||||
print_failure " SHA1 mismatch!"
|
|
||||||
rm -f "$MOD_DIR/$MOD_FILENAME"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_success " Download complete."
|
|
||||||
|
|
||||||
for file in "$MOD_DIR/${MOD_NAME}_"*".zip"; do # wildcard does usually not work in quotes: https://unix.stackexchange.com/a/67761
|
|
||||||
if [[ $file != $MOD_DIR/$MOD_FILENAME ]]; then
|
|
||||||
print_success " Deleting old version: $file"
|
|
||||||
rm -f "$file"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if [[ -f $MOD_DIR/mod-list.json ]]; then
|
|
||||||
jq -r ".mods|map(select(.enabled))|.[].name" "$MOD_DIR/mod-list.json" | while read -r mod; do
|
|
||||||
if [[ $mod != base ]]; then
|
|
||||||
update_mod "$mod"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
@ -1,13 +0,0 @@
|
|||||||
# Optimization
|
|
||||||
OPT = -O3 -flto
|
|
||||||
TARGET = rcon
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CFLAGS = -std=c17 -Wall -Wextra -pedantic $(OPT)
|
|
||||||
REMOVE = rm -f
|
|
||||||
|
|
||||||
all:
|
|
||||||
$(CC) $(CFLAGS) main.c -o $(TARGET)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(REMOVE) $(TARGET)
|
|
@ -1,217 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#define MIN_PACKET 10
|
|
||||||
#define MAX_PACKET 4096
|
|
||||||
#define MAX_BODY (MAX_PACKET - (3 * sizeof(uint32_t)) - 2)
|
|
||||||
|
|
||||||
#define RCON_HOST "127.0.0.1"
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
RCON_TYPE_RESPONSE = 0,
|
|
||||||
RCON_TYPE_EXECCOMMAND = 2,
|
|
||||||
RCON_TYPE_AUTH_RESPONSE = 2,
|
|
||||||
RCON_TYPE_AUTH = 3,
|
|
||||||
} packet_type;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t length;
|
|
||||||
uint32_t id;
|
|
||||||
packet_type type;
|
|
||||||
char body[MAX_BODY];
|
|
||||||
} packet;
|
|
||||||
|
|
||||||
int rcon_open(const char *port);
|
|
||||||
void rcon_create(packet* pkt, packet_type type, const char* body);
|
|
||||||
bool rcon_send(int rcon_socket, const packet* pkt);
|
|
||||||
bool rcon_auth(int rcon_socket, const char* password);
|
|
||||||
bool rcon_recv(int rcon_socket, packet* pkt, packet_type expected_type);
|
|
||||||
char* combine_args(int argc, char* argv[]);
|
|
||||||
char* read_password(const char* conf_dir);
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
if (argc < 2) {
|
|
||||||
fprintf(stderr, "error: missing command argument\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
srand((unsigned int)time(NULL));
|
|
||||||
|
|
||||||
const char* port = getenv("RCON_PORT");
|
|
||||||
if (port == NULL) {
|
|
||||||
fprintf(stderr, "error: missing $RCON_PORT env\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* conf_dir = getenv("CONFIG");
|
|
||||||
if (conf_dir == NULL) {
|
|
||||||
fprintf(stderr, "error: missing $CONFIG env");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rcon_socket = rcon_open(port);
|
|
||||||
if (rcon_socket == -1) {
|
|
||||||
fprintf(stderr, "error: could not connect\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rcon_auth(rcon_socket, read_password(conf_dir))) {
|
|
||||||
fprintf(stderr, "error: login failed\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
packet pkt;
|
|
||||||
rcon_create(&pkt, RCON_TYPE_EXECCOMMAND, combine_args(argc, argv));
|
|
||||||
if (!rcon_send(rcon_socket, &pkt)) {
|
|
||||||
fprintf(stderr, "error: send command failed\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rcon_recv(rcon_socket, &pkt, RCON_TYPE_RESPONSE) && pkt.length > 0) {
|
|
||||||
puts(pkt.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* combine_args(int argc, char* argv[]) {
|
|
||||||
// combine all cli arguments
|
|
||||||
char* command = malloc(MAX_BODY);
|
|
||||||
memset(command, 0, MAX_BODY);
|
|
||||||
strcat(command, argv[1]);
|
|
||||||
|
|
||||||
for (int idx = 2; idx < argc; idx++) {
|
|
||||||
strcat(command, " ");
|
|
||||||
strcat(command, argv[idx]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* read_password(const char* conf_dir) {
|
|
||||||
char* path = malloc(strlen(conf_dir) + 64);
|
|
||||||
strcpy(path, conf_dir);
|
|
||||||
strcat(path, "/rconpw");
|
|
||||||
|
|
||||||
FILE* fptr = fopen(path, "r");
|
|
||||||
fseek(fptr, 0, SEEK_END);
|
|
||||||
long fsize = ftell(fptr);
|
|
||||||
fseek(fptr, 0, SEEK_SET); /* same as rewind(f); */
|
|
||||||
|
|
||||||
char *password = malloc(fsize + 1);
|
|
||||||
fread(password, fsize, 1, fptr);
|
|
||||||
fclose(fptr);
|
|
||||||
|
|
||||||
password[fsize] = 0;
|
|
||||||
if (password[fsize-1] == '\n') {
|
|
||||||
password[fsize-1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rcon_open(const char *port) {
|
|
||||||
struct sockaddr_in address = {
|
|
||||||
.sin_family = AF_INET,
|
|
||||||
.sin_port = htons(atoi(port))
|
|
||||||
};
|
|
||||||
inet_aton(RCON_HOST, &address.sin_addr);
|
|
||||||
|
|
||||||
int rcon_socket = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (connect(rcon_socket, (struct sockaddr*) &address, sizeof(address)) < 0) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return rcon_socket;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rcon_create(packet* pkt, packet_type type, const char* body) {
|
|
||||||
size_t body_length = strlen(body);
|
|
||||||
if (body_length >= MAX_BODY - 2) {
|
|
||||||
fprintf(stderr, "error: command to long");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
pkt->id = abs(rand());
|
|
||||||
pkt->type = type;
|
|
||||||
pkt->length = (uint32_t)(sizeof(pkt->id) + sizeof(pkt->type) + body_length + 2);
|
|
||||||
|
|
||||||
memset(pkt->body, 0, MAX_BODY);
|
|
||||||
strncpy(pkt->body, body, MAX_BODY);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rcon_recv(int rcon_socket, packet* pkt, packet_type expected_type) {
|
|
||||||
memset(pkt, 0, sizeof(*pkt));
|
|
||||||
|
|
||||||
// Read response packet length
|
|
||||||
ssize_t expected_length_bytes = sizeof(pkt->length);
|
|
||||||
ssize_t rx_bytes = recv(rcon_socket, &(pkt->length), expected_length_bytes, 0);
|
|
||||||
|
|
||||||
if (rx_bytes == -1) {
|
|
||||||
perror("error: socket error");
|
|
||||||
return false;
|
|
||||||
} else if (rx_bytes == 0) {
|
|
||||||
fprintf(stderr, "error: no data recieved\n");
|
|
||||||
return false;
|
|
||||||
} else if (rx_bytes < expected_length_bytes || pkt->length < MIN_PACKET || pkt->length > MAX_PACKET) {
|
|
||||||
fprintf(stderr, "error: invalid data\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t received = 0;
|
|
||||||
while (received < pkt->length) {
|
|
||||||
rx_bytes = recv(rcon_socket, (char *)pkt + sizeof(pkt->length) + received, pkt->length - received, 0);
|
|
||||||
if (rx_bytes < 0) {
|
|
||||||
perror("error: socket error");
|
|
||||||
return false;
|
|
||||||
} else if (rx_bytes == 0) {
|
|
||||||
fprintf(stderr, "error: connection lost\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
received += rx_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pkt->type == expected_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rcon_send(int rcon_socket, const packet* pkt) {
|
|
||||||
size_t length = sizeof(pkt->length) + pkt->length;
|
|
||||||
char *ptr = (char*) pkt;
|
|
||||||
|
|
||||||
while (length > 0) {
|
|
||||||
ssize_t ret = send(rcon_socket, ptr, length, 0);
|
|
||||||
|
|
||||||
if (ret == -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr += ret;
|
|
||||||
length -= ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rcon_auth(int rcon_socket, const char* password) {
|
|
||||||
packet pkt;
|
|
||||||
rcon_create(&pkt, RCON_TYPE_AUTH, password);
|
|
||||||
|
|
||||||
if (!rcon_send(rcon_socket, &pkt)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rcon_recv(rcon_socket, &pkt, RCON_TYPE_AUTH_RESPONSE)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
92
factorio.crt
Normal file
92
factorio.crt
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB
|
||||||
|
hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
|
||||||
|
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
|
||||||
|
BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMjEy
|
||||||
|
MDAwMDAwWhcNMjkwMjExMjM1OTU5WjCBkDELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
|
||||||
|
EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
|
||||||
|
Q09NT0RPIENBIExpbWl0ZWQxNjA0BgNVBAMTLUNPTU9ETyBSU0EgRG9tYWluIFZh
|
||||||
|
bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||||
|
ADCCAQoCggEBAI7CAhnhoFmk6zg1jSz9AdDTScBkxwtiBUUWOqigwAwCfx3M28Sh
|
||||||
|
bXcDow+G+eMGnD4LgYqbSRutA776S9uMIO3Vzl5ljj4Nr0zCsLdFXlIvNN5IJGS0
|
||||||
|
Qa4Al/e+Z96e0HqnU4A7fK31llVvl0cKfIWLIpeNs4TgllfQcBhglo/uLQeTnaG6
|
||||||
|
ytHNe+nEKpooIZFNb5JPJaXyejXdJtxGpdCsWTWM/06RQ1A/WZMebFEh7lgUq/51
|
||||||
|
UHg+TLAchhP6a5i84DuUHoVS3AOTJBhuyydRReZw3iVDpA3hSqXttn7IzW3uLh0n
|
||||||
|
c13cRTCAquOyQQuvvUSH2rnlG51/ruWFgqUCAwEAAaOCAWUwggFhMB8GA1UdIwQY
|
||||||
|
MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBSQr2o6lFoL2JDqElZz
|
||||||
|
30O0Oija5zAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV
|
||||||
|
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgG
|
||||||
|
BmeBDAECATBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNv
|
||||||
|
bS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcB
|
||||||
|
AQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9E
|
||||||
|
T1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v
|
||||||
|
ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAE4rdk+SHGI2ibp3wScF9BzWRJ2p
|
||||||
|
mj6q1WZmAT7qSeaiNbz69t2Vjpk1mA42GHWx3d1Qcnyu3HeIzg/3kCDKo2cuH1Z/
|
||||||
|
e+FE6kKVxF0NAVBGFfKBiVlsit2M8RKhjTpCipj4SzR7JzsItG8kO3KdY3RYPBps
|
||||||
|
P0/HEZrIqPW1N+8QRcZs2eBelSaz662jue5/DJpmNXMyYE7l3YphLG5SEXdoltMY
|
||||||
|
dVEVABt0iN3hxzgEQyjpFv3ZBdRdRydg1vs4O2xyopT4Qhrf7W8GjEXCBgCq5Ojc
|
||||||
|
2bXhc3js9iPc0d1sjhqPpepUfJa3w/5Vjo1JXvxku88+vZbrac2/4EjxYoIQ5QxG
|
||||||
|
V/Iz2tDIY+3GH5QFlkoakdH368+PUq4NCNk+qKBR6cGHdNXJ93SrLlP7u3r7l+L4
|
||||||
|
HyaPs9Kg4DdbKDsx5Q5XLVq4rXmsXiBmGqW5prU5wfWYQ//u+aen/e7KJD2AFsQX
|
||||||
|
j4rBYKEMrltDR5FL1ZoXX/nUh8HCjLfn4g8wGTeGrODcQgPmlKidrv0PJFGUzpII
|
||||||
|
0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap
|
||||||
|
lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf
|
||||||
|
+AZxAeKCINT+b72x
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv
|
||||||
|
MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
|
||||||
|
ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
|
||||||
|
eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow
|
||||||
|
gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
|
||||||
|
BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD
|
||||||
|
VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq
|
||||||
|
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw
|
||||||
|
AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6
|
||||||
|
2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr
|
||||||
|
ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt
|
||||||
|
4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq
|
||||||
|
m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/
|
||||||
|
vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT
|
||||||
|
8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE
|
||||||
|
IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO
|
||||||
|
KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO
|
||||||
|
GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/
|
||||||
|
s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g
|
||||||
|
JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD
|
||||||
|
AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9
|
||||||
|
MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy
|
||||||
|
bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6
|
||||||
|
Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ
|
||||||
|
zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj
|
||||||
|
Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY
|
||||||
|
Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5
|
||||||
|
B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx
|
||||||
|
PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR
|
||||||
|
pu/xO28QOG8=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
|
||||||
|
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
|
||||||
|
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
|
||||||
|
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
|
||||||
|
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
|
||||||
|
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
|
||||||
|
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
|
||||||
|
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
|
||||||
|
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
|
||||||
|
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
|
||||||
|
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
|
||||||
|
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
|
||||||
|
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
|
||||||
|
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
|
||||||
|
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
|
||||||
|
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
|
||||||
|
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
|
||||||
|
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
|
||||||
|
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
|
||||||
|
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
|
||||||
|
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
|
||||||
|
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
|
||||||
|
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
|
||||||
|
-----END CERTIFICATE-----
|
2
lint.sh
2
lint.sh
@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
git ls-files --exclude='*Dockerfile' --ignored | xargs --max-lines=1 ./hadolint
|
|
43
smart_launch.sh
Executable file
43
smart_launch.sh
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -f /opt/factorio/saves/save.zip ]
|
||||||
|
then
|
||||||
|
echo "###"
|
||||||
|
echo "# Using existing map [save.zip]"
|
||||||
|
echo "###"
|
||||||
|
echo "###"
|
||||||
|
echo "# Finding latest map"
|
||||||
|
echo "###"
|
||||||
|
last_save=$(ls /opt/factorio/saves -lt | grep save |head -1 |awk '{print $(NF)}')
|
||||||
|
else
|
||||||
|
echo "###"
|
||||||
|
echo "# Creating a new map [save.zip]"
|
||||||
|
echo "###"
|
||||||
|
/opt/factorio/bin/x64/factorio --create save.zip
|
||||||
|
last_save="save.zip"
|
||||||
|
echo "###"
|
||||||
|
echo "# New map created [save.zip]"
|
||||||
|
echo "###"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Checking options
|
||||||
|
if [ "$FACTORIO_DISSALOW_COMMANDS" == false ]; then
|
||||||
|
disallow_commands=""
|
||||||
|
else
|
||||||
|
disallow_commands="--disallow-commands"
|
||||||
|
fi
|
||||||
|
if [ "$FACTORIO_NO_AUTO_PAUSE" == true ]; then
|
||||||
|
no_auto_pause="--no-auto-pause"
|
||||||
|
else
|
||||||
|
no_auto_pause=""
|
||||||
|
fi
|
||||||
|
echo "###"
|
||||||
|
echo "# Launching Game"
|
||||||
|
echo "###"
|
||||||
|
exec /opt/factorio/bin/x64/factorio \
|
||||||
|
$disallow_commands \
|
||||||
|
$no_auto_pause \
|
||||||
|
--autosave-interval ${FACTORIO_AUTOSAVE_INTERVAL} \
|
||||||
|
--autosave-slots ${FACTORIO_AUTOSAVE_SLOTS} \
|
||||||
|
--start-server \
|
||||||
|
$last_save
|
116
update.sh
116
update.sh
@ -1,116 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
SEMVER_REGEX="^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
|
||||||
|
|
||||||
stable_online_version=$(curl 'https://factorio.com/api/latest-releases' | jq '.stable.headless' -r)
|
|
||||||
experimental_online_version=$(curl 'https://factorio.com/api/latest-releases' | jq '.experimental.headless' -r)
|
|
||||||
|
|
||||||
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}')
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
echo "stable_online_version=${stable_online_version} experimental_online_version=${experimental_online_version}"
|
|
||||||
echo "stable_current_version=${stable_current_version} latest_current_version=${latest_current_version}"
|
|
||||||
|
|
||||||
if [[ -z "${stable_online_version}" ]] || [[ -z "${experimental_online_version}" ]]; then
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if [[ "${stable_current_version}" == "${stable_online_version}" ]] && [[ "${latest_current_version}" == "${experimental_online_version}" ]]; then
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
function get-semver(){
|
|
||||||
local ver=$1
|
|
||||||
local type=$2
|
|
||||||
if [[ "$ver" =~ $SEMVER_REGEX ]]; then
|
|
||||||
local major=${BASH_REMATCH[1]}
|
|
||||||
local minor=${BASH_REMATCH[2]}
|
|
||||||
local patch=${BASH_REMATCH[3]}
|
|
||||||
fi
|
|
||||||
case $type in
|
|
||||||
major)
|
|
||||||
echo "$major"
|
|
||||||
;;
|
|
||||||
minor)
|
|
||||||
echo "$minor"
|
|
||||||
;;
|
|
||||||
patch)
|
|
||||||
echo "$patch"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
stableOnlineVersionMajor=$(get-semver "${stable_online_version}" major)
|
|
||||||
stableOnlineVersionMinor=$(get-semver "${stable_online_version}" minor)
|
|
||||||
experimentalOnlineVersionMajor=$(get-semver "${experimental_online_version}" major)
|
|
||||||
experimentalOnlineVersionMinor=$(get-semver "${experimental_online_version}" minor)
|
|
||||||
stableCurrentVersionMajor=$(get-semver "${stable_current_version}" major)
|
|
||||||
stableCurrentVersionMinor=$(get-semver "${stable_current_version}" minor)
|
|
||||||
latestCurrentVersionMajor=$(get-semver "${latest_current_version}" major)
|
|
||||||
latestCurrentVersionMinor=$(get-semver "${latest_current_version}" minor)
|
|
||||||
|
|
||||||
stableOnlineVersionShort=$stableOnlineVersionMajor.$stableOnlineVersionMinor
|
|
||||||
experimentalOnlineVersionShort=$experimentalOnlineVersionMajor.$experimentalOnlineVersionMinor
|
|
||||||
stableCurrentVersionShort=$stableCurrentVersionMajor.$stableCurrentVersionMinor
|
|
||||||
latestCurrentVersionShort=$latestCurrentVersionMajor.$latestCurrentVersionMinor
|
|
||||||
|
|
||||||
echo "stableOnlineVersionShort=${stableOnlineVersionShort} experimentalOnlineVersionShort=${experimentalOnlineVersionShort}"
|
|
||||||
echo "stableCurrentVersionShort=${stableCurrentVersionShort} latestCurrentVersionShort=${latestCurrentVersionShort}"
|
|
||||||
|
|
||||||
tmpfile=$(mktemp)
|
|
||||||
|
|
||||||
# Remove stable tag
|
|
||||||
cp buildinfo.json "$tmpfile"
|
|
||||||
jq --arg stable_current_version "$stable_current_version" 'with_entries(if .key == $stable_current_version then .value.tags |= . - ["stable"] else . end)' "$tmpfile" > buildinfo.json
|
|
||||||
rm -f -- "$tmpfile"
|
|
||||||
|
|
||||||
# Remove latest tag
|
|
||||||
cp buildinfo.json "$tmpfile"
|
|
||||||
jq --arg latest_current_version "$latest_current_version" 'with_entries(if .key == $latest_current_version then .value.tags |= . - ["latest"] else . end)' "$tmpfile" > buildinfo.json
|
|
||||||
rm -f -- "$tmpfile"
|
|
||||||
|
|
||||||
# Update tag by stable
|
|
||||||
cp buildinfo.json "$tmpfile"
|
|
||||||
if [[ "$stable_online_version" == "$stable_current_version" ]]; then
|
|
||||||
jq --arg stable_current_version "$stable_current_version" --arg stable_online_version "$stable_online_version" --arg sha256 "$stable_sha256" 'with_entries(if .key == $stable_current_version then .key |= $stable_online_version | .value.sha256 |= $sha256 | .value.tags |= . - [$stable_current_version] + [$stable_online_version, "stable"] else . end)' "$tmpfile" > buildinfo.json
|
|
||||||
else
|
|
||||||
jq --arg stable_current_version "$stable_current_version" --arg stable_online_version "$stable_online_version" --arg sha256 "$stable_sha256" --arg stableOnlineVersionShort "$stableOnlineVersionShort" --arg stableOnlineVersionMajor "$stableOnlineVersionMajor" 'with_entries(if .key == $stable_current_version then .value.tags |= . - ["latest","stable",$stableOnlineVersionMajor] else . end) | to_entries | . + [{ key: $stable_online_version, value: { sha256: $sha256, tags: ["latest","stable",("stable-" + $stable_online_version),$stableOnlineVersionMajor,$stableOnlineVersionShort,$stable_online_version]}}] | from_entries' "$tmpfile" > buildinfo.json
|
|
||||||
fi
|
|
||||||
rm -f -- "$tmpfile"
|
|
||||||
|
|
||||||
# Update tag by latest
|
|
||||||
cp buildinfo.json "$tmpfile"
|
|
||||||
if [[ $experimental_online_version != "$stable_online_version" ]]; then
|
|
||||||
if [[ $stableOnlineVersionShort == "$experimentalOnlineVersionShort" ]]; then
|
|
||||||
jq --arg experimental_online_version "$experimental_online_version" --arg stable_online_version "$stable_online_version" --arg sha256 "$experimental_sha256" 'with_entries(if .key == $stable_online_version then .value.tags |= . - ["latest"] else . end) | to_entries | . + [{ key: $experimental_online_version, value: { sha256: $sha256, tags: ["latest", $experimental_online_version]}}] | from_entries' "$tmpfile" > buildinfo.json
|
|
||||||
else
|
|
||||||
jq --arg experimental_online_version "$experimental_online_version" --arg stable_online_version "$stable_online_version" --arg sha256 "$experimental_sha256" --arg experimentalOnlineVersionShort "$experimentalOnlineVersionShort" --arg experimentalOnlineVersionMajor "$experimentalOnlineVersionMajor" 'with_entries(if .key == $stable_online_version then .value.tags |= . - ["latest"] else . end) | to_entries | . + [{ key: $experimental_online_version, value: { sha256: $sha256, tags: ["latest",$experimentalOnlineVersionMajor,$experimentalOnlineVersionShort,$experimental_online_version]}}] | from_entries' "$tmpfile" > buildinfo.json
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
rm -f -- "$tmpfile"
|
|
||||||
|
|
||||||
readme_tags=$(jq --sort-keys 'keys[]' buildinfo.json | tac | (while read -r line
|
|
||||||
do
|
|
||||||
tags="$tags\n* "$(jq --sort-keys ".$line.tags | sort | .[]" buildinfo.json | sed 's/"/`/g' | sed ':a; /$/N; s/\n/, /; ta')
|
|
||||||
done && printf "%s\n\n" "$tags"))
|
|
||||||
|
|
||||||
perl -i -0777 -pe "s/<!-- start autogeneration tags -->.+<!-- end autogeneration tags -->/<!-- start autogeneration tags -->$readme_tags<!-- end autogeneration tags -->/s" README.md
|
|
||||||
|
|
||||||
# Replace VERSION and SHA256 args in docker-compose.yaml with latest stable values.
|
|
||||||
docker_compose_path="docker/docker-compose.yml"
|
|
||||||
sov="VERSION=${stable_online_version}" yq -i '.services.factorio.build.args[0] = env(sov)' "$docker_compose_path"
|
|
||||||
sha="SHA256=${stable_sha256}" yq -i '.services.factorio.build.args[1] = env(sha)' "$docker_compose_path"
|
|
||||||
|
|
||||||
git config user.name github-actions[bot]
|
|
||||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
|
||||||
|
|
||||||
git add buildinfo.json
|
|
||||||
git add README.md
|
|
||||||
git add docker/docker-compose.yml
|
|
||||||
git commit -a -m "Auto Update Factorio to stable version: ${stable_online_version} experimental version: ${experimental_online_version}"
|
|
||||||
|
|
||||||
git tag -f latest
|
|
||||||
git push
|
|
||||||
git push origin --tags -f
|
|
Reference in New Issue
Block a user