diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index a3621506f..9e9a7c957 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -5,7 +5,7 @@ on: # yamllint disable-line rule:truthy branches: [main] jobs: - push: + push-amd64: runs-on: ubuntu-latest steps: - name: Checkout @@ -28,5 +28,40 @@ jobs: - name: Docker - Build / Push uses: docker/build-push-action@v5 with: + platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + + push-arm64: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker - Login + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Docker - Metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ github.repository }} + tags: type=raw,value=dev-arm64 + flavor: latest=false + + - name: Docker - Build / Push + uses: docker/build-push-action@v5 + with: + file: Dockerfile.arm64 + platforms: linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dc70a2d9a..bd41022f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,7 +6,7 @@ on: # yamllint disable-line rule:truthy jobs: # Builds the Dockerfile and pushes it to dockerhub - release: + release-amd64: name: Release - Docker image runs-on: ubuntu-latest steps: @@ -35,6 +35,49 @@ jobs: id: docker_build uses: docker/build-push-action@v5 with: + platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + + # Builds the Dockerfile.arm64 and pushes it to dockerhub + release-arm64: + name: Release - Docker image + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker - Login + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Docker - Metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ github.repository }} + # generate Docker tags based on the following events/attributes + tags: | + type=semver,pattern=v{{version}}-arm64 + type=semver,pattern=v{{major}}.{{minor}}-arm64 + type=semver,pattern=v{{major}}-arm64 + type=raw,value=latest-arm64 + flavor: latest=false + + - name: Docker - Build / Push + id: docker_build + uses: docker/build-push-action@v5 + with: + file: Dockerfile.arm64 + platforms: linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 new file mode 100644 index 000000000..6f643709a --- /dev/null +++ b/Dockerfile.arm64 @@ -0,0 +1,111 @@ +# set envs +# SUPERCRONIC: Latest releases available at https://github.com/aptible/supercronic/releases +# RCON: Latest releases available at https://github.com/gorcon/rcon-cli/releases +# NOTICE: edit RCON_MD5SUM SUPERCRONIC_SHA1SUM when using binaries of another version or arch. +ARG SUPERCRONIC_SHA1SUM="512f6736450c56555e01b363144c3c9d23abed4c" +ARG RCON_VERSION="0.10.3" +ARG SUPERCRONIC_VERSION="0.2.29" + +# build rcon-cli for arm64-linux +FROM arm64v8/golang:1.19.3-bullseye as rcon-cli_builder + +ARG RCON_VERSION + +WORKDIR /build + +RUN apt-get update && \ + apt-get install -y gcc libc-dev wget && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +RUN wget --progress=dot:giga https://github.com/gorcon/rcon-cli/archive/refs/tags/v${RCON_VERSION}.tar.gz -O rcon.tar.gz \ + && tar -xzvf rcon.tar.gz \ + && rm rcon.tar.gz \ + && mv rcon-cli-${RCON_VERSION}/* ./ \ + && rm -rf rcon-cli-${RCON_VERSION} \ + && go get -v -t -d ./... && env GOARCH=arm64 GOOS=linux go build -v ./cmd/gorcon + +# main image +FROM sonroyaalmerol/steamcmd-arm64:latest + +ARG SUPERCRONIC_SHA1SUM +ARG SUPERCRONIC_VERSION + +USER root + +LABEL maintainer="thijs@loef.dev" \ + name="thijsvanloef/palworld-server-docker" \ + github="https://github.com/thijsvanloef/palworld-server-docker" \ + dockerhub="https://hub.docker.com/r/thijsvanloef/palworld-server-docker" \ + org.opencontainers.image.authors="Thijs van Loef" \ + org.opencontainers.image.source="https://github.com/thijsvanloef/palworld-server-docker" + +# update and install dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + procps=2:3.3.17-5 \ + wget=1.21-1+deb11u1 \ + xdg-user-dirs=0.17-2 \ + jo=1.3-2 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# install rcon and supercronic +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +COPY --from=rcon-cli_builder /build/gorcon /usr/bin/rcon-cli + +RUN wget --progress=dot:giga https://github.com/aptible/supercronic/releases/download/v${SUPERCRONIC_VERSION}/supercronic-linux-arm64 -O supercronic \ + && echo "${SUPERCRONIC_SHA1SUM}" supercronic | sha1sum -c - \ + && chmod +x supercronic \ + && mv supercronic /usr/local/bin/supercronic + +ENV PORT= \ + PUID=1000 \ + PGID=1000 \ + PLAYERS= \ + MULTITHREADING=false \ + COMMUNITY=false \ + PUBLIC_IP= \ + PUBLIC_PORT= \ + SERVER_PASSWORD= \ + SERVER_NAME= \ + ADMIN_PASSWORD= \ + UPDATE_ON_BOOT=true \ + RCON_ENABLED=true \ + RCON_PORT=25575 \ + QUERY_PORT=27015 \ + TZ=UTC \ + SERVER_DESCRIPTION= \ + BACKUP_ENABLED=true \ + DELETE_OLD_BACKUPS=false \ + OLD_BACKUP_DAYS=30 \ + BACKUP_CRON_EXPRESSION="0 0 * * *" \ + AUTO_UPDATE_ENABLED=false \ + AUTO_UPDATE_CRON_EXPRESSION="0 * * * *" \ + AUTO_UPDATE_WARN_MINUTES=30 \ + AUTO_REBOOT_ENABLED=false \ + AUTO_REBOOT_WARN_MINUTES=5 \ + AUTO_REBOOT_CRON_EXPRESSION="0 0 * * *" \ + DISCORD_WEBHOOK_URL= \ + DISCORD_CONNECT_TIMEOUT=30 \ + DISCORD_MAX_TIMEOUT=30 \ + DISCORD_PRE_UPDATE_BOOT_MESSAGE="Server is updating..." \ + DISCORD_POST_UPDATE_BOOT_MESSAGE="Server update complete!" \ + DISCORD_PRE_START_MESSAGE="Server has been started!" \ + DISCORD_PRE_SHUTDOWN_MESSAGE="Server is shutting down..." \ + DISCORD_POST_SHUTDOWN_MESSAGE="Server has been stopped!" + +COPY ./scripts/* /home/steam/server/ + +RUN chmod +x /home/steam/server/*.sh && \ + mv /home/steam/server/backup.sh /usr/local/bin/backup && \ + mv /home/steam/server/update.sh /usr/local/bin/update && \ + mv /home/steam/server/restore.sh /usr/local/bin/restore + +WORKDIR /home/steam/server + +HEALTHCHECK --start-period=5m \ + CMD pgrep "PalServer-Linux" > /dev/null || exit 1 + +EXPOSE ${PORT} ${RCON_PORT} +ENTRYPOINT ["/home/steam/server/init.sh"] diff --git a/README.md b/README.md index f8010bd99..122c04b3a 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ This repository includes an example [docker-compose.yml](/docker-compose.yml) fi ```yml services: palworld: - image: thijsvanloef/palworld-server-docker:latest + image: thijsvanloef/palworld-server-docker:latest # Use the latest-arm64 tag for arm64 hosts restart: unless-stopped container_name: palworld-server stop_grace_period: 30s # Set to however long you are willing to wait for the container to gracefully stop @@ -86,7 +86,7 @@ values. Modify your [docker-compose.yml](docker-compose.yml) to this: ```yml services: palworld: - image: thijsvanloef/palworld-server-docker:latest + image: thijsvanloef/palworld-server-docker:latest # Use the latest-arm64 tag for arm64 hosts restart: unless-stopped container_name: palworld-server stop_grace_period: 30s # Set to however long you are willing to wait for the container to gracefully stop @@ -124,7 +124,7 @@ docker run -d \ -e SERVER_DESCRIPTION=palworld-server-docker by Thijs van Loef \ --restart unless-stopped \ --stop-timeout 30 \ - thijsvanloef/palworld-server-docker:latest + thijsvanloef/palworld-server-docker:latest # Use the latest-arm64 tag for arm64 hosts ``` As an alternative, you can copy the [.env.example](.env.example) file to a new file called **.env** file. @@ -140,7 +140,7 @@ docker run -d \ --env-file .env \ --restart unless-stopped \ --stop-timeout 30 \ - thijsvanloef/palworld-server-docker:latest + thijsvanloef/palworld-server-docker:latest # Use the latest-arm64 tag for arm64 hosts ``` ### Kubernetes diff --git a/scripts/start.sh b/scripts/start.sh index 624d4c445..efd2c83b3 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -70,7 +70,19 @@ if [ "${UPDATE_ON_BOOT,,}" = true ]; then fi fi -STARTCOMMAND=("./PalServer.sh") +# Get the architecture using dpkg +architecture=$(dpkg --print-architecture) +# Check if the architecture is arm64 +if [ "$architecture" == "arm64" ]; then + # create an arm64 version of ./PalServer.sh + cp ./PalServer.sh ./PalServer-arm64.sh + # shellcheck disable=SC2016 + sed -i 's|\("$UE_PROJECT_ROOT\/Pal\/Binaries\/Linux\/PalServer-Linux-Test" Pal "$@"\)|LD_LIBRARY_PATH=/home/steam/steamcmd/linux64:$LD_LIBRARY_PATH box64 \1|' ./PalServer-arm64.sh + chmod +x ./PalServer-arm64.sh + STARTCOMMAND=("./PalServer-arm64.sh") +else + STARTCOMMAND=("./PalServer.sh") +fi if ! fileExists "${STARTCOMMAND[0]}"; then echo "Try restarting with UPDATE_ON_BOOT=true" @@ -103,7 +115,11 @@ if [ ! "$(grep -s '[^[:space:]]' /palworld/Pal/Saved/Config/LinuxServer/PalWorld printf "\e[0;32m%s\e[0m\n" "*****GENERATING CONFIG*****" # Server will generate all ini files after first run. - timeout --preserve-status 15s ./PalServer.sh 1> /dev/null + if [ "$architecture" == "arm64" ]; then + timeout --preserve-status 15s ./PalServer-arm64.sh 1> /dev/null + else + timeout --preserve-status 15s ./PalServer.sh 1> /dev/null + fi # Wait for shutdown sleep 5