From a1572f082b3c460e767a6a39cc5e00f91757ffe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn?= <17956512+snowyyd@users.noreply.github.com> Date: Sat, 1 Aug 2026 02:43:59 -0300 Subject: [PATCH 1/4] feat!: add Ubuntu 26.04 image BREAKING CHANGE: `latest` tag now points to ubuntu 26.04 refactor: unify all Dockerfile files --- .github/workflows/action-docker-publish.yml | 184 ++++++-------------- Dockerfile.ubuntu-2004 => Dockerfile | 10 +- Dockerfile.ubuntu-2204 | 151 ---------------- Dockerfile.ubuntu-2404 | 151 ---------------- README.md | 1 + 5 files changed, 61 insertions(+), 436 deletions(-) rename Dockerfile.ubuntu-2004 => Dockerfile (90%) delete mode 100644 Dockerfile.ubuntu-2204 delete mode 100644 Dockerfile.ubuntu-2404 diff --git a/.github/workflows/action-docker-publish.yml b/.github/workflows/action-docker-publish.yml index 6f82b05..5c8659f 100644 --- a/.github/workflows/action-docker-publish.yml +++ b/.github/workflows/action-docker-publish.yml @@ -1,170 +1,94 @@ name: Docker Publish + on: workflow_dispatch: push: branches: - main paths: - - Dockerfile* + - Dockerfile schedule: - cron: "0 1 * * 6" jobs: - build-ubuntu-2404: - name: Build Ubuntu 24.04 + build: + name: Build Ubuntu ${{ matrix.version }} runs-on: ubuntu-latest permissions: packages: write contents: read attestations: write id-token: write - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: | - gameservermanagers/linuxgsm - ghcr.io/gameservermanagers/linuxgsm - tags: | - latest - ubuntu - ubuntu-24.04 - - name: Build and push (Ubuntu 24.04) - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile.ubuntu-2404 - platforms: linux/amd64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + strategy: + fail-fast: false + matrix: + include: + - version: "26.04" + tags: | + latest + ubuntu + ubuntu-26.04 + - version: "24.04" + tags: ubuntu-24.04 + - version: "22.04" + tags: ubuntu-22.04 + - version: "20.04" + tags: ubuntu-20.04 - build-ubuntu-2204: - name: Build Ubuntu 22.04 - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - attestations: write - id-token: write steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v7 - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 + # - name: Set up QEMU + # uses: docker/setup-qemu-action@v4 - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v4 - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + # - name: Login to Docker Hub + # uses: docker/login-action@v4 + # with: + # username: ${{ secrets.DOCKER_HUB_USERNAME }} + # password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: | - gameservermanagers/linuxgsm - ghcr.io/gameservermanagers/linuxgsm - tags: | - ubuntu-22.04 - - - name: Build and push (Ubuntu 22.04) - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile.ubuntu-2204 - platforms: linux/amd64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - build-ubuntu-2004: - name: Build Ubuntu 20.04 - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - attestations: write - id-token: write - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + # - name: Login to GitHub Container Registry + # uses: docker/login-action@v4 + # with: + # registry: ghcr.io + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: | gameservermanagers/linuxgsm ghcr.io/gameservermanagers/linuxgsm - tags: | - ubuntu-20.04 + tags: ${{ matrix.tags }} - - name: Build and push (Ubuntu 20.04) - uses: docker/build-push-action@v6 + - name: Build and push (Ubuntu ${{ matrix.version }}) + uses: docker/build-push-action@v7 with: context: . - file: ./Dockerfile.ubuntu-2004 + file: ./Dockerfile + build-args: | + UBUNTU_VER=${{ matrix.version }} platforms: linux/amd64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - package-cleanup: - name: Cleanup Old GitHub Packages - needs: [build-ubuntu-2004, build-ubuntu-2204, build-ubuntu-2404] - runs-on: ubuntu-latest - steps: - - name: Delete Package Versions - uses: actions/delete-package-versions@v5 - with: - package-name: linuxgsm - package-type: container - min-versions-to-keep: 1 - delete-only-untagged-versions: true + # package-cleanup: + # name: Cleanup Old GitHub Packages + # needs: build + # runs-on: ubuntu-latest + # steps: + # - name: Delete Package Versions + # uses: actions/delete-package-versions@v5 + # with: + # package-name: linuxgsm + # package-type: container + # min-versions-to-keep: 1 + # delete-only-untagged-versions: true diff --git a/Dockerfile.ubuntu-2004 b/Dockerfile similarity index 90% rename from Dockerfile.ubuntu-2004 rename to Dockerfile index 8f7762c..79108e3 100644 --- a/Dockerfile.ubuntu-2004 +++ b/Dockerfile @@ -4,7 +4,9 @@ # https://github.com/GameServerManagers/docker-linuxgsm # -FROM ghcr.io/gameservermanagers/steamcmd:ubuntu-20.04 +ARG UBUNTU_VER=26.04 + +FROM ghcr.io/gameservermanagers/steamcmd:ubuntu-${UBUNTU_VER} USER root @@ -58,7 +60,7 @@ RUN echo "**** Install Base LinuxGSM Requirements ****" \ jq \ lib32gcc-s1 \ lib32stdc++6 \ - netcat \ + $(. /etc/os-release && case "$VERSION_ID" in "20.04"|"22.04") echo "netcat" ;; *) echo "netcat-openbsd" ;; esac) \ pigz \ python3 \ sudo \ @@ -87,9 +89,9 @@ RUN echo "**** Install Node.js ****" \ && mkdir -p /etc/apt/keyrings \ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ && NODE_MAJOR=20 \ - && echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ && apt-get update \ - && apt-get install nodejs -y \ + && apt-get install nodejs -y --no-install-recommends \ && apt-get -y autoremove \ && apt-get -y clean \ && rm -rf /var/lib/apt/lists/* \ diff --git a/Dockerfile.ubuntu-2204 b/Dockerfile.ubuntu-2204 deleted file mode 100644 index 2295769..0000000 --- a/Dockerfile.ubuntu-2204 +++ /dev/null @@ -1,151 +0,0 @@ -# -# LinuxGSM Base Dockerfile -# -# https://github.com/GameServerManagers/docker-linuxgsm -# - -FROM ghcr.io/gameservermanagers/steamcmd:ubuntu-22.04 - -USER root - -## Remove steam user from upstream base image if present -RUN if id -u steam >/dev/null 2>&1; then echo "Removing steam user from base image"; userdel -r steam || true; else echo "steam user not present"; fi - -LABEL maintainer="LinuxGSM " -ENV DEBIAN_FRONTEND=noninteractive -ENV TERM=xterm -ENV LGSM_GITHUBUSER=GameServerManagers -ENV LGSM_GITHUBREPO=LinuxGSM -ENV LGSM_GITHUBBRANCH=master -ENV LGSM_LOGDIR=/data/log -ENV LGSM_SERVERFILES=/data/serverfiles -ENV LGSM_DATADIR=/data/data -ENV LGSM_CONFIG=/data/config-lgsm -ENV LGSM_COMPRESSEDMAPSDIR=/data/Maps-Compressed -ENV LGSM_DEV=false -ENV GAMESERVER=jc2server -ENV VALIDATE_ON_START=false -ENV UPDATE_CHECK=60 -ENV USER=linuxgsm -ENV UID=1000 -ENV GID=1000 - -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -## Install Base LinuxGSM Requirements -RUN echo "**** Install Base LinuxGSM Requirements ****" \ - && apt-get update \ - && apt-get install -y software-properties-common \ - && add-apt-repository multiverse \ - && add-apt-repository ppa:git-core/ppa \ - && apt-get update \ - && apt-get install -y \ - bc \ - binutils \ - bsdmainutils \ - bzip2 \ - ca-certificates \ - cpio \ - cron \ - curl \ - distro-info \ - file \ - git \ - gnupg \ - gosu \ - gzip \ - hostname \ - jq \ - lib32gcc-s1 \ - lib32stdc++6 \ - netcat \ - pigz \ - python3 \ - sudo \ - tar \ - tmux \ - unzip \ - util-linux \ - uuid-runtime \ - wget \ - xz-utils \ - zstd \ - # Docker Extras - iproute2 \ - iputils-ping \ - nano \ - vim \ - && apt-get -y autoremove \ - && apt-get -y clean \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /tmp/* \ - && rm -rf /var/tmp/* - -# Install Node.js -RUN echo "**** Install Node.js ****" \ - && set -uex \ - && mkdir -p /etc/apt/keyrings \ - && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ - && NODE_MAJOR=20 \ - && echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ - && apt-get update \ - && apt-get install nodejs -y \ - && apt-get -y autoremove \ - && apt-get -y clean \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /tmp/* \ - && rm -rf /var/tmp/* \ - && npm install -g npm@latest - -# Install GameDig https://docs.linuxgsm.com/requirements/gamedig -RUN echo "**** Install GameDig ****" \ - && npm install -g gamedig@5 - -WORKDIR /app - -## Add linuxgsm user -RUN echo "**** Add linuxgsm user ****" \ - && mkdir /data \ - # Create the user - && groupadd --gid $GID $USER \ - && useradd --uid $UID --gid $GID -m $USER \ - # - # [Optional] Add sudo support. Omit if you don't need to install software after connecting. - && echo $USER ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USER \ - && chmod 0440 /etc/sudoers.d/$USER \ - && chown $USER:$USER /data - -HEALTHCHECK --interval=1m --timeout=1m --start-period=2m --retries=1 CMD /app/entrypoint-healthcheck.sh || exit 1 - -## Download linuxgsm.sh -RUN echo "**** Download linuxgsm.sh ****" \ - && set -ex \ - && curl -Lo linuxgsm.sh "https://raw.githubusercontent.com/GameServerManagers/LinuxGSM/${LGSM_GITHUBBRANCH}/linuxgsm.sh" \ - && chmod +x linuxgsm.sh - -RUN echo "**** Get LinuxGSM Modules ****" \ - && git clone --filter=blob:none --no-checkout --sparse https://github.com/GameServerManagers/LinuxGSM.git \ - && cd LinuxGSM \ - && git sparse-checkout set --cone \ - && git sparse-checkout set lgsm/modules \ - && git checkout ${LGSM_GITHUBBRANCH} \ - && mkdir -p /app/lgsm/modules \ - && mv lgsm/modules/* /app/lgsm/modules \ - && chmod +x /app/lgsm/modules/* \ - && cd ../ \ - && rm -rf LinuxGSM \ - && chown -R $USER:$USER /app - -ARG CACHEBUST=1 -RUN echo "$CACHEBUST" - -COPY entrypoint.sh /app/entrypoint.sh -COPY entrypoint-user.sh /app/entrypoint-user.sh -COPY entrypoint-healthcheck.sh /app/entrypoint-healthcheck.sh - -## Ensure entrypoint scripts have execute permissions -RUN chmod +x /app/entrypoint.sh /app/entrypoint-user.sh /app/entrypoint-healthcheck.sh - -RUN date > /build-time.txt - -ENTRYPOINT ["/bin/bash", "./entrypoint.sh"] diff --git a/Dockerfile.ubuntu-2404 b/Dockerfile.ubuntu-2404 deleted file mode 100644 index 2680805..0000000 --- a/Dockerfile.ubuntu-2404 +++ /dev/null @@ -1,151 +0,0 @@ -# -# LinuxGSM Base Dockerfile -# -# https://github.com/GameServerManagers/docker-linuxgsm -# - -FROM ghcr.io/gameservermanagers/steamcmd:ubuntu-24.04 - -USER root - -## Remove steam user from upstream base image if present -RUN if id -u steam >/dev/null 2>&1; then echo "Removing steam user from base image"; userdel -r steam || true; else echo "steam user not present"; fi - -LABEL maintainer="LinuxGSM " -ENV DEBIAN_FRONTEND=noninteractive -ENV TERM=xterm -ENV LGSM_GITHUBUSER=GameServerManagers -ENV LGSM_GITHUBREPO=LinuxGSM -ENV LGSM_GITHUBBRANCH=master -ENV LGSM_LOGDIR=/data/log -ENV LGSM_SERVERFILES=/data/serverfiles -ENV LGSM_DATADIR=/data/data -ENV LGSM_CONFIG=/data/config-lgsm -ENV LGSM_COMPRESSEDMAPSDIR=/data/Maps-Compressed -ENV LGSM_DEV=false -ENV GAMESERVER=jc2server -ENV VALIDATE_ON_START=false -ENV UPDATE_CHECK=60 -ENV USER=linuxgsm -ENV UID=1000 -ENV GID=1000 - -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -## Install Base LinuxGSM Requirements -RUN echo "**** Install Base LinuxGSM Requirements ****" \ - && apt-get update \ - && apt-get install -y software-properties-common \ - && add-apt-repository multiverse \ - && add-apt-repository ppa:git-core/ppa \ - && apt-get update \ - && apt-get install -y \ - bc \ - binutils \ - bsdmainutils \ - bzip2 \ - ca-certificates \ - cpio \ - cron \ - curl \ - distro-info \ - file \ - git \ - gnupg \ - gosu \ - gzip \ - hostname \ - jq \ - lib32gcc-s1 \ - lib32stdc++6 \ - netcat-openbsd \ - pigz \ - python3 \ - sudo \ - tar \ - tmux \ - unzip \ - util-linux \ - uuid-runtime \ - wget \ - xz-utils \ - zstd \ - # Docker Extras - iproute2 \ - iputils-ping \ - nano \ - vim \ - && apt-get -y autoremove \ - && apt-get -y clean \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /tmp/* \ - && rm -rf /var/tmp/* - -# Install Node.js -RUN echo "**** Install Node.js ****" \ - && set -uex \ - && mkdir -p /etc/apt/keyrings \ - && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ - && NODE_MAJOR=20 \ - && echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ - && apt-get update \ - && apt-get install nodejs -y \ - && apt-get -y autoremove \ - && apt-get -y clean \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /tmp/* \ - && rm -rf /var/tmp/* \ - && npm install -g npm@latest - -# Install GameDig https://docs.linuxgsm.com/requirements/gamedig -RUN echo "**** Install GameDig ****" \ - && npm install -g gamedig@5 - -WORKDIR /app - -## Add linuxgsm user -RUN echo "**** Add linuxgsm user ****" \ - && mkdir /data \ - # Create the user - && groupadd --gid $GID $USER \ - && useradd --uid $UID --gid $GID -m $USER \ - # - # [Optional] Add sudo support. Omit if you don't need to install software after connecting. - && echo $USER ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USER \ - && chmod 0440 /etc/sudoers.d/$USER \ - && chown $USER:$USER /data - -HEALTHCHECK --interval=1m --timeout=1m --start-period=2m --retries=1 CMD /app/entrypoint-healthcheck.sh || exit 1 - -## Download linuxgsm.sh -RUN echo "**** Download linuxgsm.sh ****" \ - && set -ex \ - && curl -Lo linuxgsm.sh "https://raw.githubusercontent.com/GameServerManagers/LinuxGSM/${LGSM_GITHUBBRANCH}/linuxgsm.sh" \ - && chmod +x linuxgsm.sh - -RUN echo "**** Get LinuxGSM Modules ****" \ - && git clone --filter=blob:none --no-checkout --sparse https://github.com/GameServerManagers/LinuxGSM.git \ - && cd LinuxGSM \ - && git sparse-checkout set --cone \ - && git sparse-checkout set lgsm/modules \ - && git checkout ${LGSM_GITHUBBRANCH} \ - && mkdir -p /app/lgsm/modules \ - && mv lgsm/modules/* /app/lgsm/modules \ - && chmod +x /app/lgsm/modules/* \ - && cd ../ \ - && rm -rf LinuxGSM \ - && chown -R $USER:$USER /app - -ARG CACHEBUST=1 -RUN echo "$CACHEBUST" - -COPY entrypoint.sh /app/entrypoint.sh -COPY entrypoint-user.sh /app/entrypoint-user.sh -COPY entrypoint-healthcheck.sh /app/entrypoint-healthcheck.sh - -## Ensure entrypoint scripts have execute permissions -RUN chmod +x /app/entrypoint.sh /app/entrypoint-user.sh /app/entrypoint-healthcheck.sh - -RUN date > /build-time.txt - -ENTRYPOINT ["/bin/bash", "./entrypoint.sh"] diff --git a/README.md b/README.md index fd9d45c..e668982 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ LinuxGSM is a command-line tool for quick, simple deployment and management of L ## Tags - `latest`, `ubuntu` - Latest Ubuntu LTS release +- `ubuntu-26.04` - Ubuntu 26.04 LTS 'Resolute Raccoon' - `ubuntu-24.04` - Ubuntu 24.04 LTS 'Noble Numbat' - `ubuntu-22.04` - Ubuntu 22.04 LTS 'Jammy Jackalope' - `ubuntu-20.04` - Ubuntu 20.04 LTS 'Focal Fossa' From b344ac1054ae0886c054c9a59fde2179ea858940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn?= <17956512+snowyyd@users.noreply.github.com> Date: Sat, 1 Aug 2026 02:44:26 -0300 Subject: [PATCH 2/4] refactor!: update node version to v24 BREAKING CHANGE: Node.js version is now latest LTS (v24) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 79108e3..3599c06 100644 --- a/Dockerfile +++ b/Dockerfile @@ -88,7 +88,7 @@ RUN echo "**** Install Node.js ****" \ && set -uex \ && mkdir -p /etc/apt/keyrings \ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ - && NODE_MAJOR=20 \ + && NODE_MAJOR=24 \ && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ && apt-get update \ && apt-get install nodejs -y --no-install-recommends \ From 37989b4559af8ad129919b1f0bb7c751685a9dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn?= <17956512+snowyyd@users.noreply.github.com> Date: Sat, 1 Aug 2026 02:56:06 -0300 Subject: [PATCH 3/4] refactor: use supercronic-based crons Replaced the systemd-based cron with the user-based supercronic. Since supercronic does not require SUID/SGID permissions, it can be run directly in containers with stricter security policies (`--security-opt=no-new-privileges`). The crontab file is now stored in `$LGSM_CONFIG/crontab` and is read only if `LGSM_READ_CRONTAB` env var is `true`. Compatibility with `UPDATE_CHECK` is maintained, and a helper script has been added to correctly parse and convert the user supplied value (minutes) into valid cron syntax. --- Dockerfile | 10 ++++++++ cron-converter.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++ entrypoint-user.sh | 32 ++++++++++++++++++++++-- entrypoint.sh | 3 --- 4 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 cron-converter.sh diff --git a/Dockerfile b/Dockerfile index 3599c06..9d16ddc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,9 @@ ARG UBUNTU_VER=26.04 FROM ghcr.io/gameservermanagers/steamcmd:ubuntu-${UBUNTU_VER} +ARG TARGETARCH=amd64 +ARG SUPERCRONIC_VERSION=v0.2.48 + USER root ## Remove steam user from upstream base image if present @@ -25,6 +28,7 @@ ENV LGSM_DATADIR=/data/data ENV LGSM_CONFIG=/data/config-lgsm ENV LGSM_COMPRESSEDMAPSDIR=/data/Maps-Compressed ENV LGSM_DEV=false +ENV LGSM_READ_CRONTAB=false ENV GAMESERVER=jc2server ENV VALIDATE_ON_START=false ENV UPDATE_CHECK=60 @@ -83,6 +87,11 @@ RUN echo "**** Install Base LinuxGSM Requirements ****" \ && rm -rf /tmp/* \ && rm -rf /var/tmp/* +# Install supercronic +RUN echo "**** Install Supercronic ****" \ + && wget -O /usr/local/bin/supercronic https://github.com/aptible/supercronic/releases/download/${SUPERCRONIC_VERSION}/supercronic-linux-${TARGETARCH} \ + && chmod +x /usr/local/bin/supercronic + # Install Node.js RUN echo "**** Install Node.js ****" \ && set -uex \ @@ -144,6 +153,7 @@ RUN echo "$CACHEBUST" COPY entrypoint.sh /app/entrypoint.sh COPY entrypoint-user.sh /app/entrypoint-user.sh COPY entrypoint-healthcheck.sh /app/entrypoint-healthcheck.sh +COPY cron-converter.sh /app/cron-converter.sh ## Ensure entrypoint scripts have execute permissions RUN chmod +x /app/entrypoint.sh /app/entrypoint-user.sh /app/entrypoint-healthcheck.sh diff --git a/cron-converter.sh b/cron-converter.sh new file mode 100644 index 0000000..fdd3ab5 --- /dev/null +++ b/cron-converter.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# Converts a given duration in minutes into a valid cron expression +# Outputs the cron string to stdout on success +# Returns 0 on success, 1 on invalid input or unrepresentable interval +convert_minutes_to_cron() { + local input="$1" + + # Validate input: strictly positive integer + if ! [[ "$input" =~ ^[1-9][0-9]*$ ]]; then + return 1 + fi + + local minutes=$input + + # Minute intervals (< 60 min) + if [ "$minutes" -lt 60 ]; then + echo "*/${minutes} * * * *" + return 0 + fi + + # Hour intervals (< 1440 min / 24 hrs) + if [ "$minutes" -lt 1440 ]; then + if [ "$((minutes % 60))" -ne 0 ]; then + return 1 + fi + + local hours=$((minutes / 60)) + if [ "$hours" -gt 23 ]; then + return 1 + fi + + echo "0 */${hours} * * *" + return 0 + fi + + # # Exact 1 Year (525.600 min = 365 days) + # if [ "$minutes" -eq 525600 ]; then + # echo "0 0 1 1 *" + # return 0 + # fi + + # # Exact 1 Month (43.200 min = 30 days) + # if [ "$minutes" -eq 43200 ]; then + # echo "0 0 1 * *" + # return 0 + # fi + + # Day intervals (>= 1440 min) + if [ "$((minutes % 1440))" -ne 0 ]; then + return 1 + fi + + local days=$((minutes / 1440)) + # Cron day-of-month step cannot exceed 31 + if [ "$days" -gt 31 ]; then + return 1 + fi + + echo "0 0 */${days} * *" + return 0 +} diff --git a/entrypoint-user.sh b/entrypoint-user.sh index db72891..fd4094c 100755 --- a/entrypoint-user.sh +++ b/entrypoint-user.sh @@ -91,12 +91,40 @@ else ./"${GAMESERVER}" sponsor fi +# Handle update checker/cron logic +source ./cron-converter.sh +CRON_FILE="${LGSM_CONFIG}/crontab" + if [ -n "${UPDATE_CHECK}" ] && [ "${UPDATE_CHECK}" != "0" ]; then echo -e "" echo -e "Starting Update Checks" echo -e "=================================" - echo -e "*/${UPDATE_CHECK} * * * * /app/${GAMESERVER} update > /dev/null 2>&1" | crontab - - echo -e "update will check every ${UPDATE_CHECK} minutes" + + # Do not overwrite crontab file if LGSM_READ_CRONTAB is set and the file exists + if [ -n "${LGSM_READ_CRONTAB}" ] && [ -f "${CRON_FILE}" ]; then + echo -e "Using existing crontab at ${CRON_FILE}" + RUN_SUPERCRONIC=true + else + # Convert UPDATE_CHECK to a valid cron expression + CRON_EXPR=$(convert_minutes_to_cron "${UPDATE_CHECK}") + + if [ $? -eq 0 ] && [ -n "${CRON_EXPR}" ]; then + # Write generated cron expression to file + echo "${CRON_EXPR} /app/${GAMESERVER} update > /dev/null 2>&1" > "${CRON_FILE}" + echo -e "Update schedule configured: ${CRON_EXPR} (${UPDATE_CHECK} minutes interval)" + RUN_SUPERCRONIC=true + else + echo -e "Error: Invalid UPDATE_CHECK interval ('${UPDATE_CHECK}' minutes). Disabling update checks" >&2 + RUN_SUPERCRONIC=false + fi + fi + + # Execute supercronic only if the crontab configuration is valid + if [ "${RUN_SUPERCRONIC}" = true ]; then + echo -e "Executing supercronic" + supercronic -quiet -no-reap "${CRON_FILE}" & + fi + else echo -e "" echo -e "Update checks are disabled" diff --git a/entrypoint.sh b/entrypoint.sh index 96eb0de..38462b0 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -47,9 +47,6 @@ export LGSM_CONFIG=${LGSM_CONFIG} cd /app || exit -# start cron -cron - echo -e "" echo -e "Check Permissions" echo -e "=================================" From bc9edc7b89b693309803ade7e215a8fc2abb33d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn?= <17956512+snowyyd@users.noreply.github.com> Date: Sat, 1 Aug 2026 04:06:03 -0300 Subject: [PATCH 4/4] refactor: remove cron package from Dockerfile --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9d16ddc..0dc7188 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,7 +52,6 @@ RUN echo "**** Install Base LinuxGSM Requirements ****" \ bzip2 \ ca-certificates \ cpio \ - cron \ curl \ distro-info \ file \