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