├── .dockerignore ├── .github ├── dependabot.yml └── workflows │ ├── build-experimental.yml │ ├── build-latest.yml │ ├── build-tag.yml │ ├── close-stale.yml │ ├── hadolint.yml │ ├── hub-description-tag.yml │ └── hub-description.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── docs ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── examples └── docker-compose.yml ├── experimental ├── Dockerfile ├── Dockerfile.alpine ├── Makefile ├── VERSION ├── hooks │ └── build └── root │ └── usr │ └── local │ └── bin │ ├── docker-entrypoint.sh │ └── entrypoint-functions.sh └── stable ├── Dockerfile ├── Dockerfile.alpine ├── Makefile ├── VERSION ├── hooks └── build └── root └── usr └── local └── bin ├── docker-entrypoint.sh └── entrypoint-functions.sh /.dockerignore: -------------------------------------------------------------------------------- 1 | docs 2 | .git 3 | .gitignore 4 | *.md 5 | LICENSE 6 | docker-compose.yml 7 | Makefile 8 | *.mk 9 | *.dmk 10 | *.sw? 11 | *~ 12 | tmp/* 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "docker" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | target-branch: "main" 11 | schedule: 12 | interval: "daily" 13 | 14 | # Maintain dependencies for GitHub Actions 15 | - package-ecosystem: "github-actions" 16 | directory: "/" 17 | schedule: 18 | interval: "daily" 19 | assignees: 20 | - "goofball222" 21 | -------------------------------------------------------------------------------- /.github/workflows/build-experimental.yml: -------------------------------------------------------------------------------- 1 | name: Build Experimental 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - experimental/** 10 | - .github/workflows/build-experimental.yml 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - 17 | name: Checkout 18 | uses: actions/checkout@v4 19 | - 20 | name: Set up dynamic build ARGs 21 | id: getargs 22 | run: echo "version=$(cat ./experimental/VERSION)" >> $GITHUB_OUTPUT 23 | - 24 | name: Set up Docker metadata for Alpine 25 | id: meta-alpine 26 | uses: docker/metadata-action@v5 27 | with: 28 | images: | 29 | ${{ github.repository }} 30 | ghcr.io/${{ github.repository }} 31 | tags: | 32 | type=raw,experimental-alpine 33 | # type=raw,latest-alpine 34 | # type=raw,${{ steps.getargs.outputs.version }}-alpine 35 | labels: | 36 | org.opencontainers.image.vendor=The Goofball - goofball222@gmail.com 37 | org.opencontainers.image.title=Factiorio Headless Server 38 | org.opencontainers.image.description=Factiorio Headless Server 39 | org.opencontainers.image.version=${{ steps.getargs.outputs.version }}-Alpine 40 | - 41 | name: Set up Docker metadata for Debian 42 | id: meta-debian 43 | uses: docker/metadata-action@v5 44 | with: 45 | images: | 46 | ${{ github.repository }} 47 | ghcr.io/${{ github.repository }} 48 | tags: | 49 | type=raw,experimental 50 | # type=raw,latest 51 | # type=raw,${{ steps.getargs.outputs.version }} 52 | labels: | 53 | org.opencontainers.image.vendor=The Goofball - goofball222@gmail.com 54 | org.opencontainers.image.title=Factiorio Headless Server 55 | org.opencontainers.image.description=Factiorio Headless Server 56 | org.opencontainers.image.version=${{ steps.getargs.outputs.version }}-Debian 57 | - 58 | name: Set up QEMU 59 | uses: docker/setup-qemu-action@v3 60 | - 61 | name: Set up Docker Buildx 62 | uses: docker/setup-buildx-action@v3 63 | - 64 | name: Login to DockerHub 65 | uses: docker/login-action@v3 66 | with: 67 | username: ${{ github.repository_owner }} 68 | password: ${{ secrets.DOCKERHUB_TOKEN }} 69 | - 70 | name: Login to GHCR 71 | uses: docker/login-action@v3 72 | with: 73 | registry: ghcr.io 74 | username: ${{ github.repository_owner }} 75 | password: ${{ secrets.GITHUB_TOKEN }} 76 | - 77 | name: Build and push Alpine Docker image 78 | uses: docker/build-push-action@v6 79 | with: 80 | context: ./experimental 81 | file: ./experimental/Dockerfile.alpine 82 | platforms: linux/amd64 83 | push: ${{ github.event_name != 'pull_request' }} 84 | tags: ${{ steps.meta-alpine.outputs.tags }} 85 | labels: ${{ steps.meta-alpine.outputs.labels }} 86 | build-args: VERSION=${{ steps.getargs.outputs.version }} 87 | - 88 | name: Build and push Debian Docker image 89 | uses: docker/build-push-action@v6 90 | with: 91 | context: ./experimental 92 | file: ./experimental/Dockerfile 93 | platforms: linux/amd64 94 | push: ${{ github.event_name != 'pull_request' }} 95 | tags: ${{ steps.meta-debian.outputs.tags }} 96 | labels: ${{ steps.meta-debian.outputs.labels }} 97 | build-args: VERSION=${{ steps.getargs.outputs.version }} 98 | -------------------------------------------------------------------------------- /.github/workflows/build-latest.yml: -------------------------------------------------------------------------------- 1 | name: Build Latest 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - stable/** 10 | - .github/workflows/build-latest.yml 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - 17 | name: Checkout 18 | uses: actions/checkout@v4 19 | - 20 | name: Set up dynamic build ARGs 21 | id: getargs 22 | run: echo "version=$(cat ./stable/VERSION)" >> $GITHUB_OUTPUT 23 | - 24 | name: Set up Docker metadata for Alpine 25 | id: meta-alpine 26 | uses: docker/metadata-action@v5 27 | with: 28 | images: | 29 | ${{ github.repository }} 30 | ghcr.io/${{ github.repository }} 31 | tags: | 32 | type=raw,latest-alpine 33 | type=raw,stable-alpine 34 | # type=raw,${{ steps.getargs.outputs.version }}-alpine 35 | labels: | 36 | org.opencontainers.image.vendor=The Goofball - goofball222@gmail.com 37 | org.opencontainers.image.title=Factiorio Headless Server 38 | org.opencontainers.image.description=Factiorio Headless Server 39 | org.opencontainers.image.version=${{ steps.getargs.outputs.version }}-Alpine 40 | - 41 | name: Set up Docker metadata for Debian 42 | id: meta-debian 43 | uses: docker/metadata-action@v5 44 | with: 45 | images: | 46 | ${{ github.repository }} 47 | ghcr.io/${{ github.repository }} 48 | tags: | 49 | type=raw,latest 50 | type=raw,stable 51 | # type=raw,${{ steps.getargs.outputs.version }} 52 | labels: | 53 | org.opencontainers.image.vendor=The Goofball - goofball222@gmail.com 54 | org.opencontainers.image.title=Factiorio Headless Server 55 | org.opencontainers.image.description=Factiorio Headless Server 56 | org.opencontainers.image.version=${{ steps.getargs.outputs.version }}-Debian 57 | - 58 | name: Set up QEMU 59 | uses: docker/setup-qemu-action@v3 60 | - 61 | name: Set up Docker Buildx 62 | uses: docker/setup-buildx-action@v3 63 | - 64 | name: Login to DockerHub 65 | uses: docker/login-action@v3 66 | with: 67 | username: ${{ github.repository_owner }} 68 | password: ${{ secrets.DOCKERHUB_TOKEN }} 69 | - 70 | name: Login to GHCR 71 | uses: docker/login-action@v3 72 | with: 73 | registry: ghcr.io 74 | username: ${{ github.repository_owner }} 75 | password: ${{ secrets.GITHUB_TOKEN }} 76 | - 77 | name: Build and push Alpine Docker image 78 | uses: docker/build-push-action@v6 79 | with: 80 | context: ./stable 81 | file: ./stable/Dockerfile.alpine 82 | platforms: linux/amd64 83 | push: ${{ github.event_name != 'pull_request' }} 84 | tags: ${{ steps.meta-alpine.outputs.tags }} 85 | labels: ${{ steps.meta-alpine.outputs.labels }} 86 | build-args: VERSION=${{ steps.getargs.outputs.version }} 87 | - 88 | name: Build and push Debian Docker image 89 | uses: docker/build-push-action@v6 90 | with: 91 | context: ./stable 92 | file: ./stable/Dockerfile 93 | platforms: linux/amd64 94 | push: ${{ github.event_name != 'pull_request' }} 95 | tags: ${{ steps.meta-debian.outputs.tags }} 96 | labels: ${{ steps.meta-debian.outputs.labels }} 97 | build-args: VERSION=${{ steps.getargs.outputs.version }} 98 | -------------------------------------------------------------------------------- /.github/workflows/build-tag.yml: -------------------------------------------------------------------------------- 1 | name: Build Tag 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | tags: 7 | - '*' 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - 14 | name: Checkout 15 | uses: actions/checkout@v4 16 | - 17 | name: Set up dynamic build ARGs 18 | id: getargs 19 | run: echo "version=$(cat ./stable/VERSION)" >> $GITHUB_OUTPUT 20 | - 21 | name: Set up Docker metadata for Alpine 22 | id: meta-alpine 23 | uses: docker/metadata-action@v5 24 | with: 25 | images: | 26 | ${{ github.repository }} 27 | ghcr.io/${{ github.repository }} 28 | tags: | 29 | type=raw,${{ steps.getargs.outputs.version }}-alpine 30 | labels: | 31 | org.opencontainers.image.vendor=The Goofball - goofball222@gmail.com 32 | org.opencontainers.image.title=Factiorio Headless Server 33 | org.opencontainers.image.description=Factiorio Headless Server 34 | org.opencontainers.image.version=${{ steps.getargs.outputs.version }}-Alpine 35 | - 36 | name: Set up Docker metadata for Debian 37 | id: meta-debian 38 | uses: docker/metadata-action@v5 39 | with: 40 | images: | 41 | ${{ github.repository }} 42 | ghcr.io/${{ github.repository }} 43 | tags: | 44 | type=raw,${{ steps.getargs.outputs.version }} 45 | labels: | 46 | org.opencontainers.image.vendor=The Goofball - goofball222@gmail.com 47 | org.opencontainers.image.title=Factiorio Headless Server 48 | org.opencontainers.image.description=Factiorio Headless Server 49 | org.opencontainers.image.version=${{ steps.getargs.outputs.version }}-Debian 50 | - 51 | name: Set up QEMU 52 | uses: docker/setup-qemu-action@v3 53 | - 54 | name: Set up Docker Buildx 55 | uses: docker/setup-buildx-action@v3 56 | - 57 | name: Login to DockerHub 58 | uses: docker/login-action@v3 59 | with: 60 | username: ${{ github.repository_owner }} 61 | password: ${{ secrets.DOCKERHUB_TOKEN }} 62 | - 63 | name: Login to GHCR 64 | uses: docker/login-action@v3 65 | with: 66 | registry: ghcr.io 67 | username: ${{ github.repository_owner }} 68 | password: ${{ secrets.GITHUB_TOKEN }} 69 | - 70 | name: Build and push Alpine Docker image 71 | uses: docker/build-push-action@v6 72 | with: 73 | context: ./stable 74 | file: ./stable/Dockerfile.alpine 75 | platforms: linux/amd64 76 | push: ${{ github.event_name != 'pull_request' }} 77 | tags: ${{ steps.meta-alpine.outputs.tags }} 78 | labels: ${{ steps.meta-alpine.outputs.labels }} 79 | build-args: VERSION=${{ steps.getargs.outputs.version }} 80 | - 81 | name: Build and push Debian Docker image 82 | uses: docker/build-push-action@v6 83 | with: 84 | context: ./stable 85 | file: ./stable/Dockerfile 86 | platforms: linux/amd64 87 | push: ${{ github.event_name != 'pull_request' }} 88 | tags: ${{ steps.meta-debian.outputs.tags }} 89 | labels: ${{ steps.meta-debian.outputs.labels }} 90 | build-args: VERSION=${{ steps.getargs.outputs.version }} 91 | -------------------------------------------------------------------------------- /.github/workflows/close-stale.yml: -------------------------------------------------------------------------------- 1 | # 2 | # close-stale.yml 3 | # Close open issues after a period of inactivity 4 | # Credit to the https://github.com/MarlinFirmware/Marlin team for the base file and text this action is built on. 5 | # 6 | 7 | name: Close Stale Issues 8 | 9 | on: 10 | schedule: 11 | - cron: "22 1 * * *" 12 | 13 | jobs: 14 | stale: 15 | name: Close Stale Issues 16 | if: github.repository == 'goofball222/factorio' 17 | 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - uses: actions/stale@v9 22 | with: 23 | repo-token: ${{ secrets.GITHUB_TOKEN }} 24 | stale-issue-message: | 25 | This issue has had no activity for the last 90 days. 26 | Do you still see this issue with the latest release? 27 | Please add a reply within 14 days or this issue will be automatically closed. 28 | To keep a confirmed issue open we can also add a "bug confirmed" tag. 29 | 30 | Disclaimer: This is an open community project with limited resources. 31 | Any skilled member of the community may jump in at any time to fix this issue. 32 | That can take a while depending on our busy lives so please be patient, 33 | and take advantage of other resources to help solve the issue. 34 | days-before-stale: 90 35 | days-before-close: 14 36 | stale-issue-label: 'stale-closing-soon' 37 | exempt-all-assignees: true 38 | exempt-issue-labels: 'bug confirmed,enhancement,feature request,more data needed,discussion needed,documentation needed,work needed,testing needed,help wanted,no-locking' 39 | -------------------------------------------------------------------------------- /.github/workflows/hadolint.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | # hadoint is a Dockerfile linter written in Haskell 6 | # that helps you build best practice Docker images. 7 | # More details at https://github.com/hadolint/hadolint 8 | 9 | name: Hadolint 10 | 11 | on: 12 | push: 13 | branches: [ "main" ] 14 | pull_request: 15 | # The branches below must be a subset of the branches above 16 | branches: [ "main" ] 17 | schedule: 18 | - cron: '37 16 * * 3' 19 | 20 | permissions: 21 | contents: read 22 | 23 | jobs: 24 | hadolint: 25 | name: Run hadolint scanning 26 | runs-on: ubuntu-latest 27 | permissions: 28 | contents: read # for actions/checkout to fetch code 29 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results 30 | actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status 31 | steps: 32 | - name: Checkout code 33 | uses: actions/checkout@v4 34 | 35 | - name: Run hadolint 36 | uses: hadolint/hadolint-action@v3.1.0 37 | with: 38 | dockerfile: ./stable/Dockerfile 39 | format: sarif 40 | output-file: hadolint-results.sarif 41 | no-fail: true 42 | 43 | - name: Upload analysis results to GitHub 44 | uses: github/codeql-action/upload-sarif@v3 45 | with: 46 | sarif_file: hadolint-results.sarif 47 | wait-for-processing: true 48 | -------------------------------------------------------------------------------- /.github/workflows/hub-description-tag.yml: -------------------------------------------------------------------------------- 1 | name: Hub Desc. Update on Tag 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | tags: 7 | - '*' 8 | 9 | jobs: 10 | dockerHubDescription: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - 14 | uses: actions/checkout@v4 15 | - 16 | name: Docker Hub Description 17 | uses: peter-evans/dockerhub-description@v4 18 | with: 19 | username: ${{ github.repository_owner }} 20 | password: ${{ secrets.DOCKERHUB_TOKEN }} 21 | repository: ${{ github.repository }} 22 | short-description: ${{ github.event.repository.description }} 23 | -------------------------------------------------------------------------------- /.github/workflows/hub-description.yml: -------------------------------------------------------------------------------- 1 | name: Hub Desc. Update 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - README.md 10 | - .github/workflows/hub-description.yml 11 | 12 | jobs: 13 | dockerHubDescription: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - 17 | uses: actions/checkout@v4 18 | - 19 | name: Docker Hub Description 20 | uses: peter-evans/dockerhub-description@v4 21 | with: 22 | username: ${{ github.repository_owner }} 23 | password: ${{ secrets.DOCKERHUB_TOKEN }} 24 | repository: ${{ github.repository }} 25 | short-description: ${{ github.event.repository.description }} 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.mk 2 | *.dmk 3 | *.sw? 4 | *~ 5 | tmp/* 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | * **2025-05-05** 2 | * Stable Factorio v[2.0.55](https://forums.factorio.com/129196) 3 | * Experimental Factorio v[2.0.55](https://forums.factorio.com/129196) 4 | * **2025-05-27** 5 | * Experimental Factorio v[2.0.52](https://forums.factorio.com/128974) 6 | --- 7 | * **2025-05-05** 8 | * Stable Factorio v[2.0.47](https://forums.factorio.com/128461) 9 | * Experimental Factorio v[2.0.47](https://forums.factorio.com/128461) 10 | --- 11 | * **2025-03-26** 12 | * Stable Factorio v[2.0.43](https://forums.factorio.com/127780) 13 | * Experimental Factorio v[2.0.43](https://forums.factorio.com/127780) 14 | --- 15 | * **2025-03-19** 16 | * Stable Factorio v[2.0.42](https://forums.factorio.com/127608) 17 | * Experimental Factorio v[2.0.42](https://forums.factorio.com/127608) 18 | --- 19 | * **2025-03-12** 20 | * Stable Factorio v[2.0.41](https://forums.factorio.com/127442) 21 | * Experimental Factorio v[2.0.41](https://forums.factorio.com/127442) 22 | --- 23 | * **2025-03-12** 24 | * Stable Factorio v[2.0.39](https://forums.factorio.com/127286) 25 | * Experimental Factorio v[2.0.40](https://forums.factorio.com/127425) 26 | --- 27 | * **2025-03-11** 28 | * Stable Factorio v[2.0.39](https://forums.factorio.com/127286) 29 | * Experimental Factorio v[2.0.39](https://forums.factorio.com/127286) 30 | --- 31 | * **2025-02-28** 32 | * Experimental Factorio v[2.0.37](https://forums.factorio.com/127152) 33 | --- 34 | * **2025-01-23** 35 | * Stable Factorio v[2.0.32](https://forums.factorio.com/126165) 36 | * Tag & release v2.0.32 37 | --- 38 | * **2025-01-21** 39 | * Experimental Factorio v[2.0.32](https://forums.factorio.com/126165) 40 | --- 41 | * **2025-01-21** 42 | * Stable Factorio v[2.0.30](https://forums.factorio.com/125799) 43 | * Tag & release v2.0.30 44 | --- 45 | * **2024-12-21** 46 | * Stable and experimental Factorio v[2.0.28](https://forums.factorio.com/124820) 47 | * Tag & release v2.0.28 48 | --- 49 | * **2024-12-02** 50 | * Stable and experimental Factorio v[2.0.23](https://forums.factorio.com/123194) 51 | * Tag & release v2.0.23 52 | --- 53 | * **2024-11-21** 54 | * Stable and experimental Factorio v[2.0.21](https://forums.factorio.com/122403) 55 | * Tag & release v2.0.21 56 | --- 57 | * **2024-11-19** 58 | * Stable and experimental Factorio v[2.0.20](https://forums.factorio.com/121972) 59 | * Tag & release v2.0.20 60 | --- 61 | * **2024-11-08** 62 | * Stable and experimental Factorio v[2.0.15](https://forums.factorio.com/119952) 63 | * Tag & release v2.0.15 64 | * Experimental Factorio v[2.0.16](https://forums.factorio.com/120390) 65 | --- 66 | * **2024-11-03** 67 | * Stable and experimental Factorio v[2.0.14](https://forums.factorio.com/119048) 68 | * Tag & release v2.0.14 69 | --- 70 | * **2024-10-31** 71 | * Stable and experimental Factorio v[2.0.13](https://forums.factorio.com/118651) 72 | * Tag & release v2.0.13 73 | --- 74 | * **2024-10-29** 75 | * Stable and experimental Factorio v[2.0.12](https://forums.factorio.com/118184) 76 | * Tag & release v2.0.12 77 | --- 78 | * **2024-10-23** 79 | * Stable and experimental Factorio v[2.0.11](https://forums.factorio.com/117418) 80 | * Tag & release v2.0.11 81 | --- 82 | * **2024-10-23** 83 | * Stable Factorio v[2.0.10](https://forums.factorio.com/116963) 84 | * Tag & release v2.0.10 85 | --- 86 | * **2024-10-23** 87 | * Stable Factorio v[2.0.9](https://forums.factorio.com/116641) 88 | * Tag & release v2.0.9 89 | --- 90 | * **2024-10-22** 91 | * Stable Factorio v[2.0.8](https://forums.factorio.com/116327) 92 | * Tag & release v2.0.8 93 | --- 94 | * **2024-10-21** 95 | * Stable Factorio v[2.0.7](https://forums.factorio.com/116184) 96 | * Update debian docker image 97 | * Tag & release v2.0.7 98 | --- 99 | * **2024-08-29** 100 | * Stable Factorio v[1.1.110](https://forums.factorio.com/114845) 101 | * Tag & release v1.1.110 102 | --- 103 | * **2024-07-15** 104 | * Stable Factorio v[1.1.109](https://forums.factorio.com/113778) 105 | * Tag & release v1.1.109 106 | --- 107 | * **2024-07-01** 108 | * Experimental Factorio v[1.1.109](https://forums.factorio.com/113778) 109 | --- 110 | * **2024-05-31** 111 | * Experimental Factorio v[1.1.108](https://forums.factorio.com/113699) 112 | --- 113 | * **2024-04-20** 114 | * Stable Factorio v[1.1.107](https://forums.factorio.com/112937) 115 | * Experimental Factorio v[1.1.107](https://forums.factorio.com/112937) 116 | * Tag & release v1.1.107 117 | --- 118 | * **2024-01-15** 119 | * Stable Factorio v[1.1.101](https://forums.factorio.com/110371) 120 | * Experimental Factorio v[1.1.101](https://forums.factorio.com/110371) 121 | * Tag & release v1.1.101 122 | --- 123 | * **2023-12-12** 124 | * Stable Factorio v[1.1.100](https://forums.factorio.com/110039) 125 | * Experimental Factorio v[1.1.100](https://forums.factorio.com/110039) 126 | * Tag & release v1.1.100 127 | --- 128 | * **2023-10-30** 129 | * Stable Factorio v[1.1.94](https://forums.factorio.com/109267) 130 | * Tag & release v1.1.94 131 | --- 132 | * **2023-10-27** 133 | * Experimental Factorio v[1.1.94](https://forums.factorio.com/109267) 134 | --- 135 | * **2023-10-16** 136 | * Experimental Factorio v[1.1.92](https://forums.factorio.com/108908) 137 | --- 138 | * **2023-09-21** 139 | * Stable Factorio v[1.1.91](https://forums.factorio.com/108687) 140 | * Tag & release v1.1.91 141 | --- 142 | * **2023-09-13** 143 | * Stable Factorio v[1.1.87](https://forums.factorio.com/107634) 144 | * Tag & release v1.1.87 145 | * Experimental Factorio v[1.1.91](https://forums.factorio.com/108687) 146 | --- 147 | * **2023-04-14** 148 | * Stable Factorio v[1.1.80](https://forums.factorio.com/105761) 149 | * Tag & release v1.1.80 150 | --- 151 | * **2023-03-30** 152 | * Experimental Factorio v[1.1.80](https://forums.factorio.com/105761) 153 | --- 154 | * **2023-03-20** 155 | * Experimental Factorio v[1.1.78](https://forums.factorio.com/105674) 156 | --- 157 | * **2023-03-03** 158 | * Stable Factorio v[1.1.76](https://forums.factorio.com/104820) 159 | * Tag & release v1.1.76 160 | * Experimental Factorio v[1.1.77](https://forums.factorio.com/105436) 161 | --- 162 | * **2023-01-30** 163 | * Update GitHub workflows 164 | --- 165 | * **2023-01-13** 166 | * Experimental Factorio v[1.1.76](https://forums.factorio.com/104802) 167 | --- 168 | * **2023-01-11** 169 | * Experimental Factorio v[1.1.75](https://forums.factorio.com/104765) 170 | --- 171 | * **2022-12-20** 172 | * Stable Factorio v[1.1.74](https://forums.factorio.com/104347) 173 | * Tag & release v1.1.74 174 | --- 175 | * **2022-12-06** 176 | * Experimental Factorio v[1.1.74](https://forums.factorio.com/104347) 177 | --- 178 | * **2022-12-05** 179 | * Stable Factorio v[1.1.72](https://forums.factorio.com/104069) 180 | * Tag & release v1.1.72 181 | * Experimental Factorio v[1.1.73](https://forums.factorio.com/104293) 182 | --- 183 | * **2022-11-11** 184 | * Experimental Factorio v[1.1.72](https://forums.factorio.com/104069) 185 | --- 186 | * **2022-11-04** 187 | * Experimental Factorio v[1.1.71](https://forums.factorio.com/104009) 188 | --- 189 | * **2022-10-28** 190 | * Stable Factorio v[1.1.70](https://forums.factorio.com/103723) 191 | * Tag & release v1.1.70 192 | --- 193 | * **2022-10-12** 194 | * Experimental Factorio v[1.1.70](https://forums.factorio.com/103723) 195 | --- 196 | * **2022-09-16** 197 | * Stable Factorio v[1.1.69](https://forums.factorio.com/103415) 198 | * Tag & release v1.1.69 199 | --- 200 | * **2022-09-12** 201 | * Experimental Factorio v[1.1.69](https://forums.factorio.com/103415) 202 | --- 203 | * **2022-08-29** 204 | * Stable Factorio v[1.1.68](https://forums.factorio.com/103205) 205 | * Tag & release v1.1.68 206 | --- 207 | * **2022-08-22** 208 | * Experimental Factorio v[1.1.68](https://forums.factorio.com/103205) 209 | --- 210 | * **2022-08-19** 211 | * Experimental Factorio v[1.1.67](https://forums.factorio.com/103181) 212 | --- 213 | * **2022-08-05** 214 | * Experimental Factorio v[1.1.65](https://forums.factorio.com/103072) 215 | --- 216 | * **2022-08-02** 217 | * Experimental Factorio v[1.1.64](https://forums.factorio.com/103047) 218 | --- 219 | * **2022-07-28** 220 | * Experimental Factorio v[1.1.63](https://forums.factorio.com/103004) 221 | --- 222 | * **2022-07-26** 223 | * Experimental Factorio v[1.1.62](https://forums.factorio.com/102977) 224 | --- 225 | * **2022-06-29** 226 | * Stable Factorio v[1.1.61](https://forums.factorio.com/102741) 227 | * Tag & release v1.1.61 228 | --- 229 | * **2022-06-23** 230 | * Experimental Factorio v[1.1.61](https://forums.factorio.com/102741) 231 | --- 232 | * **2022-06-06** 233 | * Experimental Factorio v[1.1.60](https://forums.factorio.com/102610) 234 | --- 235 | * **2022-05-15** 236 | * Experimental/stable Factorio v[1.1.59](https://forums.factorio.com/102341) 237 | --- 238 | * **2022-05-03** 239 | * Experimental Factorio v[1.1.58](https://forums.factorio.com/102318) 240 | --- 241 | * **2022-04-01** 242 | * Experimental Factorio v[1.1.57](https://forums.factorio.com/101801) 243 | * Stable Factorio v[1.1.57](https://forums.factorio.com/101801) via PR #30 244 | * Thanks [bourgeois](https://github.com/bourgeois) 245 | * Tag & release v1.1.57 246 | --- 247 | * **2022-03-12** 248 | * Set shutdown process kill timeout to 5 minutes, allow complex servers time to save gracefully (closes #29) 249 | --- 250 | * **2022-03-09** 251 | * Experimental Factorio v[1.1.56](https://forums.factorio.com/101801) 252 | --- 253 | * **2022-02-23** 254 | * Experimental Factorio v[1.1.55](https://forums.factorio.com/101683) 255 | * ~~Experimental Factorio v[1.1.54](https://forums.factorio.com/101680)~~ 256 | --- 257 | * **2022-01-21** 258 | * Move Factorio v[1.1.53](https://forums.factorio.com/101296) to latest/stable 259 | * Tag release 1.1.53 260 | --- 261 | * **2022-01-19** 262 | * Experimental Factorio v[1.1.53](https://forums.factorio.com/101296) 263 | --- 264 | * **2022-01-18** 265 | * ~~Experimental Factorio v[1.1.51](https://forums.factorio.com/101273)~~ 266 | * Experimental Factorio v[1.1.52](https://forums.factorio.com/101280) 267 | --- 268 | * **2021-12-29** 269 | * Move Factorio v[1.1.50](https://forums.factorio.com/100986) to latest/stable 270 | * Merge PR from [pliesveld](https://github.com/pliesveld) that adds missing procps package to Debian image 271 | * Tag release 1.1.50 272 | --- 273 | * **2021-12-21** 274 | * Experimental Factorio v[1.1.50](https://forums.factorio.com/100986) 275 | --- 276 | * **2021-12-10** 277 | * Move Factorio v[1.1.49](https://forums.factorio.com/100856) to latest/stable 278 | * Tag release 1.1.49 279 | --- 280 | * **2021-12-07** 281 | * Experimental Factorio v[1.1.49](https://forums.factorio.com/100856) 282 | --- 283 | * **2021-11-26** 284 | * Move Factorio v[1.1.48](https://forums.factorio.com/100740) to latest/stable 285 | * Thanks [sYnHybrid](https://github.com/sYnHybrid)! 286 | * Tag release 1.1.48 287 | --- 288 | * **2021-11-24** 289 | * Experimental Factorio v[1.1.48](https://forums.factorio.com/100740) 290 | --- 291 | * **2021-11-22** 292 | * Experimental Factorio v[1.1.47](https://forums.factorio.com/100691) 293 | * Move Factorio v[1.1.46](https://forums.factorio.com/100513) to latest/stable 294 | * Tag release 1.1.46 295 | --- 296 | * **2021-11-05** 297 | * Experimental Factorio v[1.1.46](https://forums.factorio.com/100513) 298 | --- 299 | * **2021-10-28** 300 | * Experimental Factorio v[1.1.45](https://forums.factorio.com/100424) 301 | --- 302 | * **2021-10-27** 303 | * Experimental Factorio v[1.1.44](https://forums.factorio.com/100412) 304 | --- 305 | * **2021-10-26** 306 | * Experimental Factorio v[1.1.43](https://forums.factorio.com/100389) 307 | --- 308 | * **2021-10-19** 309 | * Move Factorio v[1.1.42](https://forums.factorio.com/100225) to latest/stable 310 | * Tag release 1.1.42 311 | --- 312 | * **2021-10-11** 313 | * Experimental Factorio v[1.1.42](https://forums.factorio.com/100225) 314 | --- 315 | * **2021-10-05** 316 | * Move Factorio v[1.1.41](https://forums.factorio.com/100042) to latest/stable 317 | * Tag release 1.1.41 318 | --- 319 | * **2021-09-23** 320 | * Experimental Factorio v[1.1.41](https://forums.factorio.com/100042) 321 | --- 322 | * **2021-09-01** 323 | * Move Factorio v[1.1.39](https://forums.factorio.com/99796) to latest/stable 324 | * Tag release 1.1.39 325 | --- 326 | * **2021-09-01** 327 | * Experimental Factorio v[1.1.39](https://forums.factorio.com/99796) 328 | * Move Factorio v[1.1.38](https://forums.factorio.com/99653) to latest/stable 329 | * Tag release 1.1.38 330 | --- 331 | * **2021-08-18** 332 | * Experimental Factorio v[1.1.38](https://forums.factorio.com/99653) 333 | --- 334 | * **2021-08-09** 335 | * Move Factorio v[1.1.37](https://forums.factorio.com/99501) to latest/stable 336 | * Tag release 1.1.37 337 | --- 338 | * **2021-08-03** 339 | * Experimental Factorio v[1.1.37](https://forums.factorio.com/99501) 340 | --- 341 | * **2021-07-20** 342 | * Move Factorio v[1.1.36](https://forums.factorio.com/99223) to latest/stable 343 | * Tag release 1.1.36 344 | --- 345 | * **2021-06-18** 346 | * Experimental Factorio v[1.1.36](https://forums.factorio.com/99223) 347 | --- 348 | * **2021-06-18** 349 | * Move stable to Factorio v[1.1.35](https://forums.factorio.com/98877) 350 | * Tag release 1.1.35 351 | --- 352 | * **2021-06-17** 353 | * Experimental Factorio version v[1.1.35](https://forums.factorio.com/98877) 354 | * Switch to GitHub actions for building 355 | * Switch base image from frolvlad/alpine-glibc:latest to debian:buster-slim to fix issue #22 356 | * Move Alpine images to Dockerfile.alpine and -alpine tags 357 | --- 358 | * **2021-05-29** 359 | * Move stable to Factorio v[1.1.34](https://forums.factorio.com/98531) 360 | * Tag release 1.1.34 361 | --- 362 | * **2021-05-24** 363 | * Experimental Factorio version v[1.1.34](https://forums.factorio.com/98531) 364 | --- 365 | * **2021-05-14** 366 | * Move stable to Factorio v[1.1.33](https://forums.factorio.com/98176) 367 | * Tag release 1.1.33 368 | --- 369 | * **2021-05-03** 370 | * Experimental Factorio version v[1.1.33](https://forums.factorio.com/98176) 371 | --- 372 | * **2021-04-16** 373 | * Move stable to Factorio v[1.1.32](https://forums.factorio.com/97844) 374 | * Move experimental to Factorio v[1.1.32](https://forums.factorio.com/97844) 375 | * Tag release 1.1.32 376 | --- 377 | * **2021-04-05** 378 | * Move stable to Factorio v[1.1.30](https://forums.factorio.com/97284) 379 | * Tag release 1.1.30 380 | --- 381 | * **2021-03-24** 382 | * ~~Experimental Factorio version [1.1.28](https://forums.factorio.com/97273)~~ 383 | * ~~Experimental Factorio version [1.1.29](https://forums.factorio.com/97278)~~ 384 | * Experimental Factorio version [1.1.30](https://forums.factorio.com/97284) 385 | --- 386 | * **2021-03-15** 387 | * Factorio version [1.1.27](https://forums.factorio.com/96825) promoted to stable 388 | * Tag release 1.1.27 389 | --- 390 | * **2021-03-11** 391 | * Experimental Factorio version [1.1.27](https://forums.factorio.com/96825) 392 | * Factorio version [1.1.26](https://forums.factorio.com/96561) promoted to stable 393 | * Tag release 1.1.26 394 | --- 395 | * **2021-03-01** 396 | * Experimental Factorio version [1.1.26](https://forums.factorio.com/96561) 397 | * Factorio version [1.1.25](https://forums.factorio.com/96257) promoted to stable 398 | * Tag release 1.1.25 399 | --- 400 | * **2021-02-17** 401 | * Experimental Factorio version [1.1.25](https://forums.factorio.com/96257) 402 | --- 403 | * **2021-02-16** 404 | * Experimental Factorio version [1.1.24](https://forums.factorio.com/96224) 405 | --- 406 | * **2021-02-08** 407 | * Factorio version [1.1.21](https://forums.factorio.com/95730) promoted to stable 408 | * Copy functionized script updates from experimental to stable 409 | * Tag release 1.1.21 410 | --- 411 | * **2021-02-05** 412 | * Experimental Factorio version [1.1.21](https://forums.factorio.com/95730) 413 | --- 414 | * **2021-02-04** 415 | * Experimental Factorio version [1.1.20](https://forums.factorio.com/95683) 416 | --- 417 | * **2021-01-29** 418 | * Factorio version [1.1.19](https://forums.factorio.com/94988) promoted to stable 419 | * Tag release 1.1.19 420 | * Functionize experimental version entrypoint script, will deploy to stable if no issues found after ~2w 421 | * Quick-fix to stable entyrypoint script closes issue #21 422 | --- 423 | * **2021-01-26** 424 | * Experimental Factorio version [1.1.19](https://forums.factorio.com/94988) 425 | --- 426 | * **2021-01-25** 427 | ~~* Experimental Factorio version [1.1.16](https://forums.factorio.com/94925)~~ 428 | ~~* Experimental Factorio version [1.1.17](https://forums.factorio.com/94939)~~ 429 | * Experimental Factorio version [1.1.18](https://forums.factorio.com/94945) 430 | --- 431 | * **2021-01-24** 432 | * Experimental Factorio version [1.1.15](https://forums.factorio.com/94883) 433 | --- 434 | * **2021-01-23** 435 | * Experimental Factorio version [1.1.14](https://forums.factorio.com/94832) 436 | --- 437 | * **2021-01-22** 438 | * Experimental Factorio version [1.1.13](https://forums.factorio.com/94772) 439 | --- 440 | * **2021-01-16** 441 | * Experimental Factorio version [1.1.12](https://forums.factorio.com/94477) 442 | --- 443 | * **2021-01-14** 444 | ~~* Experimental Factorio version [1.1.9](https://forums.factorio.com/94351)~~ 445 | ~~* Experimental Factorio version [1.1.10](https://forums.factorio.com/94371)~~ 446 | * Experimental Factorio version [1.1.11](https://forums.factorio.com/94386) 447 | --- 448 | * **2021-01-07** 449 | ~~* Experimental Factorio version [1.1.7](https://forums.factorio.com/94013)~~ 450 | * Experimental Factorio version [1.1.8](https://forums.factorio.com/94034) 451 | --- 452 | * **2020-12-14** 453 | * Experimental Factorio version [1.1.6](https://forums.factorio.com/93072) 454 | --- 455 | * **2020-12-04** 456 | * Experimental Factorio version [1.1.5](https://forums.factorio.com/92528) 457 | --- 458 | * **2020-12-03** 459 | * Experimental Factorio version [1.1.4](https://forums.factorio.com/92480) 460 | --- 461 | * **2020-11-30** 462 | * Experimental Factorio version [1.1.3](https://forums.factorio.com/92314) 463 | --- 464 | * **2020-11-28** 465 | * Experimental Factorio version [1.1.2](https://forums.factorio.com/92158) 466 | --- 467 | * **2020-11-25** 468 | * Experimental Factorio version [1.1.1](https://forums.factorio.com/91858) 469 | --- 470 | * **2020-11-23** 471 | * Experimental Factorio version [1.1.0](https://forums.factorio.com/91657) 472 | --- 473 | * **2020-08-14** 474 | * Factorio version 1.0! [1.0.0](https://forums.factorio.com/87912) 475 | * Both "experimental" and "stable" were updated to 1.0.0 per the Factorio site releases. 476 | --- 477 | * **2020-08-11** 478 | * Bump experimental VERSION to [0.18.47](https://forums.factorio.com/87797) 479 | --- 480 | * **2020-08-10** 481 | * Bump experimental VERSION to [0.18.46](https://forums.factorio.com/87775) 482 | --- 483 | * **2020-08-07** 484 | * Bump experimental VERSION to [0.18.45](https://forums.factorio.com/87670) 485 | --- 486 | * **2020-08-06** 487 | * Bump experimental VERSION to [0.18.43](https://forums.factorio.com/87620) 488 | --- 489 | * **2020-08-03** 490 | * Bump experimental VERSION to [0.18.42](https://forums.factorio.com/87512) 491 | --- 492 | * **2020-08-01** 493 | * Bump experimental VERSION to [0.18.40](https://forums.factorio.com/87409) 494 | --- 495 | * **2020-07-30** 496 | * Bump experimental VERSION to [0.18.38](https://forums.factorio.com/87306) 497 | --- 498 | * **2020-07-29** 499 | * Bump experimental VERSION to [0.18.37](https://forums.factorio.com/87253) 500 | --- 501 | * **2020-07-15** 502 | * Bump experimental VERSION to [0.18.36](https://forums.factorio.com/86883) 503 | --- 504 | * **2020-07-07** 505 | * Bump experimental VERSION to [0.18.35](https://forums.factorio.com/86629) 506 | * Update Dockerfile label schema 507 | --- 508 | * **2020-06-26** 509 | * Bump experimental VERSION to [0.18.34](https://forums.factorio.com/86351) 510 | --- 511 | * **2020-06-24** 512 | * Bump experimental VERSION to [0.18.33](https://forums.factorio.com/86272) 513 | --- 514 | * **2020-06-16** 515 | * Bump experimental VERSION to [0.18.32](https://forums.factorio.com/86002) 516 | --- 517 | * **2020-06-10** 518 | * Bump experimental VERSION to [0.18.31](https://forums.factorio.com/85831) 519 | --- 520 | * **2020-06-03** 521 | * Bump experimental VERSION to [0.18.30](https://forums.factorio.com/85576) 522 | --- 523 | * **2020-06-01** 524 | * Bump experimental VERSION to [0.18.29](https://forums.factorio.com/85506) 525 | --- 526 | * **2020-05-28** 527 | * Bump experimental VERSION to [0.18.28](https://forums.factorio.com/85391) 528 | --- 529 | * **2020-05-26** 530 | * Bump experimental VERSION to [0.18.27](https://forums.factorio.com/85310) 531 | --- 532 | * **2020-05-21** 533 | * Bump experimental VERSION to [0.18.26](https://forums.factorio.com/85145) 534 | --- 535 | * **2020-05-19** 536 | * Bump experimental VERSION to [0.18.25](https://forums.factorio.com/85084) 537 | --- 538 | * **2020-05-12** 539 | * Bump experimental VERSION to [0.18.24](https://forums.factorio.com/84863) 540 | --- 541 | * **2020-04-30** 542 | * Bump experimental VERSION to [0.18.22](https://forums.factorio.com/84435) 543 | --- 544 | * **2020-04-24** 545 | * Bump experimental VERSION to [0.18.21](https://forums.factorio.com/84152) 546 | --- 547 | * **2020-04-20** 548 | * Bump experimental VERSION to [0.18.19](https://forums.factorio.com/83968) 549 | --- 550 | * **2020-04-09** 551 | * Bump experimental VERSION to [0.18.18](https://forums.factorio.com/83449) 552 | --- 553 | * **2020-03-27** 554 | * Bump experimental VERSION to [0.18.17](https://forums.factorio.com/82897) 555 | --- 556 | * **2020-03-25** 557 | * Bump experimental VERSION to [0.18.16](https://forums.factorio.com/82796) 558 | --- 559 | * **2020-03-20** 560 | * Bump experimental VERSION to [0.18.15](https://forums.factorio.com/82585) 561 | --- 562 | * **2020-03-18** 563 | * Bump experimental VERSION to [0.18.14](https://forums.factorio.com/82489) 564 | --- 565 | * **2020-03-17** 566 | * Bump experimental VERSION to [0.18.13](https://forums.factorio.com/82431) 567 | --- 568 | * **2020-03-10** 569 | * ~~Bump experimental VERSION to [0.18.11](https://forums.factorio.com/82156)~~ 570 | * Bump experimental VERSION to [0.18.12](https://forums.factorio.com/82162) 571 | --- 572 | * **2020-03-03** 573 | * Bump experimental VERSION to [0.18.10](https://forums.factorio.com/81931) 574 | --- 575 | * **2020-02-25** 576 | * Bump experimental VERSION to [0.18.9](https://forums.factorio.com/81631) 577 | --- 578 | * **2020-02-18** 579 | * ~~Bump experimental VERSION to [0.18.7](https://forums.factorio.com/81393)~~ 580 | * Bump experimental VERSION to [0.18.8](https://forums.factorio.com/81401) 581 | --- 582 | * **2020-02-11** 583 | * ~~Bump experimental VERSION to [0.18.5](https://forums.factorio.com/81144)~~ 584 | * Bump experimental VERSION to [0.18.6](https://forums.factorio.com/81152) 585 | * Fix CHANGELOG.md formatting 586 | --- 587 | * **2020-02-06** 588 | * Bump experimental VERSION to [0.18.4](https://forums.factorio.com/80954) 589 | --- 590 | * **2020-01-30** 591 | * Bump experimental VERSION to [0.18.3](https://forums.factorio.com/80665) 592 | --- 593 | * **2020-01-28** 594 | * Bump experimental VERSION to [0.18.2](https://forums.factorio.com/80554) 595 | --- 596 | * **2020-01-23** 597 | * Bump experimental VERSION to [0.18.1](https://forums.factorio.com/80361) 598 | --- 599 | * **2020-01-21** 600 | * Bump experimental VERSION to [0.18.0](https://forums.factorio.com/80247) 601 | --- 602 | * **2019-12-06** 603 | * Bump stable VERSION to [0.17.79](https://forums.factorio.com/78146) 604 | * Tag release 0.17.79 605 | --- 606 | * **2019-11-19** 607 | * Bump experimental VERSION to [0.17.79](https://forums.factorio.com/78146) 608 | --- 609 | * **2019-11-15** 610 | * Bump experimental VERSION to [0.17.78](https://forums.factorio.com/78027) 611 | --- 612 | * **2019-11-14** 613 | * Bump experimental VERSION to [0.17.77](https://forums.factorio.com/77985) 614 | --- 615 | * **2019-11-07** 616 | * Bump experimental VERSION to [0.17.76](https://forums.factorio.com/77706) 617 | --- 618 | * **2019-11-04** 619 | * Bump experimental VERSION to [0.17.75](https://forums.factorio.com/77551) 620 | * Bump stable VERSION to [0.17.74](https://forums.factorio.com/77212) 621 | * Tag release 0.17.74 622 | --- 623 | * **2019-10-25** 624 | * Bump experimental VERSION to [0.17.74](https://forums.factorio.com/77212) 625 | --- 626 | * **2019-10-24** 627 | * Bump experimental VERSION to [0.17.73](https://forums.factorio.com/77170) 628 | --- 629 | * **2019-10-18** 630 | * Bump experimental VERSION to [0.17.72](https://forums.factorio.com/76940) 631 | --- 632 | * **2019-10-16** 633 | * Bump experimental VERSION to [0.17.71](https://forums.factorio.com/76855) 634 | --- 635 | * **2019-09-27** 636 | * Update docker-entrypoint.sh to support new config files and scenarios 637 | * Update Dockerfile to move to a single volume "/factorio" 638 | * Update documentation listing new options 639 | --- 640 | * **2019-09-24** 641 | * Promote experimental VERSION [0.17.69](https://forums.factorio.com/75864) to stable/latest 642 | * Update build hook script to support multi-tag builds on Docker Cloud 643 | * Tag release 0.17.69 644 | --- 645 | * **2019-09-19** 646 | * Bump experimental VERSION to [0.17.69](https://forums.factorio.com/75864) 647 | --- 648 | * **2019-09-04** 649 | * Bump experimental VERSION to [0.17.68](https://forums.factorio.com/75296) 650 | --- 651 | * **2019-09-03** 652 | * Bump experimental VERSION to [0.17.67](https://forums.factorio.com/75239) 653 | * Thanks to [BlackDwarfUK](https://github.com/BlackDwarfUK) 654 | --- 655 | * **2019-08-09** 656 | * Bump experimental VERSION to [0.17.64](https://forums.factorio.com/74349) 657 | --- 658 | * **2019-08-06** 659 | * Bump experimental VERSION to [0.17.63](https://forums.factorio.com/74197) 660 | * Thanks to [BlackDwarfUK](https://github.com/BlackDwarfUK) 661 | --- 662 | * **2019-08-05** 663 | * Bump experimental VERSION to [0.17.62](https://forums.factorio.com/74005) 664 | * Thanks to [BlackDwarfUK](https://github.com/BlackDwarfUK) 665 | --- 666 | * **2019-08-02** 667 | * Bump experimental VERSION to [0.17.61](https://forums.factorio.com/73978) 668 | --- 669 | * **2019-07-31** 670 | * Bump experimental VERSION to [0.17.60](https://forums.factorio.com/73828) 671 | * Thanks to [BlackDwarfUK](https://github.com/BlackDwarfUK) 672 | --- 673 | * **2019-07-26** 674 | * Bump experimental VERSION to [0.17.59](https://forums.factorio.com/73643) 675 | * Thanks to [BlackDwarfUK](https://github.com/BlackDwarfUK) 676 | --- 677 | * **2019-07-15** 678 | * ~~Bump experimental VERSION to [0.17.57](https://forums.factorio.com/73303)~~ 679 | * Bump experimental VERSION to [0.17.58](https://forums.factorio.com/73310) 680 | --- 681 | * **2019-07-09** 682 | * Bump experimental VERSION to [0.17.55](https://forums.factorio.com/73071) 683 | --- 684 | * **2019-07-04** 685 | * Bump experimental VERSION to [0.17.54](https://forums.factorio.com/72887) 686 | --- 687 | * **2019-07-01** 688 | * Bump experimental VERSION to [0.17.53](https://forums.factorio.com/72760) 689 | --- 690 | * **2019-06-24** 691 | * Bump experimental VERSION to [0.17.52](https://forums.factorio.com/72468) 692 | --- 693 | * **2019-06-17** 694 | * Bump experimental VERSION to [0.17.50](https://forums.factorio.com/72137) 695 | --- 696 | * **2019-06-13** 697 | * Bump experimental VERSION to [0.17.49](https://forums.factorio.com/71981) 698 | --- 699 | * **2019-06-11** 700 | * Bump experimental VERSION to [0.17.48](https://forums.factorio.com/71904) 701 | --- 702 | * **2019-06-07** 703 | * Bump experimental VERSION to [0.17.47](https://forums.factorio.com/71687) 704 | --- 705 | * **2019-05-31** 706 | * Bump experimental VERSION to [0.17.45](https://forums.factorio.com/71434) 707 | --- 708 | * **2019-05-24** 709 | * Accept pull request #6 - Bump experimental VERSION to [0.17.43](https://forums.factorio.com/71197) 710 | * Thanks to [BlackDwarfUK](https://github.com/BlackDwarfUK) 711 | --- 712 | * **2019-05-21** 713 | * Bump experimental VERSION to [0.17.42](https://forums.factorio.com/71100) 714 | --- 715 | * **2019-05-17** 716 | * Bump experimental VERSION to [0.17.41](https://forums.factorio.com/70937) 717 | --- 718 | * **2019-05-16** 719 | * Bump experimental VERSION to [0.17.40](https://forums.factorio.com/70898) 720 | --- 721 | * **2019-05-14** 722 | * Bump experimental VERSION to [0.17.39](https://forums.factorio.com/70822) 723 | --- 724 | * **2019-05-12** 725 | * Bump experimental VERSION to [0.17.38](https://forums.factorio.com/70641) 726 | --- 727 | * **2019-05-08** 728 | * Bump experimental VERSION to [0.17.37](https://forums.factorio.com/70527) 729 | --- 730 | * **2019-05-03** 731 | * Bump experimental VERSION to [0.17.36](https://forums.factorio.com/70314) 732 | --- 733 | * **2019-05-02** 734 | * Bump experimental VERSION to [0.17.35](https://forums.factorio.com/70256) 735 | --- 736 | * **2019-04-27** 737 | * Bump experimental VERSION to [0.17.34](https://forums.factorio.com/70006) 738 | --- 739 | * **2019-04-24** 740 | * Bump experimental VERSION to [0.17.33](https://forums.factorio.com/69916) 741 | --- 742 | * **2019-04-18** 743 | * Bump experimental VERSION to [0.17.32](https://forums.factorio.com/69672) 744 | --- 745 | * **2019-04-13** 746 | * Bump experimental VERSION to [0.17.31](https://forums.factorio.com/69440) 747 | --- 748 | * **2019-04-12** 749 | * Bump experimental VERSION to [0.17.29](https://forums.factorio.com/69397) 750 | --- 751 | * **2019-04-09** 752 | * Bump experimental VERSION to [0.17.28](https://forums.factorio.com/69275) 753 | --- 754 | * **2019-04-08** 755 | * Bump experimental VERSION to [0.17.26](https://forums.factorio.com/69229) 756 | --- 757 | * **2019-04-04** 758 | * Bump experimental VERSION to [0.17.25](https://forums.factorio.com/69031) 759 | --- 760 | * **2019-04-02** 761 | * Bump experimental VERSION to [0.17.24](https://forums.factorio.com/68909) 762 | * Update Dockerfile headless package link. Factorio CDN not behaving with Docker Cloud in the last couple of builds. 763 | --- 764 | * **2019-03-29** 765 | * Bump experimental VERSION to [0.17.23](https://forums.factorio.com/68710) 766 | * Touch changelog to bump git commit, attempting to get Docker Hub to stop caching bad data. 767 | --- 768 | * **2019-03-26** 769 | * ~~Bump experimental VERSION to [0.17.19](https://forums.factorio.com/68509)~~ 770 | * ~~Bump experimental VERSION to [0.17.20](https://forums.factorio.com/68525)~~ 771 | * Bump experimental VERSION to [0.17.21](https://forums.factorio.com/68548) 772 | --- 773 | * **2019-03-25** 774 | * Bump experimental VERSION to [0.17.18](https://forums.factorio.com/68443) 775 | --- 776 | * **2019-03-21** 777 | * Bump experimental VERSION to [0.17.17](https://forums.factorio.com/68235) 778 | --- 779 | * **2019-03-19** 780 | * Bump experimental VERSION to [0.17.16](https://forums.factorio.com/68126) 781 | --- 782 | * **2019-03-18** 783 | * Bump experimental VERSION to [0.17.15](https://forums.factorio.com/68030) 784 | --- 785 | * **2019-03-15** 786 | * ~~Bump experimental VERSION to [0.17.13](https://forums.factorio.com/67758)~~ 787 | * Bump experimental VERSION to [0.17.14](https://forums.factorio.com/67782) 788 | --- 789 | * **2019-03-14** 790 | * Bump experimental VERSION to [0.17.12](https://forums.factorio.com/67694) 791 | --- 792 | * **2019-03-11** 793 | * ~~Bump experimental VERSION to [0.17.10](https://forums.factorio.com/67424)~~ 794 | * Bump experimental VERSION to [0.17.11](https://forums.factorio.com/67480) 795 | --- 796 | * **2019-03-08** 797 | * Bump experimental VERSION to [0.17.9](https://forums.factorio.com/67151) 798 | * Update script to resolve GitHub issue #5 - Allow setting game and RCON port by ENV 799 | * Update documentation to reflect additional ENV variables for server ports 800 | --- 801 | * **2019-03-07** 802 | * Bump experimental VERSION to [0.17.8](https://forums.factorio.com/67041) 803 | --- 804 | * **2019-03-06** 805 | * Bump experimental VERSION to [0.17.7](https://forums.factorio.com/66956) 806 | --- 807 | * **2019-03-05** 808 | * Bump experimental VERSION to [0.17.6](https://forums.factorio.com/66854) 809 | --- 810 | * **2019-03-04** 811 | * Bump experimental VERSION to [0.17.5](https://forums.factorio.com/66705) 812 | --- 813 | * **2019-03-01** 814 | * Bump experimental VERSION to [0.17.4](https://forums.factorio.com/66156) 815 | * Update change log and push to github to test webhook changes, nothing to see here... 816 | --- 817 | * **2019-02-28** 818 | * Bump experimental VERSION to [0.17.3](https://forums.factorio.com/65940) 819 | --- 820 | * **2019-02-27** 821 | * Bump experimental VERSION to [0.17.2](https://forums.factorio.com/65580) 822 | --- 823 | * **2019-02-26** 824 | * ~~Bump experimental VERSION to [0.17.0](https://forums.factorio.com/65070)~~ 825 | * Bump experimental VERSION to [0.17.1](https://forums.factorio.com/65227) 826 | --- 827 | * **2018-08-24** 828 | * Update Dockerfile 829 | * Change FACTORIO_GID and FACTORIO_UID to PGID/PUID 830 | * Change apk commands to stop caching package lists and use virtual for build deps 831 | * Rework post-build cleanup 832 | * Add support for RUN_CHOWN flag 833 | * Add tzdata package 834 | * docker-entrypoint.sh 835 | * Add support for RUN_CHOWN flag 836 | * Change FACTORIO_GID and FACTORIO_UID to PGID/PUID 837 | * Add -o flag to groupmod/usermod - allow setting custom GID/UID when already exists 838 | * Update documentation to reflect variable changes 839 | * Update build hooks script 840 | --- 841 | * **2018-06-19** 842 | * Bump stable VERSION to [0.16.51](https://forums.factorio.com/61009) 843 | --- 844 | * **2018-06-15** 845 | * Bump experimental VERSION to [0.16.51](https://forums.factorio.com/61009) 846 | --- 847 | * **2018-06-14** 848 | * Update Dockerfile to remove depreciated "MAINTAINER", move info to LABEL "vendor" value 849 | --- 850 | * **2018-06-11** 851 | * Bump experimental VERSION to [0.16.50](https://forums.factorio.com/60929) 852 | --- 853 | * **2018-06-08** 854 | * Bump experimental VERSION to [0.16.49](https://forums.factorio.com/60868) 855 | --- 856 | * **2018-06-07** 857 | * Bump experimental VERSION to [0.16.48](https://forums.factorio.com/60839) 858 | --- 859 | * **2018-05-31** 860 | * Bump experimental VERSION to [0.16.47](https://forums.factorio.com/60713) 861 | --- 862 | * **2018-05-22** 863 | * Bump experimental VERSION to [0.16.44](https://forums.factorio.com/60548) 864 | * Bump experimental VERSION to [0.16.45](https://forums.factorio.com/60556) 865 | --- 866 | * **2018-05-14** 867 | * Bump experimental VERSION to [0.16.43](https://forums.factorio.com/60361) 868 | --- 869 | * **2018-05-13** 870 | * Bump experimental VERSION to [0.16.42](https://forums.factorio.com/60266) 871 | --- 872 | * **2018-05-03** 873 | * Bump experimental VERSION to [0.16.41](https://forums.factorio.com/60051) 874 | --- 875 | * **2018-05-02** 876 | * Bump experimental VERSION to [0.16.40](https://forums.factorio.com/60039) 877 | --- 878 | * **2018-04-30** 879 | * Bump experimental VERSION to [0.16.39](https://forums.factorio.com/59984) 880 | --- 881 | * **2018-04-26** 882 | * Bump experimental VERSION to [0.16.38](https://forums.factorio.com/59877) 883 | --- 884 | * **2018-04-23** 885 | * Bump experimental VERSION to [0.16.37](https://forums.factorio.com/59802) 886 | --- 887 | * **2018-03-29** 888 | * Bump stable VERSION to [0.16.36](https://forums.factorio.com/59134) 889 | * Tag stable release 0.16.36 890 | --- 891 | * **2018-03-26** 892 | * Bump experimental VERSION to [0.16.35](https://forums.factorio.com/59005) 893 | --- 894 | * **2018-03-22** 895 | * Bump experimental VERSION to [0.16.34](https://forums.factorio.com/58962) 896 | --- 897 | * **2018-03-20** 898 | * Bump experimental VERSION to [0.16.32](https://forums.factorio.com/58890) 899 | --- 900 | * **2018-03-19** 901 | * Bump experimental VERSION to [0.16.31](https://forums.factorio.com/58853) 902 | --- 903 | * **2018-03-12** 904 | * Bump experimental VERSION to [0.16.30](https://forums.factorio.com/58649) 905 | --- 906 | * **2018-03-05** 907 | * Bump experimental VERSION to [0.16.28](https://forums.factorio.com/58417) 908 | --- 909 | * **2018-02-28:** 910 | * Bump experimental VERSION to [0.16.27](https://forums.factorio.com/58281) 911 | --- 912 | * **2018-02-26:** 913 | * Bump experimental VERSION to [0.16.26](https://forums.factorio.com/58199) 914 | --- 915 | * **2018-02-19:** 916 | * Bump experimental VERSION to [0.16.25](https://forums.factorio.com/57993) 917 | --- 918 | * **2018-02-15:** 919 | * Bump experimental VERSION to [0.16.24](https://forums.factorio.com/57846) 920 | --- 921 | * **2018-02-12:** 922 | * Bump experimental VERSION to [0.16.23](https://forums.factorio.com/57752) 923 | --- 924 | * **2018-02-02:** 925 | * Bump experimental VERSION to [0.16.22](https://forums.factorio.com/57402) 926 | --- 927 | * **2018-02-01:** 928 | * Bump experimental VERSION to [0.16.21](https://forums.factorio.com/57372) 929 | --- 930 | * **2018-01-26:** 931 | * Bump experimental VERSION to [0.16.20](https://forums.factorio.com/57181) 932 | --- 933 | * **2018-01-25:** 934 | * Bump experimental VERSION to [0.16.19](https://forums.factorio.com/57117) 935 | --- 936 | * **2018-01-23:** 937 | * Bump experimental VERSION to [0.16.18](https://forums.factorio.com/56998) 938 | --- 939 | * **2018-01-22:** 940 | * Bump experimental VERSION to [0.16.17](https://forums.factorio.com/56919) 941 | --- 942 | * **2018-01-10:** 943 | * Bump experimental VERSION to [0.16.16](https://forums.factorio.com/56444) 944 | --- 945 | * **2018-01-05:** 946 | * Bump experimental VERSION to [0.16.15](https://forums.factorio.com/56222) 947 | * Update README.md formatting and wording 948 | --- 949 | * **2018-01-04:** 950 | * Bump experimental VERSION to [0.16.14](https://forums.factorio.com/56182) 951 | --- 952 | * **2018-01-03:** 953 | * Bump experimental VERSION to [0.16.13](https://forums.factorio.com/56126) 954 | --- 955 | * **2017-12-31:** 956 | * Bump experimental VERSION to [0.16.12](https://forums.factorio.com/55966) 957 | --- 958 | * **2017-12-30:** 959 | * Bump experimental VERSION to [0.16.11](https://forums.factorio.com/55929) 960 | --- 961 | * **2017-12-30:** 962 | * Bump experimental VERSION to [0.16.10](https://forums.factorio.com/55905) 963 | --- 964 | * **2017-12-21:** 965 | * Bump experimental VERSION to [0.16.7](https://forums.factorio.com/55505) 966 | --- 967 | * **2017-12-18:** 968 | * Bump experimental VERSION to [0.16.6](https://forums.factorio.com/55316) 969 | --- 970 | * **2017-12-17:** 971 | * Bump experimental VERSION to [0.16.5](https://forums.factorio.com/55165) 972 | --- 973 | * **2017-12-16:** 974 | * Bump experimental VERSION to [0.16.4](https://forums.factorio.com/55030) 975 | --- 976 | * **2017-12-15:** 977 | * Bump experimental VERSION to [0.16.3](https://forums.factorio.com/54890) 978 | --- 979 | * **2017-12-14:** 980 | * Bump experimental VERSION to [0.16.2](https://forums.factorio.com/54754) 981 | --- 982 | * **2017-12-13:** 983 | * Bump experimental VERSION to [0.16.0](https://forums.factorio.com/54538) 984 | --- 985 | * **2017-12-04:** 986 | * Bump stable VERSION to [0.15.40](https://forums.factorio.com/54307) 987 | * Tag release-0.15.40 988 | --- 989 | * **2017-11-30:** 990 | * Bump experimental VERSION to [0.15.40](https://forums.factorio.com/54307) 991 | --- 992 | * **2017-11-27:** 993 | * Bump experimental VERSION to [0.15.39](https://forums.factorio.com/54257) 994 | --- 995 | * **2017-11-24:** 996 | * Bump experimental VERSION to [0.15.38](https://forums.factorio.com/54181) 997 | --- 998 | * **2017-10-23:** 999 | * Add GitHub docs folder 1000 | * Move CONTRIBUTING.md from root 1001 | * Create ISSUE_TEMPLATE.md 1002 | * Create PULL_REQUEST_TEMPLATE.md 1003 | * Update .dockerignore to exclude docs folder 1004 | --- 1005 | * **2017-10-17:** 1006 | * Bump stable VERSION to [0.15.37](https://forums.factorio.com/53453) 1007 | * Bump experimental VERSION to [0.15.37](https://forums.factorio.com/53453) 1008 | * Tag release-0.15.37 1009 | --- 1010 | * **2017-10-10:** 1011 | * Bump experimental VERSION to [0.15.36](https://forums.factorio.com/53280) 1012 | --- 1013 | * **2017-09-28:** 1014 | * Bump experimental VERSION to [0.15.35](https://forums.factorio.com/53019) 1015 | * Rename factorio-init to docker-entrypoint.sh, move to root/usr/local/bin 1016 | * Remove factorio.crt 1017 | * docker-entrypoint.sh changes: 1018 | * Change functionality to run application as limited user for security 1019 | * Add variables for changing baked-in factorio user/group UID/GID, FACTORIO_GID, FACTORIO_UID 1020 | * Add functionality to ensure correct file permissions/ownership for data, mods, configs, etc. 1021 | * Add variable RUNAS_UID0 to allow to revert to running as root/UID=0 if needed 1022 | * Add termination signal handling and shutdown routine 1023 | * Functionize logging stamper 1024 | * Add support for running container with non-default CMD 1025 | * Dockerfile changes: 1026 | * Change WORKDIR to /opt/factorio 1027 | * Add FACTORIO_GID=999 and FACTORIO_UID=999 defaults 1028 | * Add RUNAS_UID0=false default 1029 | * Switch to COPY root folder instead of individual files 1030 | * Add "set -x" and reformat RUN section for clarity 1031 | * Add packages shadow & su-exec to support running as non-UID=0 user 1032 | * Add -C /opt to tar to force extract of factorio folder to correct location 1033 | * Create volume folders via bash to ensure they're chowned to container factorio UID/GID 1034 | * Add 'chown -R factorio:factorio /opt/factorio' 1035 | * Change ENTRYPOINT to use renamed docker-entrypoint.sh 1036 | * Add CMD "factorio" to set default docker-entrypoint.sh action 1037 | * docker-compose.yml moved to examples folder, updated to remove init and switch back to version 2 1038 | * README.md updates to document new variables and functionality 1039 | --- 1040 | * **2017-08-23:** 1041 | * Bump stable VERSION to [0.15.34](https://forums.factorio.com/52108) 1042 | * Devs silently moved this from experimental to stable, not sure of exact date 1043 | * Tag release-0.15.34 1044 | --- 1045 | * **2017-08-23:** 1046 | * Change experimental VERSION to [0.15.34](https://forums.factorio.com/52108) 1047 | * Add docker-compose.yml example 1048 | * Update documentation to recommend use of --init flag for container run/term signal handling 1049 | * Update Makefiles to use --init flag for "make start" 1050 | --- 1051 | * **2017-08-15:** 1052 | * Where possible switched from 2 spaces to 4 spaces for indent, readability. 1053 | * Add clean process to Makefiles 1054 | --- 1055 | * **2017-08-15:** 1056 | * Update stable VERSION to Factorio [v0.15.33](https://forums.factorio.com/51695) 1057 | * Tagged release-0.15.33 1058 | * Change to Makefiles for local builds. Automates injecting build args including VERSION 1059 | * Add hooks/build script for Docker Hub automated labels 1060 | * Rename factorio_launch.sh to factorio-init 1061 | * Change Dockerfile to support build args and labels 1062 | * Switch Dockerfile to start factorio-init via entrypoint 1063 | * Change Dockerfile to support ENV/-e flags at build and run 1064 | * Change factorio-init to support ENV/-e flags at build and run 1065 | * Move changelog to CHANGELOG.md file 1066 | * Update README.md 1067 | --- 1068 | * **2018-08-09:** 1069 | * Updated experimental tag to Factorio [v0.15.33](https://forums.factorio.com/51695) 1070 | --- 1071 | * **2017-08-06:** 1072 | * Updated factorio_launch.sh to use RCON.pwd file in `/opt/factorio/config` 1073 | * If `/opt/factorio/config/RCON.pwd' is not found a random password will be generated and saved in it 1074 | * All versions remain unchanged, no other changes of note 1075 | --- 1076 | * **2017-08-02:** 1077 | * Rename "unstable" tag to "experimental" 1078 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | -include *.mk 2 | 3 | 4 | 5 | SUBDIRS := $(wildcard */.) 6 | SUBDIRS := $(SUBDIRS:%/.=%) 7 | 8 | 9 | 10 | .PHONY: latest $(SUBDIRS) 11 | 12 | 13 | latest: 14 | ${MAKE} -C stable TAG=latest 15 | 16 | $(SUBDIRS): 17 | ${MAKE} -C ${MAKECMDGOALS} 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Containerized Factorio Headless Server 2 | 3 | [![Latest Build Status](https://github.com/goofball222/factorio/actions/workflows/build-latest.yml/badge.svg)](https://github.com/goofball222/factorio/actions/workflows/build-latest.yml) [![Docker Pulls](https://img.shields.io/docker/pulls/goofball222/factorio.svg)](https://hub.docker.com/r/goofball222/factorio/) [![Docker Stars](https://img.shields.io/docker/stars/goofball222/factorio.svg)](https://hub.docker.com/r/goofball222/factorio/) [![License](https://img.shields.io/github/license/goofball222/factorio.svg)](https://github.com/goofball222/factorio) 4 | 5 | | Docker Tag | Factorio Version | Description | Release Date | 6 | | --- | :---: | --- | :---: | 7 | | [latest, stable](https://github.com/goofball222/factorio/blob/main/stable/Dockerfile) | [2.0.55](https://forums.factorio.com/129196) | Factorio headless server stable release | 2025-06-02 | 8 | | [experimental](https://github.com/goofball222/factorio/blob/main/experimental/Dockerfile) | [2.0.55](https://forums.factorio.com/129196) | Factorio headless server experimental release | 2025-06-02 | 9 | | [2.0.55](https://github.com/goofball222/factorio/releases/tag/2.0.30) | [2.0.55](https://forums.factorio.com/129196) | Factorio headless server stable static release | 2025-06-02 | 10 | 11 | --- 12 | 13 | * [Recent changes, see: GitHub CHANGELOG.md](https://github.com/goofball222/factorio/blob/main/CHANGELOG.md) 14 | * [Report any bugs, issues or feature requests on GitHub](https://github.com/goofball222/factorio/issues) 15 | 16 | --- 17 | 18 | For security/attack surface reduction the container is configured to run the Factorio headless server with an internal user & group `factorio` having a pre-set UID & GID of 999. 19 | The container will attempt to adjust permissions on mapped volumes and data to match before dropping privileges to start the Factorio server processes. 20 | If the container is being run with a different Docker --user setting permissions may need to be fixed manually. 21 | 22 | IE: `chown -R 999:999 factorio` 23 | 24 | A custom UID and GID can be configured for the container internal factorio user and group. For more information see the "Environment variables" section in this document. 25 | 26 | --- 27 | 28 | **Always stop the existing container and make a VERIFIED backup copy of your Factorio save data before installing newer images.** 29 | 30 | --- 31 | 32 | ## Usage 33 | 34 | **The container has a single volume `/factorio` with the following structure:** 35 | 36 | factorio 37 | |-- config 38 | | |-- map-gen-settings.json 39 | | |-- map-gen-settings.example.json 40 | | |-- map-settings.json 41 | | |-- map-settings.example.json 42 | | |-- RCON.pw 43 | | |-- server-adminlist.json 44 | | |-- server-banlist.json 45 | | |-- server-settings.json 46 | | `-- server-whitelist.json 47 | |-- mods 48 | | `-- mod.zip 49 | |-- saves 50 | | `-- save.zip 51 | `-- scenarios 52 | `-- scenario.zip 53 | 54 | **The container exposes two ports:** 55 | * `27015/tcp`: Factorio RCON port 56 | * `34197/udp`: Factorio default server port 57 | 58 | --- 59 | 60 | **The most basic way to run this container:** 61 | 62 | ```bash 63 | $ docker run --name factorio -d \ 64 | -p 34197:34197/udp \ 65 | goofball222/factorio 66 | ``` 67 | 68 | --- 69 | 70 | **Recommended: run via [Docker Compose](https://docs.docker.com/compose/):** 71 | 72 | Have the container store the config, mods, saves, and scenarios on a local file-system or in a specific, known data volume (recommended for persistence and troubleshooting) and expose the RCON port for admin: 73 | 74 | ```bash 75 | 76 | version: '3' 77 | 78 | services: 79 | factorio: 80 | image: goofball222/factorio 81 | container_name: factorio 82 | restart: unless-stopped 83 | ports: 84 | - "27015:27015" 85 | - "34197:34197/udp" 86 | volumes: 87 | - /etc/localtime:/etc/localtime:ro 88 | - .:/factorio 89 | environment: 90 | - TZ=UTC 91 | 92 | ``` 93 | 94 | [Example basic `docker-compose.yml` file](https://raw.githubusercontent.com/goofball222/factorio/main/examples/docker-compose.yml) 95 | 96 | --- 97 | 98 | **Logs are available directly from the running container, IE: "docker logs factorio"** 99 | 100 | --- 101 | 102 | **Environment variables:** 103 | 104 | | Variable | Default | Description | 105 | | :--- | :---: | --- | 106 | | `DEBUG` | ***false*** | Set to *true* for extra container verbosity for debugging | 107 | | `FACTORIO_OPTS` | ***unset*** | Add custom command line options to factorio server executable at runtime | 108 | | `FACTORIO_PORT` | ***unset*** | Override server default port for game client connections | 109 | | `FACTORIO_RCON_PASSWORD` | ***unset*** | Specify the server RCON password | 110 | | `FACTORIO_RCON_PORT` | ***27015*** | Specifies the server RCON admin port | 111 | | `FACTORIO_SCENARIO` | ***unset*** | Specifies a scenario name for the server to run | 112 | | `PGID` | ***999*** | Specifies the GID for the container internal factorio group (used for file ownership) | 113 | | `PUID` | ***999*** | Specifies the UID for the container internal factorio user (used for process and file ownership) | 114 | | `RUN_CHOWN` | ***true*** | Set to *false* to disable the container automatic `chown` at startup. Speeds up startup process on overlay2 Docker hosts. **NB/IMPORTANT:** It's critical that you insure directory/data permissions on all mapped volumes are correct before disabling this or Factorio will not start. | 115 | | `RUNAS_UID0` | ***false*** | Set to *true* to force the container to run the Factorio server process as UID=0 (root) - **NB/IMPORTANT:** running with this set to "true" is insecure | 116 | 117 | --- 118 | 119 | During the first launch of the container the server-settings.json and map-gen-settings.json config files will be populated with the Factorio sample/defaults if they don't already exist. It is highly recommended to edit these files and relaunch the container afterwards or provide pre-setup copies in the config directory prior to first launch. The config sample files are available in the headless server tar.gz file in the "data" folder. The container will also generate a default map / save.zip in the saves folder if one is not found on launch. 120 | 121 | The RCON password can be set via the FACTORIO_RCON_PASSWORD ENV flag or loaded from `/factorio/config/RCON.pwd` each time the container is started. If the FACTORIO_RCON_PASSWORD ENV var is not set or the RCON.pwd file is not present a random RCON password will be generated and saved in `/factorio/config/RCON.pwd`. The active RCON password can also be found at the start of the container log file at each launch. 122 | 123 | --- 124 | 125 | ## Optional config examples 126 | 127 | `config/server-whitelist.json` - **if present only the configured Factorio users will be allowed access** 128 | 129 | [ 130 | "user1", 131 | "user2", 132 | "user3" 133 | ] 134 | 135 | `config/server-banlist.json` - if present the configured Factorio user IDs will be denied access 136 | 137 | [ 138 | "banneduser1", 139 | "banneduser2", 140 | "banneduser3", 141 | "banneduser4" 142 | ] 143 | 144 | `config/server-adminlist.json` - if present the configured Factorio user IDs will have admin access 145 | 146 | [ 147 | "adminuser1", 148 | "adminuser2" 149 | ] 150 | 151 | [//]: # (Licensed under the Apache 2.0 license) 152 | [//]: # (Copyright 2019 The Goofball - goofball222@gmail.com) 153 | -------------------------------------------------------------------------------- /docs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Code Changes 2 | 3 | * Make sure you have a [GitHub account](https://github.com/signup/free) 4 | * Submit an issue for your request, assuming one does not already exist. 5 | * Clearly describe the issue including steps to reproduce when it is a bug. 6 | * Make sure you fill in the earliest version that you know has the issue. 7 | * Fork the repository on GitHub 8 | 9 | ## Making Changes 10 | 11 | * Create a topic branch from where you want to base your work. 12 | * This is usually the master branch. 13 | * Only target release branches if you are certain your fix must be on that 14 | branch. 15 | * To quickly create a topic branch based on master; `git checkout -b 16 | fix/master/my_contribution master`. Please avoid working directly on the 17 | `master` branch. 18 | * Make commits of logical units. 19 | * Check for unnecessary whitespace with `git diff --check` before committing. 20 | * Make sure your commit messages are in the proper format. 21 | 22 | ```` 23 | (#1234) Make the example in CONTRIBUTING imperative and concrete 24 | 25 | Without this patch applied the example commit message in the CONTRIBUTING 26 | document is not a concrete example. This is a problem because the 27 | contributor is left to imagine what the commit message should look like 28 | based on a description rather than an example. This patch fixes the 29 | problem by making the example concrete and imperative. 30 | 31 | The first line is a real life imperative statement with a issue number 32 | from GitHub. The body describes the behavior without the patch, why 33 | this is a problem, and how the patch fixes the problem when applied. 34 | ```` 35 | 36 | * Build and run the container with your proposed changes to insure nothing else 37 | was accidentally broken. 38 | 39 | ## Making Trivial Changes 40 | 41 | ### Documentation 42 | 43 | For changes of a trivial nature to comments and documentation, it is not 44 | always necessary to create a new issue. In this case, it is 45 | appropriate to start the first line of a commit with '(doc)' instead of 46 | a ticket number. 47 | 48 | ```` 49 | (doc) Add documentation commit example to CONTRIBUTING 50 | 51 | There is no example for contributing a documentation commit 52 | to the goofball222/factorio repository. This is a problem because 53 | the contributor is left to assume how a commit of this nature 54 | may appear. 55 | 56 | The first line is a real life imperative statement with '(doc)' in 57 | place of what would have been the ticket number in a 58 | non-documentation related commit. The body describes the nature of 59 | the new documentation or comments added. 60 | ```` 61 | 62 | ## Submitting Changes 63 | 64 | * Push your changes to a topic branch in your fork of the repository. 65 | * Submit a pull request to the repository. 66 | * Maintainers will review and provide feedback on the pull request within two weeks. 67 | * After feedback has been given we expect responses within two weeks. After two 68 | weeks we may close the pull request if it isn't showing any activity. 69 | 70 | ## Revert Policy 71 | If the code change results in a failure, we will make our best effort to 72 | correct the error. If a fix cannot be determined and committed within 24 hours 73 | of its discovery, the commit(s) responsible _may_ be reverted, at the 74 | discretion of the committer and maintainers. This action would be taken 75 | to help maintain passing states in the Docker hub builds. 76 | 77 | The original contributor will be notified of the revert in the GitHub issue 78 | or pull request associated with the change. A reference to the failure/error 79 | from Docker hub as a result of the code change will also be added to the 80 | comments. 81 | 82 | 83 | -------------------------------------------------------------------------------- /docs/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Reporting bugs/issues 2 | 3 | * When reporting a bug/issue: 4 | * Ensure that you are using the latest release. 5 | * Revert any custom modifications or environment varibles to insure they're not the cause. 6 | 7 | * Please provide the following information: 8 | * OS/distribution version (command for your OS may differ): 9 | IE: 10 | ```bash 11 | user@host:~$ lsb_release -a 12 | No LSB modules are available. 13 | Distributor ID: Ubuntu 14 | Description: Ubuntu 16.04.3 LTS 15 | Release: 16.04 16 | Codename: xenial 17 | ``` 18 | 19 | * Docker version: 20 | IE: 21 | ```bash 22 | user@host:~$ docker --version 23 | Docker version 17.05.0-ce, build 89658be 24 | ``` 25 | 26 | * Labels from container: 27 | IE: 28 | ```bash 29 | user@host:~$ docker inspect goofball222/factorio:latest 30 | ... 31 | "Labels": { 32 | "org.label-schema.build-date": "2017-10-17T18:24:31Z", 33 | "org.label-schema.license": "Apache-2.0", 34 | "org.label-schema.name": "Factorio Headless Server", 35 | "org.label-schema.schema-version": "1.0", 36 | "org.label-schema.url": "https://github.com/goofball222/factorio", 37 | "org.label-schema.vcs-ref": "003adec", 38 | "org.label-schema.vcs-url": "https://github.com/goofball222/factorio.git", 39 | "org.label-schema.vendor": "goofball222", 40 | "org.label-schema.version": "0.15.37" 41 | } 42 | ... 43 | ``` 44 | 45 | * Details on how to reproduce the trouble, if available: 46 | -------------------------------------------------------------------------------- /docs/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes # . 2 | 3 | Changes proposed in this pull request: 4 | - 5 | - 6 | - 7 | 8 | @goofball222 9 | -------------------------------------------------------------------------------- /examples/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | factorio: 5 | image: goofball222/factorio 6 | container_name: factorio 7 | restart: unless-stopped 8 | ports: 9 | - "27015:27015" 10 | - "34197:34197/udp" 11 | volumes: 12 | - /etc/localtime:/etc/localtime:ro 13 | - .:/factorio 14 | environment: 15 | - TZ=UTC 16 | -------------------------------------------------------------------------------- /experimental/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bookworm-slim 2 | 3 | ARG BUILD_DATE 4 | ARG VCS_REF 5 | ARG VERSION 6 | 7 | LABEL \ 8 | org.opencontainers.image.vendor="The Goofball - goofball222@gmail.com" \ 9 | org.opencontainers.image.url="https://github.com/goofball222/factorio" \ 10 | org.opencontainers.image.title="Factiorio Headless Server" \ 11 | org.opencontainers.image.description="Factiorio Headless Server" \ 12 | org.opencontainers.image.version=$VERSION \ 13 | org.opencontainers.image.source="https://github.com/goofball222/factorio" \ 14 | org.opencontainers.image.revision=$VCS_REF \ 15 | org.opencontainers.image.created=$BUILD_DATE \ 16 | org.opencontainers.image.licenses="Apache-2.0" 17 | 18 | ENV \ 19 | DEBIAN_FRONTEND=noninteractive \ 20 | DEBUG=false \ 21 | PGID=999 \ 22 | PUID=999 \ 23 | RUN_CHOWN=true \ 24 | RUNAS_UID0=false 25 | 26 | WORKDIR /opt/factorio 27 | 28 | COPY root / 29 | 30 | RUN \ 31 | set -x \ 32 | && groupadd -r factorio -g $PGID \ 33 | && useradd --no-log-init -r -u $PUID -g $PGID factorio \ 34 | && mkdir -p /usr/share/man/man1 \ 35 | && apt-get -qqy update \ 36 | && apt-get -qqy install apt-utils \ 37 | && apt-get -qqy --no-install-recommends install \ 38 | ca-certificates curl gosu procps xz-utils > /dev/null \ 39 | && curl -sSL https://www.factorio.com/get-download/$VERSION/headless/linux64 -o /tmp/factorio_headless_x64_$VERSION.tar.xz \ 40 | && tar -xJf /tmp/factorio_headless_x64_$VERSION.tar.xz -C /opt \ 41 | && bash -c 'mkdir -p {/factorio,/factorio/config,/factorio/mods,/factorio/saves,/factorio/scenarios}' \ 42 | && ln -s /factorio/config /opt/factorio/config \ 43 | && ln -s /factorio/mods /opt/factorio/mods \ 44 | && ln -s /factorio/saves /opt/factorio/saves \ 45 | && ln -s /factorio/scenarios /opt/factorio/scenarios \ 46 | && apt-get -qqy purge \ 47 | apt-utils ca-certificates curl xz-utils > /dev/null \ 48 | && chown -R factorio:factorio /opt/factorio /factorio \ 49 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /var/log/* 50 | 51 | EXPOSE 34197/udp 27015/tcp 52 | 53 | VOLUME ["/factorio"] 54 | 55 | ENTRYPOINT ["docker-entrypoint.sh"] 56 | 57 | CMD ["factorio"] 58 | -------------------------------------------------------------------------------- /experimental/Dockerfile.alpine: -------------------------------------------------------------------------------- 1 | FROM frolvlad/alpine-glibc:latest 2 | 3 | ARG BUILD_DATE 4 | ARG VCS_REF 5 | ARG VERSION 6 | 7 | LABEL \ 8 | org.opencontainers.image.vendor="The Goofball - goofball222@gmail.com" \ 9 | org.opencontainers.image.url="https://github.com/goofball222/factorio" \ 10 | org.opencontainers.image.title="Factiorio Headless Server" \ 11 | org.opencontainers.image.description="Factiorio Headless Server" \ 12 | org.opencontainers.image.version=$VERSION \ 13 | org.opencontainers.image.source="https://github.com/goofball222/factorio" \ 14 | org.opencontainers.image.revision=$VCS_REF \ 15 | org.opencontainers.image.created=$BUILD_DATE \ 16 | org.opencontainers.image.licenses="Apache-2.0" 17 | 18 | ENV \ 19 | DEBUG=false \ 20 | PGID=999 \ 21 | PUID=999 \ 22 | RUN_CHOWN=true \ 23 | RUNAS_UID0=false 24 | 25 | WORKDIR /opt/factorio 26 | 27 | COPY root / 28 | 29 | RUN \ 30 | set -x \ 31 | && delgroup ping \ 32 | && addgroup -g $PGID factorio \ 33 | && adduser -D -G factorio -u $PUID factorio \ 34 | && apk add -q --no-cache --virtual .build-deps \ 35 | curl \ 36 | && apk add -q --no-cache \ 37 | bash coreutils shadow su-exec tzdata \ 38 | && curl -sSL https://www.factorio.com/get-download/$VERSION/headless/linux64 -o /tmp/factorio_headless_x64_$VERSION.tar.xz \ 39 | && tar -xJf /tmp/factorio_headless_x64_$VERSION.tar.xz -C /opt \ 40 | && bash -c 'mkdir -p {/factorio,/factorio/config,/factorio/mods,/factorio/saves,/factorio/scenarios}' \ 41 | && ln -s /factorio/config /opt/factorio/config \ 42 | && ln -s /factorio/mods /opt/factorio/mods \ 43 | && ln -s /factorio/saves /opt/factorio/saves \ 44 | && ln -s /factorio/scenarios /opt/factorio/scenarios \ 45 | && chown -R factorio:factorio /opt/factorio /factorio \ 46 | && apk del -q --purge .build-deps \ 47 | && rm -rf /tmp/* /var/cache/apk/* 48 | 49 | EXPOSE 34197/udp 27015/tcp 50 | 51 | VOLUME ["/factorio"] 52 | 53 | ENTRYPOINT ["docker-entrypoint.sh"] 54 | 55 | CMD ["factorio"] 56 | -------------------------------------------------------------------------------- /experimental/Makefile: -------------------------------------------------------------------------------- 1 | -include ../*.mk 2 | -include *.mk 3 | 4 | 5 | 6 | NS ?= goofball222 7 | 8 | IMAGE_NAME ?= factorio 9 | CONTAINER_NAME ?= factorio 10 | CONTAINER_INSTANCE ?= default 11 | 12 | VCS_REF := $(strip $(shell git rev-parse --short HEAD)) 13 | BUILD_DATE := $(strip $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")) 14 | VERSION := $(strip $(shell cat VERSION)) 15 | 16 | ifndef VERSION 17 | $(error You need to create a VERSION file to build a release) 18 | endif 19 | 20 | ifndef TAG 21 | TAG := $(notdir $(shell pwd)) 22 | endif 23 | 24 | 25 | 26 | .PHONY: build shell debug run start stop rm rmi test clean 27 | 28 | 29 | 30 | default: build 31 | 32 | 33 | 34 | build: 35 | docker build \ 36 | --build-arg VCS_REF=$(VCS_REF) \ 37 | --build-arg BUILD_DATE=$(BUILD_DATE) \ 38 | --build-arg VERSION=$(VERSION) \ 39 | -t $(NS)/$(IMAGE_NAME):$(TAG) . 40 | 41 | shell: 42 | -docker run -it --rm --name $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) $(PORTS) $(VOLUMES) $(OTHER) $(ENV) $(NS)/$(IMAGE_NAME):$(TAG) /bin/bash 43 | 44 | run: 45 | -docker run --rm --name $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) $(PORTS) $(VOLUMES) $(OTHER) $(ENV) $(NS)/$(IMAGE_NAME):$(TAG) 46 | 47 | start: 48 | -docker run -d --name $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) $(PORTS) $(VOLUMES) $(OTHER) $(ENV) $(NS)/$(IMAGE_NAME):$(TAG) 49 | 50 | stop: 51 | -docker stop $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) 52 | 53 | rm: 54 | -docker rm $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) 55 | 56 | rmi: 57 | -docker rmi $(NS)/$(IMAGE_NAME):$(TAG) 58 | 59 | test: 60 | @echo docker build \ 61 | --build-arg VCS_REF=$(VCS_REF) \ 62 | --build-arg BUILD_DATE=$(BUILD_DATE) \ 63 | --build-arg VERSION=$(VERSION) \ 64 | -t $(NS)/$(IMAGE_NAME):$(TAG) . 65 | 66 | clean: stop rm rmi 67 | -------------------------------------------------------------------------------- /experimental/VERSION: -------------------------------------------------------------------------------- 1 | 2.0.55 2 | -------------------------------------------------------------------------------- /experimental/hooks/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # $IMAGE_NAME var is injected into the build so the tag is correct. 4 | 5 | #echo "Build hook running" 6 | docker build \ 7 | --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ 8 | --build-arg VCS_REF=`git rev-parse --short HEAD` \ 9 | --build-arg VERSION=`cat VERSION` \ 10 | -f $DOCKERFILE_PATH -t $DOCKER_REPO:${DOCKER_TAG//,/ -t $DOCKER_REPO:} . 11 | -------------------------------------------------------------------------------- /experimental/root/usr/local/bin/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Init script for Factorio headless server Docker container 4 | # License: Apache-2.0 5 | # Github: https://github.com/goofball222/factorio 6 | SCRIPT_VERSION="1.4.1" 7 | # Last updated date: 2022-03-12 8 | 9 | set -Eeuo pipefail 10 | 11 | if [ "${DEBUG}" == 'true' ]; 12 | then 13 | set -x 14 | fi 15 | 16 | . /usr/local/bin/entrypoint-functions.sh 17 | 18 | BASEDIR="/opt/factorio" 19 | BINDIR=${BASEDIR}/bin 20 | DATADIR=${BASEDIR}/data 21 | CONFIGDIR=${BASEDIR}/config 22 | MODDIR=${BASEDIR}/mods 23 | SAVEDIR=${BASEDIR}/saves 24 | SCENARIODIR=${BASEDIR}/scenarios 25 | 26 | FACTORIO=${BINDIR}/x64/factorio 27 | 28 | VOLDIR=${VOLDIR:-"/factorio"} 29 | VOLCONFIGDIR=${VOLDIR}/config 30 | VOLMODDIR=${VOLDIR}/mods 31 | VOLSAVEDIR=${VOLDIR}/saves 32 | VOLSCENARIODIR=${VOLDIR}/scenarios 33 | 34 | f_log "INFO - Script version ${SCRIPT_VERSION}" 35 | f_log "INFO - Entrypoint functions version ${ENTRYPOINT_FUNCTIONS_VERSION}" 36 | 37 | cd ${BASEDIR} 38 | 39 | f_exit_handler() { 40 | f_log "INFO - Exit signal received, commencing shutdown" 41 | pkill -15 -f ${FACTORIO} 42 | for i in `seq 0 299`; 43 | do 44 | [ -z "$(pgrep -f ${FACTORIO})" ] && break 45 | # kill it with fire if it hasn't stopped itself after 5 minutes 46 | [ $i -gt 298 ] && pkill -9 -f ${FACTORIO} || true 47 | sleep 1 48 | done 49 | f_log "INFO - Shutdown complete. Nothing more to see here. Have a nice day!" 50 | f_log "INFO - Exit with status code ${?}" 51 | exit ${?}; 52 | } 53 | 54 | f_idle_handler() { 55 | while true 56 | do 57 | tail -f /dev/null & wait ${!} 58 | done 59 | } 60 | 61 | trap 'kill ${!}; f_exit_handler' SIGHUP SIGINT SIGQUIT SIGTERM 62 | 63 | if [ "$(id -u)" = '0' ]; then 64 | f_log "INFO - Entrypoint running with UID 0 (root)" 65 | if [[ "${@}" == 'factorio' ]]; then 66 | f_giduid 67 | f_chkdir 68 | f_chown 69 | f_setup 70 | if [ "${RUNAS_UID0}" == 'true' ]; then 71 | f_log "INFO - RUNAS_UID0 = 'true', running Factorio Headless as UID 0 (root)" 72 | f_log "WARN - ======================================================================" 73 | f_log "WARN - *** Running app as UID 0 (root) is an insecure configuration ***" 74 | f_log "WARN - ======================================================================" 75 | f_log "EXEC - ${FACTORIO} ${FACTORIO_OPTS}" 76 | exec 0<&- 77 | exec ${FACTORIO} ${FACTORIO_OPTS} & 78 | f_idle_handler 79 | else 80 | if [ -x "/sbin/su-exec" ]; then 81 | f_log "INFO - Use su-exec to drop priveleges and start Factorio Headless as GID=${PGID}, UID=${PUID}" 82 | f_log "EXEC - su-exec factorio:factorio ${FACTORIO} ${FACTORIO_OPTS}" 83 | exec 0<&- 84 | exec su-exec factorio:factorio ${FACTORIO} ${FACTORIO_OPTS} & 85 | f_idle_handler 86 | elif [ -x "/usr/sbin/gosu" ]; then 87 | f_log "INFO - Use gosu to drop privileges and start Factorio Headless as GID=${PGID}, UID=${PUID}" 88 | f_log "EXEC - gosu factorio:factorio ${FACTORIO} ${FACTORIO_OPTS}" 89 | exec 0<&- 90 | exec gosu factorio:factorio ${FACTORIO} ${FACTORIO_OPTS} & 91 | f_idle_handler 92 | else 93 | f_log "ERROR - su-exec/gosu NOT FOUND. Run state is invalid. Exiting." 94 | exit 1; 95 | fi 96 | fi 97 | else 98 | f_log "EXEC - ${@} as UID 0 (root)" 99 | exec "${@}" 100 | fi 101 | else 102 | f_log "WARN - Container/entrypoint not started as UID 0 (root)" 103 | f_log "WARN - Unable to change permissions or set custom GID/UID if configured" 104 | f_log "WARN - Process will be spawned with GID=$(id -g), PID=$(id -u)" 105 | f_log "WARN - Depending on permissions requested command may not work" 106 | if [[ "${@}" == 'factorio' ]]; then 107 | f_chkdir 108 | f_setup 109 | f_log "EXEC - ${FACTORIO} ${FACTORIO_OPTS}" 110 | exec 0<&- 111 | exec ${FACTORIO} ${FACTORIO_OPTS} & 112 | f_idle_handler 113 | else 114 | f_log "EXEC - ${@}" 115 | exec "${@}" 116 | fi 117 | fi 118 | 119 | # Script should never make it here, but just in case exit with a generic error code if it does 120 | exit 1; 121 | -------------------------------------------------------------------------------- /experimental/root/usr/local/bin/entrypoint-functions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # entrypoint-functions.sh script for Factorio headless server Docker container 4 | # License: Apache-2.0 5 | # Github: https://github.com/goofball222/factorio 6 | ENTRYPOINT_FUNCTIONS_VERSION="1.1.0" 7 | # Last updated date: 2021-06-17 8 | 9 | f_chkdir() { 10 | # Make sure required directories exist in ${VOLDIR} - IE: new install with empty volume on host mapped over default volume 11 | [ -d ${VOLDIR}/config ] || mkdir -p ${VOLDIR}/config 12 | [ -d ${VOLDIR}/mods ] || mkdir -p ${VOLDIR}/mods 13 | [ -d ${VOLDIR}/saves ] || mkdir -p ${VOLDIR}/saves 14 | [ -d ${VOLDIR}/scenarios ] || mkdir -p ${VOLDIR}/scenarios 15 | } 16 | 17 | f_chown() { 18 | if [ "${RUN_CHOWN}" == 'false' ]; then 19 | if [ ! "$(stat -c %u ${BASEDIR})" = "${PUID}" ] || [ ! "$(stat -c %u ${VOLDIR})" = "${PUID}" ] \ 20 | || [ ! "$(stat -c %u ${VOLCONFIGDIR})" = "${PUID}" ] || [ ! "$(stat -c %u ${DATADIR})" = "${PUID}" ] \ 21 | || [ ! "$(stat -c %u ${VOLMODDIR})" = "${PUID}" ] || [ ! "$(stat -c %u ${VOLSAVEDIR})" = "${PUID}" ] \ 22 | || [ ! "$(stat -c %u ${VOLSCENARIODIR})" = "${PUID}" ]; then 23 | f_log "WARN - Configured PUID doesn't match owner of a required directory. Ignoring RUN_CHOWN=false" 24 | f_log "INFO - Ensuring permissions are correct before continuing - 'chown -R factorio:factorio ${BASEDIR} ${VOLDIR}'" 25 | f_log "INFO - Running recursive 'chown' on Docker overlay2 storage is **really** slow. This may take a bit." 26 | chown -R factorio:factorio ${BASEDIR} ${VOLDIR} 27 | else 28 | f_log "INFO - RUN_CHOWN set to 'false' - Not running 'chown -R factorio:factorio ${BASEDIR}', assume permissions are right." 29 | fi 30 | elif [ "${RUNAS_UID0}" == 'true' ]; then 31 | f_log "INFO - RUNAS_UID0=true - Not running 'chown -R factorio:factorio ${BASEDIR} ${VOLDIR}', no need to worry about permissions." 32 | else 33 | f_log "INFO - Ensuring permissions are correct before continuing - 'chown -R factorio:factorio ${BASEDIR}'" 34 | f_log "INFO - Running recursive 'chown' on Docker overlay2 storage is **really** slow. This may take a bit." 35 | chown -R factorio:factorio ${BASEDIR} ${VOLDIR} 36 | fi 37 | } 38 | 39 | f_giduid() { 40 | FACTORIO_GID=${FACTORIO_GID:-} 41 | FACTORIO_UID=${FACTORIO_UID:-} 42 | if [ ! -z "${FACTORIO_GID}" ]; then 43 | f_log "INFO - FACTORIO_GID is set. Please use the updated PGID variable. Automatically converting to PGID." 44 | PGID=${FACTORIO_GID} 45 | fi 46 | if [ ! -z "${FACTORIO_UID}" ]; then 47 | f_log "INFO - FACTORIO_UID is set. Please use the updated PUID variable. Automatically converting to PUID." 48 | PUID=${FACTORIO_UID} 49 | fi 50 | if [ "$(id factorio -g)" != "${PGID}" ] || [ "$(id factorio -u)" != "${PUID}" ]; then 51 | f_log "INFO - Setting custom factorio GID/UID: GID=${PGID}, UID=${PUID}" 52 | groupmod -o -g ${PGID} factorio 53 | usermod -o -u ${PUID} factorio 54 | else 55 | f_log "INFO - GID/UID for factorio are unchanged: GID=${PGID}, UID=${PUID}" 56 | fi 57 | } 58 | 59 | f_load_save() { 60 | # We avoid using --start-server-load-latest here, as the latest save might not be the desired one 61 | # Ex: If you change from scenario to default gameplay but forgot to delete scenario.zip it would be loaded instead of save.zip 62 | FACTORIO_OPTS="${FACTORIO_OPTS} --start-server ${SAVE_NAME} --server-settings ${CONFIGDIR}/server-settings.json --server-id ${CONFIGDIR}/server-id.json" 63 | } 64 | 65 | f_log() { 66 | echo "$(date +"[%Y-%m-%d %T,%3N]") $*" 67 | } 68 | 69 | f_setup() { 70 | FACTORIO_OPTS="${FACTORIO_OPTS:-}" 71 | FACTORIO_PORT=${FACTORIO_PORT:-} 72 | FACTORIO_RCON_PASSWORD=${FACTORIO_RCON_PASSWORD:-} 73 | FACTORIO_RCON_PORT=${FACTORIO_RCON_PORT:-27015} 74 | FACTORIO_SCENARIO=${FACTORIO_SCENARIO:-} 75 | if [ ! -z "${FACTORIO_PORT}" ]; then 76 | FACTORIO_OPTS="${FACTORIO_OPTS} --port ${FACTORIO_PORT}" 77 | fi 78 | 79 | f_log "INFO - Remove any incomplete *.tmp.zip from crash/forced exit in ${SAVEDIR}" 80 | rm -f ${SAVEDIR}/*.tmp.zip 81 | 82 | if [ ! -z "${FACTORIO_RCON_PASSWORD}" ]; then 83 | f_log "INFO - Using RCON password found in ENV" 84 | FACTORIO_RCON_PASSWORD=${FACTORIO_RCON_PASSWORD} 85 | else 86 | # Check for RCON password file, generate random and set if doesn't exist 87 | if [ ! -f "${CONFIGDIR}/RCON.pwd" ]; then 88 | f_log "INFO - No RCON.pwd found in ${CONFIGDIR}, generating random" 89 | set +o pipefail 90 | FACTORIO_RCON_PASSWORD=$(cat /dev/urandom | tr -dc 'a-f0-9' | head -c16) 91 | set -o pipefail 92 | echo "${FACTORIO_RCON_PASSWORD}" > "${CONFIGDIR}/RCON.pwd" 93 | chown factorio:factorio ${CONFIGDIR}/RCON.pwd 94 | else 95 | f_log "INFO - Using existing RCON.pwd found in ${CONFIGDIR}" 96 | FACTORIO_RCON_PASSWORD=$(cat ${CONFIGDIR}/RCON.pwd) 97 | fi 98 | fi 99 | 100 | f_log "INFO - RCON password is '${FACTORIO_RCON_PASSWORD}'" 101 | FACTORIO_OPTS="${FACTORIO_OPTS} --rcon-port=${FACTORIO_RCON_PORT} --rcon-password ${FACTORIO_RCON_PASSWORD}" 102 | 103 | # Copy example configs to CONFIGDIR 104 | cp -p ${DATADIR}/server-settings.example.json ${CONFIGDIR}/server-settings.example.json 105 | f_log "INFO - Copied latest server-settings.example.json to ${CONFIGDIR}" 106 | cp -p ${DATADIR}/map-gen-settings.example.json ${CONFIGDIR}/map-gen-settings.example.json 107 | f_log "INFO - Copied latest map-gen-settings.example.json to ${CONFIGDIR}" 108 | 109 | # Copy example configs to working configuration if they don't exist 110 | if [ ! -f "${CONFIGDIR}/server-settings.json" ]; then 111 | f_log "WARN - No server-settings.json found in ${CONFIGDIR}, copying from example" 112 | cp -p ${DATADIR}/server-settings.example.json ${CONFIGDIR}/server-settings.json 113 | else 114 | f_log "INFO - Using existing server-settings.json found in ${CONFIGDIR}" 115 | fi 116 | 117 | if [ ! -f "${CONFIGDIR}/map-gen-settings.json" ]; then 118 | f_log "WARN - No map-gen-settings.json found in ${CONFIGDIR}, copying from example" 119 | cp -p ${DATADIR}/map-gen-settings.example.json ${CONFIGDIR}/map-gen-settings.json 120 | else 121 | f_log "INFO - Using existing map-gen-settings.json found in ${CONFIGDIR}" 122 | fi 123 | 124 | # Check for banlist file in config dir, set launch options to use if found 125 | if [ ! -f "${CONFIGDIR}/server-banlist.json" ]; then 126 | f_log "INFO - No server-banlist.json found in ${CONFIGDIR}, ignoring" 127 | else 128 | f_log "INFO - Using server-banlist.json found in ${CONFIGDIR}" 129 | FACTORIO_OPTS="${FACTORIO_OPTS} --server-banlist ${CONFIGDIR}/server-banlist.json" 130 | fi 131 | 132 | # Check for whitelist file in config dir, set launch options to use if found 133 | if [ ! -f "${CONFIGDIR}/server-whitelist.json" ]; then 134 | f_log "INFO - No server-whitelist.json found in ${CONFIGDIR}, ignoring" 135 | else 136 | f_log "INFO - Using server-whitelist.json found in ${CONFIGDIR}" 137 | FACTORIO_OPTS="${FACTORIO_OPTS} --server-whitelist ${CONFIGDIR}/server-whitelist.json --use-server-whitelist" 138 | fi 139 | 140 | # Check for admin list file in config dir, set launch options to use if found 141 | if [ ! -f "${CONFIGDIR}/server-adminlist.json" ]; then 142 | f_log "INFO - No server-adminlist.json found in ${CONFIGDIR}, ignoring" 143 | else 144 | f_log "INFO - Using server-adminlist.json found in ${CONFIGDIR}" 145 | FACTORIO_OPTS="${FACTORIO_OPTS} --server-adminlist ${CONFIGDIR}/server-adminlist.json" 146 | fi 147 | 148 | # Choose save file name. Scenario saves are named as the scenario itself. 149 | if [ ! -z "${FACTORIO_SCENARIO}" ]; then 150 | SAVE_NAME="${FACTORIO_SCENARIO}" 151 | else 152 | SAVE_NAME="save" 153 | fi 154 | 155 | # Check for existing save file, use if found. Generate new with settings if not. 156 | if [ ! -f "${SAVEDIR}/${SAVE_NAME}.zip" ]; then 157 | f_log "WARN - No ${SAVE_NAME}.zip found in ${SAVEDIR}" 158 | f_log "INFO - Creating new map / ${SAVE_NAME}.zip in ${SAVEDIR} with settings from ${CONFIGDIR}/map-gen-settings.json" 159 | if [ ! -z "${FACTORIO_SCENARIO}" ]; then 160 | FACTORIO_OPTS="${FACTORIO_OPTS} --start-server-load-scenario ${FACTORIO_SCENARIO} --server-settings ${CONFIGDIR}/server-settings.json --server-id ${CONFIGDIR}/server-id.json" 161 | else 162 | if [ -x "/sbin/su-exec" ]; then 163 | su-exec factorio:factorio ${FACTORIO} --create ${VOLSAVEDIR}/save.zip --map-gen-settings ${CONFIGDIR}/map-gen-settings.json 164 | f_load_save 165 | elif [ -x "/usr/sbin/gosu" ]; then 166 | gosu factorio:factorio ${FACTORIO} --create ${VOLSAVEDIR}/save.zip --map-gen-settings ${CONFIGDIR}/map-gen-settings.json 167 | f_load_save 168 | else 169 | f_log "ERROR - su-exec/gosu NOT FOUND. Run state is invalid. Exiting." 170 | exit 1; 171 | fi 172 | fi 173 | else 174 | f_log "INFO - Loading ${SAVE_NAME}.zip found in ${SAVEDIR}" 175 | f_load_save 176 | fi 177 | 178 | } 179 | -------------------------------------------------------------------------------- /stable/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bookworm-slim 2 | 3 | ARG BUILD_DATE 4 | ARG VCS_REF 5 | ARG VERSION 6 | 7 | LABEL \ 8 | org.opencontainers.image.vendor="The Goofball - goofball222@gmail.com" \ 9 | org.opencontainers.image.url="https://github.com/goofball222/factorio" \ 10 | org.opencontainers.image.title="Factiorio Headless Server" \ 11 | org.opencontainers.image.description="Factiorio Headless Server" \ 12 | org.opencontainers.image.version=$VERSION \ 13 | org.opencontainers.image.source="https://github.com/goofball222/factorio" \ 14 | org.opencontainers.image.revision=$VCS_REF \ 15 | org.opencontainers.image.created=$BUILD_DATE \ 16 | org.opencontainers.image.licenses="Apache-2.0" 17 | 18 | ENV \ 19 | DEBIAN_FRONTEND=noninteractive \ 20 | DEBUG=false \ 21 | PGID=999 \ 22 | PUID=999 \ 23 | RUN_CHOWN=true \ 24 | RUNAS_UID0=false 25 | 26 | WORKDIR /opt/factorio 27 | 28 | COPY root / 29 | 30 | RUN \ 31 | set -x \ 32 | && groupadd -r factorio -g $PGID \ 33 | && useradd --no-log-init -r -u $PUID -g $PGID factorio \ 34 | && mkdir -p /usr/share/man/man1 \ 35 | && apt-get -qqy update \ 36 | && apt-get -qqy install apt-utils \ 37 | && apt-get -qqy --no-install-recommends install \ 38 | ca-certificates curl gosu procps xz-utils > /dev/null \ 39 | && curl -sSL https://www.factorio.com/get-download/$VERSION/headless/linux64 -o /tmp/factorio_headless_x64_$VERSION.tar.xz \ 40 | && tar -xJf /tmp/factorio_headless_x64_$VERSION.tar.xz -C /opt \ 41 | && bash -c 'mkdir -p {/factorio,/factorio/config,/factorio/mods,/factorio/saves,/factorio/scenarios}' \ 42 | && ln -s /factorio/config /opt/factorio/config \ 43 | && ln -s /factorio/mods /opt/factorio/mods \ 44 | && ln -s /factorio/saves /opt/factorio/saves \ 45 | && ln -s /factorio/scenarios /opt/factorio/scenarios \ 46 | && apt-get -qqy purge \ 47 | apt-utils ca-certificates curl xz-utils > /dev/null \ 48 | && chown -R factorio:factorio /opt/factorio /factorio \ 49 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /var/log/* 50 | 51 | EXPOSE 34197/udp 27015/tcp 52 | 53 | VOLUME ["/factorio"] 54 | 55 | ENTRYPOINT ["docker-entrypoint.sh"] 56 | 57 | CMD ["factorio"] 58 | -------------------------------------------------------------------------------- /stable/Dockerfile.alpine: -------------------------------------------------------------------------------- 1 | FROM frolvlad/alpine-glibc:latest 2 | 3 | ARG BUILD_DATE 4 | ARG VCS_REF 5 | ARG VERSION 6 | 7 | LABEL \ 8 | org.opencontainers.image.vendor="The Goofball - goofball222@gmail.com" \ 9 | org.opencontainers.image.url="https://github.com/goofball222/factorio" \ 10 | org.opencontainers.image.title="Factiorio Headless Server" \ 11 | org.opencontainers.image.description="Factiorio Headless Server" \ 12 | org.opencontainers.image.version=$VERSION \ 13 | org.opencontainers.image.source="https://github.com/goofball222/factorio" \ 14 | org.opencontainers.image.revision=$VCS_REF \ 15 | org.opencontainers.image.created=$BUILD_DATE \ 16 | org.opencontainers.image.licenses="Apache-2.0" 17 | 18 | ENV \ 19 | DEBUG=false \ 20 | PGID=999 \ 21 | PUID=999 \ 22 | RUN_CHOWN=true \ 23 | RUNAS_UID0=false 24 | 25 | WORKDIR /opt/factorio 26 | 27 | COPY root / 28 | 29 | RUN \ 30 | set -x \ 31 | && delgroup ping \ 32 | && addgroup -g $PGID factorio \ 33 | && adduser -D -G factorio -u $PUID factorio \ 34 | && apk add -q --no-cache --virtual .build-deps \ 35 | curl \ 36 | && apk add -q --no-cache \ 37 | bash coreutils shadow su-exec tzdata \ 38 | && curl -sSL https://www.factorio.com/get-download/$VERSION/headless/linux64 -o /tmp/factorio_headless_x64_$VERSION.tar.xz \ 39 | && tar -xJf /tmp/factorio_headless_x64_$VERSION.tar.xz -C /opt \ 40 | && bash -c 'mkdir -p {/factorio,/factorio/config,/factorio/mods,/factorio/saves,/factorio/scenarios}' \ 41 | && ln -s /factorio/config /opt/factorio/config \ 42 | && ln -s /factorio/mods /opt/factorio/mods \ 43 | && ln -s /factorio/saves /opt/factorio/saves \ 44 | && ln -s /factorio/scenarios /opt/factorio/scenarios \ 45 | && chown -R factorio:factorio /opt/factorio /factorio \ 46 | && apk del -q --purge .build-deps \ 47 | && rm -rf /tmp/* /var/cache/apk/* 48 | 49 | EXPOSE 34197/udp 27015/tcp 50 | 51 | VOLUME ["/factorio"] 52 | 53 | ENTRYPOINT ["docker-entrypoint.sh"] 54 | 55 | CMD ["factorio"] 56 | -------------------------------------------------------------------------------- /stable/Makefile: -------------------------------------------------------------------------------- 1 | -include ../*.mk 2 | -include *.mk 3 | 4 | 5 | 6 | NS ?= goofball222 7 | 8 | IMAGE_NAME ?= factorio 9 | CONTAINER_NAME ?= factorio 10 | CONTAINER_INSTANCE ?= default 11 | 12 | VCS_REF := $(strip $(shell git rev-parse --short HEAD)) 13 | BUILD_DATE := $(strip $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")) 14 | VERSION := $(strip $(shell cat VERSION)) 15 | 16 | ifndef VERSION 17 | $(error You need to create a VERSION file to build a release) 18 | endif 19 | 20 | ifndef TAG 21 | TAG := $(notdir $(shell pwd)) 22 | endif 23 | 24 | 25 | 26 | .PHONY: build shell debug run start stop rm rmi test clean 27 | 28 | 29 | 30 | default: build 31 | 32 | 33 | 34 | build: 35 | docker build \ 36 | --build-arg VCS_REF=$(VCS_REF) \ 37 | --build-arg BUILD_DATE=$(BUILD_DATE) \ 38 | --build-arg VERSION=$(VERSION) \ 39 | -t $(NS)/$(IMAGE_NAME):$(TAG) . 40 | 41 | shell: 42 | -docker run -it --rm --name $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) $(PORTS) $(VOLUMES) $(OTHER) $(ENV) $(NS)/$(IMAGE_NAME):$(TAG) /bin/bash 43 | 44 | run: 45 | -docker run --rm --name $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) $(PORTS) $(VOLUMES) $(OTHER) $(ENV) $(NS)/$(IMAGE_NAME):$(TAG) 46 | 47 | start: 48 | -docker run -d --name $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) $(PORTS) $(VOLUMES) $(OTHER) $(ENV) $(NS)/$(IMAGE_NAME):$(TAG) 49 | 50 | stop: 51 | -docker stop $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) 52 | 53 | rm: 54 | -docker rm $(CONTAINER_NAME)_$(CONTAINER_INSTANCE) 55 | 56 | rmi: 57 | -docker rmi $(NS)/$(IMAGE_NAME):$(TAG) 58 | 59 | test: 60 | @echo docker build \ 61 | --build-arg VCS_REF=$(VCS_REF) \ 62 | --build-arg BUILD_DATE=$(BUILD_DATE) \ 63 | --build-arg VERSION=$(VERSION) \ 64 | -t $(NS)/$(IMAGE_NAME):$(TAG) . 65 | 66 | clean: stop rm rmi 67 | -------------------------------------------------------------------------------- /stable/VERSION: -------------------------------------------------------------------------------- 1 | 2.0.55 2 | -------------------------------------------------------------------------------- /stable/hooks/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # $IMAGE_NAME var is injected into the build so the tag is correct. 4 | 5 | #echo "Build hook running" 6 | docker build \ 7 | --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ 8 | --build-arg VCS_REF=`git rev-parse --short HEAD` \ 9 | --build-arg VERSION=`cat VERSION` \ 10 | -f $DOCKERFILE_PATH -t $DOCKER_REPO:${DOCKER_TAG//,/ -t $DOCKER_REPO:} . 11 | -------------------------------------------------------------------------------- /stable/root/usr/local/bin/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Init script for Factorio headless server Docker container 4 | # License: Apache-2.0 5 | # Github: https://github.com/goofball222/factorio 6 | SCRIPT_VERSION="1.4.1" 7 | # Last updated date: 2022-03-12 8 | 9 | set -Eeuo pipefail 10 | 11 | if [ "${DEBUG}" == 'true' ]; 12 | then 13 | set -x 14 | fi 15 | 16 | . /usr/local/bin/entrypoint-functions.sh 17 | 18 | BASEDIR="/opt/factorio" 19 | BINDIR=${BASEDIR}/bin 20 | DATADIR=${BASEDIR}/data 21 | CONFIGDIR=${BASEDIR}/config 22 | MODDIR=${BASEDIR}/mods 23 | SAVEDIR=${BASEDIR}/saves 24 | SCENARIODIR=${BASEDIR}/scenarios 25 | 26 | FACTORIO=${BINDIR}/x64/factorio 27 | 28 | VOLDIR=${VOLDIR:-"/factorio"} 29 | VOLCONFIGDIR=${VOLDIR}/config 30 | VOLMODDIR=${VOLDIR}/mods 31 | VOLSAVEDIR=${VOLDIR}/saves 32 | VOLSCENARIODIR=${VOLDIR}/scenarios 33 | 34 | f_log "INFO - Script version ${SCRIPT_VERSION}" 35 | f_log "INFO - Entrypoint functions version ${ENTRYPOINT_FUNCTIONS_VERSION}" 36 | 37 | cd ${BASEDIR} 38 | 39 | f_exit_handler() { 40 | f_log "INFO - Exit signal received, commencing shutdown" 41 | pkill -15 -f ${FACTORIO} 42 | for i in `seq 0 299`; 43 | do 44 | [ -z "$(pgrep -f ${FACTORIO})" ] && break 45 | # kill it with fire if it hasn't stopped itself after 5 minutes 46 | [ $i -gt 298 ] && pkill -9 -f ${FACTORIO} || true 47 | sleep 1 48 | done 49 | f_log "INFO - Shutdown complete. Nothing more to see here. Have a nice day!" 50 | f_log "INFO - Exit with status code ${?}" 51 | exit ${?}; 52 | } 53 | 54 | f_idle_handler() { 55 | while true 56 | do 57 | tail -f /dev/null & wait ${!} 58 | done 59 | } 60 | 61 | trap 'kill ${!}; f_exit_handler' SIGHUP SIGINT SIGQUIT SIGTERM 62 | 63 | if [ "$(id -u)" = '0' ]; then 64 | f_log "INFO - Entrypoint running with UID 0 (root)" 65 | if [[ "${@}" == 'factorio' ]]; then 66 | f_giduid 67 | f_chkdir 68 | f_chown 69 | f_setup 70 | if [ "${RUNAS_UID0}" == 'true' ]; then 71 | f_log "INFO - RUNAS_UID0 = 'true', running Factorio Headless as UID 0 (root)" 72 | f_log "WARN - ======================================================================" 73 | f_log "WARN - *** Running app as UID 0 (root) is an insecure configuration ***" 74 | f_log "WARN - ======================================================================" 75 | f_log "EXEC - ${FACTORIO} ${FACTORIO_OPTS}" 76 | exec 0<&- 77 | exec ${FACTORIO} ${FACTORIO_OPTS} & 78 | f_idle_handler 79 | else 80 | if [ -x "/sbin/su-exec" ]; then 81 | f_log "INFO - Use su-exec to drop priveleges and start Factorio Headless as GID=${PGID}, UID=${PUID}" 82 | f_log "EXEC - su-exec factorio:factorio ${FACTORIO} ${FACTORIO_OPTS}" 83 | exec 0<&- 84 | exec su-exec factorio:factorio ${FACTORIO} ${FACTORIO_OPTS} & 85 | f_idle_handler 86 | elif [ -x "/usr/sbin/gosu" ]; then 87 | f_log "INFO - Use gosu to drop privileges and start Factorio Headless as GID=${PGID}, UID=${PUID}" 88 | f_log "EXEC - gosu factorio:factorio ${FACTORIO} ${FACTORIO_OPTS}" 89 | exec 0<&- 90 | exec gosu factorio:factorio ${FACTORIO} ${FACTORIO_OPTS} & 91 | f_idle_handler 92 | else 93 | f_log "ERROR - su-exec/gosu NOT FOUND. Run state is invalid. Exiting." 94 | exit 1; 95 | fi 96 | fi 97 | else 98 | f_log "EXEC - ${@} as UID 0 (root)" 99 | exec "${@}" 100 | fi 101 | else 102 | f_log "WARN - Container/entrypoint not started as UID 0 (root)" 103 | f_log "WARN - Unable to change permissions or set custom GID/UID if configured" 104 | f_log "WARN - Process will be spawned with GID=$(id -g), PID=$(id -u)" 105 | f_log "WARN - Depending on permissions requested command may not work" 106 | if [[ "${@}" == 'factorio' ]]; then 107 | f_chkdir 108 | f_setup 109 | f_log "EXEC - ${FACTORIO} ${FACTORIO_OPTS}" 110 | exec 0<&- 111 | exec ${FACTORIO} ${FACTORIO_OPTS} & 112 | f_idle_handler 113 | else 114 | f_log "EXEC - ${@}" 115 | exec "${@}" 116 | fi 117 | fi 118 | 119 | # Script should never make it here, but just in case exit with a generic error code if it does 120 | exit 1; 121 | -------------------------------------------------------------------------------- /stable/root/usr/local/bin/entrypoint-functions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # entrypoint-functions.sh script for Factorio headless server Docker container 4 | # License: Apache-2.0 5 | # Github: https://github.com/goofball222/factorio 6 | ENTRYPOINT_FUNCTIONS_VERSION="1.1.0" 7 | # Last updated date: 2021-06-17 8 | 9 | f_chkdir() { 10 | # Make sure required directories exist in ${VOLDIR} - IE: new install with empty volume on host mapped over default volume 11 | [ -d ${VOLDIR}/config ] || mkdir -p ${VOLDIR}/config 12 | [ -d ${VOLDIR}/mods ] || mkdir -p ${VOLDIR}/mods 13 | [ -d ${VOLDIR}/saves ] || mkdir -p ${VOLDIR}/saves 14 | [ -d ${VOLDIR}/scenarios ] || mkdir -p ${VOLDIR}/scenarios 15 | } 16 | 17 | f_chown() { 18 | if [ "${RUN_CHOWN}" == 'false' ]; then 19 | if [ ! "$(stat -c %u ${BASEDIR})" = "${PUID}" ] || [ ! "$(stat -c %u ${VOLDIR})" = "${PUID}" ] \ 20 | || [ ! "$(stat -c %u ${VOLCONFIGDIR})" = "${PUID}" ] || [ ! "$(stat -c %u ${DATADIR})" = "${PUID}" ] \ 21 | || [ ! "$(stat -c %u ${VOLMODDIR})" = "${PUID}" ] || [ ! "$(stat -c %u ${VOLSAVEDIR})" = "${PUID}" ] \ 22 | || [ ! "$(stat -c %u ${VOLSCENARIODIR})" = "${PUID}" ]; then 23 | f_log "WARN - Configured PUID doesn't match owner of a required directory. Ignoring RUN_CHOWN=false" 24 | f_log "INFO - Ensuring permissions are correct before continuing - 'chown -R factorio:factorio ${BASEDIR} ${VOLDIR}'" 25 | f_log "INFO - Running recursive 'chown' on Docker overlay2 storage is **really** slow. This may take a bit." 26 | chown -R factorio:factorio ${BASEDIR} ${VOLDIR} 27 | else 28 | f_log "INFO - RUN_CHOWN set to 'false' - Not running 'chown -R factorio:factorio ${BASEDIR}', assume permissions are right." 29 | fi 30 | elif [ "${RUNAS_UID0}" == 'true' ]; then 31 | f_log "INFO - RUNAS_UID0=true - Not running 'chown -R factorio:factorio ${BASEDIR} ${VOLDIR}', no need to worry about permissions." 32 | else 33 | f_log "INFO - Ensuring permissions are correct before continuing - 'chown -R factorio:factorio ${BASEDIR}'" 34 | f_log "INFO - Running recursive 'chown' on Docker overlay2 storage is **really** slow. This may take a bit." 35 | chown -R factorio:factorio ${BASEDIR} ${VOLDIR} 36 | fi 37 | } 38 | 39 | f_giduid() { 40 | FACTORIO_GID=${FACTORIO_GID:-} 41 | FACTORIO_UID=${FACTORIO_UID:-} 42 | if [ ! -z "${FACTORIO_GID}" ]; then 43 | f_log "INFO - FACTORIO_GID is set. Please use the updated PGID variable. Automatically converting to PGID." 44 | PGID=${FACTORIO_GID} 45 | fi 46 | if [ ! -z "${FACTORIO_UID}" ]; then 47 | f_log "INFO - FACTORIO_UID is set. Please use the updated PUID variable. Automatically converting to PUID." 48 | PUID=${FACTORIO_UID} 49 | fi 50 | if [ "$(id factorio -g)" != "${PGID}" ] || [ "$(id factorio -u)" != "${PUID}" ]; then 51 | f_log "INFO - Setting custom factorio GID/UID: GID=${PGID}, UID=${PUID}" 52 | groupmod -o -g ${PGID} factorio 53 | usermod -o -u ${PUID} factorio 54 | else 55 | f_log "INFO - GID/UID for factorio are unchanged: GID=${PGID}, UID=${PUID}" 56 | fi 57 | } 58 | 59 | f_load_save() { 60 | # We avoid using --start-server-load-latest here, as the latest save might not be the desired one 61 | # Ex: If you change from scenario to default gameplay but forgot to delete scenario.zip it would be loaded instead of save.zip 62 | FACTORIO_OPTS="${FACTORIO_OPTS} --start-server ${SAVE_NAME} --server-settings ${CONFIGDIR}/server-settings.json --server-id ${CONFIGDIR}/server-id.json" 63 | } 64 | 65 | f_log() { 66 | echo "$(date +"[%Y-%m-%d %T,%3N]") $*" 67 | } 68 | 69 | f_setup() { 70 | FACTORIO_OPTS="${FACTORIO_OPTS:-}" 71 | FACTORIO_PORT=${FACTORIO_PORT:-} 72 | FACTORIO_RCON_PASSWORD=${FACTORIO_RCON_PASSWORD:-} 73 | FACTORIO_RCON_PORT=${FACTORIO_RCON_PORT:-27015} 74 | FACTORIO_SCENARIO=${FACTORIO_SCENARIO:-} 75 | if [ ! -z "${FACTORIO_PORT}" ]; then 76 | FACTORIO_OPTS="${FACTORIO_OPTS} --port ${FACTORIO_PORT}" 77 | fi 78 | 79 | f_log "INFO - Remove any incomplete *.tmp.zip from crash/forced exit in ${SAVEDIR}" 80 | rm -f ${SAVEDIR}/*.tmp.zip 81 | 82 | if [ ! -z "${FACTORIO_RCON_PASSWORD}" ]; then 83 | f_log "INFO - Using RCON password found in ENV" 84 | FACTORIO_RCON_PASSWORD=${FACTORIO_RCON_PASSWORD} 85 | else 86 | # Check for RCON password file, generate random and set if doesn't exist 87 | if [ ! -f "${CONFIGDIR}/RCON.pwd" ]; then 88 | f_log "INFO - No RCON.pwd found in ${CONFIGDIR}, generating random" 89 | set +o pipefail 90 | FACTORIO_RCON_PASSWORD=$(cat /dev/urandom | tr -dc 'a-f0-9' | head -c16) 91 | set -o pipefail 92 | echo "${FACTORIO_RCON_PASSWORD}" > "${CONFIGDIR}/RCON.pwd" 93 | chown factorio:factorio ${CONFIGDIR}/RCON.pwd 94 | else 95 | f_log "INFO - Using existing RCON.pwd found in ${CONFIGDIR}" 96 | FACTORIO_RCON_PASSWORD=$(cat ${CONFIGDIR}/RCON.pwd) 97 | fi 98 | fi 99 | 100 | f_log "INFO - RCON password is '${FACTORIO_RCON_PASSWORD}'" 101 | FACTORIO_OPTS="${FACTORIO_OPTS} --rcon-port=${FACTORIO_RCON_PORT} --rcon-password ${FACTORIO_RCON_PASSWORD}" 102 | 103 | # Copy example configs to CONFIGDIR 104 | cp -p ${DATADIR}/server-settings.example.json ${CONFIGDIR}/server-settings.example.json 105 | f_log "INFO - Copied latest server-settings.example.json to ${CONFIGDIR}" 106 | cp -p ${DATADIR}/map-gen-settings.example.json ${CONFIGDIR}/map-gen-settings.example.json 107 | f_log "INFO - Copied latest map-gen-settings.example.json to ${CONFIGDIR}" 108 | 109 | # Copy example configs to working configuration if they don't exist 110 | if [ ! -f "${CONFIGDIR}/server-settings.json" ]; then 111 | f_log "WARN - No server-settings.json found in ${CONFIGDIR}, copying from example" 112 | cp -p ${DATADIR}/server-settings.example.json ${CONFIGDIR}/server-settings.json 113 | else 114 | f_log "INFO - Using existing server-settings.json found in ${CONFIGDIR}" 115 | fi 116 | 117 | if [ ! -f "${CONFIGDIR}/map-gen-settings.json" ]; then 118 | f_log "WARN - No map-gen-settings.json found in ${CONFIGDIR}, copying from example" 119 | cp -p ${DATADIR}/map-gen-settings.example.json ${CONFIGDIR}/map-gen-settings.json 120 | else 121 | f_log "INFO - Using existing map-gen-settings.json found in ${CONFIGDIR}" 122 | fi 123 | 124 | # Check for banlist file in config dir, set launch options to use if found 125 | if [ ! -f "${CONFIGDIR}/server-banlist.json" ]; then 126 | f_log "INFO - No server-banlist.json found in ${CONFIGDIR}, ignoring" 127 | else 128 | f_log "INFO - Using server-banlist.json found in ${CONFIGDIR}" 129 | FACTORIO_OPTS="${FACTORIO_OPTS} --server-banlist ${CONFIGDIR}/server-banlist.json" 130 | fi 131 | 132 | # Check for whitelist file in config dir, set launch options to use if found 133 | if [ ! -f "${CONFIGDIR}/server-whitelist.json" ]; then 134 | f_log "INFO - No server-whitelist.json found in ${CONFIGDIR}, ignoring" 135 | else 136 | f_log "INFO - Using server-whitelist.json found in ${CONFIGDIR}" 137 | FACTORIO_OPTS="${FACTORIO_OPTS} --server-whitelist ${CONFIGDIR}/server-whitelist.json --use-server-whitelist" 138 | fi 139 | 140 | # Check for admin list file in config dir, set launch options to use if found 141 | if [ ! -f "${CONFIGDIR}/server-adminlist.json" ]; then 142 | f_log "INFO - No server-adminlist.json found in ${CONFIGDIR}, ignoring" 143 | else 144 | f_log "INFO - Using server-adminlist.json found in ${CONFIGDIR}" 145 | FACTORIO_OPTS="${FACTORIO_OPTS} --server-adminlist ${CONFIGDIR}/server-adminlist.json" 146 | fi 147 | 148 | # Choose save file name. Scenario saves are named as the scenario itself. 149 | if [ ! -z "${FACTORIO_SCENARIO}" ]; then 150 | SAVE_NAME="${FACTORIO_SCENARIO}" 151 | else 152 | SAVE_NAME="save" 153 | fi 154 | 155 | # Check for existing save file, use if found. Generate new with settings if not. 156 | if [ ! -f "${SAVEDIR}/${SAVE_NAME}.zip" ]; then 157 | f_log "WARN - No ${SAVE_NAME}.zip found in ${SAVEDIR}" 158 | f_log "INFO - Creating new map / ${SAVE_NAME}.zip in ${SAVEDIR} with settings from ${CONFIGDIR}/map-gen-settings.json" 159 | if [ ! -z "${FACTORIO_SCENARIO}" ]; then 160 | FACTORIO_OPTS="${FACTORIO_OPTS} --start-server-load-scenario ${FACTORIO_SCENARIO} --server-settings ${CONFIGDIR}/server-settings.json --server-id ${CONFIGDIR}/server-id.json" 161 | else 162 | if [ -x "/sbin/su-exec" ]; then 163 | su-exec factorio:factorio ${FACTORIO} --create ${VOLSAVEDIR}/save.zip --map-gen-settings ${CONFIGDIR}/map-gen-settings.json 164 | f_load_save 165 | elif [ -x "/usr/sbin/gosu" ]; then 166 | gosu factorio:factorio ${FACTORIO} --create ${VOLSAVEDIR}/save.zip --map-gen-settings ${CONFIGDIR}/map-gen-settings.json 167 | f_load_save 168 | else 169 | f_log "ERROR - su-exec/gosu NOT FOUND. Run state is invalid. Exiting." 170 | exit 1; 171 | fi 172 | fi 173 | else 174 | f_log "INFO - Loading ${SAVE_NAME}.zip found in ${SAVEDIR}" 175 | f_load_save 176 | fi 177 | 178 | } 179 | --------------------------------------------------------------------------------