How to setup own minecraft server

How to setup own minecraft server

W tym wpisie, który będzie stosunkowo krótki przedstawię krok po kroku, jakie czynności podjąć aby uruchomić własny serwer Minecraft. Bazować będę na czystej instalacji Ubuntu 22.04 oraz na najnowszej wersji Minecraft - 1.20.4, mimo to wpis powinien pomóc Tobie w uruchomieniu serwera w dowolnej wersji.

Aby świadczyć usługę przez internet, tj. aby ktoś spoza Twojej sieci mógł się podłączyć do Twojego serwera, koniecznie potrzebujesz posiadać publiczny adres IP

JAVA #

Sposób pierwszy, wykorzystanie plików binarnych i uruchomienie instancji bezpośrednio w Java. Na sam początek zainstalować należy java-jdk, java-jre

sudo apt install -y openjdk-17-jdk openjdk-17-jre

Następnym krokiem jest przygotowanie użytkownika z poziomu, którego będziemy uruchamiać nasz serwer. Krok jest opcjonalny, jednak mocno zalezam aby przejść przez ten punkt. W przypadku jakiegoś włamania poprzez atak na usługę serwera minecraft, potencjalny atakujący będzie mógł zrobić tyle na ile pozwolą jemu uprawnienia użytkownika, który uruchomił usługę, z tego właśnie względu zalecam aby był użytkownik dedykowany dla działania serwera minecraft (czy każdej innej usługi).

useradd -c "minecraft server" -m -s /bin/bash minecraft

W powyższym przykładzie wykorzystałem polecenie useradd w celu utworzenia użytkownika o loginie minecraft, z ustawioną powłoką systemową na /bin/bash oraz ustawionym komentarzem minecraft server w celu latwiejszej identyfikacji cóż to za user i po co w systemie. Ostatnim parametrem -m jest flaga instrująca program do utworzenia katalogu domowego w /home. Teraz dokonuję przełączenia się na nowo powstałego użytkownika, aby to z jego konta dokonać dalszych prac.

su - minecraft

W powyższym minecraft to nazwa użytkownika, którego przed chwilą utworzyłem. I to w sumie tyle jeżeli chodzi o część opcjonalną, a wysoce zalecaną. W kolejnym kroku będzie utworzenie katalogu, gdzie chciałbym aby się znalazły wszystkie powiązane pliki z usługą, a następnie przełączam się do powstałego katalogu.

mkdir server
cd server

Na stronie minecraft.net znajduje się link do najnowszej wersji, w moim przypadku na moment pisanie tego posta jest to wersja 1.20.4. Skopiowałem link prowadzący bezpośrednio do wybranego przeze mnie pliku i za pomocą wget zapisuje plik do mojego katalogu server. Fakt, że plik zapisze mi się w wybranym przeze mnie katalogu wynika z tego, że w kroku poprzednim przeszedłem do wybranego miejsca docelowego poleceniem cd.

wget https://piston-data.mojang.com/v1/objects/8dd1a28015f51b1803213892b50b7b4fc76e594d/server.jar

Teraz nie stoi nic na przeszkodzie, aby uruchomić serwer i spróbować się do niego podłączyć klientem.

java -Xmx1024M -Xms1024M -jar server.jar nogui

Pierwsze uruchomienie zakończy się błędem i komunikatem jak ten poniżej

[10:28:57] [ServerMain/ERROR]: Failed to load properties from file: server.properties
java.nio.file.NoSuchFileException: server.properties
        at sun.nio.fs.UnixException.translateToIOException(UnixException.java:92) ~[?:?]
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106) ~[?:?]
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[?:?]
        at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218) ~[?:?]
        at java.nio.file.Files.newByteChannel(Files.java:380) ~[?:?]
        at java.nio.file.Files.newByteChannel(Files.java:432) ~[?:?]
        at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:422) ~[?:?]
        at java.nio.file.Files.newInputStream(Files.java:160) ~[?:?]
        at ame.b(SourceFile:62) ~[server-1.20.4.jar:?]
        at amb.a(SourceFile:138) ~[server-1.20.4.jar:?]
        at amc.<init>(SourceFile:12) ~[server-1.20.4.jar:?]
        at net.minecraft.server.Main.main(SourceFile:112) ~[server-1.20.4.jar:?]
        at net.minecraft.bundler.Main.lambda$run$0(Main.java:54) ~[?:?]
        at java.lang.Thread.run(Thread.java:840) ~[?:?]
[10:28:57] [ServerMain/WARN]: Failed to load eula.txt
[10:28:57] [ServerMain/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.

Oznacza to tyle, że nie wykryło zapoznania się z EULA oraz brakuje ustawień w pliku server.properties. Na koniec wszystkiego plik server.properties jest generowany oraz powstaje także plik eula.txt. Akceptacja postawień licencyjnych odbywa się poprzez zapoznanie się z ich treścią, które dostępne są pod linkiem znajdującym się w pliku eula.txt, a następnie zmianie wartości false na true. Drugą rzeczą jaką zrobię to przełączenie serwera w tryb offline. Odbywa się to poprzez zmianę w pliku server.properties wartości dla online-mode - tym razem na odwrot - z true na false. Po tych zmianach możemy ponownie wywołać wcześniejsze polecenie.

java -Xmx1024M -Xms1024M -jar server.jar nogui

That’s all. Server jest up & running, można się podłączać.

Autorun #

Skoro jest to serwer, to mogłaby być chęć aby usługa uruchamiała się razem ze startem systemu, odpalenie ponowne w przypadku nie oczekiwanego krachu serwera. Wiele razy spotkałem się, że remedium na ciągłe działanie usługi to było wykorzystanie screen i o ile faktycznie pozowli na działanie w tle bez potrzeby bycia podłączonym do maszyny przez SSH, to o tyle nie wystartuje się samoczynnie w przypadku nie oczekiwanego zakończenia działania procesu. Poniżej zaprezentuje kilka możliwości. Możesz dowolnie wybrać, którą drogą chcesz iść.

supervisord #

Screen nie daje rady, nie startuje usługi? To tu wchodzi cały na biało supervisord.

Zacznijmy od tego jak to zainstalować.

apt install supervisor

Pliki konfiguracyjne dla tej usługi są przechowywane w /etc/supervisor. Natomiast w podfolderze conf.d są przechowywane konfiguracje tworzone przez administratorów systemu i tu też utworzymy nasz plik minecraft.conf z treścią:

[program:minecraft-server]
command=/usr/bin/java -Xmn128M -Xmx2048M -jar /home/minecraft/server/server.jar nogui
directory=/home/minecraft/server
user=minecraft
group=minecraft
autostart=true
autorestart=true
stdout_logfile=/home/minecraft/server/logs/stdout.log
stderr_logfile=/home/minecraft/server/logs/stderr.log

Słów kilka wyjaśnienia. W nawiasach kwadratowych musimy zachować odpowiednią składnię jaką jest program:naszaDowolnaNazwa, w nastepnych wierszach opisujemy usługę. command to informacja jakie polecenie chcemy wywołać i chyba na pierwszy rzut oka widać, że należy podać pełną ścieżkę do java oraz do pliku server.jar, który był wcześniej pobierany. W następnych wierszach definiujemy na czyich prawach usługa ma się uruchamiać. Ja wcześniej utworzyłem użytkownika minecraft w części opcjonalnej, a jednocześnie system domyślnie utworzył grupę o tej samej nazwie, dlatego u mnie user oraz group posiadają wartość minecraft. Natomiast jeżeli czytelniku pominąłeś tą część ( nie wierzę, że to piszę ) wpisz konto root ( matko! jakie to jest złe ). Kolejne wiersze to definiujemy czy ma nastąpić autostart, a także autorestart w przypadku awari. Dwa ostatnie są odpowiedzialne za wskazanie ścieżek gdzie mają być zapisywane logi - ja chciałem mieć wszystko w jednym miejscu, więc bez wachania wskazałem podkatalog logs dla katalogu server, który także wcześniej tworzyłem. Po zrestartowaniu usługi supervisor, nasza usługa uruchomi się automatycznie.

systemd restart supervisor

W celu zobaczenia czy supervisor zaczytał nasz plik konfiguracyjny możemy skorzystać z supervisorctl

root@minecraft:/home/minecraft/server/logs# supervisorctl
minecraft-server                 RUNNING   pid 4475, uptime 0:03:11

Także, można zweryfikować jak wygląda na liście procesów

root@minecraft:/home/minecraft/server/logs# ps aufwx
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           2  0.0  0.0      0     0 ?        S    09:29   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   09:29   0:00  \_ [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   09:29   0:00  \_ [rcu_par_gp]
---CUT---
root        4474  0.2  0.6  34220 27580 ?        Ss   11:23   0:00 /usr/bin/python3 /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
minecra+    4475 76.2 23.9 4199480 960732 ?      Sl   11:23   0:57  \_ /usr/bin/java -Xmn128M -Xmx2048M -jar /home/minecraft/server/server.jar nogui

Widać, że proces supervisord uruchomiony na prawach użytkownika root, ma podproces na prawach użytkownika minecraft. Jak zarządzać tak uruchomioną usługą? Bardzo prosto.

supervisor> ?

default commands (type help <topic>):
=====================================
add    exit      open  reload  restart   start   tail
avail  fg        pid   remove  shutdown  status  update
clear  maintail  quit  reread  signal    stop    version

Na liście powyżej, która jest wynikiem wpisania ‘?’ do CLI supervisord. W przypadku jeśli mamy potrzebę zatrzymania serwer minecraft wpiszemy stop minecraft-server, jeśli chcemy poznać obecny status uruchomionych usług przez supervisord, to skorzystać można z polecenia status, wystartować - start minecraft-server, a w przypadku śledzenia logów, skorzystać można z tail minecraft-server.

supervisor> stop minecraft-server
minecraft-server: stopped
supervisor> status
minecraft-server                 STOPPED   Dec 24 11:30 AM
supervisor> start minecraft-server
minecraft-server: started
supervisor> tail minecraft-server
Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:53] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:54] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:54] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:55] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:55] [Worker-Main-1/INFO]: Preparing spawn area: 0%
[11:23:56] [Server thread/INFO]: Time elapsed: 13868 ms
[11:23:56] [Server thread/INFO]: Done (22.772s)! For help, type "help"
Starting net.minecraft.server.Main

supervisor>

W tej części opisałem w jaki sposób zainstalować oraz skonfigurować supervisord, do tego aby zadbał o nasz serwer minecraft.

systemd #

systemd, to już domyślna usługa dla linuksa, która jest odpowiedzialna za dbanie o uruchamianie wskazanych usług, a także i przede wszystkim systemowych. Nie ma potrzeby nic więcej doinstalowywać. Zatem przejdźmy od razu do konfigurowania. Tworzymy plik konfiguracyjny

systemctl edit --force --full minecraft.service

I wklejamy konigurację, zmieniając parametry pod nasze potrzeby:

[Unit]
Description=Minecraft Server
Wants=network-online.target
After=network-online.target

[Service]
# Ensure to set the correct user and working directory (installation directory of your server) here
User=minecraft
WorkingDirectory=/home/minecraft/server

# You can customize the maximum amount of memory as well as the JVM flags here
ExecStart=/usr/bin/java -Xmn128M -Xmx2048M -jar /home/minecraft/server/server.jar nogui

# Restart the server when it is stopped or crashed after 30 seconds
# Comment out RestartSec if you want to restart immediately
Restart=always
RestartSec=30

# Alternative: Restart the server only when it stops regularly
# Restart=on-success

# Do not remove this!
StandardInput=null

[Install]
WantedBy=multi-user.target

Sekcja Unit nie wymaga żadnych zmian, natomiast w Service w user ustawiamy użytkownika, na prawach którego będzie działać usługa, ja w tym miejscu wpisałem nazwę użytkownika minecraft, którego utworzyłem w częsci opcjonalnej, lecz mocno rekomendowanej, możesz wpisać root lecz jest to cholernie złe i ogromnie nie zalecane. Workingdirectory to informacja, o katalogu roboczym dla usługi i ponownie wskazałem folder, który utworzyłem wcześniej. ExecStart to wartość, która przechowuje informacje o tym co ma się uruchomić i tu podałem pełną ścieżkę do pliku java oraz pełną ścieżkę do pliku server.jar. Po zapisaniu zmian możemy przeładować ustawienia demonów, uruchomić usługę oraz dodać ją do autostartu.

systemctl daemon-reload
systemctl start minecraft
systemctl enable minecraft

Logi na bieżące można zobaczyć używając komendy

journalctl -fu minecraft
Powyżej używam `minecraft` ponieważ taką nazwę podałem w trakcie tworzenia pliku .service na początku tego rozdziału.

To tyle, po wystartowaniu usługi jestem w stanie podlaczyć sie do swojego nowego serwera minecraft.

Docker #

Kiedyś zapewne powstanie jakiś wpis wprowadzający w temateyke konteneryzacji. Natomiast to nie ten czas, bardziej chcę się tu skupić jak zainstalować i wprowadzić w uruchomienie.

Sama instalacja na systemie Ubuntu 22.04, jest nieziemsko prosta. Jako root wywolujesz poniższego oneliner’a

curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh

W następnym kroku przygotuję sobie katalog, w którym chcę mieć wszystkie potrzebne pliki, żeby nie całość nie rozrzuciła się w losowych miejscach.

mkdir -p /apps/minecraft

Zostanie tutaj wykorzystany gotowy obraz itzg/docker-minecraft-server. Jak później zobaczymy obraz ten potrafi wiele. Zatem do wyżej utworzonego katalogu tworzę plik docker-compose.yml o następującej zawartości.

version: "3.8"

services:
  mc:
    image: itzg/minecraft-server
    environment:
      EULA: "true"
      ONLINE_MODE: "false"
    ports:
      - "25565:25565"
    volumes:
      - data:/data
    stdin_open: true
    tty: true
    restart: unless-stopped
volumes:
  data: {}
Pamiętaj, że jest to plik yaml i jest bardzo wrażliwy na wcięcia

Kiedy zmiany zostaną wprowadzone oraz zapisane ostatnią rzeczą do uruchomienia usługi jest wydanie polecenia docker compose up -d. Ta komenda wywoła pobranie obrazu z hub.docker.com jeśli jeszcze nie ma go na maszynie, przygotuje sieć wewnętrzną, wolumin, a na samym końcu uruchomi kontener z odpowiednimi parametrami.

Ważną dokumentacją dotyczącą konfigurowania serwera w kontenerze będzie dokumentacja dotycząca zmiennych dla tego obrazu. Wynika to z tego, że zamiast zmieniać wartości w pliku bezpośrednio server.properties będzie się to odbywać poprzez zmienne. Bazując na powyższym przykładzie, są 2 zmienny:

  • EULA - definiująca zatwierdzenie warunków licencyjnych
  • ONLINE_MODE - definiująca, że serwer w tym przypadku jest offline, może przyjmować graczy bez konta Mojang

Jeżeli będzie potrzeba wprowadzenia innych parametrów, należy je odnaleźć na w/w stronie dokuemntacji, a następnie wprowadzić zmiany do pliku docker-compose.yml, po czym za pomocą polecenia docker compose up -d wywołać przeładowanie kontenera. Docker “zauważy” zmiany wprowadzone w pliku i utworzy na nowo kontener z naszą usługą.

Comments powered by Talkyard.