Update Docker and NGINX configurations

This commit is contained in:
Janis
2023-12-08 00:26:23 +01:00
parent 4126feef38
commit 92054a114d
7 changed files with 94 additions and 62 deletions

View File

@@ -1,10 +1,14 @@
import logging
from requestHandler import RequestHandler from requestHandler import RequestHandler
from utils import docker_container_mapping from utils import docker_container_mapping
from dockerHandler import DockerHandler from dockerHandler import DockerHandler
from nginxHandler import NginxHandler from nginxHandler import NginxHandler
logging.basicConfig(level=logging.INFO)
def main(): def main():
try:
port_ip_map = docker_container_mapping() port_ip_map = docker_container_mapping()
# Create a DockerHandler instance # Create a DockerHandler instance
@@ -19,9 +23,13 @@ def main():
# Create a RequestHandler instance for each port # Create a RequestHandler instance for each port
for port in port_ip_map.keys(): for port in port_ip_map.keys():
print(f'Creating request handler for port {port}') logging.info(f'Creating request handler for port {port}')
request_handler = RequestHandler(int(port), docker_handler) request_handler = RequestHandler(int(port), docker_handler)
request_handler.start() request_handler.start()
except Exception as e:
logging.error(f'An error occurred: {e}')
if __name__ == "__main__":
main() main()

View File

@@ -1,45 +1,60 @@
import docker import docker
import os import os
import logging
class DockerHandler: class DockerHandler:
def __init__(self, base_url, port_ip_map): def __init__(self, base_url, port_ip_map):
print( logging.info(
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.base_url = base_url
self.client = docker.DockerClient(base_url=base_url) self.client = docker.DockerClient(base_url=base_url)
self.port_ip_map = port_ip_map self.port_ip_map = port_ip_map
self.current_network = self.get_current_network() self.current_network = self.get_current_network()
def get_current_container(self):
current_container_name = os.environ.get('HOSTNAME')
try:
return self.client.containers.get(current_container_name)
except docker.errors.NotFound:
logging.error(f'Container {current_container_name} not found')
return None
def get_current_container_ip(self): def get_current_container_ip(self):
# Get IP of current container # Get IP of current container
current_container_name = os.environ.get('HOSTNAME') current_container = self.get_current_container()
current_container = self.client.containers.get(current_container_name) if current_container:
networks = current_container.attrs['NetworkSettings']['Networks'] networks = current_container.attrs['NetworkSettings']['Networks']
current_network = list(networks.keys())[0] current_network = list(networks.keys())[0]
current_container_ip = networks[current_network]['IPAddress'] return networks[current_network]['IPAddress']
return current_container_ip return None
def get_current_network(self): def get_current_network(self):
# Get network of current container # Get network of current container
current_container_name = os.environ.get('HOSTNAME') current_container = self.get_current_container()
current_container = self.client.containers.get(current_container_name) if current_container:
networks = current_container.attrs['NetworkSettings']['Networks'] networks = current_container.attrs['NetworkSettings']['Networks']
current_network = list(networks.keys())[0] return list(networks.keys())[0]
return current_network return None
def get_container_by_ip(self, ip): def get_container_by_ip(self, ip):
try:
containers = self.client.containers.list(all=True) containers = self.client.containers.list(all=True)
except docker.errors.APIError as e:
logging.error(f'Error getting container list: {e}')
return None
for container in containers: for container in containers:
networks = container.attrs['NetworkSettings']['Networks'] networks = container.attrs['NetworkSettings']['Networks']
if self.current_network in networks and networks[self.current_network]['IPAMConfig']['IPv4Address'] == ip: if self.current_network in networks and networks[self.current_network]['IPAMConfig']['IPv4Address'] == ip:
print( logging.info(
f'Found container {container.name} with ip {ip} in network {self.current_network}') f'Found container {container.name} with ip {ip} in network {self.current_network}')
return container return container
print( logging.info(
f'No docker container found with ip {ip} in network {self.current_network}') f'No docker container found with ip {ip} in network {self.current_network}')
return None return None
def is_container_starting(self, container): def is_container_starting(self, container):
if container:
return container.attrs['State']['Health']['Status'] == 'starting' return container.attrs['State']['Health']['Status'] == 'starting'
return False

View File

@@ -1,4 +1,5 @@
import os import os
import logging
class NginxHandler: class NginxHandler:
@@ -6,14 +7,14 @@ class NginxHandler:
self.config_path = config_path self.config_path = config_path
def start(self): def start(self):
print('Starting NGINX...') logging.info('Starting NGINX...')
os.system('nginx > /dev/null 2>&1 &') os.system('nginx > /dev/null 2>&1 &')
print('NGINX started') logging.info('NGINX started')
def stop(self): def stop(self):
print('Stopping NGINX...') logging.info('Stopping NGINX...')
os.system('nginx -s stop') os.system('nginx -s stop')
print('NGINX stopped') logging.info('NGINX stopped')
def restart(self): def restart(self):
self.stop() self.stop()
@@ -21,13 +22,13 @@ class NginxHandler:
def print_config(self): def print_config(self):
with open(self.config_path, 'r') as f: with open(self.config_path, 'r') as f:
print(f.read()) logging.info(f.read())
def setup_config_file(self, port_ip_map, current_container_ip): def setup_config_file(self, port_ip_map, current_container_ip):
proxy_timeout = "5s" proxy_timeout = "5s"
self.stop() self.stop()
print('Setting up NGINX config file...') logging.info('Setting up NGINX config file...')
print('port_ip_map: {}'.format(port_ip_map)) logging.info('port_ip_map: {}'.format(port_ip_map))
nginx_conf = open(self.config_path, 'w+') nginx_conf = open(self.config_path, 'w+')
nginx_conf.truncate() nginx_conf.truncate()
nginx_conf.write('worker_processes 5;\n') nginx_conf.write('worker_processes 5;\n')
@@ -57,5 +58,5 @@ class NginxHandler:
nginx_conf.write(' }\n') nginx_conf.write(' }\n')
nginx_conf.write('}\n') nginx_conf.write('}\n')
nginx_conf.close() nginx_conf.close()
print('NGINX config file setup complete') logging.info('NGINX config file setup complete')
self.start() self.start()

View File

@@ -1,5 +1,6 @@
import os import os
import socket import socket
import logging
import threading import threading
from utils import docker_container_mapping from utils import docker_container_mapping
@@ -12,81 +13,86 @@ class RequestHandler(threading.Thread):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('localhost', self.port) server_address = ('localhost', self.port)
print(f'Starting up on {server_address[0]} port {server_address[1]}') logging.info(
f'Starting up on {server_address[0]} port {server_address[1]}')
self.sock.bind(server_address) self.sock.bind(server_address)
self.sock.listen(1) self.sock.listen(1)
def restart(self): def restart(self):
print(f'Restarting request handler for port {self.port}') logging.info(f'Restarting request handler for port {self.port}')
self.sock.close() self.sock.close()
self.__init__(self.port, self.docker_handler) self.__init__(self.port, self.docker_handler)
def run(self): def run(self):
while True: while True:
try: try:
print(f'Waiting for a connection on port {self.port}') logging.info(f'Waiting for a connection on port {self.port}')
self.connection, self.client_address = self.sock.accept() self.connection, self.client_address = self.sock.accept()
try: try:
print('Connection from', self.client_address) logging.info('Connection from', self.client_address)
self.handle_request() self.handle_request()
except Exception as e: except Exception as e:
print( logging.info(
f'Error in request handler for port {self.port}: {e}') f'Error in request handler for port {self.port}: {e}')
print('Restarting request handler...') logging.info('Restarting request handler...')
self.restart() self.restart()
finally: finally:
self.connection.close() self.connection.close()
self.restart() self.restart()
except Exception as e: except Exception as e:
print(f'Error in request handler for port {self.port}: {e}') logging.info(
print('Restarting request handler...') f'Error in request handler for port {self.port}: {e}')
logging.info('Restarting request handler...')
self.restart() self.restart()
def handle_request(self): def handle_request(self):
print(f'Handling request on port {self.port}') logging.info(f'Handling request on port {self.port}')
container_ip = docker_container_mapping().get(str(self.port)) container_ip = docker_container_mapping().get(str(self.port))
if container_ip: if container_ip:
container = self.docker_handler.get_container_by_ip( container = self.docker_handler.get_container_by_ip(
container_ip) container_ip)
isStarting = self.docker_handler.is_container_starting(container) isStarting = self.docker_handler.is_container_starting(container)
request = self.connection.recv(1024) request = self.connection.recv(1024)
print(f'Received request: {request}') logging.info(f'Received request: {request}')
# b'\x1b\x00\xfb\x05\x14mc.tealfire.de\x00FML3\x00c\xa0\x02\x1a\x00\x07DerTyp7\x01\xf2]\x9a\x18*\xeaJ\xed\xbe0g\x9c\x8aT\xa9t' # b'\x1b\x00\xfb\x05\x14mc.tealfire.de\x00FML3\x00c\xa0\x02\x1a\x00\x07DerTyp7\x01\xf2]\x9a\x18*\xeaJ\xed\xbe0g\x9c\x8aT\xa9t'
if request[0] == 0x10 or request[0] == 0x15 or request[0] == 0x1b: if request[0] == 0x10 or request[0] == 0x15 or request[0] == 0x1b:
if b'\x02' in request: if b'\x02' in request:
print(f'Detected join/login request for {container_ip}') logging.info(
f'Detected join/login request for {container_ip}')
if isStarting: if isStarting:
print( logging.info(
f'Container {container_ip} is already starting...') f'Container {container_ip} is already starting...')
self.forward_request_to_placeholder( self.forward_request_to_placeholder(
request, isStarting) request, isStarting)
else: else:
print(f'Starting container {container_ip}') logging.info(f'Starting container {container_ip}')
container.start() container.start()
elif b'\x01' in request: elif b'\x01' in request:
print(f'Detected ping request for {container_ip}') logging.info(f'Detected ping request for {container_ip}')
self.forward_request_to_placeholder(request, isStarting) self.forward_request_to_placeholder(request, isStarting)
elif request[0] == 0xFE: elif request[0] == 0xFE:
print(f'Detected legacy ping request for {container_ip}') logging.info(
f'Detected legacy ping request for {container_ip}')
self.forward_request_to_placeholder(request, isStarting) self.forward_request_to_placeholder(request, isStarting)
else: else:
print(f'Detected unknown request for {container_ip}') logging.info(f'Detected unknown request for {container_ip}')
self.forward_request_to_placeholder(request, isStarting) self.forward_request_to_placeholder(request, isStarting)
else: else:
print(f'No container mapped to port {self.port}') logging.info(f'No container mapped to port {self.port}')
def forward_request_to_placeholder(self, request, isStarting=False): def forward_request_to_placeholder(self, request, isStarting=False):
print('Forwarding request to placeholder server') logging.info('Forwarding request to placeholder server')
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
ip = os.environ.get('PLACEHOLDER_SERVER_SLEEPING_IP') ip = os.environ.get('PLACEHOLDER_SERVER_SLEEPING_IP')
if isStarting: if isStarting:
print('Container is starting. Using starting placeholder IP') logging.info(
'Container is starting. Using starting placeholder IP')
ip = os.environ.get('PLACEHOLDER_SERVER_STARTING_IP') ip = os.environ.get('PLACEHOLDER_SERVER_STARTING_IP')
if not ip: if not ip:
print('No placeholder server IP found') logging.info('No placeholder server IP found')
return return
try: try:
server_socket.connect((ip, 25565)) server_socket.connect((ip, 25565))
@@ -94,5 +100,6 @@ class RequestHandler(threading.Thread):
response = server_socket.recv(1024) response = server_socket.recv(1024)
self.connection.sendall(response) self.connection.sendall(response)
except Exception as e: except Exception as e:
print(f'Error while handling request on port {self.port}: {e}') logging.info(
f'Error while handling request on port {self.port}: {e}')
self.restart() self.restart()

View File

@@ -1 +1 @@
docker docker==6.1.3

1
build.sh Normal file
View File

@@ -0,0 +1 @@
docker build -t dertyp7/minecraft_server_auto_starter:latest .

View File

@@ -1 +1 @@
docker compose up -d --build docker compose up -d