mirror of
https://github.com/DerTyp7/docker_minecraft_server_auto_starter.git
synced 2025-10-29 12:42:09 +01:00
Update Docker configuration and Nginx setup
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# Use the official Nginx base image
|
# Use the official Nginx base image
|
||||||
FROM nginx:1.25.3
|
FROM nginx:1.25.3
|
||||||
|
|
||||||
ENV PORT_IP_MAP ""
|
ENV PORT_MAP ""
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
ENV PLACEHOLDER_SERVER_SLEEPING_IP ""
|
ENV PLACEHOLDER_SERVER_SLEEPING_IP ""
|
||||||
ENV PLACEHOLDER_SERVER_STARTING_IP ""
|
ENV PLACEHOLDER_SERVER_STARTING_IP ""
|
||||||
|
|||||||
30
app/app.py
30
app/app.py
@@ -1,4 +1,5 @@
|
|||||||
import logging
|
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
|
||||||
@@ -9,24 +10,45 @@ logging.basicConfig(level=logging.INFO)
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
try:
|
try:
|
||||||
port_ip_map = docker_container_mapping()
|
port_map = docker_container_mapping()
|
||||||
|
|
||||||
# Create a DockerHandler instance
|
# Create a DockerHandler instance
|
||||||
docker_handler = DockerHandler(
|
docker_handler = DockerHandler(
|
||||||
'unix://var/run/docker.sock', port_ip_map)
|
'unix://var/run/docker.sock', port_map)
|
||||||
|
|
||||||
# Create an NginxHandler instance
|
# Create an NginxHandler instance
|
||||||
nginx_handler = NginxHandler('/etc/nginx/nginx.conf')
|
nginx_handler = NginxHandler('/etc/nginx/nginx.conf')
|
||||||
|
print(1)
|
||||||
|
docker_handler.get_ip_by_dns_name(
|
||||||
|
docker_handler.get_current_container_name())
|
||||||
|
print(2)
|
||||||
|
|
||||||
nginx_handler.setup_config_file(
|
nginx_handler.setup_config_file(
|
||||||
docker_container_mapping(), docker_handler.get_current_container_ip())
|
port_map, docker_handler.get_ip_by_dns_name(docker_handler.get_current_container_name()), docker_handler)
|
||||||
|
print(3)
|
||||||
|
|
||||||
nginx_handler.print_config()
|
nginx_handler.print_config()
|
||||||
|
|
||||||
# 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_map.keys():
|
||||||
logging.info(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()
|
||||||
|
|
||||||
|
# DEBUG
|
||||||
|
logging.info(
|
||||||
|
'-----------------------------DEBUG--------------------------------')
|
||||||
|
logging.info(
|
||||||
|
f'Current container: {docker_handler.get_current_container_name()}')
|
||||||
|
logging.info(
|
||||||
|
f'Current container ip: {docker_handler.get_ip_by_dns_name(docker_handler.get_current_container_name())}')
|
||||||
|
logging.info(
|
||||||
|
f'Current network: {docker_handler.get_current_network()}')
|
||||||
|
|
||||||
|
docker_handler.print_all_container_names()
|
||||||
|
logging.info(
|
||||||
|
'-----------------------------DEBUG END--------------------------------')
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f'An error occurred: {e}')
|
logging.error(f'An error occurred: {e}')
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
|
from math import log
|
||||||
|
import socket
|
||||||
import docker
|
import docker
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class DockerHandler:
|
class DockerHandler:
|
||||||
def __init__(self, base_url, port_ip_map):
|
def __init__(self, base_url, port_map):
|
||||||
logging.info(
|
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_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_map = port_map
|
||||||
self.current_network = self.get_current_network()
|
self.current_network = self.get_current_network()
|
||||||
|
logging.info('Docker handler initialized')
|
||||||
|
logging.info(f'Current network: {self.current_network}')
|
||||||
|
|
||||||
def get_current_container(self):
|
def get_current_container(self):
|
||||||
current_container_name = os.environ.get('HOSTNAME')
|
current_container_name = os.environ.get('HOSTNAME')
|
||||||
@@ -20,13 +24,15 @@ class DockerHandler:
|
|||||||
logging.error(f'Container {current_container_name} not found')
|
logging.error(f'Container {current_container_name} not found')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_current_container_ip(self):
|
def get_current_container_name(self):
|
||||||
# Get IP of current container
|
# Get DNS name of current container
|
||||||
current_container = self.get_current_container()
|
current_container = self.get_current_container()
|
||||||
if current_container:
|
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]
|
||||||
return networks[current_network]['IPAddress']
|
if 'Aliases' in networks[current_network]:
|
||||||
|
dns_name = networks[current_network]['Aliases'][0]
|
||||||
|
return dns_name
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_current_network(self):
|
def get_current_network(self):
|
||||||
@@ -54,7 +60,67 @@ class DockerHandler:
|
|||||||
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 get_container_by_name(self, name):
|
||||||
|
try:
|
||||||
|
return self.client.containers.get(name)
|
||||||
|
except docker.errors.NotFound:
|
||||||
|
logging.error(f'Container {name} not found')
|
||||||
|
return None
|
||||||
|
|
||||||
def is_container_starting(self, container):
|
def is_container_starting(self, container):
|
||||||
if container:
|
if container:
|
||||||
return container.attrs['State']['Health']['Status'] == 'starting'
|
return container.attrs['State']['Health']['Status'] == 'starting'
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def print_all_container_names(self):
|
||||||
|
try:
|
||||||
|
containers = self.client.containers.list(
|
||||||
|
all=True, filters={"network": self.current_network})
|
||||||
|
|
||||||
|
if containers is None:
|
||||||
|
logging.info('No containers found')
|
||||||
|
return None
|
||||||
|
|
||||||
|
for container in containers:
|
||||||
|
logging.info(f'Container name: {container.name}')
|
||||||
|
# get docker compose dns name
|
||||||
|
networks = container.attrs['NetworkSettings']['Networks']
|
||||||
|
if self.current_network in networks:
|
||||||
|
logging.info(
|
||||||
|
f'Container ip: {networks[self.current_network]["IPAMConfig"]["IPv4Address"]}')
|
||||||
|
else:
|
||||||
|
logging.info(f'Container ip: None')
|
||||||
|
|
||||||
|
except docker.errors.APIError as e:
|
||||||
|
logging.error(f'Error getting container list: {e}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_ip_by_dns_name(self, dns_name):
|
||||||
|
# dEBUG Print all containers with their network ip and dns name
|
||||||
|
for container in self.client.containers.list(all=True):
|
||||||
|
networks = container.attrs['NetworkSettings']['Networks']
|
||||||
|
if self.current_network in networks:
|
||||||
|
logging.info(
|
||||||
|
f'Container {container.name} ip: {networks[self.current_network]["IPAMConfig"]["IPv4Address"]}, dns name: {networks[self.current_network]["Aliases"]}')
|
||||||
|
|
||||||
|
try:
|
||||||
|
containers = self.client.containers.list(
|
||||||
|
all=True, filters={"network": self.current_network})
|
||||||
|
|
||||||
|
if containers is None:
|
||||||
|
logging.info('No containers found')
|
||||||
|
return None
|
||||||
|
|
||||||
|
for container in containers:
|
||||||
|
networks = container.attrs['NetworkSettings']['Networks']
|
||||||
|
if self.current_network in networks and dns_name in networks[self.current_network]['Aliases']:
|
||||||
|
logging.info(
|
||||||
|
f'Found container {container.name} with dns name {dns_name} in network {self.current_network}')
|
||||||
|
return networks[self.current_network]['IPAMConfig']['IPv4Address']
|
||||||
|
logging.info(
|
||||||
|
f'No docker container found with dns name {dns_name} in network {self.current_network}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
except docker.errors.APIError as e:
|
||||||
|
logging.error(f'Error getting container list: {e}')
|
||||||
|
return None
|
||||||
|
|||||||
@@ -24,11 +24,16 @@ class NginxHandler:
|
|||||||
with open(self.config_path, 'r') as f:
|
with open(self.config_path, 'r') as f:
|
||||||
logging.info(f.read())
|
logging.info(f.read())
|
||||||
|
|
||||||
def setup_config_file(self, port_ip_map, current_container_ip):
|
def setup_config_file(self, port_map, current_container_ip, docker_handler):
|
||||||
|
print(f'-------------------> {port_map}')
|
||||||
|
if port_map is None:
|
||||||
|
logging.error('port_map is None')
|
||||||
|
return
|
||||||
|
|
||||||
proxy_timeout = "5s"
|
proxy_timeout = "5s"
|
||||||
self.stop()
|
self.stop()
|
||||||
logging.info('Setting up NGINX config file...')
|
logging.info('Setting up NGINX config file...')
|
||||||
logging.info('port_ip_map: {}'.format(port_ip_map))
|
logging.info('port_map: {}'.format(port_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')
|
||||||
@@ -40,9 +45,14 @@ class NginxHandler:
|
|||||||
|
|
||||||
# This looks confusing, but the nginx.conf looks good when it's done
|
# This looks confusing, but the nginx.conf looks good when it's done
|
||||||
# Example for the nginx-example.conf file is in the repo root directory
|
# Example for the nginx-example.conf file is in the repo root directory
|
||||||
for port in port_ip_map:
|
if isinstance(port_map, dict):
|
||||||
|
for port in port_map:
|
||||||
|
print(f'-------------------> {port_map}')
|
||||||
|
ip = docker_handler.get_ip_by_dns_name(port_map[port])
|
||||||
|
print(f'-------------------> {port_map[port]}, {ip}')
|
||||||
|
|
||||||
nginx_conf.write(f' upstream upstream_{port} {{\n')
|
nginx_conf.write(f' upstream upstream_{port} {{\n')
|
||||||
nginx_conf.write(f' server {port_ip_map[port]}:25565;\n')
|
nginx_conf.write(f' server {ip}:25565;\n')
|
||||||
nginx_conf.write(f' server 127.0.0.1:{port} backup;\n')
|
nginx_conf.write(f' server 127.0.0.1:{port} backup;\n')
|
||||||
nginx_conf.write(' }\n')
|
nginx_conf.write(' }\n')
|
||||||
|
|
||||||
@@ -56,6 +66,9 @@ class NginxHandler:
|
|||||||
|
|
||||||
nginx_conf.write(f' proxy_pass upstream_{port};\n')
|
nginx_conf.write(f' proxy_pass upstream_{port};\n')
|
||||||
nginx_conf.write(' }\n')
|
nginx_conf.write(' }\n')
|
||||||
|
else:
|
||||||
|
logging.error('port_map is not a dictionary')
|
||||||
|
|
||||||
nginx_conf.write('}\n')
|
nginx_conf.write('}\n')
|
||||||
nginx_conf.close()
|
nginx_conf.close()
|
||||||
logging.info('NGINX config file setup complete')
|
logging.info('NGINX config file setup complete')
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ class RequestHandler(threading.Thread):
|
|||||||
|
|
||||||
def handle_request(self):
|
def handle_request(self):
|
||||||
logging.info(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 = self.docker_handler.get_ip_by_dns_name(
|
||||||
|
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)
|
||||||
@@ -85,11 +86,13 @@ class RequestHandler(threading.Thread):
|
|||||||
def forward_request_to_placeholder(self, request, isStarting=False):
|
def forward_request_to_placeholder(self, request, isStarting=False):
|
||||||
logging.info('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 = self.docker_handler.get_ip_by_dns_name(
|
||||||
|
os.environ.get('PLACEHOLDER_SERVER_SLEEPING_SERVICE'))
|
||||||
if isStarting:
|
if isStarting:
|
||||||
logging.info(
|
logging.info(
|
||||||
'Container is starting. Using starting placeholder IP')
|
'Container is starting. Using starting placeholder IP')
|
||||||
ip = os.environ.get('PLACEHOLDER_SERVER_STARTING_IP')
|
ip = self.docker_handler.get_ip_by_dns_name(
|
||||||
|
os.environ.get('PLACEHOLDER_SERVER_STARTING_SERVICE'))
|
||||||
|
|
||||||
if not ip:
|
if not ip:
|
||||||
logging.info('No placeholder server IP found')
|
logging.info('No placeholder server IP found')
|
||||||
|
|||||||
13
app/utils.py
13
app/utils.py
@@ -1,8 +1,11 @@
|
|||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import socket
|
||||||
|
import socket
|
||||||
|
|
||||||
|
|
||||||
def docker_container_mapping():
|
def docker_container_mapping():
|
||||||
port_ip_map_str = os.environ.get('PORT_IP_MAP')
|
port_ip_map_str = os.environ.get('PORT_MAP')
|
||||||
# Convert the environment variable to a Python dictionary
|
# Convert the environment variable to a Python dictionary
|
||||||
port_ip_map = {}
|
port_ip_map = {}
|
||||||
for line in port_ip_map_str.split('\n'):
|
for line in port_ip_map_str.split('\n'):
|
||||||
@@ -11,3 +14,11 @@ def docker_container_mapping():
|
|||||||
port_ip_map[port.strip()] = ip.strip()
|
port_ip_map[port.strip()] = ip.strip()
|
||||||
|
|
||||||
return port_ip_map
|
return port_ip_map
|
||||||
|
|
||||||
|
|
||||||
|
def get_ip_by_dns_name(dns_name):
|
||||||
|
try:
|
||||||
|
return socket.gethostbyname(dns_name, resolver='127.0.0.1')
|
||||||
|
except socket.gaierror:
|
||||||
|
logging.error(f'Could not resolve dns name {dns_name}')
|
||||||
|
return None
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
version: "3.9"
|
version: "3.9"
|
||||||
|
|
||||||
networks:
|
|
||||||
# You need to have a network with static ips for the servers
|
|
||||||
mc_network:
|
|
||||||
driver: bridge
|
|
||||||
ipam:
|
|
||||||
driver: default
|
|
||||||
config:
|
|
||||||
- subnet: 172.20.0.0/16
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
auto_starter:
|
auto_starter:
|
||||||
container_name: mc_auto_starter
|
container_name: mc_auto_starter
|
||||||
@@ -19,19 +10,16 @@ services:
|
|||||||
- 25566:25566
|
- 25566:25566
|
||||||
environment:
|
environment:
|
||||||
# The ip of the placeholder servers below
|
# The ip of the placeholder servers below
|
||||||
PLACEHOLDER_SERVER_SLEEPING_IP: "172.20.0.3"
|
PLACEHOLDER_SERVER_SLEEPING_SERVICE: "mc_placeholder_server_sleeping"
|
||||||
PLACEHOLDER_SERVER_STARTING_IP: "172.20.0.4"
|
PLACEHOLDER_SERVER_STARTING_SERVICE: "mc_placeholder_server_starting"
|
||||||
|
|
||||||
# Port mapping for the servers
|
# Port mapping for the servers
|
||||||
# The key is the external port of the placeholder server
|
# The key is the external port of the placeholder server
|
||||||
# The value is the internal ip of the actual server
|
# The value is the internal ip of the actual server
|
||||||
# Don't change the server port in the actual server. Use this instead
|
# Don't change the server port in the actual server. Use this instead
|
||||||
PORT_IP_MAP: |
|
PORT_MAP: |
|
||||||
25565: 172.20.0.5
|
25565: "mc"
|
||||||
25566: 172.20.0.6
|
25566: "mc2"
|
||||||
networks:
|
|
||||||
mc_network:
|
|
||||||
ipv4_address: 172.20.0.2
|
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
|
||||||
@@ -60,15 +48,37 @@ services:
|
|||||||
GENERATE_STRUCTURES: "false"
|
GENERATE_STRUCTURES: "false"
|
||||||
ALLOW_NETHER: "false"
|
ALLOW_NETHER: "false"
|
||||||
ALLOW_END: "false"
|
ALLOW_END: "false"
|
||||||
networks:
|
|
||||||
mc_network:
|
|
||||||
ipv4_address: 172.20.0.3
|
|
||||||
|
|
||||||
mc_placeholder_server_starting:
|
mc_placeholder_server_starting:
|
||||||
container_name: mc_placeholder_server_starting
|
container_name: mc_placeholder_server_starting
|
||||||
restart: always
|
restart: always
|
||||||
image: itzg/minecraft-server:java8
|
image: itzg/minecraft-server:java8
|
||||||
environment:
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
MOTD: "Starting, please wait..."
|
||||||
|
|
||||||
|
# The placeholder servers should be as lightweight as possible
|
||||||
|
MAX_PLAYERS: "0"
|
||||||
|
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"
|
||||||
|
|
||||||
|
# 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"
|
||||||
VERSION: "1.12.2"
|
VERSION: "1.12.2"
|
||||||
EULA: "TRUE"
|
EULA: "TRUE"
|
||||||
MOTD: "Starting, please wait..."
|
MOTD: "Starting, please wait..."
|
||||||
@@ -86,31 +96,7 @@ services:
|
|||||||
GENERATE_STRUCTURES: "false"
|
GENERATE_STRUCTURES: "false"
|
||||||
ALLOW_NETHER: "false"
|
ALLOW_NETHER: "false"
|
||||||
ALLOW_END: "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: "Example Server 1"
|
|
||||||
MAX_PLAYERS: "1"
|
|
||||||
|
|
||||||
# Enable autostop, so the auto_starter makes sense
|
|
||||||
ENABLE_AUTOSTOP: "TRUE"
|
|
||||||
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:
|
|
||||||
mc_network:
|
|
||||||
ipv4_address: 172.20.0.5
|
|
||||||
mc2:
|
mc2:
|
||||||
container_name: example_mc_server_2
|
container_name: example_mc_server_2
|
||||||
image: itzg/minecraft-server
|
image: itzg/minecraft-server
|
||||||
@@ -122,11 +108,8 @@ services:
|
|||||||
MAX_PLAYERS: "1"
|
MAX_PLAYERS: "1"
|
||||||
|
|
||||||
# Enable autostop, so the auto_starter makes sense
|
# Enable autostop, so the auto_starter makes sense
|
||||||
ENABLE_AUTOSTOP: "TRUE"
|
ENABLE_AUTOSTOP: "FALSE"
|
||||||
AUTOSTOP_TIMEOUT_EST: "10"
|
AUTOSTOP_TIMEOUT_EST: "10"
|
||||||
AUTOSTOP_TIMEOUT_INIT: "10"
|
AUTOSTOP_TIMEOUT_INIT: "10"
|
||||||
#! Dont change SERVER_PORT. Use PORT_IP_MAP in auto_starter instead.
|
#! Dont change SERVER_PORT. Use PORT_IP_MAP in auto_starter instead.
|
||||||
# SERVER_PORT default is "25565"
|
# SERVER_PORT default is "25565"
|
||||||
networks:
|
|
||||||
mc_network:
|
|
||||||
ipv4_address: 172.20.0.6
|
|
||||||
|
|||||||
Reference in New Issue
Block a user