Why I Chose Nexus Repository Over Artifactory When Using Docker

DZone 's Guide to

Why I Chose Nexus Repository Over Artifactory When Using Docker

A developer goes through his process of choosing between Artifactory and Nexus for his Docker needs.

· DevOps Zone ·
Free Resource

Editor’s NoteAsaf Mesika is Core Senior Developer at Logz.io and participates in the Israeli Java Community User Group on meetup.com. He has “bare minimum patience” with open source products.

A couple of days ago, I needed to setup Logz.io’s first internal Maven repository. We’re a youngish company in the field of Log Analysis and haven’t needed a Maven repository so far. We rely heavily on open source technologies but the need to fork and patch these technologies arises all too often.

Until the merge takes place, the code’s artifacts need to be hosted somewhere accessible to the build system — internal Maven Repository to the rescue.

Open Source Repository Choices

When trying open source products, especially in Startups, you have a very low threshold of patience for things not working. I think open source products must invest in the onboarding user experience as much as possible.

I am aware of two open source products: Artifactory by JFrog and Nexus Repository Manager by Sonatype. I leaned to Artifactory since I remember it being more feature rich, and being used by many popular open source products.

In this article I describe a case study of how I failed to install Artifactory using Docker following their official guide and compared that 3 min installation of Nexus.

Chapter 1: Artifactory Installation

I searched for “Installing Artifactory using Docker” and got to this official guide.

First thing I created a couple of directories they advised as highly recommended to mount:

mkdir -p /var/artifactory/data
mkdir /var/artifactory/logs
mkdir /var/artifactory/backup
mkdir /var/artifactory/etc

I then continued to run the Docker image:

docker run — name artifactory -p 80:8081 -e “ARTIFACTORY_HOME=/var/opt/jfrog/artifactory” -v /var/artifactory/data:/var/opt/jfrog/artifactory/data -v /var/artifactory/logs:/var/opt/jfrog/artifactory/logs -v /var/artifactory/backup:/var/opt/jfrog/artifactory/backup -v /var/artifactory/etc:/var/opt/jfrog/artifactory/etc jfrog-docker-reg2.bintray.io/jfrog/artifactory-oss:latest

I got this first error message:

Unable to find image ‘jfrog-docker-reg2.bintray.io/jfrog/artifactory-oss:latest’ locally
latest: Pulling from jfrog/artifactory-oss
a2c33fe967de: Pull complete
b527c153b530: Pull complete
63f70f5a23b8: Pull complete
333ee72b10ae: Pull complete
3297c49bbe77: Pull complete
e2f19b824bda: Pull complete
e907a4f03f92: Pull complete
25981fad9a81: Pull complete
37226b35a736: Pull complete
2d90bd8d7cb9: Pull complete
ac1fc7130559: Pull complete
4f43cce3cb41: Pull complete
Digest: sha256:d8f0022b19a3f88a01565d970a0cc0d72e851700f6eded920388c016bc1d25dc
Status: Downloaded newer image for jfrog-docker-reg2.bintray.io/jfrog/artifactory-oss:latest
nginx: unrecognized service
grep: /var/opt/jfrog/artifactory/etc/default: No such file or directory
** ERROR: Artifactory pid destination ARTIFACTORY_PID was not set in /etc/opt/jfrog/artifactory/default ! Please add it!
  1. I don’t understand why NGINX is an unrecognized service
  2. The script tried to grep a file named default in /var/opt/jfrog/artifactory/etc — the directory I was told to mount and failed. It makes sense it failed since the directory is empty.

The main error is that ARTIFACTORY_PID is missing. At first I was sure I was missing an environment variable in my run command. I googled the error and found a “How can I use own located folders as volumes in docker artifactory container?” StackOverflow question, which explained that inside the Docker container there are files inside the etc folder which get overriden due to the volume of the etc folder. They suggested a fix to run Docker with the command /bin/bash, copy the contents of the folder to my host etc folder, and then continue. That was way too much work for me.

I settled by removing the mount of etc folder and continued. I ran the command again without that mount and got:

nginx: unrecognized service
Starting Artifactory tomcat as user artifactory…
Max number of open files: 524288
Using ARTIFACTORY_HOME: /var/opt/jfrog/artifactory
Using ARTIFACTORY_PID: /var/opt/jfrog/run/artifactory.pid
Creating directory /var/opt/jfrog/artifactory/logs/catalina
mkdir: cannot create directory `/var/opt/jfrog/artifactory/logs/catalina’: Permission denied
Creating directory /var/opt/jfrog/artifactory/temp
Creating directory /var/opt/jfrog/artifactory/work
touch: cannot touch `/opt/jfrog/artifactory/tomcat/logs/catalina.out’: No such file or directory
/opt/jfrog/artifactory/tomcat/bin/catalina.sh: line 401: /opt/jfrog/artifactory/tomcat/logs/catalina.out: No such file or directory
** ERROR: Artifactory Tomcat server did not start. Please check the logs

So it couldn’t create a directory under the logs folder I created and mounted. This is something I did many times, including with Graphite and logz.io’sjmx2graphite.

I checked permissions on those directories. I was running as root, and the directories had write access as root — which was the same user I used when I was running the Docker Artifactory image.

I Googled some more to learn about how Docker treats permissions and about this problem in Artifactory and saw that they run their Tomcat application as “artifactory” user, which may be the reason why they can’t write to this directory.

It didn’t make sense to me to change access to a user which doesn’t exists on the host, only by using its internal Unix user id (only residing inside the Docker image). I discarded the idea of giving write access to ALL, which doesn’t sound very secure to me.

At this point, after spending roughly an hour, I gave up and tried a second option: Nexus.

Chapter 2: Sonatype Nexus Repository Manager

Sonatype Nexus Repository Manager is a product I’ve worked with for many years dating back to 2009 when I was working at Cotendo, and also in my time at Akamai. I was very pleased with it, so I tried to use it again.

I got to this installation article. I immediately gave them bonus points for being completely open source about it — a GitHub repo with its Dockerfile and a very good readme. What I love about it is that you can take that Dockerfile and create your own version with your config very easily.

Compare this with Artifactory:

  • You can’t find their Dockerfile (Try googling “artifactory docker dockerfile”)
  • Their installation guide is inside a wiki which doesn’t allow commenting, so people end up improving this doc using StackOverflow, as opposed to comments or just Pull Request / Issues on the repo hosting the Dockerfile

I ran the following command to create a volume container hosting the persisted files, per the guide suggestion:

docker run -d — name nexus-data sonatype/nexus echo “data-only container for nexus”

Next I ran the Nexus image:

docker run -d -p 80:8081 — name nexus — volumes-from nexus-data sonatype/nexus

Boom! I’m done! 3 minutes and I happily surf to their admin page.


Sonatype did some great work with the UX of installing their open source product using Docker. Artifactory has some way to go to achieve this. Here are suggestions to them:

  • Put your Dockerfile as a Git repository
  • Open the installation guide to comments or place it as README.MD in the git repo
  • Fix all the problems — make it truly 3 minutes installation for first time users.

Originally published by Asaf Mesika. 

nexus ,repository ,docker ,maven

Published at DZone with permission of Asaf Mesika , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}