diff --git a/app/app.py b/app/app.py index 77e9288..dab4f23 100644 --- a/app/app.py +++ b/app/app.py @@ -2,6 +2,7 @@ from requestHandler import RequestHandler from utils import docker_container_mapping from dockerHandler import DockerHandler from nginxHandler import NginxHandler +import time def main(): @@ -11,16 +12,17 @@ def main(): docker_handler = DockerHandler( 'unix://var/run/docker.sock', port_ip_map) - # Create a RequestHandler instance for each port - for port in port_ip_map.keys(): - request_handler = RequestHandler(port, docker_handler) - request_handler.start() - # Create an NginxHandler instance nginx_handler = NginxHandler('/etc/nginx/nginx.conf') nginx_handler.setup_config_file( docker_container_mapping(), docker_handler.get_current_container_ip()) nginx_handler.print_config() + # Create a RequestHandler instance for each port + for port in port_ip_map.keys(): + print(f'Creating request handler for port {port}') + request_handler = RequestHandler(int(port), docker_handler) + request_handler.start() + main() diff --git a/app/dockerHandler.py b/app/dockerHandler.py index 7e04b9a..b244c65 100644 --- a/app/dockerHandler.py +++ b/app/dockerHandler.py @@ -5,7 +5,7 @@ import os class DockerHandler: def __init__(self, base_url, port_ip_map): print( - f'initializing docker handler with base url {base_url} and port ip map {port_ip_map}') + f'Initializing docker handler with base url {base_url} and port ip map: {port_ip_map}') self.base_url = base_url self.client = docker.DockerClient(base_url=base_url) self.port_ip_map = port_ip_map diff --git a/app/requestHandler.py b/app/requestHandler.py index 8dcb000..5a2f2f2 100644 --- a/app/requestHandler.py +++ b/app/requestHandler.py @@ -17,13 +17,18 @@ class RequestHandler(threading.Thread): def run(self): while True: - print(f'Waiting for a connection on port {self.port}') - self.connection, self.client_address = self.sock.accept() try: - print('Connection from', self.client_address) - self.handle_request() - finally: - self.connection.close() + print(f'Waiting for a connection on port {self.port}') + self.connection, self.client_address = self.sock.accept() + try: + print('Connection from', self.client_address) + self.handle_request() + finally: + self.connection.close() + except Exception as e: + print(f'Error in request handler for port {self.port}: {e}') + print('Restarting request handler...') + self.__init__(self.port, self.docker_handler) def handle_request(self): print(f'Handling request on port {self.port}') @@ -36,25 +41,26 @@ class RequestHandler(threading.Thread): if request[0] == 0x10: if b'\x01' in request: print(f'Detected ping request for {container_ip}') - self.forward_request_to_server(request, isStarting) + self.forward_request_to_placeholder(request, isStarting) elif b'\x02' in request: print(f'Detected join/login request for {container_ip}') if isStarting: print( f'Container {container_ip} is already starting...') - self.forward_request_to_server(request, isStarting) + self.forward_request_to_placeholder( + request, isStarting) else: print(f'Starting container {container_ip}') container.start() elif request[0] == 0xFE: print(f'Detected legacy ping request for {container_ip}') - self.forward_request_to_server(request, isStarting) + self.forward_request_to_placeholder(request, isStarting) else: print(f'No container mapped to port {self.port}') - def forward_request_to_server(self, request, isStarting=False): + def forward_request_to_placeholder(self, request, isStarting=False): print('Forwarding request to placeholder server') with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket: ip = os.environ.get('PLACEHOLDER_SERVER_SLEEPING_IP') diff --git a/docker-compose.yml b/docker-compose.yml index 74a1b9b..fe555c5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,7 @@ networks: services: auto_starter: container_name: mc_auto_starter + restart: always build: . ports: - 25565:25565 @@ -39,46 +40,72 @@ services: # Keep in mind these servers are consuming some resources mc_placeholder_server_sleeping: container_name: mc_placeholder_server_sleeping - image: itzg/minecraft-server + restart: always + image: itzg/minecraft-server:java8 environment: - type: "PAPER" + VERSION: "1.12.2" EULA: "TRUE" - MOTD: "Sleeping | Join & Wait to wake up" + MOTD: "Sleeping | Join to wake up" + + # The placeholder servers should be as lightweight as possible MAX_PLAYERS: "0" - MAX_MEMORY: "500M" - INIT_MEMORY: "100M" + MAX_MEMORY: "512M" + INIT_MEMORY: "512M" + LEVEL_TYPE: "FLAT" + JVM_XX_OPTS: "-XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -XX:+UseCompressedOops" + VIEW_DISTANCE: "1" + SPAWN_ANIMALS: "false" + SPAWN_MONSTERS: "false" + SNOOPER_ENABLED: "false" + GENERATE_STRUCTURES: "false" + ALLOW_NETHER: "false" + ALLOW_END: "false" networks: mc_network: ipv4_address: 172.20.0.3 mc_placeholder_server_starting: container_name: mc_placeholder_server_starting - image: itzg/minecraft-server + restart: always + image: itzg/minecraft-server:java8 environment: - type: "PAPER" + VERSION: "1.12.2" EULA: "TRUE" - MOTD: "Starting..." + MOTD: "Starting, please wait..." + + # The placeholder servers should be as lightweight as possible MAX_PLAYERS: "0" - MAX_MEMORY: "500M" - INIT_MEMORY: "100M" + MAX_MEMORY: "512M" + INIT_MEMORY: "512M" + LEVEL_TYPE: "FLAT" + JVM_XX_OPTS: "-XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -XX:+UseCompressedOops" + VIEW_DISTANCE: "1" + SPAWN_ANIMALS: "false" + SPAWN_MONSTERS: "false" + SNOOPER_ENABLED: "false" + GENERATE_STRUCTURES: "false" + ALLOW_NETHER: "false" + ALLOW_END: "false" networks: mc_network: ipv4_address: 172.20.0.4 # These are the actual servers + # For itzg/minecraft-server you can find the documentation here: https://docker-minecraft-server.readthedocs.io/en/latest/variables/ mc: container_name: example_mc_server_1 image: itzg/minecraft-server + restart: no #! This is important. If you restart the server automatically, the auto_starter will not work environment: type: "PAPER" EULA: "TRUE" - MOTD: "TEST1" - MAX_PLAYERS: "0" + MOTD: "Example Server 1" + MAX_PLAYERS: "1" # Enable autostop, so the auto_starter makes sense ENABLE_AUTOSTOP: "TRUE" - AUTOSTOP_TIMEOUT_EST: "30" - AAUTOSTOP_TIMEOUT_INIT: "10" + AUTOSTOP_TIMEOUT_EST: "10" + AUTOSTOP_TIMEOUT_INIT: "10" #! Dont change SERVER_PORT. Use PORT_IP_MAP in auto_starter instead. #! SERVER_PORT default is "25565" networks: @@ -87,15 +114,17 @@ services: mc2: container_name: example_mc_server_2 image: itzg/minecraft-server + restart: no #! This is important. If you restart the server automatically, the auto_starter will not work environment: type: "PAPER" EULA: "TRUE" - MOTD: "TEST2" + MOTD: "Example Server 2" + MAX_PLAYERS: "1" # Enable autostop, so the auto_starter makes sense ENABLE_AUTOSTOP: "TRUE" - AUTOSTOP_TIMEOUT_EST: "30" - AAUTOSTOP_TIMEOUT_INIT: "10" + AUTOSTOP_TIMEOUT_EST: "10" + AUTOSTOP_TIMEOUT_INIT: "10" #! Dont change SERVER_PORT. Use PORT_IP_MAP in auto_starter instead. # SERVER_PORT default is "25565" networks: