From 0e2975fb369f841aa4400826dd222b2e56fbab03 Mon Sep 17 00:00:00 2001
From: Peter Nerlich <peter.nerlich+dev@googlemail.com>
Date: Wed, 5 May 2021 13:30:42 +0200
Subject: [PATCH] replace shell scripts by ansible playbooks/roles, provide
 under MIT license

---
 LICENSE                                       |  21 ++
 Vagrantfile                                   |  11 +
 hosts.yml                                     |   3 +
 install_deps.sh                               |  24 --
 kif_minetest_mapserver/.travis.yml            |  29 ++
 kif_minetest_mapserver/.yamllint              |  33 +++
 kif_minetest_mapserver/README.md              |  79 ++++++
 kif_minetest_mapserver/defaults/main.yml      |  12 +
 .../defaults/production_secrets.yml           |   7 +
 kif_minetest_mapserver/handlers/main.yml      |  16 ++
 kif_minetest_mapserver/meta/main.yml          |  50 ++++
 .../molecule/default/INSTALL.rst              |  23 ++
 .../molecule/default/converge.yml             |  11 +
 .../molecule/default/molecule.yml             |  20 ++
 .../molecule/default/verify.yml               |  21 ++
 .../tasks/disable_mapserver.yml               |   7 +
 .../tasks/install_mapserver.yml               |  46 +++
 kif_minetest_mapserver/tasks/main.yml         |  44 +++
 .../tasks/server_prepare.yml                  |  24 ++
 .../templates/mapserver.json.j2               |  81 ++++++
 .../templates/mapserver.service.j2            |  14 +
 kif_minetest_server/.travis.yml               |  29 ++
 kif_minetest_server/.yamllint                 |  33 +++
 kif_minetest_server/README.md                 |  73 +++++
 kif_minetest_server/defaults/main.yml         | 262 ++++++++++++++++++
 .../defaults/production_secrets.yml           |  15 +
 kif_minetest_server/handlers/main.yml         |  16 ++
 kif_minetest_server/meta/main.yml             |  48 ++++
 .../molecule/default/INSTALL.rst              |  23 ++
 .../molecule/default/converge.yml             |  11 +
 .../molecule/default/molecule.yml             |  20 ++
 .../molecule/default/verify.yml               |  15 +
 kif_minetest_server/tasks/config_minetest.yml |  36 +++
 .../tasks/install_minetest.yml                |  39 +++
 kif_minetest_server/tasks/install_mods.yml    |  37 +++
 kif_minetest_server/tasks/main.yml            |  74 +++++
 .../tasks/server_dependencies.yml             |  28 ++
 kif_minetest_server/tasks/server_prepare.yml  |  67 +++++
 kif_minetest_server/templates/map_meta.txt.j2 | 173 ++++++++++++
 .../templates/minetest.conf.j2                |  69 +++++
 .../templates/minetest.service.j2             |  14 +
 kif_minetest_server/templates/world.mt.j2     |  18 ++
 production.yml                                |   7 +
 restart_server.sh                             |   4 -
 testing.yml                                   |   8 +
 update_mods.sh                                |   9 -
 update_server.sh                              |  23 --
 47 files changed, 1667 insertions(+), 60 deletions(-)
 create mode 100644 LICENSE
 create mode 100644 Vagrantfile
 create mode 100644 hosts.yml
 delete mode 100644 install_deps.sh
 create mode 100644 kif_minetest_mapserver/.travis.yml
 create mode 100644 kif_minetest_mapserver/.yamllint
 create mode 100644 kif_minetest_mapserver/README.md
 create mode 100644 kif_minetest_mapserver/defaults/main.yml
 create mode 100644 kif_minetest_mapserver/defaults/production_secrets.yml
 create mode 100644 kif_minetest_mapserver/handlers/main.yml
 create mode 100644 kif_minetest_mapserver/meta/main.yml
 create mode 100644 kif_minetest_mapserver/molecule/default/INSTALL.rst
 create mode 100644 kif_minetest_mapserver/molecule/default/converge.yml
 create mode 100644 kif_minetest_mapserver/molecule/default/molecule.yml
 create mode 100644 kif_minetest_mapserver/molecule/default/verify.yml
 create mode 100644 kif_minetest_mapserver/tasks/disable_mapserver.yml
 create mode 100644 kif_minetest_mapserver/tasks/install_mapserver.yml
 create mode 100644 kif_minetest_mapserver/tasks/main.yml
 create mode 100644 kif_minetest_mapserver/tasks/server_prepare.yml
 create mode 100644 kif_minetest_mapserver/templates/mapserver.json.j2
 create mode 100644 kif_minetest_mapserver/templates/mapserver.service.j2
 create mode 100644 kif_minetest_server/.travis.yml
 create mode 100644 kif_minetest_server/.yamllint
 create mode 100644 kif_minetest_server/README.md
 create mode 100644 kif_minetest_server/defaults/main.yml
 create mode 100644 kif_minetest_server/defaults/production_secrets.yml
 create mode 100644 kif_minetest_server/handlers/main.yml
 create mode 100644 kif_minetest_server/meta/main.yml
 create mode 100644 kif_minetest_server/molecule/default/INSTALL.rst
 create mode 100644 kif_minetest_server/molecule/default/converge.yml
 create mode 100644 kif_minetest_server/molecule/default/molecule.yml
 create mode 100644 kif_minetest_server/molecule/default/verify.yml
 create mode 100644 kif_minetest_server/tasks/config_minetest.yml
 create mode 100644 kif_minetest_server/tasks/install_minetest.yml
 create mode 100644 kif_minetest_server/tasks/install_mods.yml
 create mode 100644 kif_minetest_server/tasks/main.yml
 create mode 100644 kif_minetest_server/tasks/server_dependencies.yml
 create mode 100644 kif_minetest_server/tasks/server_prepare.yml
 create mode 100644 kif_minetest_server/templates/map_meta.txt.j2
 create mode 100644 kif_minetest_server/templates/minetest.conf.j2
 create mode 100644 kif_minetest_server/templates/minetest.service.j2
 create mode 100644 kif_minetest_server/templates/world.mt.j2
 create mode 100644 production.yml
 delete mode 100644 restart_server.sh
 create mode 100644 testing.yml
 delete mode 100644 update_mods.sh
 delete mode 100644 update_server.sh

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..b2f9106
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Konferenz der Informatikfachschaften
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100644
index 0000000..d8063a9
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,11 @@
+Vagrant.require_version ">= 1.8.0"
+
+Vagrant.configure(2) do |config|
+
+  config.vm.box = "generic/ubuntu2004"
+
+  config.vm.provision "ansible" do |ansible|
+    ansible.verbose = "v"
+    ansible.playbook = "testing.yml"
+  end
+end
diff --git a/hosts.yml b/hosts.yml
new file mode 100644
index 0000000..a79e590
--- /dev/null
+++ b/hosts.yml
@@ -0,0 +1,3 @@
+all:
+  hosts:
+    kif_minetest:
diff --git a/install_deps.sh b/install_deps.sh
deleted file mode 100644
index 17a7df3..0000000
--- a/install_deps.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-apt install \
-	git \
-	g++ \
-	make \
-	libc6-dev \
-	libirrlicht-dev \
-	cmake \
-	libbz2-dev \
-	libpng-dev \
-	libjpeg-dev \
-	libxxf86vm-dev \
-	libgl1-mesa-dev \
-	libsqlite3-dev \
-	libogg-dev \
-	libvorbis-dev \
-	libopenal-dev \
-	libcurl4-gnutls-dev \
-	libfreetype6-dev \
-	zlib1g-dev \
-	libgmp-dev \
-	libjsoncpp-dev \
-	libpq-dev
-
diff --git a/kif_minetest_mapserver/.travis.yml b/kif_minetest_mapserver/.travis.yml
new file mode 100644
index 0000000..36bbf62
--- /dev/null
+++ b/kif_minetest_mapserver/.travis.yml
@@ -0,0 +1,29 @@
+---
+language: python
+python: "2.7"
+
+# Use the new container infrastructure
+sudo: false
+
+# Install ansible
+addons:
+  apt:
+    packages:
+    - python-pip
+
+install:
+  # Install ansible
+  - pip install ansible
+
+  # Check ansible version
+  - ansible --version
+
+  # Create ansible.cfg with correct roles_path
+  - printf '[defaults]\nroles_path=../' >ansible.cfg
+
+script:
+  # Basic role syntax check
+  - ansible-playbook tests/test.yml -i tests/inventory --syntax-check
+
+notifications:
+  webhooks: https://galaxy.ansible.com/api/v1/notifications/
\ No newline at end of file
diff --git a/kif_minetest_mapserver/.yamllint b/kif_minetest_mapserver/.yamllint
new file mode 100644
index 0000000..8827676
--- /dev/null
+++ b/kif_minetest_mapserver/.yamllint
@@ -0,0 +1,33 @@
+---
+# Based on ansible-lint config
+extends: default
+
+rules:
+  braces:
+    max-spaces-inside: 1
+    level: error
+  brackets:
+    max-spaces-inside: 1
+    level: error
+  colons:
+    max-spaces-after: -1
+    level: error
+  commas:
+    max-spaces-after: -1
+    level: error
+  comments: disable
+  comments-indentation: disable
+  document-start: disable
+  empty-lines:
+    max: 3
+    level: error
+  hyphens:
+    level: error
+  indentation: disable
+  key-duplicates: enable
+  line-length: disable
+  new-line-at-end-of-file: disable
+  new-lines:
+    type: unix
+  trailing-spaces: disable
+  truthy: disable
diff --git a/kif_minetest_mapserver/README.md b/kif_minetest_mapserver/README.md
new file mode 100644
index 0000000..dccf046
--- /dev/null
+++ b/kif_minetest_mapserver/README.md
@@ -0,0 +1,79 @@
+KIF Minetest Mapserver
+======================
+
+A role for setting up the mapserver in combination with minetest for the Konferenz der Informatikfachschaften
+
+Requirements
+------------
+
+None
+
+Role Variables
+--------------
+
+* `use_production_secrets`: bool, default: `false`. Whether to use secrets for production from the vault file. Requires you to know and supply the password.
+* `mapserver_key`: string, default: `CHANGE_TO_PROPER_PASSWORD`. Secret for exchanging in-game data from the companion mod with the mapserver. Please, please always have this be something different than the default.
+* `mapserver_version`: string, default: `4.2`. Which mapserver release to use. Refers to the release tag of the official git repository.
+* `mapserver_active`: bool, default: `true`. Whether the mapserver should be running and start automatically on reboot. Useful for disabling the mapserver, which not using this role would not accomplish.
+* `mapserver_port`: number, default: `8080`. Port to open the mapserver on.
+* `mapserver_dir`: string, default: `/var/lib/minetest/minetest_mapserver`. Path of the directory where the mapserver binary should be placed.
+* `world_dir`: string, default: `/var/lib/minetest/world`. Path of the directory where to expect the world. Please refer to the official mapserver documentation on how the program interacts with the world data.
+
+Variables for the `kif_minetest_server` role:
+
+* `server_secure_http_mods`: list, default: `['mapserver']`. Please refer to the official minetest documentation.
+* `mapserver_url`: string, default: `http://127.0.0.1:{{ mapserver_port }}`. URL over which the mapserver companion mod to should exchange in-game data with the mapserver.
+* `mapserver_key`: string, default: `CHANGE_TO_PROPER_PASSWORD`. Secret for exchanging in-game data from the companion mod with the mapserver. Please, please always have this be something different than the default.
+* `use_production_secrets`: bool, default: `false`. Whether to use secrets for production from the vault file. Requires you to know and supply the password.
+* `minetest_version`: string, default: `5.3.0`. Which minetest version to use. Refers to the commit, tag or branch of the official git repository where minetest is compiled from.
+* `minetest_game_version`: string, default: `5.3.0`. Which minetest game version to use. Refers to the commit, tag or branch of the official git repository.
+* `mods_version`: string, default: `master`. Refers to the commit, tag or branch of the repository holding the mods.
+* `mods_git_repo`: string, default: `'https://gitlab.fachschaften.org/minetest/minetest_mods.git'`. URL of the repository holding the mods that should be used.
+* `update_mods_cron_job`: bool, default: `true`. Whether to create a cron job to update mods automatically each day. Refers cron to `update.sh` which must be present at the root of the mods repository.
+* `minetest_base_dir`: string, default: `/var/lib/minetest`. Path of the home directory of the minetest user, where all the minetest things should be placed.
+* `server_auth_backend`: string, default: `sqlite3`. Please refer to the minetest documentation.
+* `server_player_backend`: string, default: `postgresql`. Please refer to the minetest documentation.
+* `server_backend`: string, default: `postgresql`. Please refer to the minetest documentation.
+* `psql_host`: string, default: `127.0.0.1`. Host for connecting to PostgreSQL, if that backend is to be used.
+* `psql_user`: string, default: `minetest`. User for connecting to PostgreSQL, if that backend is to be used.
+* `psql_password`: string, default: `CHANGE_TO_PROPER_DB_PASSWORD`. Password for connecting to PostgreSQL, if that backend is to be used. Please, please always have this be something different than the default.
+* `psql_db`: string, default: `minetest-db`. Database name for connecting to PostgreSQL, if that backend is to be used.
+* `minetest_seed`: string or number, default: `3374822340961073250`. Seed when generating the minetest world.
+* `server_address`: string, default: `minetest.kif.rocks`. Address to expect the server to be accessible as.
+* `server_announce`: bool, default: `true`. Whether to announce the server status to a public server list. Please refer to the minetest documentation.
+* `server_serverlist_url`: string, default: `servers.minetest.net`. URL of the server list to announce the server status to, if enabled. Please refer to the minetest documentation.
+* `server_port`: number, default: `30000`. Port to open the minetest server on.
+* `server_default_password`: string, default: `CHANGE_TO_PROPER_PLAYER_PASSWORD`. Default password for new clients connecting to the server. Please, please always have this be something different than the default.
+* `server_default_privs`: list, default: `['interact', 'shout', 'railway_operator', 'interlocking', 'itm', 'train_operator', 'ui_full', 'travelnet_attach', 'track_builder', 'home', 'atlatc']`. Priviledges to give new players. Please refer to the official minetest documentation as well as the documentation of the mods registering the priviledges.
+* `load_mods`: list, default omitted for brevity. Mods to enable.
+* `disabled_mods`: list, default omitted for brevity. Mods to explicitly disable. Not needed for the configuration, but for idempotence as the minetest server adds the present but not enabled mods to the config on startup.
+* *for more please refer to the documentation of `kif_minetest_server`*
+
+Dependencies
+------------
+
+- `kif_minetest_server` role
+
+Example Playbook
+----------------
+
+Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
+
+    - hosts: servers
+      roles:
+        - role: kif_minetest_mapserver
+          server_player_backend: sqlite3
+          server_backend: sqlite3
+          server_announce: false
+          mapserver_key: "{{ lookup('password', '/dev/null chars=ascii_letters,digits,hexdigits,punctuation length=16') }}"
+
+License
+-------
+
+MIT
+
+Author Information
+------------------
+
+- https://minetest.kif.rocks/
+- https://gitlab.fachschaften.org/minetest/
diff --git a/kif_minetest_mapserver/defaults/main.yml b/kif_minetest_mapserver/defaults/main.yml
new file mode 100644
index 0000000..b9e2230
--- /dev/null
+++ b/kif_minetest_mapserver/defaults/main.yml
@@ -0,0 +1,12 @@
+---
+use_production_secrets: false
+
+mapserver_key: CHANGE_TO_PROPER_PASSWORD
+
+mapserver_version: 4.2
+
+mapserver_active: true
+mapserver_port: 8080
+
+mapserver_dir: /var/lib/minetest/minetest_mapserver
+world_dir: /var/lib/minetest/world
diff --git a/kif_minetest_mapserver/defaults/production_secrets.yml b/kif_minetest_mapserver/defaults/production_secrets.yml
new file mode 100644
index 0000000..e9adf46
--- /dev/null
+++ b/kif_minetest_mapserver/defaults/production_secrets.yml
@@ -0,0 +1,7 @@
+$ANSIBLE_VAULT;1.1;AES256
+33663234333164626530303833663564383362383863396339666637323231346666383032323561
+6531663037383235363539643866623035333032393662340a353735306666353838623334636162
+37636133333036376336393132613366656139393438353836633732393165316265373062353531
+6465333666353036660a366639343263396666323037363236633566633634336264663636343034
+65393666393764616165363136366166613032363332326239313630323962396562346261396164
+3431336665306130396365393266306261373963343834326130
diff --git a/kif_minetest_mapserver/handlers/main.yml b/kif_minetest_mapserver/handlers/main.yml
new file mode 100644
index 0000000..d658863
--- /dev/null
+++ b/kif_minetest_mapserver/handlers/main.yml
@@ -0,0 +1,16 @@
+---
+- name: Stop mapserver
+  ansible.builtin.systemd:
+    name: mapserver
+    state: stopped
+    daemon-reload: true
+  become: true
+  listen: stop mapserver
+
+- name: Restart mapserver
+  ansible.builtin.systemd:
+    name: mapserver
+    state: restarted
+    daemon-reload: true
+  become: true
+  listen: restart mapserver
diff --git a/kif_minetest_mapserver/meta/main.yml b/kif_minetest_mapserver/meta/main.yml
new file mode 100644
index 0000000..4520aeb
--- /dev/null
+++ b/kif_minetest_mapserver/meta/main.yml
@@ -0,0 +1,50 @@
+galaxy_info:
+  author: Peter Nerlich
+  description: minetest mapserver as the KIF uses it
+  namespace: peter_nerlich
+  company: KIF
+
+  # If the issue tracker for your role is not on github, uncomment the
+  # next line and provide a value
+  # issue_tracker_url: http://example.com/issue/tracker
+
+  # Choose a valid license ID from https://spdx.org - some suggested licenses:
+  # - BSD-3-Clause (default)
+  # - MIT
+  # - GPL-2.0-or-later
+  # - GPL-3.0-only
+  # - Apache-2.0
+  # - CC-BY-4.0
+  license: CC-BY-4.0
+
+  min_ansible_version: 2.1
+
+  # If this a Container Enabled role, provide the minimum Ansible Container version.
+  # min_ansible_container_version:
+
+  #
+  # Provide a list of supported platforms, and for each platform a list of versions.
+  # If you don't wish to enumerate all versions for a particular platform, use 'all'.
+  # To view available platforms and versions (or releases), visit:
+  # https://galaxy.ansible.com/api/v1/platforms/
+  #
+  platforms:
+  - name: Ubuntu
+    versions:
+    - "20.04"
+
+  galaxy_tags:
+    - kif
+    - minetest
+    - mapserver
+    # List tags for your role here, one per line. A tag is a keyword that describes
+    # and categorizes the role. Users find roles by searching for tags. Be sure to
+    # remove the '[]' above, if you add tags to this list.
+    #
+    # NOTE: A tag is limited to a single word comprised of alphanumeric characters.
+    #       Maximum 20 tags per role.
+
+dependencies:
+  - role: kif_minetest_server
+  # List your role dependencies here, one per line. Be sure to remove the '[]' above,
+  # if you add dependencies to this list.
diff --git a/kif_minetest_mapserver/molecule/default/INSTALL.rst b/kif_minetest_mapserver/molecule/default/INSTALL.rst
new file mode 100644
index 0000000..0c4bf5c
--- /dev/null
+++ b/kif_minetest_mapserver/molecule/default/INSTALL.rst
@@ -0,0 +1,23 @@
+*********************************
+Vagrant driver installation guide
+*********************************
+
+Requirements
+============
+
+* Vagrant
+* Virtualbox, Parallels, VMware Fusion, VMware Workstation or VMware Desktop
+
+Install
+=======
+
+Please refer to the `Virtual environment`_ documentation for installation best
+practices. If not using a virtual environment, please consider passing the
+widely recommended `'--user' flag`_ when invoking ``pip``.
+
+.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
+.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
+
+.. code-block:: bash
+
+    $ pip install 'molecule_vagrant'
diff --git a/kif_minetest_mapserver/molecule/default/converge.yml b/kif_minetest_mapserver/molecule/default/converge.yml
new file mode 100644
index 0000000..a39c39d
--- /dev/null
+++ b/kif_minetest_mapserver/molecule/default/converge.yml
@@ -0,0 +1,11 @@
+---
+- name: Converge
+  hosts: all
+  tasks:
+    - name: "Include kif_minetest_mapserver"
+      include_role:
+        name: "kif_minetest_mapserver"
+      vars:
+        server_player_backend: sqlite3
+        server_backend: sqlite3
+        server_announce: false
diff --git a/kif_minetest_mapserver/molecule/default/molecule.yml b/kif_minetest_mapserver/molecule/default/molecule.yml
new file mode 100644
index 0000000..6af60a1
--- /dev/null
+++ b/kif_minetest_mapserver/molecule/default/molecule.yml
@@ -0,0 +1,20 @@
+---
+dependency:
+  name: galaxy
+driver:
+  name: vagrant
+  provider:
+    name: libvirt
+platforms:
+  - name: instance-kif-mapserver
+    box: generic/ubuntu2004
+    cpus: 4
+    memory: 4096
+provisioner:
+  name: ansible
+verifier:
+  name: ansible
+lint: |
+  set -e
+  yamllint .
+  ansible-lint . -x 503
diff --git a/kif_minetest_mapserver/molecule/default/verify.yml b/kif_minetest_mapserver/molecule/default/verify.yml
new file mode 100644
index 0000000..e1a5981
--- /dev/null
+++ b/kif_minetest_mapserver/molecule/default/verify.yml
@@ -0,0 +1,21 @@
+---
+# This is an example playbook to execute Ansible tests.
+
+- name: Verify
+  hosts: all
+  gather_facts: false
+  tasks:
+  - name: Populate service facts
+    ansible.builtin.service_facts:
+
+  - name: Check that the minetest service is running
+    assert:
+      that:
+        - ('minetest.service' in ansible_facts.services)
+        - ansible_facts.services['minetest.service'].state == 'running'
+
+  - name: Check that the mapserver service is running
+    assert:
+      that:
+        - ('mapserver.service' in ansible_facts.services)
+        - ansible_facts.services['mapserver.service'].state == 'running'
diff --git a/kif_minetest_mapserver/tasks/disable_mapserver.yml b/kif_minetest_mapserver/tasks/disable_mapserver.yml
new file mode 100644
index 0000000..116555f
--- /dev/null
+++ b/kif_minetest_mapserver/tasks/disable_mapserver.yml
@@ -0,0 +1,7 @@
+---
+- name: Disable mapserver service
+  ansible.builtin.systemd:
+    name: mapserver
+    enabled: false
+    daemon-reload: true
+  become: true
diff --git a/kif_minetest_mapserver/tasks/install_mapserver.yml b/kif_minetest_mapserver/tasks/install_mapserver.yml
new file mode 100644
index 0000000..a0e0a58
--- /dev/null
+++ b/kif_minetest_mapserver/tasks/install_mapserver.yml
@@ -0,0 +1,46 @@
+---
+- name: Download mapserver binary
+  get_url:
+    url: "https://github.com/minetest-mapserver/mapserver/releases/download/{{ mapserver_version }}/mapserver-linux-x86_64"
+    dest: "{{ mapserver_dir }}/mapserver-linux-x86_64"
+  become: true
+  notify:
+    - restart mapserver
+
+- name: Set file permissions for mapserver binary
+  file:
+    path: "{{ mapserver_dir }}/mapserver-linux-x86_64"
+    state: file
+    mode: u=rwx,g=r,o=r
+    owner: minetest
+    group: minetest
+  become: true
+  notify:
+    - restart mapserver
+
+- name: Create mapserver service
+  template:
+    src: mapserver.service.j2
+    dest: /etc/systemd/system/mapserver.service
+    mode: u=rw,g=r,o=r
+  become: true
+  notify:
+    - restart mapserver
+
+- name: Enable mapserver service
+  ansible.builtin.systemd:
+    name: mapserver
+    enabled: true
+    daemon-reload: true
+  become: true
+
+- name: Create mapserver config
+  template:
+    src: mapserver.json.j2
+    dest: "{{ world_dir }}/mapserver.json"
+    mode: u=rwX,g=rX,o=rX
+    owner: minetest
+    group: minetest
+  become: true
+  notify:
+    - restart mapserver
diff --git a/kif_minetest_mapserver/tasks/main.yml b/kif_minetest_mapserver/tasks/main.yml
new file mode 100644
index 0000000..5fe188e
--- /dev/null
+++ b/kif_minetest_mapserver/tasks/main.yml
@@ -0,0 +1,44 @@
+---
+- name: Use production secrets
+  include_vars: "defaults/production_secrets.yml"
+  when: use_production_secrets
+
+- name: Enforce proper passwords
+  assert:
+    that: not (item.pw | b64decode).startswith('CHANGE_TO_PROPER_')
+    fail_msg: "{{ item.name }} is not set to a proper password!"
+    quiet: true
+  with_items:
+    - name: mapserver_key
+      pw: "{{ mapserver_key | b64encode }}"
+  ignore_errors: True
+
+- name: Prepare system for installation
+  include_tasks: server_prepare.yml
+  tags: prepare
+
+- name: Install mapserver
+  include_tasks: install_mapserver.yml
+  tags: mapserver
+  when: mapserver_active
+
+- name: Wait for world db to exist...
+  wait_for:
+    path: "{{ world_dir }}/map.sqlite"
+  when: server_backend == "sqlite3"
+
+- name: Run handlers
+  meta: flush_handlers
+
+- name: Start mapserver
+  ansible.builtin.systemd:
+    name: mapserver
+    state: started
+  become: true
+  tags: mapserver
+  when: mapserver_active
+
+- name: Disable mapserver
+  include_tasks: disable_mapserver.yml
+  tags: mapserver
+  when: not mapserver_active
diff --git a/kif_minetest_mapserver/tasks/server_prepare.yml b/kif_minetest_mapserver/tasks/server_prepare.yml
new file mode 100644
index 0000000..f7e6d94
--- /dev/null
+++ b/kif_minetest_mapserver/tasks/server_prepare.yml
@@ -0,0 +1,24 @@
+---
+- name: Create group 'minetest'
+  group:
+    name: minetest
+  become: true
+
+- name: Create user 'minetest'
+  user:
+    name: minetest
+    group: minetest
+    home: "{{ minetest_base_dir }}"
+  become: true
+
+- name: Assign directories to minetest group and owner
+  file:
+    path: "{{ item }}"
+    state: directory
+    mode: u=rwX,g=rX,o=rX
+    owner: minetest
+    group: minetest
+  with_items:
+    - "{{ mapserver_dir }}"
+    - "{{ world_dir }}"
+  become: true
diff --git a/kif_minetest_mapserver/templates/mapserver.json.j2 b/kif_minetest_mapserver/templates/mapserver.json.j2
new file mode 100644
index 0000000..4ee35ac
--- /dev/null
+++ b/kif_minetest_mapserver/templates/mapserver.json.j2
@@ -0,0 +1,81 @@
+{
+	"configversion": 1,
+	"port": {{ mapserver_port }},
+	"enableprometheus": true,
+	"enablerendering": true,
+	"enablesearch": true,
+	"enableinitialrendering": true,
+	"enabletransparency": false,
+	"enablemediarepository": false,
+	"webdev": false,
+	"webapi": {
+		"enablemapblock": false,
+		"secretkey": "{{ mapserver_key }}"
+	},
+	"layers": [
+		{
+			"id": 0,
+			"name": "Oberfläche",
+			"from": -1,
+			"to": 9
+		},
+		{
+			"id": 1,
+			"name": "-700 (Tiefe Freefalltower)",
+			"from": -50,
+			"to": -40
+		},
+		{
+			"id": 2,
+			"name": "Gebirge",
+			"from": 7,
+			"to": 18
+		}
+	],
+	"renderingfetchlimit": 10000,
+	"renderingjobs": 2,
+	"renderingqueue": 100,
+	"incrementalrenderingtimer": "5s",
+	"mapobjects": {
+		"areas": true,
+		"bones": true,
+		"protector": true,
+		"xpprotector": false,
+		"privprotector": false,
+		"technic_quarry": false,
+		"technic_switch": false,
+		"technic_anchor": false,
+		"technic_reactor": false,
+		"luacontroller": true,
+		"digiterms": true,
+		"digilines": true,
+		"travelnet": true,
+		"mapserver_player": true,
+		"mapserver_poi": true,
+		"mapserver_label": true,
+		"mapserver_trainline": true,
+		"mapserver_border": true,
+		"tileserverlegacy": true,
+		"mission": false,
+		"jumpdrive": false,
+		"smartshop": false,
+		"fancyvend": false,
+		"atm": false,
+		"train": true,
+		"trainsignal": true,
+		"minecart": false,
+		"locator": false
+	},
+	"mapblockaccessor": {
+		"expiretime": "15s",
+		"purgetime": "30s",
+		"maxitems": 500
+	},
+	"defaultoverlays": [
+		"mapserver_poi",
+		"mapserver_label",
+		"mapserver_player",
+		"mapserver_trainline",
+		"train"
+	]
+}
\ No newline at end of file
diff --git a/kif_minetest_mapserver/templates/mapserver.service.j2 b/kif_minetest_mapserver/templates/mapserver.service.j2
new file mode 100644
index 0000000..3273eb3
--- /dev/null
+++ b/kif_minetest_mapserver/templates/mapserver.service.j2
@@ -0,0 +1,14 @@
+[Unit]
+Description=Mapserver
+
+[Service]
+Type=simple
+User=minetest
+Group=minetest
+ExecStart={{ mapserver_dir }}/mapserver-linux-x86_64
+WorkingDirectory={{ world_dir }}
+Restart=on-failure
+RestartSec=2
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/kif_minetest_server/.travis.yml b/kif_minetest_server/.travis.yml
new file mode 100644
index 0000000..36bbf62
--- /dev/null
+++ b/kif_minetest_server/.travis.yml
@@ -0,0 +1,29 @@
+---
+language: python
+python: "2.7"
+
+# Use the new container infrastructure
+sudo: false
+
+# Install ansible
+addons:
+  apt:
+    packages:
+    - python-pip
+
+install:
+  # Install ansible
+  - pip install ansible
+
+  # Check ansible version
+  - ansible --version
+
+  # Create ansible.cfg with correct roles_path
+  - printf '[defaults]\nroles_path=../' >ansible.cfg
+
+script:
+  # Basic role syntax check
+  - ansible-playbook tests/test.yml -i tests/inventory --syntax-check
+
+notifications:
+  webhooks: https://galaxy.ansible.com/api/v1/notifications/
\ No newline at end of file
diff --git a/kif_minetest_server/.yamllint b/kif_minetest_server/.yamllint
new file mode 100644
index 0000000..8827676
--- /dev/null
+++ b/kif_minetest_server/.yamllint
@@ -0,0 +1,33 @@
+---
+# Based on ansible-lint config
+extends: default
+
+rules:
+  braces:
+    max-spaces-inside: 1
+    level: error
+  brackets:
+    max-spaces-inside: 1
+    level: error
+  colons:
+    max-spaces-after: -1
+    level: error
+  commas:
+    max-spaces-after: -1
+    level: error
+  comments: disable
+  comments-indentation: disable
+  document-start: disable
+  empty-lines:
+    max: 3
+    level: error
+  hyphens:
+    level: error
+  indentation: disable
+  key-duplicates: enable
+  line-length: disable
+  new-line-at-end-of-file: disable
+  new-lines:
+    type: unix
+  trailing-spaces: disable
+  truthy: disable
diff --git a/kif_minetest_server/README.md b/kif_minetest_server/README.md
new file mode 100644
index 0000000..3d819a1
--- /dev/null
+++ b/kif_minetest_server/README.md
@@ -0,0 +1,73 @@
+KIF Minetest Server
+===================
+
+A role for setting up a minetest server for the Konferenz der Informatikfachschaften
+
+Requirements
+------------
+
+None (?)
+
+Role Variables
+--------------
+
+TODO: complete documentation
+
+Most important variables:
+
+* `use_production_secrets`: bool, default: `false`. Whether to use secrets for production from the vault file. Requires you to know and supply the password.
+* `minetest_version`: string, default: `5.3.0`. Which minetest version to use. Refers to the commit, tag or branch of the official git repository where minetest is compiled from.
+* `minetest_game_version`: string, default: `5.3.0`. Which minetest game version to use. Refers to the commit, tag or branch of the official git repository.
+* `mods_version`: string, default: `master`. Refers to the commit, tag or branch of the repository holding the mods.
+* `mods_git_repo`: string, default: `'https://gitlab.fachschaften.org/minetest/minetest_mods.git'`. URL of the repository holding the mods that should be used.
+* `update_mods_cron_job`: bool, default: `true`. Whether to create a cron job to update mods automatically each day. Refers cron to `update.sh` which must be present at the root of the mods repository.
+* `minetest_base_dir`: string, default: `/var/lib/minetest`. Path of the home directory of the minetest user, where all the minetest things should be placed.
+* `server_auth_backend`: string, default: `sqlite3`. Please refer to the minetest documentation.
+* `server_player_backend`: string, default: `postgresql`. Please refer to the minetest documentation.
+* `server_backend`: string, default: `postgresql`. Please refer to the minetest documentation.
+* `psql_host`: string, default: `127.0.0.1`. Host for connecting to PostgreSQL, if that backend is to be used.
+* `psql_user`: string, default: `minetest`. User for connecting to PostgreSQL, if that backend is to be used.
+* `psql_password`: string, default: `CHANGE_TO_PROPER_DB_PASSWORD`. Password for connecting to PostgreSQL, if that backend is to be used. Please, please always have this be something different than the default.
+* `psql_db`: string, default: `minetest-db`. Database name for connecting to PostgreSQL, if that backend is to be used.
+* `minetest_seed`: string or number, default: `3374822340961073250`. Seed when generating the minetest world.
+* `server_address`: string, default: `minetest.kif.rocks`. Address to expect the server to be accessible as.
+* `server_announce`: bool, default: `true`. Whether to announce the server status to a public server list. Please refer to the minetest documentation.
+* `server_serverlist_url`: string, default: `servers.minetest.net`. URL of the server list to announce the server status to, if enabled. Please refer to the minetest documentation.
+* `server_port`: number, default: `30000`. Port to open the minetest server on.
+* `server_default_password`: string, default: `CHANGE_TO_PROPER_PLAYER_PASSWORD`. Default password for new clients connecting to the server. Please, please always have this be something different than the default.
+* `server_default_privs`: list, default: `['interact', 'shout', 'railway_operator', 'interlocking', 'itm', 'train_operator', 'ui_full', 'travelnet_attach', 'track_builder', 'home', 'atlatc']`. Priviledges to give new players. Please refer to the official minetest documentation as well as the documentation of the mods registering the priviledges.
+* `server_secure_http_mods`: list, default: `['mapserver']`. Please refer to the official minetest documentation.
+* `mapserver_url`: string, default: `http://127.0.0.1:{{ mapserver_port }}`. URL over which the mapserver companion mod to should exchange in-game data with the mapserver.
+* `mapserver_key`: string, default: `CHANGE_TO_PROPER_PASSWORD`. Secret for exchanging in-game data from the companion mod with the mapserver. Please, please always have this be something different than the default.
+* `load_mods`: list, default omitted for brevity. Mods to enable.
+* `disabled_mods`: list, default omitted for brevity. Mods to explicitly disable. Not needed for the configuration, but for idempotence as the minetest server adds the present but not enabled mods to the config on startup.
+* ...
+
+Dependencies
+------------
+
+None
+
+Example Playbook
+----------------
+
+Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
+
+    - hosts: servers
+      roles:
+        - role: kif_minetest_server
+          server_player_backend: sqlite3
+          server_backend: sqlite3
+          server_announce: false
+          server_default_password: CHANGE_TO_PROPER_PASSWORD
+
+License
+-------
+
+MIT
+
+Author Information
+------------------
+
+- https://minetest.kif.rocks/
+- https://gitlab.fachschaften.org/minetest/
diff --git a/kif_minetest_server/defaults/main.yml b/kif_minetest_server/defaults/main.yml
new file mode 100644
index 0000000..da0dddd
--- /dev/null
+++ b/kif_minetest_server/defaults/main.yml
@@ -0,0 +1,262 @@
+---
+use_production_secrets: false
+
+minetest_version: 5.3.0
+minetest_game_version: 5.3.0
+mods_version: master
+
+minetest_base_dir: /var/lib/minetest
+
+mods_git_repo: 'https://gitlab.fachschaften.org/minetest/minetest_mods.git'
+minetest_git_repo: 'https://github.com/minetest/minetest.git'
+minetest_game_git_repo: 'https://github.com/minetest/minetest_game.git'
+
+server_auth_backend: sqlite3
+server_player_backend: postgresql
+server_backend: postgresql
+
+psql_host: 127.0.0.1
+psql_user: minetest
+psql_password: CHANGE_TO_PROPER_DB_PASSWORD
+psql_db: minetest-db
+
+update_mods_cron_job: true
+
+server_language: de
+server_name: KIF Minetest Server
+server_description: Minetest-Server für die Konferenz der Informatikfachschaften
+server_motd: KIF Minetest Server
+server_kick_msg_shutdown: WIR SCHLIESSEN! Der Server ist für den Dauerbetrieb gedacht, also ist es vermutlich ein Neustart. Im Normalfall, wenn keine größeren Wartungsarbeiten stattfinden oder ein Admin was kaputt gemacht hat, dürfte er in genauuu...... DIESEM Moment wieder laufen. Ansonsten versuch es in den nächsen Minuten doch nochmal!
+server_kick_msg_crash: Ups! Das war wohl nichts. Uns ist tatsächlich der Server abgeschmiert. Bitte melde das den Admins, falls die nicht schon dran tüfteln...
+
+minetest_seed: 3374822340961073250
+
+server_address: minetest.kif.rocks
+server_announce: true
+server_serverlist_url: servers.minetest.net
+server_port: 30000
+server_ipv6_server: true
+server_enable_ipv6: true
+
+server_max_users: 100
+server_enable_damage: true
+server_enable_pvp: false
+server_enable_minimap: true
+server_creative_mode: false
+server_free_move: true
+server_fast_move: true
+server_noclip: true
+server_default_password: CHANGE_TO_PROPER_PLAYER_PASSWORD
+server_disallow_empty_password: true
+server_default_privs:
+  - interact
+  - shout
+  - railway_operator
+  - interlocking
+  - itm
+  - train_operator
+  - ui_full
+  - travelnet_attach
+  - track_builder
+  - home
+  - atlatc
+server_admin_name: PeterNerlich
+server_ask_reconnect_on_crash: true
+server_debug_log_level: warning
+server_debug_log_size_max: 50
+server_max_block_generate_distance: 10
+server_max_block_send_distance: 10
+server_max_simultaneous_block_sends_per_client: 50
+server_max_simultaneous_block_sends_server_total: 500
+server_max_packets_per_iteration: 2048
+server_active_object_send_range_blocks: 7
+server_active_block_range: 6
+server_secure_http_mods:
+  - mapserver
+
+mapserver_enable_crafting: true
+mapserver_url: http://127.0.0.1:{{ mapserver_port }}
+mapserver_key: CHANGE_TO_PROPER_MAPSERVER_KEY
+moreblocks_stairsplus_in_creative_inventory: false
+advtrains_wagon_load_range: 192
+advtrains_show_ids: true
+advtrains_lines_rwt_realtime: follow_real
+
+load_mods:
+  - 3d_armor
+  - 3d_armor_ip
+  - 3d_armor_sfinv
+  - 3d_armor_stand
+  - 3d_armor_ui
+  - advtrains
+  - advtrains_freight_train
+  - advtrains_interlocking
+  - advtrains_itrainmap
+  - advtrains_line_automation
+  - advtrains_luaautomation
+  - advtrains_railbus
+  - advtrains_signals_ks
+  - advtrains_train_industrial
+  - advtrains_train_japan
+  - advtrains_train_jre231
+  - advtrains_train_rocket
+  - advtrains_train_steam
+  - advtrains_train_subway
+  - advtrains_train_track
+  - ambience
+  - areas
+  - assets
+  - bakedclay
+  - basic_materials
+  - basic_signs
+  - beacons
+  - bike
+  - biome_lib
+  - boards
+  - bonemeal
+  - building_blocks
+  - character_creator
+  - coloredwood
+  - computer
+  - death_markers
+  - digilines
+  - digiterms
+  - display_api
+  - elevators
+  - fake_fire
+  - farming
+  - font_api
+  - font_metro
+  - food
+  - food_basic
+  - hbarmor
+  - hbhunger
+  - homedecor_3d_extras
+  - homedecor_bathroom
+  - homedecor_bedroom
+  - homedecor_books
+  - homedecor_climate_control
+  - homedecor_clocks
+  - homedecor_cobweb
+  - homedecor_common
+  - homedecor_doors_and_gates
+  - homedecor_electrical
+  - homedecor_electronics
+  - homedecor_exterior
+  - homedecor_fences
+  - homedecor_foyer
+  - homedecor_furniture
+  - homedecor_furniture_medieval
+  - homedecor_gastronomy
+  - homedecor_kitchen
+  - homedecor_laundry
+  - homedecor_lighting
+  - homedecor_misc
+  - homedecor_office
+  - homedecor_pictures_and_paintings
+  - homedecor_roofing
+  - homedecor_seating
+  - homedecor_tables
+  - homedecor_trash_cans
+  - homedecor_wardrobe
+  - homedecor_windows_and_treatments
+  - hudbars
+  - ilights
+  - illumination
+  - inbox
+  - itemframes
+  - kif_custom
+  - kiffood
+  - lavalamp
+  - led_marquee
+  - mapserver
+  - mesecar
+  - mesecons
+  - mesecons_alias
+  - mesecons_blinkyplant
+  - mesecons_button
+  - mesecons_commandblock
+  - mesecons_delayer
+  - mesecons_detector
+  - mesecons_doors
+  - mesecons_extrawires
+  - mesecons_fpga
+  - mesecons_gates
+  - mesecons_hydroturbine
+  - mesecons_insulated
+  - mesecons_lamp
+  - mesecons_lightstone
+  - mesecons_luacontroller
+  - mesecons_materials
+  - mesecons_microcontroller
+  - mesecons_movestones
+  - mesecons_mvps
+  - mesecons_noteblock
+  - mesecons_pistons
+  - mesecons_powerplant
+  - mesecons_pressureplates
+  - mesecons_random
+  - mesecons_receiver
+  - mesecons_solarpanel
+  - mesecons_stickyblocks
+  - mesecons_switch
+  - mesecons_torch
+  - mesecons_walllever
+  - mesecons_wires
+  - mobkit
+  - mokapi
+  - moreblocks
+  - morelights
+  - morelights_extras
+  - morelights_modern
+  - morelights_vintage
+  - moreores
+  - moretrains_basic
+  - moretrains_industrial
+  - moretrains_japan
+  - moretrains_steam
+  - moretrains_vintage
+  - moretrees
+  - my_castle_doors
+  - my_cottage_doors
+  - my_default_doors
+  - my_door_wood
+  - my_fancy_doors
+  - my_future_doors
+  - my_garage_door
+  - my_hidden_doors
+  - my_misc_doors
+  - my_old_doors
+  - my_saloon_doors
+  - my_sliding_doors
+  - ontime_clocks
+  - orienteering
+  - petz
+  - pie
+  - pipeworks
+  - plasmascreen
+  - protector
+  - shields
+  - signs
+  - signs_api
+  - signs_lib
+  - signs_road
+  - stained_glass
+  - steles
+  - street_signs
+  - streetlights_api
+  - streetlights_lamps
+  - streetlights_poles
+  - streets
+  - tfl_s7stock
+  - travelnet
+  - ts_workshop
+  - unified_inventory
+  - unifiedbricks
+  - unifieddyes
+  - waffles
+  - wield3d
+  - wieldview
+disabled_mods:
+  - skinsdb
+  - snowdrift
diff --git a/kif_minetest_server/defaults/production_secrets.yml b/kif_minetest_server/defaults/production_secrets.yml
new file mode 100644
index 0000000..25306a0
--- /dev/null
+++ b/kif_minetest_server/defaults/production_secrets.yml
@@ -0,0 +1,15 @@
+$ANSIBLE_VAULT;1.1;AES256
+62663730313036373665633761386263336564666162356162363363646532343939396231363031
+3238333331663734636433633631313435343535313737640a313166316132366635333261373461
+63636165656566636562316566643236643630316238616466666535303566356532653830343063
+3430386561666663610a303062393033313464356664353435333932313333636533626162656637
+32336537313037326538373532663664333865303738633937356661373332396132633433623062
+37383034613431333733373662623662623031396337643065326231626136336434363030653765
+39313464316266353630643630303066356233616130383235333633646361363165316362393939
+38323063343531343431663361366262363632323035353230356132353838626563336463306466
+31366264346437313262356130633332376630383537316332616162663137333530666337323264
+39643961306531396265306266336534363530633662396338396232333261666162633237666430
+62313261306366643536326133616264663936326637333833393039616435333961386665303134
+33643733316366303365646564613030626336333033343963373461643138616433646263613363
+35373037633736383534376435646339373164366261653234663637636566646431623634636236
+3935366239343764323561363339653866326464353434313936
diff --git a/kif_minetest_server/handlers/main.yml b/kif_minetest_server/handlers/main.yml
new file mode 100644
index 0000000..ea8600f
--- /dev/null
+++ b/kif_minetest_server/handlers/main.yml
@@ -0,0 +1,16 @@
+---
+- name: Stop Minetest server
+  ansible.builtin.systemd:
+    name: minetest
+    state: stopped
+    daemon-reload: true
+  become: true
+  listen: stop minetest server
+
+- name: Restart Minetest server
+  ansible.builtin.systemd:
+    name: minetest
+    state: restarted
+    daemon-reload: true
+  become: true
+  listen: restart minetest server
diff --git a/kif_minetest_server/meta/main.yml b/kif_minetest_server/meta/main.yml
new file mode 100644
index 0000000..d9c0349
--- /dev/null
+++ b/kif_minetest_server/meta/main.yml
@@ -0,0 +1,48 @@
+galaxy_info:
+  author: Peter Nerlich
+  description: minetest server as the KIF uses it
+  namespace: peter_nerlich
+  company: KIF
+
+  # If the issue tracker for your role is not on github, uncomment the
+  # next line and provide a value
+  # issue_tracker_url: http://example.com/issue/tracker
+
+  # Choose a valid license ID from https://spdx.org - some suggested licenses:
+  # - BSD-3-Clause (default)
+  # - MIT
+  # - GPL-2.0-or-later
+  # - GPL-3.0-only
+  # - Apache-2.0
+  # - CC-BY-4.0
+  license: CC-BY-4.0
+
+  min_ansible_version: 2.1
+
+  # If this a Container Enabled role, provide the minimum Ansible Container version.
+  # min_ansible_container_version:
+
+  #
+  # Provide a list of supported platforms, and for each platform a list of versions.
+  # If you don't wish to enumerate all versions for a particular platform, use 'all'.
+  # To view available platforms and versions (or releases), visit:
+  # https://galaxy.ansible.com/api/v1/platforms/
+  #
+  platforms:
+  - name: Ubuntu
+    versions:
+    - "20.04"
+
+  galaxy_tags:
+    - kif
+    - minetest
+    # List tags for your role here, one per line. A tag is a keyword that describes
+    # and categorizes the role. Users find roles by searching for tags. Be sure to
+    # remove the '[]' above, if you add tags to this list.
+    #
+    # NOTE: A tag is limited to a single word comprised of alphanumeric characters.
+    #       Maximum 20 tags per role.
+
+dependencies: []
+  # List your role dependencies here, one per line. Be sure to remove the '[]' above,
+  # if you add dependencies to this list.
diff --git a/kif_minetest_server/molecule/default/INSTALL.rst b/kif_minetest_server/molecule/default/INSTALL.rst
new file mode 100644
index 0000000..0c4bf5c
--- /dev/null
+++ b/kif_minetest_server/molecule/default/INSTALL.rst
@@ -0,0 +1,23 @@
+*********************************
+Vagrant driver installation guide
+*********************************
+
+Requirements
+============
+
+* Vagrant
+* Virtualbox, Parallels, VMware Fusion, VMware Workstation or VMware Desktop
+
+Install
+=======
+
+Please refer to the `Virtual environment`_ documentation for installation best
+practices. If not using a virtual environment, please consider passing the
+widely recommended `'--user' flag`_ when invoking ``pip``.
+
+.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
+.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
+
+.. code-block:: bash
+
+    $ pip install 'molecule_vagrant'
diff --git a/kif_minetest_server/molecule/default/converge.yml b/kif_minetest_server/molecule/default/converge.yml
new file mode 100644
index 0000000..175ef90
--- /dev/null
+++ b/kif_minetest_server/molecule/default/converge.yml
@@ -0,0 +1,11 @@
+---
+- name: Converge
+  hosts: all
+  tasks:
+    - name: "Include kif_minetest_server"
+      include_role:
+        name: "kif_minetest_server"
+      vars:
+        server_player_backend: sqlite3
+        server_backend: sqlite3
+        server_announce: false
diff --git a/kif_minetest_server/molecule/default/molecule.yml b/kif_minetest_server/molecule/default/molecule.yml
new file mode 100644
index 0000000..0d22c03
--- /dev/null
+++ b/kif_minetest_server/molecule/default/molecule.yml
@@ -0,0 +1,20 @@
+---
+dependency:
+  name: galaxy
+driver:
+  name: vagrant
+  provider:
+    name: libvirt
+platforms:
+  - name: instance-kif-minetest
+    box: generic/ubuntu2004
+    cpus: 4
+    memory: 4096
+provisioner:
+  name: ansible
+verifier:
+  name: ansible
+lint: |
+  set -e
+  yamllint .
+  ansible-lint . -x 503
diff --git a/kif_minetest_server/molecule/default/verify.yml b/kif_minetest_server/molecule/default/verify.yml
new file mode 100644
index 0000000..5862a8f
--- /dev/null
+++ b/kif_minetest_server/molecule/default/verify.yml
@@ -0,0 +1,15 @@
+---
+# This is an example playbook to execute Ansible tests.
+
+- name: Verify
+  hosts: all
+  gather_facts: false
+  tasks:
+  - name: Populate service facts
+    ansible.builtin.service_facts:
+
+  - name: Check that the minetest service is running
+    assert:
+      that:
+        - ('minetest.service' in ansible_facts.services)
+        - ansible_facts.services['minetest.service'].state == 'running'
diff --git a/kif_minetest_server/tasks/config_minetest.yml b/kif_minetest_server/tasks/config_minetest.yml
new file mode 100644
index 0000000..a47a58e
--- /dev/null
+++ b/kif_minetest_server/tasks/config_minetest.yml
@@ -0,0 +1,36 @@
+---
+- name: Create Minetest config
+  template:
+    src: minetest.conf.j2
+    dest: "{{ minetest_base_dir }}/minetest.conf"
+    mode: u=rwX,g=rX,o=rX
+    owner: minetest
+    group: minetest
+  become: true
+  register: config_file
+  notify:
+    - restart minetest server
+
+- name: Create world config
+  template:
+    src: world.mt.j2
+    dest: "{{ minetest_base_dir }}/world/world.mt"
+    mode: u=rwX,g=rX,o=rX
+    owner: minetest
+    group: minetest
+  become: true
+  register: world_file
+  notify:
+    - restart minetest server
+
+- name: Create map meta config
+  template:
+    src: map_meta.txt.j2
+    dest: "{{ minetest_base_dir }}/world/map_meta.txt"
+    mode: u=rwX,g=rX,o=rX
+    owner: minetest
+    group: minetest
+  become: true
+  register: map_file
+  notify:
+    - restart minetest server
diff --git a/kif_minetest_server/tasks/install_minetest.yml b/kif_minetest_server/tasks/install_minetest.yml
new file mode 100644
index 0000000..d94eddc
--- /dev/null
+++ b/kif_minetest_server/tasks/install_minetest.yml
@@ -0,0 +1,39 @@
+---
+- name: Get newest Minetest
+  ansible.builtin.git:
+    repo: "{{ minetest_git_repo }}"
+    dest: "{{ minetest_base_dir }}/minetest_source"
+    force: true
+    version: "{{ minetest_version }}"
+  diff: false
+  become: true
+  register: minetest_repo
+
+- name: Build Minetest
+  command:
+    cmd: "{{ item }}"
+    chdir: "{{ minetest_base_dir }}/minetest_source"
+  with_items:
+    - cmake . -DRUN_IN_PLACE=TRUE -DBUILD_SERVER=TRUE -DBUILD_CLIENT=FALSE -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/
+    - make -j4
+  become: true
+  register: minetest_build
+  when: minetest_repo.changed
+
+- name: Create Minetest service
+  template:
+    src: minetest.service.j2
+    dest: /etc/systemd/system/minetest.service
+    mode: u=rw,g=r,o=r
+  become: true
+  notify:
+    - restart minetest server
+
+- name: Get newest Minetest-Game
+  ansible.builtin.git:
+    repo: "{{ minetest_game_git_repo }}"
+    dest: "{{ minetest_base_dir }}/minetest_game"
+    force: true
+    version: "{{ minetest_game_version }}"
+  become: true
+  register: game_repo
diff --git a/kif_minetest_server/tasks/install_mods.yml b/kif_minetest_server/tasks/install_mods.yml
new file mode 100644
index 0000000..a020e6a
--- /dev/null
+++ b/kif_minetest_server/tasks/install_mods.yml
@@ -0,0 +1,37 @@
+
+- name: Check for newest mods
+  ansible.builtin.git:
+    repo: "{{ mods_git_repo }}"
+    dest: "{{ minetest_base_dir }}/minetest_mods"
+    force: true
+    recursive: false
+    version: "{{ mods_version }}"
+  become: true
+  register: mods_repo
+
+- name: Download newest mods
+  ansible.builtin.git:
+    repo: "{{ mods_git_repo }}"
+    dest: "{{ minetest_base_dir }}/minetest_mods"
+    force: true
+    recursive: true
+    version: "{{ mods_version }}"
+  become: true
+  when: mods_repo.changed
+  register: mods_repo
+
+- name: Create cron job to automatically update mods
+  ansible.builtin.cron:
+    name: KIF minetest update mods
+    job: "cd {{ minetest_base_dir }}/minetest_mods && ./update.sh && systemctl restart minetest"
+    minute: "56"
+    hour: "03"
+  become: true
+  when: update_mods_cron_job
+
+- name: Remove auto update cron job
+  ansible.builtin.cron:
+    name: KIF minetest update mods
+    state: absent
+  become: true
+  when: not update_mods_cron_job
diff --git a/kif_minetest_server/tasks/main.yml b/kif_minetest_server/tasks/main.yml
new file mode 100644
index 0000000..93f6693
--- /dev/null
+++ b/kif_minetest_server/tasks/main.yml
@@ -0,0 +1,74 @@
+---
+- name: Use production secrets
+  include_vars: "defaults/production_secrets.yml"
+  when: use_production_secrets
+
+- name: Enforce proper passwords
+  assert:
+    that: not (item.pw | b64decode).startswith('CHANGE_TO_PROPER_')
+    fail_msg: "{{ item.name }} is not set to a proper password!"
+    quiet: true
+  with_items:
+    - name: psql_password
+      pw: "{{ psql_password | b64encode }}"
+    - name: server_default_password
+      pw: "{{ server_default_password | b64encode }}"
+  ignore_errors: True
+
+- name: Install dependencies
+  include_tasks: server_dependencies.yml
+  tags: dependencies
+
+- name: Prepare system for installation
+  include_tasks: server_prepare.yml
+  tags: prepare
+
+- name: Install Minetest
+  include_tasks: install_minetest.yml
+  tags: build
+
+- name: Create config
+  include_tasks: config_minetest.yml
+  tags: config
+
+- name: Enable Minetest service
+  ansible.builtin.systemd:
+    name: minetest
+    enabled: true
+    daemon-reload: true
+  become: true
+
+- name: Install mods
+  include_tasks: install_mods.yml
+  tags: mods
+
+- name: Dissolve overlayfs structure
+  ansible.posix.mount:
+    path: "{{ minetest_base_dir }}/minetest"
+    state: absent
+  become: true
+  when: minetest_build.changed or game_repo.changed or mods_repo.changed
+
+- name: Create read only overlayfs structure
+  ansible.posix.mount:
+    path: "{{ minetest_base_dir }}/minetest"
+    src: overlay # not needed because the options take care of everything, but still required by ansible
+    opts: "lowerdir={{ lower_dirs | reverse | zip_longest([],fillvalue=minetest_base_dir) | map('reverse') | map('join', '/') | join(':') }}"
+    state: mounted
+    fstype: overlay
+  become: true
+  vars:
+    lower_dirs:
+      - .overlayfs/src_root
+      - .overlayfs/game_root
+      - .overlayfs/mods_root
+      - .overlayfs/conf_root
+
+- name: Run handlers
+  meta: flush_handlers
+
+- name: Start minetest
+  ansible.builtin.systemd:
+    name: minetest
+    state: started
+  become: true
diff --git a/kif_minetest_server/tasks/server_dependencies.yml b/kif_minetest_server/tasks/server_dependencies.yml
new file mode 100644
index 0000000..3c9a4fe
--- /dev/null
+++ b/kif_minetest_server/tasks/server_dependencies.yml
@@ -0,0 +1,28 @@
+---
+- name: Install dependencies available through apt
+  apt:
+    pkg:
+      - git
+      - g++
+      - make
+      - libc6-dev
+      - libirrlicht-dev
+      - cmake
+      - libbz2-dev
+      - libpng-dev
+      - libjpeg-dev
+      - libxxf86vm-dev
+      - libgl1-mesa-dev
+      - libsqlite3-dev
+      - libogg-dev
+      - libvorbis-dev
+      - libopenal-dev
+      - libcurl4-gnutls-dev
+      - libfreetype6-dev
+      - zlib1g-dev
+      - libgmp-dev
+      - libjsoncpp-dev
+      - libpq-dev
+    update_cache: true
+    cache_valid_time: 86400  # One day
+  become: true
diff --git a/kif_minetest_server/tasks/server_prepare.yml b/kif_minetest_server/tasks/server_prepare.yml
new file mode 100644
index 0000000..02a426a
--- /dev/null
+++ b/kif_minetest_server/tasks/server_prepare.yml
@@ -0,0 +1,67 @@
+---
+- name: Create group 'minetest'
+  group:
+    name: minetest
+  become: true
+
+- name: Create user 'minetest'
+  user:
+    name: minetest
+    group: minetest
+    home: "{{ minetest_base_dir }}"
+  become: true
+
+- name: Assign directories to minetest group and owner
+  file:
+    path: "{{ minetest_base_dir }}/{{ item }}"
+    state: directory
+    mode: u=rwX,g=rX,o=rX
+    owner: minetest
+    group: minetest
+  with_items:
+    - minetest
+    - minetest_game
+    - minetest_source
+    - minetest_mods
+    - world
+    - .overlayfs/workdir
+    - .overlayfs/src_root
+    - .overlayfs/game_root/games/
+    - .overlayfs/mods_root/
+    - .overlayfs/conf_root/worlds/
+    - minetest_mapserver
+  become: true
+
+- name: Create writable debug log
+  file:
+    path: "{{ minetest_base_dir }}/debug.txt"
+    state: touch
+    access_time: preserve
+    modification_time: preserve
+    mode: u=rwX,g=rX,o=rX
+    owner: minetest
+    group: minetest
+  become: true
+
+- name: Link userfriendly directories into overlayfs structure
+  file:
+    path: "{{ minetest_base_dir }}/{{ item.onto }}"
+    src: "{{ minetest_base_dir }}/{{ item.src }}"
+    state: link
+    owner: minetest
+    group: minetest
+    force: true
+  with_items:
+    - src: minetest_source
+      onto: .overlayfs/src_root
+    - src: minetest_game
+      onto: .overlayfs/game_root/games/minetest_game
+    - src: minetest_mods
+      onto: .overlayfs/mods_root/mods
+    - src: minetest.conf
+      onto: .overlayfs/conf_root/minetest.conf
+    - src: debug.txt
+      onto: .overlayfs/conf_root/debug.txt
+    - src: world
+      onto: .overlayfs/conf_root/worlds/world
+  become: true
diff --git a/kif_minetest_server/templates/map_meta.txt.j2 b/kif_minetest_server/templates/map_meta.txt.j2
new file mode 100644
index 0000000..49ff1a4
--- /dev/null
+++ b/kif_minetest_server/templates/map_meta.txt.j2
@@ -0,0 +1,173 @@
+mgvalleys_np_dungeons = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.8
+	seed = 0
+	spread = (500,500,500)
+	scale = 0.5
+	octaves = 2
+	offset = 0.9
+}
+mgvalleys_np_cavern = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.63
+	seed = 59033
+	spread = (768,256,768)
+	scale = 1
+	octaves = 6
+	offset = 0
+}
+mgvalleys_np_cave2 = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.5
+	seed = 10325
+	spread = (67,67,67)
+	scale = 12
+	octaves = 3
+	offset = 0
+}
+mgvalleys_np_valley_profile = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 1
+	seed = 777
+	spread = (512,512,512)
+	scale = 0.5
+	octaves = 1
+	offset = 0.6
+}
+mgvalleys_np_rivers = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.6
+	seed = -6050
+	spread = (256,256,256)
+	scale = 1
+	octaves = 5
+	offset = 0
+}
+mgvalleys_altitude_chill = 90
+mgvalleys_spflags = altitude_chill, humid_rivers, vary_river_depth, altitude_dry
+mgvalleys_large_cave_num_min = 0
+mg_biome_np_heat_blend = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 1
+	seed = 13
+	spread = (8,8,8)
+	scale = 1.5
+	octaves = 2
+	offset = 0
+}
+mgvalleys_np_inter_valley_fill = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.8
+	seed = 1993
+	spread = (256,512,256)
+	scale = 1
+	octaves = 6
+	offset = 0
+}
+mg_flags = caves, dungeons, light, decorations, biomes
+mg_name = valleys
+mgvalleys_river_depth = 4
+mgvalleys_np_valley_depth = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 1
+	seed = -1914
+	spread = (512,512,512)
+	scale = 4
+	octaves = 1
+	offset = 5
+}
+chunksize = 5
+water_level = 1
+mgvalleys_cavern_limit = -256
+mapgen_limit = 31000
+mgvalleys_np_filler_depth = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.5
+	seed = 1605
+	spread = (256,256,256)
+	scale = 1.2
+	octaves = 3
+	offset = 0
+}
+mgvalleys_np_cave1 = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.5
+	seed = 52534
+	spread = (61,61,61)
+	scale = 12
+	octaves = 3
+	offset = 0
+}
+mg_biome_np_heat = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.5
+	seed = 5349
+	spread = (1000,1000,1000)
+	scale = 50
+	octaves = 3
+	offset = 50
+}
+mgvalleys_small_cave_num_min = 0
+seed = {{ minetest_seed }}
+mgvalleys_large_cave_num_max = 2
+mg_biome_np_humidity_blend = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 1
+	seed = 90003
+	spread = (8,8,8)
+	scale = 1.5
+	octaves = 2
+	offset = 0
+}
+mgvalleys_large_cave_flooded = 0.5
+mgvalleys_cave_width = 0.09
+mg_biome_np_humidity = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.5
+	seed = 842
+	spread = (1000,1000,1000)
+	scale = 50
+	octaves = 3
+	offset = 50
+}
+mgvalleys_small_cave_num_max = 0
+mgvalleys_river_size = 5
+mgvalleys_cavern_taper = 192
+mgvalleys_cavern_threshold = 0.6
+mgvalleys_dungeon_ymin = -31000
+mgvalleys_np_terrain_height = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 0.4
+	seed = 5202
+	spread = (1024,1024,1024)
+	scale = 50
+	octaves = 6
+	offset = -10
+}
+mgvalleys_large_cave_depth = -33
+mgvalleys_dungeon_ymax = 63
+mgvalleys_np_inter_valley_slope = {
+	flags = defaults
+	lacunarity = 2
+	persistence = 1
+	seed = 746
+	spread = (128,128,128)
+	scale = 0.5
+	octaves = 1
+	offset = 0.5
+}
+[end_of_params]
diff --git a/kif_minetest_server/templates/minetest.conf.j2 b/kif_minetest_server/templates/minetest.conf.j2
new file mode 100644
index 0000000..c75fba6
--- /dev/null
+++ b/kif_minetest_server/templates/minetest.conf.j2
@@ -0,0 +1,69 @@
+# Server settings
+server_name = {{ server_name }}
+server_description = {{ server_description }}
+motd = {{ server_motd }}
+server_address = {{ server_address }}
+server_announce = {{ server_announce }}
+serverlist_url = {{ server_serverlist_url }}
+port = {{ server_port }}
+ipv6_server = {{ server_ipv6_server }}
+enable_ipv6 = {{ server_enable_ipv6 }}
+
+# Game settings
+language = {{ server_language }}
+default_game = minetest
+max_users = {{ server_max_users }}
+enable_damage = {{ server_enable_damage }}
+enable_pvp = {{ server_enable_pvp }}
+enable_minimap = {{ server_enable_minimap }}
+creative_mode = {{ server_creative_mode }}
+free_move = {{ server_free_move }}
+fast_move = {{ server_fast_move }}
+noclip = {{ server_noclip }}
+
+# Auth and Privs
+default_password = {{ server_default_password }}
+default_privs = {{ server_default_privs|join(", ") }}
+disallow_empty_password = {{ server_disallow_empty_password }}
+
+# Admin name
+name = {{ server_admin_name }}
+
+# Error handling
+kick_msg_shutdown = {{ server_kick_msg_shutdown }}
+kick_msg_crash = {{ server_kick_msg_crash }}
+ask_reconnect_on_crash = {{ server_ask_reconnect_on_crash }}
+debug_log_level = {{ server_debug_log_level }}
+debug_log_size_max = {{ server_debug_log_size_max }}
+
+# Performance settings
+chat_message_max_size = 500
+chat_message_limit_per_10sec = 10.0
+chat_message_limit_trigger_kick = 50
+deprecated_lua_api_handling = legacy
+server_unload_unused_data_timeout = 300
+block_send_optimize_distance = 11
+server_side_occlusion_culling = false
+max_block_generate_distance = {{ server_max_block_generate_distance }}
+max_block_send_distance = {{ server_max_block_send_distance }}
+max_simultaneous_block_sends_per_client = {{ server_max_simultaneous_block_sends_per_client }}
+max_simultaneous_block_sends_server_total = {{ server_max_simultaneous_block_sends_server_total }}
+max_packets_per_iteration = {{ server_max_packets_per_iteration }}
+active_object_send_range_blocks = {{ server_active_object_send_range_blocks }}
+active_block_range = {{ server_active_block_range }}
+
+# Map generator
+mg_name = valleys
+mgvalleys_spflags = altitude_chill,humid_rivers,vary_river_depth,altitude_dry
+
+# Mod config
+secure.http_mods = {{ server_secure_http_mods|join(", ") }}
+mapserver.enable_crafting = {{ mapserver_enable_crafting }}
+mapserver.url = {{ mapserver_url }}
+mapserver.key = {{ mapserver_key }}
+areas.self_protection = true
+mesecon.luacontroller_lightweight_interrupts = true
+moreblocks.stairsplus_in_creative_inventory = {{ moreblocks_stairsplus_in_creative_inventory }}
+advtrains_wagon_load_range = {{ advtrains_wagon_load_range }}
+advtrains_show_ids = {{ advtrains_show_ids }}
+advtrains_lines_rwt_realtime = {{ advtrains_lines_rwt_realtime }}
diff --git a/kif_minetest_server/templates/minetest.service.j2 b/kif_minetest_server/templates/minetest.service.j2
new file mode 100644
index 0000000..9068c39
--- /dev/null
+++ b/kif_minetest_server/templates/minetest.service.j2
@@ -0,0 +1,14 @@
+[Unit]
+Description=Minetest
+
+[Service]
+Type=simple
+User=minetest
+Group=minetest
+ExecStart={{ minetest_base_dir }}/minetest/bin/minetestserver --quiet
+WorkingDirectory={{ minetest_base_dir }}/minetest
+Restart=on-failure
+RestartSec=5s
+
+[Install]
+WantedBy=multi-user.target
diff --git a/kif_minetest_server/templates/world.mt.j2 b/kif_minetest_server/templates/world.mt.j2
new file mode 100644
index 0000000..6a52b74
--- /dev/null
+++ b/kif_minetest_server/templates/world.mt.j2
@@ -0,0 +1,18 @@
+creative_mode = false
+auth_backend = {{ server_auth_backend }}
+player_backend = {{ server_player_backend }}
+gameid = minetest
+enable_damage = {{ server_enable_damage }}
+backend = {{ server_backend }}
+{% if 'postgresql' in [server_auth_backend, server_player_backend, server_backend] %}
+pgsql_connection = host={{ psql_host }} user={{ psql_user }} password={{ psql_password }} dbname={{ psql_db }}
+pgsql_player_connection = host={{ psql_host }} user={{ psql_user }} password={{ psql_password }} dbname={{ psql_db }}
+{% endif %}
+
+{% for mod in load_mods|sort() %}
+load_mod_{{ mod }} = true
+{% endfor %}
+
+{% for mod in disabled_mods|sort() %}
+load_mod_{{ mod }} = false
+{% endfor %}
diff --git a/production.yml b/production.yml
new file mode 100644
index 0000000..dfc1bd3
--- /dev/null
+++ b/production.yml
@@ -0,0 +1,7 @@
+---
+- hosts: all
+  roles:
+    - role: kif_minetest_mapserver
+      vars:
+        use_production_secrets: true
+        mapserver_key: "{{ lookup('password', '/dev/null chars=ascii_letters,digits,hexdigits,punctuation length=16') }}"
diff --git a/restart_server.sh b/restart_server.sh
deleted file mode 100644
index 6af34f8..0000000
--- a/restart_server.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-
-systemctl restart minetest
-systemctl restart mapserver
diff --git a/testing.yml b/testing.yml
new file mode 100644
index 0000000..cd27340
--- /dev/null
+++ b/testing.yml
@@ -0,0 +1,8 @@
+---
+- hosts: all
+  roles:
+    - role: kif_minetest_mapserver
+      vars:
+        server_player_backend: sqlite3
+        server_backend: sqlite3
+        server_announce: false
diff --git a/update_mods.sh b/update_mods.sh
deleted file mode 100644
index f5b75fc..0000000
--- a/update_mods.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-# This is the directory and version of the main server code
-MINETEST_MODS_DIR=/var/lib/minetest/minetest_mods
-MINETEST_VERSION=5.2.0
-
-# Mods repo has its own update script, so we just call it!
-cd $MINETEST_MODS_DIR
-./update.sh
diff --git a/update_server.sh b/update_server.sh
deleted file mode 100644
index ade97c2..0000000
--- a/update_server.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-# This is the directory and version of the main server code
-MINETEST_TARGET_DIR=/var/lib/minetest/minetest
-MINETEST_VERSION=5.2.0
-
-# This is the directory and version of the base game/mod, i.e. the "minetest_game"
-MINETEST_GAME_DIR=/var/lib/minetest/minetest_game
-MINETEST_GAME_VERSION=5.2.0
-
-# Pull correct version of minetest_game
-cd $MINETEST_GAME_DIR
-git fetch -t
-git checkout $MINETEST_GAME_VERSION
-
-# Pull correct version of minetest
-cd $MINETEST_TARGET_DIR
-git fetch -t
-git checkout $MINETEST_VERSION
-
-# Build it
-cmake . -DRUN_IN_PLACE=TRUE -DBUILD_SERVER=TRUE -DBUILD_CLIENT=FALSE -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/
-make -j4
-- 
GitLab