From a3b2b006cc84e05321da2c6eef307356745d8219 Mon Sep 17 00:00:00 2001 From: Alex Macocian Date: Thu, 12 Sep 2024 01:25:40 +0200 Subject: [PATCH] Add project files. --- .gitignore | 4 ++++ Backup.ps1 | 45 ++++++++++++++++++++++++++++++++++++++++ Build.ps1 | 25 ++++++++++++++++++++++ Dockerfile | 41 ++++++++++++++++++++++++++++++++++++ Readme.md | 29 ++++++++++++++++++++++++++ Restore.ps1 | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Start.ps1 | 26 +++++++++++++++++++++++ Stop.ps1 | 15 ++++++++++++++ 8 files changed, 245 insertions(+) create mode 100644 .gitignore create mode 100644 Backup.ps1 create mode 100644 Build.ps1 create mode 100644 Dockerfile create mode 100644 Readme.md create mode 100644 Restore.ps1 create mode 100644 Start.ps1 create mode 100644 Stop.ps1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca49cbd --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +backup/ +logs/ +plugins/ +.vs/ \ No newline at end of file diff --git a/Backup.ps1 b/Backup.ps1 new file mode 100644 index 0000000..6e383ba --- /dev/null +++ b/Backup.ps1 @@ -0,0 +1,45 @@ +$containerName = "minecraft-server" +$backupDir = "$(pwd)/backup" + +if (-not (Test-Path -Path $backupDir)) { + Write-Host "Creating backup directory: $backupDir" + New-Item -ItemType Directory -Path $backupDir +} + +$container = docker ps -a --filter "name=$containerName" --format "{{.ID}}" +if (-not $container) { + Write-Host "The container $containerName does not exist. Cannot proceed with backup." + exit +} + +$itemsToBackup = @( + "/minecraft/banned-ips.json", + "/minecraft/banned-players.json", + "/minecraft/bukkit.yml", + "/minecraft/help.yml", + "/minecraft/commands.yml", + "/minecraft/ops.json", + "/minecraft/permissions.yml", + "/minecraft/server.properties", + "/minecraft/spigot.yml", + "/minecraft/usercache.json", + "/minecraft/whitelist.json", + "/minecraft/world", + "/minecraft/world_nether", + "/minecraft/world_the_end" +) + +foreach ($item in $itemsToBackup) { + $itemName = [System.IO.Path]::GetFileName($item) + $destination = "$backupDir/$itemName" + Write-Host "Backing up $item to $destination" + if ($item -like "*/world*" -or $item -eq "/minecraft/world" -or $item -eq "/minecraft/world_nether" -or $item -eq "/minecraft/world_the_end") { + Write-Host "Backing up directory $item" + docker cp "$($containerName):$($item)" "$($backupDir)/" + } else { + Write-Host "Backing up file $item" + docker cp "$($containerName):$($item)" "$($destination)" + } +} + +Write-Host "Backup completed successfully." diff --git a/Build.ps1 b/Build.ps1 new file mode 100644 index 0000000..43d5114 --- /dev/null +++ b/Build.ps1 @@ -0,0 +1,25 @@ +$containerName = "minecraft-server" +$imageName = "minecraft-spigot:latest" + +$container = docker ps -a --filter "name=$containerName" --format "{{.ID}}" +if ($container) { + Write-Host "Stopping existing container: $containerName" + docker stop $containerName + Write-Host "Removing existing container: $containerName" + docker rm $containerName +} else { + Write-Host "No existing container found with name: $containerName" +} + +$image = docker images --filter "reference=$imageName" --format "{{.ID}}" +if ($image) { + Write-Host "Removing existing image: $imageName" + docker rmi $imageName +} else { + Write-Host "No existing image found with name: $imageName" +} + +Write-Host "Building new image: $imageName" +docker build -t $imageName . + +Write-Host "Build completed successfully!" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4496f0d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +FROM ubuntu:latest AS builder + +# Install Spigot dependencies +# This installs normal dependencies, sets up zulu apt repository and installs zulu21-jdk +RUN apt-get update && apt-get install -y \ + curl \ + git \ + wget \ + bash \ + gnupg \ + ca-certificates \ + && curl -s https://repos.azul.com/azul-repo.key | gpg --dearmor -o /usr/share/keyrings/azul.gpg \ + && echo "deb [signed-by=/usr/share/keyrings/azul.gpg] https://repos.azul.com/zulu/deb stable main" | tee /etc/apt/sources.list.d/zulu.list \ + && apt-get update && apt-get install -y zulu21-jdk + +WORKDIR /minecraft + +# Setup spigot.jar +# This downloads BuildTools.jar and uses that to build a new spigot.jar +RUN mkdir buildtools \ + && cd buildtools \ + && wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar \ + && java -jar BuildTools.jar --rev latest \ + && mv spigot-*.jar /minecraft/spigot.jar \ + && rm -rf /minecraft/buildtools + +# Accept EULA +RUN echo "eula=true" > /minecraft/eula.txt + +FROM alpine:latest AS runner + +COPY --from=builder /minecraft /minecraft + +RUN apk add --no-cache openjdk21-jre eudev + +WORKDIR /minecraft + +# Move spigot to server directory +EXPOSE 25565 + +CMD /bin/sh -c "java -Xmx2G -Xms512M -jar /minecraft/spigot.jar nogui > /minecraft/logs/output.log 2> /minecraft/logs/error.log" \ No newline at end of file diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..a53bf0d --- /dev/null +++ b/Readme.md @@ -0,0 +1,29 @@ +# Docker image for minecraft servers + +**Requires docker and powershell** + +## First run + +- Run `Build.ps1` to build the image +- Run `mkdir plugins` +- Copy your plugins into `plugins` folder +- Run `Start.ps1` +- Run `Backup.ps1` +- Run `Stop.ps1` +- Edit your server files in the `backup` directory. *Edit stuff such as password, commands, etc.* **The container needs to exist for this to work** +- Run `Restore.ps1` to restore your modified files into the container. **The container needs to run for this to work** +- Run `Start.ps1` +- Check `logs` folder for logs. `output.log` and `error.log` contain the *stdout* and *stderr* of the java process + +## Script glossary + +### `Build.ps1` to build the docker image +If the server is currently running, it will be stopped and rebuilt. **Any changes in the docker container will be lost. Backup your files before building** +### `Start.ps1` to start the server +### `Stop.ps1` to stop the server +### `Backup.ps1` to create a backup of the minecraft files +- If the container does not exist, backup will fail +- If the container exists, your files will be placed in `/backup/` folder +### `Restore.ps1` to restore your minecraft files onto the server +- If the container does not exist, restore will fail +- If the container exists, your files will be restored from `/backup/` folder to the server container \ No newline at end of file diff --git a/Restore.ps1 b/Restore.ps1 new file mode 100644 index 0000000..45fadbe --- /dev/null +++ b/Restore.ps1 @@ -0,0 +1,60 @@ +$containerName = "minecraft-server" +$backupDir = "$(pwd)/backup" + +if (-not (Test-Path -Path $backupDir)) { + Write-Host "Backup directory does not exist: $backupDir" + exit +} + +$container = docker ps -a --filter "name=$containerName" --format "{{.ID}}" +if (-not $container) { + Write-Host "The container $containerName does not exist. Cannot proceed with restore." + exit +} + +$container = docker ps --filter "name=$containerName" --filter "status=running" --format "{{.ID}}" +if ($container) { + Write-Host "Stopping the running container: $containerName" + docker stop $containerName +} else { + Write-Host "The container $containerName is not running." +} + +$itemsToRestore = @( + "banned-ips.json", + "banned-players.json", + "bukkit.yml", + "help.yml", + "commands.yml", + "ops.json", + "permissions.yml", + "server.properties", + "spigot.yml", + "usercache.json", + "whitelist.json", + "world", + "world_nether", + "world_the_end" +) + +foreach ($item in $itemsToRestore) { + $source = "$backupDir/$item" + $destination = "/minecraft/$item" + Write-Host "Restoring $item from $source to $destination" + if (Test-Path $source) { + if ((Get-Item $source).PSIsContainer) { + Write-Host "Restoring directory $item" + docker cp "$source" "$($containerName):/minecraft" + } else { + Write-Host "Restoring file $item" + docker cp "$source" "$($containerName):$destination" + } + } else { + Write-Host "File or directory $item does not exist in the backup." + } +} + +Write-Host "Starting the container: $containerName" +docker start $containerName + +Write-Host "Restore and restart completed successfully." diff --git a/Start.ps1 b/Start.ps1 new file mode 100644 index 0000000..d808f7e --- /dev/null +++ b/Start.ps1 @@ -0,0 +1,26 @@ +$containerName = "minecraft-server" +$imageName = "minecraft-spigot:latest" + +$container = docker ps -a --filter "name=$containerName" --format "{{.ID}}" +if ($container) { + $isRunning = docker ps --filter "name=$containerName" --filter "status=running" --format "{{.ID}}" + if ($isRunning) { + Write-Host "The container '$containerName' is already running." + } else { + Write-Host "The container '$containerName' exists but is not running. Starting it..." + docker start $containerName + } +} else { + Write-Host "The container '$containerName' does not exist. Creating it..." + docker create --name $containerName ` + -p 25565:25565 ` + -v "$(pwd)/plugins:/minecraft/plugins" ` + -v "$(pwd)/logs:/minecraft/logs" ` + --restart unless-stopped ` + minecraft-spigot + + Write-Host "Starting the container '$containerName'..." + docker start $containerName +} + +Write-Host "Server running at 25565..." diff --git a/Stop.ps1 b/Stop.ps1 new file mode 100644 index 0000000..201c070 --- /dev/null +++ b/Stop.ps1 @@ -0,0 +1,15 @@ +$containerName = "minecraft-server" +$container = docker ps -a --filter "name=$containerName" --format "{{.ID}}" +if ($container) { + $isRunning = docker ps --filter "name=$containerName" --filter "status=running" --format "{{.ID}}" + if ($isRunning) { + Write-Host "The container '$containerName' is running. Stopping it..." + docker stop $containerName + } else { + Write-Host "The container '$containerName' exists but is not running." + } +} else { + Write-Host "No container found with name: $containerName" +} + +Write-Host "Stopped"