Awasu » Using Nexus when building Docker images
Tuesday 9th August 2022 10:55 AM

We now have Nexus proxying artifacts for some of the more common online repositories. We would also like to use it when building Docker images, and the principles are mostly the same, although there are a few considerations.

DNS inside containers

If you are referencing the Nexus server via a name (e.g. in this tutorial, I've been using nexus3), then this name must resolve from inside a Docker container. If you're having trouble getting this to work, you can add something like this:

--add-host nexus3:192.168.50.42

to your docker build command, to temporarily add an entry to the hosts file.

Alternatively, you can add this:

--network host

to connect the container to the host's network[1]Instead of its own private network., where the name should resolve normally.

You can also configure DNS servers in your /etc/docker/daemon.json file e.g.

{
    "dns": [ "8.8.8.8", "1.1.1.1", "10.2.2.1" ]
}

although this will then apply to all your containers.

Proxying for PyPi

As described earlier, we need to set up a pip.conf file that tells pip to connect to our Nexus server. Since we're inside a container, we can just configure this globally, so set the file up somewhere in your Docker context, and then modify the Dockerfile to copy it into the container[2]This, of course, needs to be done before you use pip for the first time.:

COPY pip.conf /etc/

Proxying for npm

As described earlier, we need to configure Nexus as the npm registry, so simply add the following to the Dockerfile:

RUN npm config set registry http://nexus3:8081/repository/npm-proxy

Proxying for RPM-based package managers

With the demise of Centos 8, the go-to base image is probably now Rocky Linux.

Create a new yum (proxy) repo in Nexus, as described earlier, called e.g. rocky-proxy, with a remote repository URL of http://dl.rockylinux.org.

Then, create a file called nexus3-proxy.repo in your Docker context that looks like this:

[nexus3-proxy-baseos]
name=Nexus 3 Proxy - BaseOS (Rocky Linux $releasever)
baseurl=http://nexus3:8081/repository/rocky-proxy/$contentdir/$releasever/BaseOS/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
repo_gpgcheck=0
priority=1

[nexus3-proxy-appstream]
name=Nexus 3 Proxy - AppStream (Rocky Linux $releasever)
baseurl=http://nexus3:8081/repository/rocky-proxy/$contentdir/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
repo_gpgcheck=0
priority=1

[nexus3-proxy-extras]
name=Nexus 3 Proxy - Extras (Rocky Linux $releasever)
baseurl=http://nexus3:8081/repository/rocky-proxy/$contentdir/$releasever/extras/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
repo_gpgcheck=0
priority=1

and modify the Dockerfile to copy it into the container:

COPY nexus3-proxy.repo /etc/yum.repos.d/

Note that the old .repo files will still be there inside the container, which means that images will fail to build if there is no internet access[3]Because dnf will be trying to update from those repo's, but can't., so if you want to be able to build images while offline, you will also need to delete these files:

RUN cd /etc/yum.repos.d/ && \
    rm -f Rocky-BaseOS.repo Rocky-AppStream.repo Rocky-Extras.repo

Proxying for apt-based package managers

Rocky Linux doesn't provide 32-bit ARM Docker images, so I'm still using Debian 10 (Buster) as my base image for containers running on a Raspberry Pi 4.

Examining /etc/apt/sources.list inside an image, we see that there are three repo's:

deb http://deb.debian.org/debian buster main
deb http://security.debian.org/debian-security buster/updates main
deb http://deb.debian.org/debian buster-updates main

but two of them have the same base URL, so we only need to set up two Nexus proxy repo's, with the following base URL's:

  • http://deb.debian.org/debian
  • http://security.debian.org/debian-security

We then write a new sources.list file, to replace the standard one e.g.

deb http://nexus3:8081/repository/debian-buster buster main
deb http://nexus3:8081/repository/debian-buster-security buster/updates main
deb http://nexus3:8081/repository/debian-buster buster-updates main

and copy it in at the start of the Dockerfile:

COPY nexus3-sources.list /etc/apt/sources.list

Note that for a Docker image, you would typically only want the security updates, but in this case, since Buster is no longer the stable (i.e. latest) release, we might as well get everything, since things are unlikely to change.

References

References
1 Instead of its own private network.
2 This, of course, needs to be done before you use pip for the first time.
3 Because dnf will be trying to update from those repo's, but can't.
Have your say