Created
March 7, 2019 11:11
-
-
Save romanpeters/136270409663308d29f0f69fa187833c to your computer and use it in GitHub Desktop.
Automatically start and stop Minecraft server docker container (itzg/minecraft-server)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This script automatically starts and stops a Minecraft server's Docker container. | |
If someone tries to join the container is started. | |
If no players are online anymore the container is stopped. | |
""" | |
import socket | |
import time | |
import subprocess | |
import logging | |
import sys | |
# adjust these variables as needed | |
HOST = "127.0.0.1" | |
PORT = 25565 | |
CONTAINER = "minecraft-server" | |
logger = logging.getLogger() | |
logging.basicConfig(level=logging.DEBUG) | |
def start_server(): | |
command = f"docker start {CONTAINER}" | |
subprocess.run(command.split()) | |
logger.info("Started server") | |
def stop_server(): | |
command = f"docker stop {CONTAINER}" | |
subprocess.run(command.split()) | |
logger.info("Stopped server") | |
def players_online(): | |
command = f"docker exec {CONTAINER} mcstatus localhost status" | |
try: | |
status = subprocess.check_output(command.split()) | |
except subprocess.CalledProcessError: | |
logger.warn(f"Failed to check mcstatus, assuming {CONTAINER} is not running") | |
False | |
else: | |
if "players: 0" in str(status): | |
return False | |
return True | |
def wait_for_connection(): | |
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
serversocket.bind((HOST, PORT)) | |
serversocket.listen(5) | |
logger.info("Waiting for connection...") | |
(clientsocket, address) = serversocket.accept() | |
logger.info(f"Got a connection from {address}") | |
clientsocket.send("Server is starting".encode("utf-8")) | |
logger.debug("Closing sockets") | |
clientsocket.close() | |
serversocket.close() | |
def wait_for_empty_server(): | |
while players_online(): | |
logger.debug("Minecraft Server is active, sleeping for 300 seconds") | |
time.sleep(300) | |
logger.debug("Minecraft Server is not active") | |
if __name__=="__main__": | |
# Start the main flow | |
while True: | |
wait_for_empty_server() | |
sys.stdout.flush() # show log in systemd service | |
stop_server() | |
sys.stdout.flush() | |
wait_for_connection() | |
sys.stdout.flush() | |
logger.debug("Wait 1 second for the port to become available") | |
time.sleep(1) | |
start_server() | |
sys.stdout.flush() | |
logger.debug("Wait 90 seconds for the player to join") | |
time.sleep(90) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment