Luanti containers, part 1: Comparing docker-compose and podman-compose rootful
I currently use Docker to run my Luanti game server and related services. But because I use RHEL derivatives (Rocky Linux, primarily), I wanted to see how the podman tech would work. Here's first post in a short series, explaining the differences in running Luanti in docker versus podman.
Docker-compose
I use docker-compose, so I define all the services in one file. It is very convenient for small scale deployments!
files/2026/listings/luanti-docker-compose.yml (Source)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File: /home/luanti/game-onyx/docker-compose.yml # Author: bgstack15 # Startdate: 2026-02-20-6 08:42 # History: # 2025 # this app in the container will not read the ~/.minetest/minetest.conf, particularly for mcl_keepInventory=true, so I had to modify ~/.minetest/games/mineclonia/minetest.conf # Reference: # https://github.com/linuxserver/docker-luanti # https://github.com/minetest-mapserver/mapserver/blob/master/docker-compose.yml # https://github.com/minetest-mapserver/mapserver/blob/master/doc/install.md more useful # https://github.com/pandorabox-io/pandorabox.io/blob/master/docker-compose.yml#L45-L57 --- version: "3.5" services: luanti: image: lscr.io/linuxserver/luanti:latest networks: - luanti environment: - PUID=1009 - PGID=1009 - TZ=Etc/UTC - "CLI_ARGS=--gameid mineclonia --worldname world" volumes: - /home/luanti/game-onyx/:/config/.minetest ports: - 30070:30000/udp restart: unless-stopped mapserver: image: ghcr.io/minetest-mapserver/mapserver:latest restart: always networks: - luanti volumes: - /home/luanti/game-onyx/worlds/world:/minetest working_dir: "/minetest" ports: - 30071:8080/tcp ui: image: ghcr.io/minetest-go/mtui:latest restart: always environment: WORLD_DIR: "/world" LOGLEVEL: debug #COOKIE_DOMAIN: "www.example.com" #COOKIE_SECURE: "false" #COOKIE_PATH: "/games/luanti/namibia/ui" SERVER_NAME: "Onyx" #WASM_MINETEST_HOST: "minetest" API_KEY: "ExampleKeyGoesHere" #all features: "api,shell,luashell,minetest_config,docker,modmanagement,signup,chat,minetest_web" # enable features does not work. I had to be an admin from minetest.conf `name=<myname>` and then visit webpage and enable shell, luashell, chat ENABLE_FEATURES: "shell,luashell,chat" volumes: - "/home/luanti/game-onyx/worlds/world:/world" #- "postgres_socket:/var/run/postgresql" networks: - luanti ports: - 30072:8080/tcp networks: luanti: name: luanti07 ... |
I use a third-party image, and not the official Luanti image. The only reason is I found it first on the world wide web. The Mineclonia client side mod does not need anything special in server-side, so any image will suffice.
The environment variables PUID and GUID are specific to this image of Luanti, based on the build team's consistency between all their images.
Even with SELinux enforcing on the docker host, the container doesn't seem to need special selinux tags on the volume mounts :z.
The restart: unless-stopped makes the docker daemon restart these even at reboot.
And, it's a little out of scope here, but the minetest.conf needs to set mapserver.url and mtui.url values to the container names of those other services.
Podman compose rootful
This is the experimental stage for me, and it took me a little while to get it working.
files/2026/listings/luanti-rootful-podman-compose.yml (Source)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File: /home/luanti/game-onyx/docker-compose.yml # Author: bgstack15 # Startdate: 2026-02-20-6 08:42 # History: # 2025 # this app in the container will not read the ~/.minetest/minetest.conf, particularly for mcl_keepInventory=true, so I had to modify ~/.minetest/games/mineclonia/minetest.conf # Reference: # https://github.com/linuxserver/docker-luanti # https://github.com/minetest-mapserver/mapserver/blob/master/docker-compose.yml # https://github.com/minetest-mapserver/mapserver/blob/master/doc/install.md more useful # https://github.com/pandorabox-io/pandorabox.io/blob/master/docker-compose.yml#L45-L57 --- version: "3.5" services: luanti: image: lscr.io/linuxserver/luanti:latest networks: - luanti environment: - PUID=1009 - PGID=1009 - TZ=Etc/UTC - "CLI_ARGS=--gameid mineclonia --worldname world" volumes: # lscr.io image needs ./main-config/minetest.conf - /home/luanti/game-onyx/:/config/.minetest/:z ports: - 30070:30000/udp - 30070:30000/tcp restart: unless-stopped mapserver: image: ghcr.io/minetest-mapserver/mapserver:latest restart: always networks: - luanti volumes: - /home/luanti/game-onyx/worlds/world:/minetest:z working_dir: "/minetest" ports: - 30071:8080/tcp ui: image: ghcr.io/minetest-go/mtui:latest restart: always environment: WORLD_DIR: "/world" LOGLEVEL: debug #COOKIE_DOMAIN: "www.example.com" #COOKIE_SECURE: "false" #COOKIE_PATH: "/games/luanti/namibia/ui" SERVER_NAME: "Onyx" #WASM_MINETEST_HOST: "minetest" API_KEY: "ExampleKeyGoesHere" #all features: "api,shell,luashell,minetest_config,docker,modmanagement,signup,chat,minetest_web" # enable features does not work. I had to be an admin from minetest.conf `name=<myname>` and then visit webpage and enable shell, luashell, chat ENABLE_FEATURES: "shell,luashell,chat" volumes: - "/home/luanti/game-onyx/worlds/world:/world:z" #- "postgres_socket:/var/run/postgresql" networks: - luanti ports: - 30072:8080/tcp networks: luanti: name: luanti07 ... |
Of course, install podman and podman-compose.
sudo dnf install -y podman podman-compose sudo mkdir -p /etc/containers/containers.conf.d echo "compose_warning_logs=false" | sudo tee /etc/containers/containers.conf.d/60-warnings.conf sudo groupadd --gid 1009 luanti sudo useradd --gid 1009 --uid 1009 luanti # I have not set a password sudo loginctl enable-linger 1009
For the user to work with podman, I had to enable linger. I'm not going to go into the plagued history of this, today. This is necessary for any future podman use by this user, including the upcoming blog posts.
I had to use rootful podman (sudo podman-compose up) because the lscr.io image does some chown operations at initialization, and do not work in rootless mode.
I ran into some selinux problems, or at least I think I did. It certainly didn't hurt me to use the :z selinux option. Lowercase Z means podman should relabel the file objects for multiple containers, but uppercase Z would mean a private, unshared label for just this one container.
Common
The reverse proxy and port forwarding is out of scope for this document.
Comments