diff --git a/Dockerfile b/Dockerfile index 7f8e2c0..ed76f57 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -FROM ubuntu:20.04 - +FROM debian:12-slim + ARG TARGETPLATFORM # Set by Docker, see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope ENV UID=1000 @@ -18,12 +18,14 @@ ENV AMP_SUPPORT_LEVEL=UNSUPPORTED ENV AMP_SUPPORT_TOKEN=AST0/MTAD ENV AMP_SUPPORT_TAGS="nosupport docker community unofficial unraid" ENV AMP_SUPPORT_URL="https://github.com/MitchTalmadge/AMP-dockerized/" +ENV LD_LIBRARY_PATH="./:/opt/cubecoders/amp/:/AMP/" ARG DEBIAN_FRONTEND=noninteractive # Initialize RUN apt-get update && \ apt-get install -y --no-install-recommends \ + apt-transport-https \ jq \ sed \ tzdata \ @@ -35,7 +37,6 @@ RUN apt-get update && \ /var/lib/apt/lists/* \ /var/tmp/* - # Configure Locales RUN apt-get update && \ apt-get install -y --no-install-recommends locales && \ @@ -53,58 +54,55 @@ ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 -# Add Mono apt source +# Install Mono RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - apt-transport-https \ + apt-get install -y \ dirmngr \ - software-properties-common \ - gnupg \ - ca-certificates && \ - apt-get -y clean && \ - apt-get -y autoremove --purge && \ - rm -rf \ - /tmp/* \ - /var/lib/apt/lists/* \ - /var/tmp/* -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \ - echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" | tee /etc/apt/sources.list.d/mono-official-stable.list - - -# Install Mono Certificates -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - ca-certificates-mono && \ + ca-certificates \ + gnupg && \ + gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/mono-official-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \ + echo "deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/debian stable-buster main" | tee /etc/apt/sources.list.d/mono-official-stable.list && \ + apt-get update && \ + apt-get install -y mono-devel && \ apt-get -y clean && \ apt-get -y autoremove --purge && \ rm -rf \ /tmp/* \ /var/lib/apt/lists/* \ /var/tmp/* -RUN wget -O /tmp/cacert.pem https://curl.haxx.se/ca/cacert.pem && \ - cert-sync /tmp/cacert.pem - # Declare and install AMP dependencies +# AMP core dependencies ARG AMPDEPS="\ - # Dependencies for AMP: - tmux \ + bzip2 \ + coreutils \ + curl \ + gdb \ git \ + git-lfs \ + gnupg \ + iputils-ping \ + libc++-dev \ + libc6 \ + libatomic1 \ + libgdiplus \ + liblua5.3-0 \ + libpulse-dev \ + libsqlite3-0 \ + libzstd1 \ + locales \ + numactl \ + procps \ + software-properties-common \ socat \ + tmux \ unzip \ - iputils-ping \ - procps" - -ARG MCDEPS="\ - # Dependencies for Minecraft: - openjdk-17-jre-headless \ - openjdk-11-jre-headless \ - openjdk-8-jre-headless" - + xz-utils" + +# srcds (TF2, GMod, ...) dependencies ARG SRCDSDEPS="\ - # Dependencies for srcds (TF2, GMod, ...) - lib32gcc1 \ + lib32gcc-s1 \ lib32stdc++6 \ lib32z1 \ libbz2-1.0:i386 \ @@ -115,25 +113,34 @@ ARG SRCDSDEPS="\ libsdl2-2.0-0:i386 \ libtinfo5:i386" -ARG FACDEPS="\ - # Dependencies for Factorio: - xz-utils" - -RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ +# Needed for games that require Wine and Xvfb +ARG WINEXVFB="\ + fonts-wine \ + libwine \ + libwine:i386 \ + python3 \ + python3-venv \ + cabextract \ + wine \ + wine32 \ + wine64 \ + wine-binfmt \ + winbind \ + xauth \ + xvfb" + +RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ dpkg --add-architecture aarch64 && \ apt-get update && \ apt-get install -y \ - $AMPDEPS \ - $MCDEPS \ - $FACDEPS; \ + $AMPDEPS; \ else \ - dpkg --add-architecture i386 && \ + dpkg --add-architecture i386 && \ apt-get update && \ apt-get install -y \ - $AMPDEPS \ - $MCDEPS \ - $SRCDSDEPS \ - $FACDEPS; \ + $AMPDEPS \ + $SRCDSDEPS \ + $WINEXVFB; \ fi && \ apt-get -y clean && \ apt-get -y autoremove --purge && \ @@ -142,11 +149,13 @@ RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ /var/lib/apt/lists/* \ /var/tmp/* -# Set Java default -RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ - update-alternatives --set java /usr/lib/jvm/java-17-openjdk-arm64/bin/java; \ - else update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java; \ - fi +# Install Adoptium JDK +RUN wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | tee /etc/apt/keyrings/adoptium.asc && \ + echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list && \ + apt-get update && \ + apt-get install -y temurin-8-jdk temurin-11-jdk temurin-17-jdk temurin-21-jdk && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* # Manually install ampinstmgr by extracting it from the deb package. # Docker doesn't have systemctl and other things that AMP's deb postinst expects, @@ -158,10 +167,11 @@ RUN apt-get update && \ apt-transport-https # Add CubeCoders repository and key -RUN apt-key adv --fetch-keys http://repo.cubecoders.com/archive.key && \ +RUN wget -qO - http://repo.cubecoders.com/archive.key | gpg --dearmor > /etc/apt/trusted.gpg.d/cubecoders-archive-keyring.gpg && \ if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ apt-add-repository "deb http://repo.cubecoders.com/aarch64 debian/"; \ - else apt-add-repository "deb http://repo.cubecoders.com/ debian/"; \ + else \ + apt-add-repository "deb http://repo.cubecoders.com/ debian/"; \ fi && \ apt-get update && \ # Just download (don't actually install) ampinstmgr diff --git a/entrypoint/main.sh b/entrypoint/main.sh index 8366319..caa2e6a 100644 --- a/entrypoint/main.sh +++ b/entrypoint/main.sh @@ -16,6 +16,7 @@ echo "" source /opt/entrypoint/utils.sh source /opt/entrypoint/routines.sh trap 'handle_error' ERR +trap_with_arg 'shutdown' INT TERM HUP QUIT KILL # Migrate legacy vars export AMP_LICENCE=${LICENCE:-${AMP_LICENCE:-"notset"}} @@ -45,10 +46,9 @@ else fi start_amp -# Trap SIGTERM for a graceful shutdown -trap "stop_amp" SIGTERM # Sleep echo "AMP is now running. Logs can be viewed through AMP web UI or at ampdata/instances/Main/AMP_Logs" +monitor_amp & tail -f /dev/null & wait $! diff --git a/entrypoint/routines.sh b/entrypoint/routines.sh index b6dbb14..2bb93c8 100644 --- a/entrypoint/routines.sh +++ b/entrypoint/routines.sh @@ -62,7 +62,7 @@ configure_timezone() { } create_amp_user() { - echo "Creating AMP user..." + echo "Creating AMP group..." if [ ! "$(getent group ${GID})" ]; then # Create group addgroup \ @@ -70,17 +70,22 @@ create_amp_user() { amp fi APP_GROUP=$(getent group ${GID} | awk -F ":" '{ print $1 }') + echo "Group Created: ${APP_GROUP} (${GID})" + + echo "Creating AMP user..." if [ ! "$(getent passwd ${UID})" ]; then # Create user adduser \ - --uid ${UID} \ - --shell /bin/bash \ - --no-create-home \ - --ingroup ${APP_GROUP} \ - --system \ - amp + --uid ${UID} \ + --shell /bin/bash \ + --no-create-home \ + --disabled-password \ + --gecos "" \ + --ingroup ${APP_GROUP} \ + amp fi APP_USER=$(getent passwd ${UID} | awk -F ":" '{ print $1 }') + echo "User Created: ${APP_USER} (${UID})" } handle_error() { @@ -95,6 +100,14 @@ handle_error() { exit 1 } +monitor_amp() { + # Periodically process pending tasks (e.g. upgrade, reboots, ...) + while true; do + run_amp_command_silently "ProcessPendingTasks" + sleep 5 # The UI's restart timeout is 10 seconds, so let's be safe. + done +} + run_startup_script() { # Users may provide their own startup script for installing dependencies, etc. STARTUP_SCRIPT="/home/amp/scripts/startup.sh" @@ -105,9 +118,18 @@ run_startup_script() { fi } +shutdown() { + echo "Shutting down... (Signal ${1})" + if [ -n "${AMP_STARTED}" ] && [ "${AMP_STARTED}" -eq 1 ] && [ "${1}" != "KILL" ]; then + stop_amp + fi + exit 0 +} + start_amp() { echo "Starting AMP..." run_amp_command "StartBoot" + export AMP_STARTED=1 echo "AMP Started!" } @@ -115,7 +137,6 @@ stop_amp() { echo "Stopping AMP..." run_amp_command "StopAll" echo "AMP Stopped." - exit 0 } upgrade_instances() { diff --git a/entrypoint/utils.sh b/entrypoint/utils.sh index 79b4e77..34bfcd2 100644 --- a/entrypoint/utils.sh +++ b/entrypoint/utils.sh @@ -10,4 +10,16 @@ does_main_instance_exist() { run_amp_command() { su ${APP_USER} --command "ampinstmgr $1" -} \ No newline at end of file +} + +run_amp_command_silently() { + su ${APP_USER} --command "ampinstmgr --silent $1" +} + +trap_with_arg() { + # Credit https://stackoverflow.com/a/2183063/2364405 + func="$1" ; shift + for sig ; do + trap "$func $sig" "$sig" + done +} diff --git a/example-configs/README.md b/example-configs/README.md new file mode 100644 index 0000000..72aa479 --- /dev/null +++ b/example-configs/README.md @@ -0,0 +1,8 @@ +# Example Configs + +## Which one do I use? +- If you're using Unraid's Docker tool, this directory doesn't apply to you. +- If you think there's a chance that you'll ever want to run more than one game server, start with the `ads` config. This will launch an "ADS" instance which can be used to create other instances. +- If you want to run one specific game only, you can just use one of those configs (e.g. `factorio`) +- If you have an old McMyAdmin license (if you don't know what this is, you don't have one), then you must use the `mcmyadmin` config. +- These are just examples -- you can of course make your own config! You don't even have to use `docker compose` if you don't want to, and know what you're doing. \ No newline at end of file