Skip to content

Instantly share code, notes, and snippets.

@romanpeters
Created March 7, 2019 11:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save romanpeters/136270409663308d29f0f69fa187833c to your computer and use it in GitHub Desktop.
Save romanpeters/136270409663308d29f0f69fa187833c to your computer and use it in GitHub Desktop.
Automatically start and stop Minecraft server docker container (itzg/minecraft-server)
"""
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