Disclaimer
This is just like a memo for myself. No detailed explanation. Please google the keywords if you need.
Goal
To launch Minecraft server for with friends (= outside of my LAN) using my old laptop.
Some said they want to play Java Edition (JE), whilst others wanted Bedrock Edition (BE). So I tryed running both versions simultaneously, which is now successfully working.
Requirements
- Assuming up to 5 users' simultaneous connections
- Shutdown automatically every morning, and reboot every evening (some people warn that one should not run a laptop for 24h as a server)
- Assign one of my sub-domain for the server so that users can access the server easily.
Rig
ASUS UX305FA-5Y71
- CPU: Core M-5Y71 (2 cores, 4 threads, 1.2 GHz base - 2.9 GHz max., TDP 4.5W)
- RAM: 8GB
- Strage: 128GB SSD
Ubuntu 20.04 LTS (with GUI) was already installed.
What I did
Unplug its inner battery
This is a very important step for safety. The rig is expected to be connected with the power plug while running as a server, which is an inadequate condition for the Li-ion battery.
Open the bottom cover of the laptop, and unplug the battery from the circuit board. Then, mask the battery-side connecter with tape to isolate electrically.
Preparation
- Install Docker
Follow the instruction in Docker official document. - Install SSH Server (
sudo apt install openssh-server) - Make Directories:
- ~/Minecraft
- ./data
- ./mc-backup
- ~/Minecraft-be
- ./data
- ~/Minecraft
- Disable GUI (
sudo systemctl set-default multi-user.target)
(You can do this whenever you like, and redo this bysudo systemctl set-default graphical.target)
cf. https://tek2tech.com/ubuntu-2004-desktop-environment/
Pull Docker Image
- https://hub.docker.com/r/itzg/minecraft-server
- https://hub.docker.com/r/itzg/mc-backup
- https://hub.docker.com/r/itzg/minecraft-bedrock-server
cf.
https://frontl1ne.net/2019/10/docker-minecraft/
Write docker-compose.yml
cf. https://oldbigbuddha.dev/posts/my-server-for-minecraft
version: "3"
services:
# Application
mc-paper:
image: itzg/minecraft-server
ports:
- 25565:25565
- 25575:25575
environment:
EULA: "TRUE"
TYPE: "PAPER"
INIT_MEMORY: "1G"
MAX_MEMORY: "4G"
STOP_SERVER_ANNOUNCE_DELAY: 60
# Disable following AutoPause-related settings
# due to Spigot's error.
#
# ENABLE_AUTOPAUSE: "TRUE"
# MAX_TICK_TIME: "-1"
# More aggressive settings for demo purposes
# AUTOPAUSE_TIMEOUT_INIT: "30"
# AUTOPAUSE_TIMEOUT_EST: "10"
#
# OVERRIDE_SERVER_PROPERTIES: "TRUE"
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
tty: true
stdin_open: true
restart: always
deploy:
resources:
limits:
memory: 4500m
# Backup
backup:
image: itzg/mc-backup
environment:
BACKUP_INTERVAL: "6h"
PRUNE_BACKUPS_DAYS: 3
PAUSE_IF_NO_PLAYERS: "false"
INITIAL_DELAY: "10m"
depends_on:
- mc-paper
volumes:
- ./data:/data:ro
- ./mc-backups:/backups
- /etc/timezone:/etc/timezone:ro
restart: unless-stopped
network_mode: "service:mc-paper"
version: "3"
services:
# Application
mc-be:
image: itzg/minecraft-bedrock-server
ports:
- 19132:19132/udp
environment:
EULA: "TRUE"
SERVER_NAME: "My_MineCraft_Bedrock"
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
tty: true
stdin_open: true
restart: always
deploy:
resources:
limits:
memory: 2500m
To make the RAM resource limits effective, we need to desiginate --compatibility options when docker-compose up and down. This is not recommended, according to the docker official. If your machine has plenty amount of RAM, you may not need to determine the limit and use --compatibility option.
Allow the user to run docker without sudo
cf. https://qiita.com/DQNEO/items/da5df074c48b012152ee
$ sudo groupadd docker
$ sudo gpasswd -a <USERNAME> docker
$ sudo systemctl restart docker
Then, reboot (or relogin) to enable the setting.
Define Firewall Ruleset
$ sudo ufw status
Status: active
To Action From
-- ------ ----
22 ALLOW 192.168.11.0/24
25565/tcp ALLOW Anywhere
25575 ALLOW 192.168.11.0/24
19132 ALLOW Anywhere
25565/tcp (v6) ALLOW Anywhere (v6)
19132 (v6) ALLOW Anywhere (v6)
Note:
- Port 22 ... for SSH (only from LAN)
- Port 25565 ... for Minecraft Java Edition (TCP)
- Port 25575 ... for Minecraft Java RCON (only from LAN) (TCP)
- Port 19132 ... for Minecraft Bedrock Edition (UDP (+TCP ?))
Don't forget setting the port forwarding up of the router.
Prevent the System from Sleep Mode When the Lid is Closed
Add HandleLidSwitch=ignore in /etc/systemd/logind.conf.
Prepare Shell Scripts for docker-compose up and docker-compose down
#!usr/bin/bash -l
echo `date +%Y-%m-%dT%H:%M:%S`\| Launching JAVA Edition on mc-je screen
/usr/bin/screen -U -A -m -d -S mc-je /usr/local/bin/docker-compose --file /home/<USERNAME>/Minecraft/docker-compose.yml --compatibility up
echo `date +%Y-%m-%dT%H:%M:%S`\| Waiting for 5 min ...
sleep 300
echo `date +%Y-%m-%dT%H:%M:%S`\| Launching BedRock Edition on the mc-be screen
/usr/bin/screen -U -A -m -d -S mc-be /usr/local/bin/docker-compose --file /home/<USERNAME>/Minecraft-be/docker-compose.yml --compatibility up
#!usr/bin/bash -l
echo `date +%Y-%m-%dT%H:%M:%S`\| Shutting Minecraft JAVA Edition down...
/usr/local/bin/docker-compose --file /home/<USERNAME>/Minecraft/docker-compose.yml --compatibility down -t 600
echo `date +%Y-%m-%dT%H:%M:%S`\| Shutting Minecraft BedRock Edition down...
/usr/local/bin/docker-compose --file /home/<USERNAME>/Minecraft-be/docker-compose.yml --compatibility down -t 600
Save backups and transfer them to NAS via FTP
cf. https://qiita.com/kabegamikamio/items/9c1a30c63de31be834da
For JAVA editon, we can use itzg/mc-backup docker package. However, for bedrock edition, we need to manage backup by ourselves.
#!/bin/bash
TARGET_DIR=/home/<USERNAME>/Minecraft-be/data/worlds
BACKUP_DIR=/home/<USERNAME>/Minecraft-be/backup/`date +%Y-%m-%d_%H:%M:%S`
BACKUP_FOLDER=/home/<USERNAME>/Minecraft-be/backup/
NUM_GENS=5
delete_file () {
CNT=0
for file in `ls -1t ${BACKUP_FOLDER}*.zip`
do
CNT=$((CNT+1))
if [ $CNT -le $NUM_GENS ]; then
continue
fi
eval "rm ${file}"
done
}
makezip () {
zip ${1} -r ${2}
}
make_zip $BACKUP_DIR $TARGET_DIR
delete_file
This code compresses the world folder to a timestamped zip file and delete past file to remain last NUM_GEN (=5, in this example) backups.
And, to keep these backups more solidly, I upload them onto my local NAS using FTP:
#!/usr/bin/bash -l
/usr/bin/ftp -n >> /home/<USERNAME>/Minecraft/ftp-upload.log << EOF
verbose
open <IP ADDRESS>
user <FTP USERNAME> <FTP PASSWORD>
prompt
passive
cd /mc-backup/je/
lcd /home/<USERNAME>/Minecraft/mc-backups
mput *
cd /mc-backup/be
lcd /home/<USERNAME>/Minecraft-be/backup
mput *
bye
EOF
Note: it may be better to designate "ftp -n -p" to make sure to use active mode.
Write crontab settings
$ crontab -e
This command opens the crontab setting file with an editor. My setting is as below:
# m h dom mon dow command
SHELL=/usr/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin/
@reboot bash -l /home/<USERNAME>/Minecraft/Minecraft-up.sh >> /home/(USERNAME)/Minecraft/Minecraft-up.log 2>&1
00 1 * * * bash -l /home/<USERNAME>/Minecraft-be/be-backup.sh >> /home/(USERNAME)/Minecraft-be/be-backup.log 2>&1
5 8 * * * bash -l /home/<USERNAME>/Minecraft/Minecraft-down.sh >> /home/(USERNAME)/Minecraft/Minecraft-down.log 2>&1
10 8 * * * bash -l /home/<USERNAME>/Minecraft-be/be-backup.sh >> /home/(USERNAME)/Minecraft-be/be-backup.log 2>&1
15 8 * * * bash -l /home/<USERNAME>/Minecraft/Minecraft-down.sh >> /home/(USERNAME)/Minecraft/Minecraft-down.log 2>&1
To set up auto scheduled shutdown and restart using rtcwake, we need to execute crontab under sudo:
$ crontab -e
# m h dom mon dow command
SHELL=/usr/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
20 8 * * * /usr/sbin/rtcwake -s 36000 -m off >> /home/<USERNAME>/Minecraft/Minecraft-servershutdown.log 2>&1
This setting schedules automatic shutdown (=-m off) at 08:20 every morning and automatic reboot at 18:20 (= -s 36000 = 36,000 seconds = 10 hours after 08:20).
cf.
https://awnet.org/archives/53
https://freefielder.jp/blog/2018/07/ubuntu-cron-sudo.html
Appendix. Automatic Login when booted
This is possibly unnecessary for this work.
One may be need to create /etc/systemd/system/getty@tty1.service.d directory and override.conf file before execute the scripts above.
sudo systemctl edit getty@tty1
[Service]
ExecStart=
ExecStart=-/sbin/agetty/ --noissue --autologin (USERNAME) %I $TERM
Type=idle
cf.
https://zenn.dev/noraworld/articles/ubuntu-reboot-auto-login
https://askubuntu.com/questions/819117/how-can-i-get-autologin-at-startup-working-on-ubuntu-server-16-04-1