diff --git a/Dockerfile b/Dockerfile index d435410..164ea03 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ FROM nginx:1.25.3 ENV PORT_IP_MAP "" ENV PYTHONUNBUFFERED=1 ENV PLACEHOLDER_SERVER_SLEEPING_IP "" +ENV PLACEHOLDER_SERVER_STARTING_IP "" # Install Python and pip RUN apt-get update && apt-get install -y python3 python3-pip python3-venv diff --git a/app/dockerHandler.py b/app/dockerHandler.py index dc6b8cd..5f28e82 100644 --- a/app/dockerHandler.py +++ b/app/dockerHandler.py @@ -40,3 +40,7 @@ class DockerHandler: print('no docker container found with ip {} in network {}'.format( ip, self.current_network)) return None + + def is_container_starting(self, container): + print(container.attrs['State']['Health']['Status']) + return container.attrs['State']['Health']['Status'] == 'starting' diff --git a/app/nginxHandler.py b/app/nginxHandler.py index 2b05d6e..a6451f0 100644 --- a/app/nginxHandler.py +++ b/app/nginxHandler.py @@ -25,7 +25,6 @@ class NginxHandler: print(f.read()) def setup_config_file(self, port_ip_map, current_container_ip): - placeholder_ip = os.environ.get('PLACEHOLDER_SERVER_SLEEPING_IP') proxy_timeout = "5s" self.stop() print('Setting up NGINX config file...') @@ -42,9 +41,6 @@ class NginxHandler: nginx_conf.write( ' server 127.0.0.1:{} backup;\n'.format(port)) - nginx_conf.write( - ' server {}:25565 backup;\n'.format(placeholder_ip)) - nginx_conf.write(' }\n') nginx_conf.write(' server {\n') diff --git a/app/requestHandler.py b/app/requestHandler.py index d587aff..765668d 100644 --- a/app/requestHandler.py +++ b/app/requestHandler.py @@ -1,4 +1,4 @@ -import json +import os import socket import threading from utils import docker_container_mapping @@ -32,27 +32,39 @@ class RequestHandler(threading.Thread): print('handling request on port {}'.format(self.port)) container_ip = docker_container_mapping().get(str(self.port)) if container_ip: + container = self.docker_handler.get_container_by_ip( + container_ip) + isStarting = self.docker_handler.is_container_starting(container) request = self.connection.recv(1024) - print('---------------------------') - print(request) - print('---------------------------') - if request[0] == 0x10: if b'\x01' in request: print('ping') - self.redirect_to_placeholder() + self.forward_request_to_server(request, isStarting) elif b'\x02' in request: print('join') - print('starting docker container {}'.format(container_ip)) - self.docker_handler.get_container_by_ip( - container_ip).start() + if isStarting: + print('container is starting, waiting for 5 seconds') + self.forward_request_to_server(request, isStarting) + else: + print('starting docker container {}'.format(container_ip)) + container.start() elif request[0] == 0xFE: print('legacy server list ping') - self.redirect_to_placeholder() + self.forward_request_to_server(request, isStarting) else: print('no docker container mapped to this port') - def redirect_to_placeholder(self): - print('redirecting to placeholder') + def forward_request_to_server(self, request, isStarting=False): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket: + ip = os.environ.get('PLACEHOLDER_SERVER_SLEEPING_IP') + if isStarting: + print('----------------container is starting, waiting for 5 seconds') + ip = os.environ.get('PLACEHOLDER_SERVER_STARTING_IP') + + server_socket.connect( + (ip, 25565)) + server_socket.sendall(request) + response = server_socket.recv(1024) + self.connection.sendall(response) diff --git a/docker-compose.yml b/docker-compose.yml index c8d6909..9a96bb7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,8 @@ services: - 25566:25566 environment: PLACEHOLDER_SERVER_SLEEPING_IP: "172.20.0.3" + PLACEHOLDER_SERVER_STARTING_IP: "172.20.0.4" + PORT_IP_MAP: | 25565: 172.20.0.5 25566: 172.20.0.6 @@ -26,8 +28,8 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock - mc_placeholder_server: - container_name: mc_placeholder_server + mc_placeholder_server_sleeping: + container_name: mc_placeholder_server_sleeping image: itzg/minecraft-server environment: type: "PAPER" @@ -40,6 +42,20 @@ services: mc_network: ipv4_address: 172.20.0.3 + mc_placeholder_server_starting: + container_name: mc_placeholder_server_starting + image: itzg/minecraft-server + environment: + type: "PAPER" + EULA: "TRUE" + MOTD: "Starting..." + MAX_PLAYERS: "0" + MAX_MEMORY: "500M" + INIT_MEMORY: "100M" + networks: + mc_network: + ipv4_address: 172.20.0.4 + mc: container_name: example_mc_server_1 image: itzg/minecraft-server @@ -48,6 +64,9 @@ services: EULA: "TRUE" MOTD: "TEST1" MAX_PLAYERS: "0" + ENABLE_AUTOSTOP: "TRUE" + AUTOSTOP_TIMEOUT_EST: "30" + AAUTOSTOP_TIMEOUT_INIT: "10" #! Dont change SERVER_PORT. Use PORT_IP_MAP in auto_starter instead. #! SERVER_PORT default is "25565" networks: @@ -60,6 +79,9 @@ services: type: "PAPER" EULA: "TRUE" MOTD: "TEST2" + ENABLE_AUTOSTOP: "TRUE" + AUTOSTOP_TIMEOUT_EST: "30" + AAUTOSTOP_TIMEOUT_INIT: "10" #! Dont change SERVER_PORT. Use PORT_IP_MAP in minecraft_server_auto_starter instead. #! SERVER_PORT default is "25565" networks: