joesturge / lazymc-docker-proxy

Put your Minecraft containers to rest when idle.
GNU General Public License v3.0
27 stars 4 forks source link
docker lazymc minecraft

lazymc-docker-proxy

By using this image, you can combine the straightforward management of Minecraft servers using itzg/minecraft-server with the efficiency of lazymc.

If you have multiple Docker Minecraft servers and you are low on resources or want to save compute power, this project is for you. With lazymc-docker-proxy, you can dynamically start a Docker Minecraft server when a player joins and shut it down when the server is idle.

This project is also somewhat inspired by lazytainer.

example

Usage

Vanilla minimal Example

Here is a minimal Docker Compose example using itzg/minecraft-server as the server:

⚠️ It is very important that you assign static IP Address to each container. This is due to quirk in how lazymc monitors the servers, it does not expect the IP address of a server to change, this can happen when a container stops and starts again There is an opened issue for this. As this is an issue with lazymc itself it is unlikely that a fix can be found. Im open to suggestions on this.

# Lazymc requires that the minecraft server have a static IP.
#
# To ensure that our servers have a static IP we need to create
# a network for our services to use.
#
# By default, Docker uses 172.17.0.0/16 subnet range.
# So we need to create a new network in a different subnet
# See the readme for more information.
#
# Please ensure that the subnet falls within the private CIDRs:
# https://datatracker.ietf.org/doc/html/rfc1918#section-3
#
# And that it is not in use by anything else.
networks:
  minecraft-network:
    driver: bridge    
    ipam:
      config:
        - subnet: 172.18.0.0/16

services:
  lazymc:
    image: ghcr.io/joesturge/lazymc-docker-proxy:latest
    # the IPs should start at .2 as .1 is reserved for the gateway
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.2
    restart: unless-stopped
    volumes:
      # you should mount the minecraft server dir under /server, using read only.
      - data:/server:ro
      # you need to supply the docker socket, so that the container can run docker command
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      # lazymc-docker-proxy acts as a proxy, so there is
      # no need to expose the server port on the Minecraft container
      - "25565:25565"

  # Standard Docker Minecraft server, also works with other server types
  mc:
    image: itzg/minecraft-server:java21
    # Assign a static IP to the server container
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.3
    # We need to add a label here so that lazymc-docker-proxy knows which
    # container to manage
    labels:
      # Set lazymc.enabled to true to enable lazymc on this container
      - lazymc.enabled=true
      # Required to find the container to manage it
      - lazymc.group=mc
      # Point to the service name of the Minecraft server
      - lazymc.server.address=mc:25565
    tty: true
    stdin_open: true
    # This container should be managed solely by the lazymc container
    # so set restart to no, or else the container will start again...
    restart: no
    environment:
      EULA: "TRUE"
    volumes:
      - data:/data

volumes:
  data:

Multiple server support

This container can also proxy to and control multiple containers at once. You could use it with itzg/mc-router if you choose to:

networks:
  minecraft-network:
    driver: bridge    
    ipam:
      config:
        - subnet: 172.18.0.0/16

services:
  router: 
    # You can use mc-router to route external traffic to your
    # servers via lazymc using the Host header.
    #
    # This allows you to run multiple servers on the same external port
    image: itzg/mc-router
    # You need to assign a static IP to the mc-router container
    # the IPs should start at .2 as .1 is reserved for the gateway
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.2
    depends_on:
      - lazymc
    environment:
      # Primary is exposed on port 25565 of lazymc
      # Secondary is exposed on port 25566 of lazmc
      MAPPING: |
        primary.example.com=lazymc:25565
        secondary.example.com=lazymc:25566
    # If using mc-router you only need to expose port 25565
    # on this container alone
    ports:
      - "25565:25565"

  lazymc:
    image: ghcr.io/joesturge/lazymc-docker-proxy:latest
    # Assign a static IP to the lazymc container
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.3
    restart: unless-stopped
    environment:
      RUST_LOG: "trace"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # primary server volume mount, should match the label
      - data-primary:/server/primary:ro
      # secondary server volume mount, should match the label
      - data-secondary:/server/secondary:ro
    # If you are using mc-router you don't actually need
    # to expose these port, but these ports match the ports
    # specified on the labels on the minecraft containers
    # ports:
    #  - "25565:25565"
    #  - "25566:25566"

  primary:
    image: itzg/minecraft-server:java21
    # Assign a static IP to the primary server container
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.4
    labels:
      - lazymc.enabled=true
      - lazymc.group=primary
      - lazymc.server.address=primary:25565
      # If using with multiple servers you should specify
      # which port you want to this server to be accessible
      # from on the lazymc-docker-proxy container
      - lazymc.port=25565
      # If using with multiple servers you should specify
      # which path you have mounted the server volume on
      - lazymc.server.directory=/server/primary
    tty: true
    stdin_open: true
    restart: no
    environment:
      EULA: "TRUE"
    volumes:
      # mount the primary server volume
      - data-primary:/data

  secondary:
    image: itzg/minecraft-server:java21
    # Assign a static IP to the secondary server container
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.5
    labels:
      - lazymc.enabled=true
      - lazymc.server.address=secondary:25565
      - lazymc.group=secondary
      # If using with multiple servers you should specify
      # which port you want to this server to be accessible
      # from on the lazymc-docker-proxy container
      - lazymc.port=25566
      # If using with multiple servers you should specify
      # which path you have mounted the server volume on
      - lazymc.server.directory=/server/secondary
    tty: true
    stdin_open: true
    restart: no
    environment:
      EULA: "TRUE"
    volumes:
      # mount the secondary server volume
      - data-secondary:/data

volumes:
  # volume for primary server
  data-primary:
  # volume for secondary server
  data-secondary:

Forge 1.19.2

networks:
  minecraft-network:
    driver: bridge    
    ipam:
      config:
        - subnet: 172.18.0.0/16

services:
  lazymc:
    image: ghcr.io/joesturge/lazymc-docker-proxy:latest
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.2
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - data:/server:ro
    ports:
      - "25565:25565"

  mc:
    image: itzg/minecraft-server:java21
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.3
    labels:
      - lazymc.enabled=true
      - lazymc.group=mc
      - lazymc.server.address=mc:25565
      # The minecraft client version of the forge server
      - lazymc.public.version=1.19.2
      # The minecraft protocol version of the forge server
      - lazymc.public.protocol=760
      # Set to true on a forge server
      - lazymc.server.forge=true
    tty: true
    stdin_open: true
    restart: no
    environment:
      EULA: "TRUE"
      TYPE: FORGE
      # The minecraft client version
      VERSION: "1.19.2"
    volumes:
      - data:/data

volumes:
  data:

Configuration using labels

The suggested way to manage the lazymc settings on your minecraft containers is to use container labels.

This allows you to manage multiple minecraft servers at once.

Here is the list of the supported container labels which can be added to the minecraft server container which will be picked up by lazymc-docker-proxy (* is required):

Note: wake_on_crash and wake_on_start are not configurable due to how lazymc starts the server. When running in Docker Compose, all containers are started by default, so wake_on_start must also be true when using this image. wake_on_crash is also true as it is recommended to launch the Minecraft server with restart: no.
Note: rcon configurations are not supported as this app relies on the SIGTERM signal to stop the server.

If you want more details or have issues, you can also refer to the lazymc documentation.

Also, refer to the lazymc config example. You may notice that the environment variables are named in the same way. This is intentional...

Environment Variables

You can enable debug logging using the RUST_LOG env var.

Deprecated

⚠️ Using environment variables to configure the server is deprecated and will be removed in the next release, please use container labels on the minecraft server instead. These are still available for the time being.

Here is a full list of the environment variables supported by this image (* is required):

Development

Thanks for wanting to contribute! Please read the contributing guidelines first off.

Compile locally

To develop changes fork this repo and ensure you have the following installed:

Then run the following

cargo build --release

to build the executable under target/release directory.

Docker

To build the dockerfile locally you can run (from the project root)

docker build .

It is good to also check this before committing to make sure you did not break the build

Testing

There are bats integration test for this application. Which each perform the following:

  1. Builds the docker compose file
  2. Starts the docker compose environment
  3. Waits for the minecraft container(s) to start
  4. Waits for lazymc to stop the minecraft container(s)

These checks are performed in using github actions on every commit

Changelog

This project uses keepachangelog to maintain it's changelog. If you are proposing a change please update the changelog by adding your changes under the [Unreleased] header

Thanks

Thanks for taking the time to check this project out, I hope it helps you manage your minecraft servers for years to come!