Extremely Efficient Minecraft (almost) 1.16.4 Server

The goal of today’s blogpost is to get a Minecraft server which is joinable from 1.16.4 at reasonable performance running on a very cheap VPS. Sounds impossible, but it’s doable, with a catch.


Cuberite is a complete rewrite of the Minecraft server, written in the C++ programming language, which makes the server a lot more efficient than the offical Java server, or even PaperMC (which is based on the official Java server). The problem with Cuberite is that it only supports versions 1.8-1.12.2, which means that players would have to change settings in their launchers in order to launch the older version and join your server. As I said earlier, the goal of today’s post is to be able to join from a 1.16.4 client. That’s where ViaVersion comes in.


ViaVersion is a Spigot/Paper/BungeeCord plugin which allows a player to join from any newer version of minecraft than the version which server runs (obviously missing out on newer features like the updated nether, but it’s a comprimise which I think is acceptable considering that this setup uses so little resources.)

ViaVersion, however, being a Spigot plugin, cannot run on Cuberite. So what gives? How are we going to tie this all together? The answer is Bungeecord.


Bungeecord is a Minecraft server proxy. That is, a player will connect to Bungeecord and Bungeecord will connect the player to the server. Bungeecord manages authentication with Mojang, and most importantly allows you to use some Spigot plugins, namely ViaVersion.

For this tutorial we will be using Waterfall, which is PaperMC’s more performant fork of Bungee, however using ordinary Bungeecord would still work.

Here is a diagram to help you understand

How to do it

Setting up Cuberite

I am going to assume that you are connected to the server via SSH and that port 25565 is open.

The first thing you will want to do is install Docker, Docker-compose and UFW. Docker and Docker-compose are tools which create containers to run Bungeecord and Cuberite inside of, and UFW is a simple firewall manager to manage access from the outside world.

sudo apt install -y docker.io docker-compose ufw

Now we’re gonna start setting up Cuberite in Docker-compose.

mkdir /srv/cuberite
cd /srv/cuberite
nano docker-compose.yml

What this does is create a folder which we can run cuberite out of, and open a file called docker-compose.yml, which is the file we can use to tell docker-compose how to set things up.

Paste this into the docker-compose.yml file:

  image: mehmetahsen/cuberite
    - ./server:/cuberite
    - 25575:25565

  tty: "true"
  restart: unless-stopped

Now we can start the server:

docker-compose up -d

and wait a minute or two for docker to download Cuberite and for Cuberite to generate the terrain and the files it needs. Note that running the docker-compose command only works when you’re in the directory which contains the docker-compose.yml file.

If you like you can change your version to 1.12.2 and test out the server, to make sure it’s all working properly.

Next we need to edit cuberite’s config to allow connections from BungeeCord:

nano server/settings.ini

Under the section called “Authentication” make the following changes:

  • Change “Authenticate” to 0 and
  • Change “AllowBungeeCord” to 1

Ignore the other parts of the config file, unless you see something there which you would like to change.

Now, restart the Cuberite server to apply your changes:

docker-compose restart

Setting up BungeeCord

The process for setting up BungeeCord is quite similar to setting up Cuberite.

First, make the folder which stores all the BungeeCord stuff and enter it

mkdir /srv/bungeecord
cd /srv/bungeecord

Next make a file which tells docker-compose how to set things up

nano docker-compose.yml

and paste in this:

version: "3"

    image: itzg/bungeecord
    network_mode: "host"
      - "./proxy:/server"
      BUNGEE_BASE_URL: "https://papermc.io/ci/job/Waterfall/"
    restart: unless-stopped

and start Bungeecord so it can fetch the files it needs and do some initial setup:

docker-compose up -d

then wait a minute or two for it to set things up

Now we can edit the config file to tell BungeeCord to look for the Cuberite server, and tell it to use the default Minecraft port.

nano ./proxy/config.yml

and edit the following parts:

  • Change query_port: 25577 into query_port: 25565
  • Change host: into host:
  • Change the address under servers to localhost:25575

Here’s an example:

prevent_proxy_connections: false
- query_port: 25565
  motd: '&1A Cuberite server proxied by BungeeCord'
  tab_list: GLOBAL_PING
  query_enabled: false
  proxy_protocol: false
  ping_passthrough: false
  - lobby
  bind_local_address: true
  max_players: 1
  tab_size: 60
  force_default_server: false

    motd: '&1Just another BungeeCord - Forced Host'
    address: localhost:25575
    restricted: false


To install ViaVersion, you’ll need to grab the latest version from their CI server. Click here: https://ci.viaversion.com/job/ViaVersion/ and right-click the latest one, then press “Copy link address”

Then you need to type the following command to download the plugin and place it in the correct directory, replacing the address in this example with the link you just copied to the latest version:

wget -O ./proxy/plugins/ViaVersion.jar https://ci.viaversion.com/job/ViaVersion/lastSuccessfulBuild/artifact/jar/target/ViaVersion-3.2.2-SNAPSHOT.jar

and restart to apply the changes:

docker-compose restart

Setting up the firewall

This part is quite important, as if left unprotected, players can connect directly to the Cuberite server instead of through BungeeCord. Because we put the Cuberite server into “offline” mode, it does not authenticate players and anyone could log in to your account and steal your items, or gain op priveleges.

sudo ufw allow 25565
sudo ufw allow ssh
sudo ufw enable

Now your server is ready for players to join!

Leave a Reply

Your email address will not be published.