Setting up Nexus using Caddy and Docker

Introduction / The Problem

Recently, I’ve encountered a problem. I host Jenkins and Nexus on one server. Nexus requires Java 8 while Jenkins recommends Java 11. I did not want my entire server to be stuck on Java 8, so I decided to put Nexus in a Docker container. That way, my entire server no longer requires Java 8. Here’s how I did it. This tutorial will assume you are using Ubuntu 20.04.


Firstly, you’ll want to make sure you actually have Docker installed. To verify, you can run the following:

docker version

If you get an output, you’re all set. If Docker isn’t installed, you can install it with the following command:

curl -sSL | CHANNEL=stable bash

Installing Caddy

For this tutorial, we will be using Caddy as the webserver. The reason for using Caddy is because Caddy offers automatic HTTPS certificates, and it’s super easy to setup a reverse proxy. Run the following commands to install Caddy:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf '' | sudo tee /etc/apt/trusted.gpg.d/caddy-stable.asc
curl -1sLf '' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Commands retrieved from on March 24, 2022.

If you go to your server’s IP address, you should see a page that welcomes you to Caddy. If you have another webserver installed, you can setup a reverse proxy with that. However, it is much more complicated, which is why we will be using Caddy. If you don’t see the webpage generated from Caddy, you likely have another webserver installed and in use already. This tutorial won’t cover setting up reverse proxies with other servers such as Apache or nginx.

Running the Container

If you’re just looking for the command, here it is:

docker run -d -p --name nexus -v nexus-data:/nexus-data sonatype/nexus3

Let’s break the command down. This will run a new Docker container in detached mode. This means you will not see any logs from it. I’ll show you how to see the logs later. The -p 8081:8081 simply maps port 8081 on your machine from Nexus. If you want to use a different port, you must change the first one. For example, if I wanted to run it on port 8082, I would use the following instead: -p 8082:8081. The --name nexus simply gives it a nice name. If you don’t do this, Docker will assign it a name automatically which can be confusing. The -v nexus-data:/nexus-data creates a new volume for all of your data on Nexus to be stored. The last part is simply the image to use.

Note that depending on your server’s hardware, it can take a few minutes for Nexus to start up. The following command will let you see logs from the container:

docker logs nexus

You should see a message that says Nexus was started after a few minutes.

Setting up Caddy

To actually change the settings for Caddy, we use the Caddyfile. On Ubuntu, the Caddyfile should be at: /etc/caddy/Caddyfile. Use your preferred text editor to open the Caddyfile.

nano /etc/caddy/Caddyfile

Unless you have other things setup with Caddy, you can delete all the sample code. Replace the <domain> with your actual domain. For example, if I wanted to host it at, I’d enter in place of <domain>. Do not include the “< >” symbols, just the domain. If you decided to use anything other than port 8081, you’ll want to change that as well. If I were to use port 8082, the line would be reverse_proxy http://localhost:8082 instead.

<domain> {
	reverse_proxy http://localhost:8081

Seriously, it’s that dead simple. That’s how you setup a reverse proxy with HTTPS using Caddy. It’s much easier than Apache or nginx.

Once you’ve done that, run the following to restart Caddy:

sudo service caddy restart

At this point, you should be able to access Nexus at the domain you specified in the Caddyfile. If you click “Sign in” it will say there is a file with your admin password that you need to use. To actually get this file, you simply need to go to where your Docker volumes are. You should be able to access it by changing directories using this command:

cd /var/lib/docker/volumes/nexus-data/_data

The volume name will be whatever you set in the docker run command. If you run ls, you should see something like this

admin.password  cache  elasticsearch  generated-bundles  javaprefs  keystores  log     port                 tmp
blobs           db     etc            instances  lock       orient  restore-from-backup

There it is! You now just have to display it using the cat command:

cat admin.password

You should see a bunch of numbers and letters. You should be able to use the username “admin” and the randomly generated password to login. You will be asked to change the password. At this point, your installation is complete. However, there’s still one problem. If you restart your server, the Docker container won’t start back up automatically. We’ll need to slightly modify the command to achieve this.

Making Nexus restart

First, stop the container.

docker stop nexus

Now, use the following command instead.

docker run -d -p --restart unless-stopped --name nexus -v nexus-data:/nexus-data sonatype/nexus3 

Now, Nexus will start automatically on a server restart. However, you can still stop it with the docker stop command.

Updating Nexus

To update it, you’ll want to stop the nexus container, remove it, pull the image, and then start it again. The following commands should do it:

docker stop nexus
docker rm nexus
docker pull sonatype/nexus3
docker run -d -p --restart unless-stopped --name nexus -v nexus-data:/nexus-data sonatype/nexus3 

Note that removing the container shouldn’t delete any of your data if you followed the tutorial correctly. You shouldn’t need to modify anything else as long as the container name and port mappings match up with what you had before.

I hope this tutorial helped you setup Nexus 3. It can be quite a hassle especially since you essentially need to use a reverse proxy for HTTPS. Caddy makes reverse proxying much easier. The advantage of running Nexus in Docker is that your server installation is no longer stuck on Java 8. This is the easiest and best way I’ve found to get Nexus 3 working so far. If you have any questions or suggestions, feel free to leave a comment.