From a816b838d9eea47426dec6e3a9d293724e08c6d4 Mon Sep 17 00:00:00 2001 From: nokotan Date: Sun, 6 Sep 2026 01:25:18 +0300 Subject: [PATCH] init_project --- .dockerignore | 2 + .gitea/workflows/build.yaml | 136 ++++++++++++++++++++++++++++++++++++ .gitignore | 1 + Dockerfile | 53 ++++++++++++++ README.MD | 33 +++++++++ docker-compose.yaml | 12 ++++ entrypoint.sh | 44 ++++++++++++ 7 files changed, 281 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitea/workflows/build.yaml create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.MD create mode 100644 docker-compose.yaml create mode 100755 entrypoint.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..70debfb --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +*.yaml +.gitea \ No newline at end of file diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..6a6a50d --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,136 @@ +name: Build and publish Factorio image + +on: + schedule: + # Ежедневно в 04:00 UTC + - cron: "0 4 * * *" + + workflow_dispatch: + +env: + NEXUS_REGISTRY: images.docker.nokotan.ru + IMAGE_NAME: images.docker.nokotan.ru/nokotan/factorio + +jobs: + check-version: + name: Check Factorio version + runs-on: ubuntu-latest + + outputs: + version: ${{ steps.factorio-version.outputs.version }} + should_build: ${{ steps.check-tag.outputs.should_build }} + + steps: + - name: Install CA + run: | + curl -fsSL http://info.noko.tan/install.sh | sudo bash -s -- nokotan_ca.crt + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install tools + shell: bash + run: | + set -eux + + if ! command -v jq >/dev/null 2>&1; then + sudo apt-get update + sudo apt-get install -y jq + fi + + - name: Get latest stable Factorio version + id: factorio-version + shell: bash + run: | + set -euo pipefail + + VERSION="$( + curl -fsSL https://factorio.com/api/latest-releases \ + | jq -r '.stable.headless' + )" + + if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then + echo "Could not determine Factorio version" + exit 1 + fi + + echo "Latest stable Factorio version: $VERSION" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Check whether version was already built + id: check-tag + shell: bash + run: | + set -euo pipefail + + VERSION="${{ steps.factorio-version.outputs.version }}" + TAG="factorio-${VERSION}" + + git fetch --tags origin + + if git show-ref --tags --verify --quiet "refs/tags/${TAG}"; then + echo "Version ${VERSION} was already built" + echo "should_build=false" >> "$GITHUB_OUTPUT" + else + echo "New version detected: ${VERSION}" + echo "should_build=true" >> "$GITHUB_OUTPUT" + fi + + build-and-push: + name: Build and publish Docker image + needs: check-version + + if: needs.check-version.outputs.should_build == 'true' + + runs-on: Most Perfomance Runner + + steps: + - name: Install CA + run: | + curl -fsSL http://info.noko.tan/install.sh | sudo bash -s -- nokotan_ca.crt + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Log in to Nexus Docker Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.NEXUS_REGISTRY }} + username: ${{ secrets.NEXUS_USERNAME }} + password: ${{ secrets.NEXUS_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Factorio image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: true + build-args: | + FACTORIO_VERSION=${{ needs.check-version.outputs.version }} + tags: | + ${{ env.IMAGE_NAME }}:${{ needs.check-version.outputs.version }} + ${{ env.IMAGE_NAME }}:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Create Git tag + shell: bash + env: + VERSION: ${{ needs.check-version.outputs.version }} + run: | + set -euo pipefail + + TAG="factorio-${VERSION}" + + git config user.name "gitea-actions[bot]" + git config user.email "gitea-actions[bot]@localhost" + + git tag -a "$TAG" \ + -m "Build Factorio ${VERSION}" + + git push origin "$TAG" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7f75f64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +factorio \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..11df703 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,53 @@ +FROM debian:bookworm-slim + +ARG FACTORIO_VERSION + +ENV FACTORIO_HOME=/opt/factorio \ + FACTORIO_DATA=/factorio + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + xz-utils \ + libstdc++6 \ + libgcc-s1 \ + sudo; \ + rm -rf /var/lib/apt/lists/*; \ + test -n "${FACTORIO_VERSION}"; \ + mkdir -p /opt; \ + curl -fL \ + "https://factorio.com/get-download/${FACTORIO_VERSION}/headless/linux64" \ + -o /tmp/factorio.tar.xz; \ + tar -xJf /tmp/factorio.tar.xz -C /opt; \ + rm -f /tmp/factorio.tar.xz; \ + useradd \ + --create-home \ + --uid 1000 \ + --shell /bin/bash \ + factorio; \ + mkdir -p \ + "${FACTORIO_DATA}/saves" \ + "${FACTORIO_DATA}/mods" \ + "${FACTORIO_DATA}/config"; \ + chown -R factorio:factorio \ + "${FACTORIO_HOME}" \ + "${FACTORIO_DATA}" + + +COPY entrypoint.sh / +RUN chmod +x /entrypoint.sh && chown factorio:factorio /entrypoint.sh + +WORKDIR ${FACTORIO_DATA} + +USER factorio + +VOLUME ["/factorio"] + +EXPOSE 34197/udp +EXPOSE 27015/tcp + +ENTRYPOINT ["/entrypoint.sh"] + +CMD ["--start-server", "/factorio/saves/world.zip", "--server-settings", "/factorio/config/server-settings.json"] diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..cf9f516 --- /dev/null +++ b/README.MD @@ -0,0 +1,33 @@ +# Factorio Docker image compose + +## Об репозитоии +Этот репозиторий автоматически собирает стабильную ветку factorio. +Получить готовый Dockerimage можно по images.docker.nokotan.ru/nokotan/factorio + +# Volumes +Все основное находится так +``` +/factorio +| ++-saves +| +-world.zip ++-mods ++-config + +-server-settings.json +``` +Структура автоматически создается при запуске контейнера. При пробросе volumes, нужно назначить владельца папки 1000:1000 +# compose.yaml +```yaml +services: + app: + image: images.docker.nokotan.ru/nokotan/factorio:latest + container_name: factorio + restart: unless-stopped + + ports: + - "27015:27015" + - "34197:34197/udp" + + volumes: + - ./factorio:/factorio/ +``` \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..1ce50aa --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,12 @@ +services: + app: + image: images.docker.nokotan.ru/nokotan/factorio:latest + container_name: factorio + restart: unless-stopped + + ports: + - "27015:27015" + - "34197:34197/udp" + + volumes: + - ./factorio:/factorio/ \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..dc6ff71 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +set -eu + + + +SAVE_FILE="/factorio/saves/world.zip" +SETTINGS_FILE="/factorio/config/server-settings.json" + +mkdir -p \ + /factorio/saves \ + /factorio/config + +if [ ! -f "$SETTINGS_FILE" ]; then + cat > "$SETTINGS_FILE" <<'EOF' +{ + "name": "Factorio Server", + "description": "Automatically generated Factorio world", + "max_players": 10, + "visibility": { + "public": false, + "lan": true + }, + "game_password": "", + "allow_commands": "admins-only", + "autosave_interval": 10, + "autosave_slots": 3, + "auto_pause": true +} +EOF +fi + +if [ ! -f "$SAVE_FILE" ]; then + echo "Save file not found. Creating a new Factorio world..." + + /opt/factorio/bin/x64/factorio \ + --create "$SAVE_FILE" + + echo "New world created: $SAVE_FILE" +else + echo "Using existing world: $SAVE_FILE" +fi + +exec /opt/factorio/bin/x64/factorio "$@"