DEV Community

loading...
Cover image for Preconfigured Nexus Repository Manager (NXRM) Docker container
DoiT International

Preconfigured Nexus Repository Manager (NXRM) Docker container

Meir Gabay
I'm passionate about studying and teaching. DevOps Engineer @ Binah.ai
Originally published at meirg.co.il Updated on ・4 min read

TL;DR: Link To Project @ GitHub - unfor19/nexus-ops

Recently, I've been looking for a way to avoid hitting DockerHub rate limits. One of the solutions that I came up with was deploying Nexus Repository Manager OSS (NXRM) as part of my CI/CD environment, so the CI/CD runners hit NXRM instead of DockerHub when attempting to pull public Docker images.

As always, I Googled a lot on how to get started with NXRM, and it seemed like it's best just to run it locally and see how it goes.

Ladies and gents, I give you my hands-on experience with provisioning a preconfigured NXRM Docker container.

The Goal

NXRM Docker container that is preconfigured with DockerHub and AWS ECR Public Gallery. Here's what I found in Google:

My Issue With Existing Solutions

I want to run the init-script immediately when NXRM is ready and part of the NXRM startup. I don't want to execute any script manually on my machine; everything should be done as part of NXRM's startup process. Most existing solutions describe running something on your machine that will communicate with NXRM; I'm looking for something different.

Desired Outcome

Let's break it into a few bullet points that will describe the desired output.

  • The init-script is readable and easy to maintain.
  • Restarting the NXRM container should be idempotent; the init-script should not attempt to create existing resources.
  • The init-script should be written in a popular scripting language, like Bash (so I chose Bash).
  • Automated actions should be done using NXRM REST API, to support adding more features easily. Since I chose Bash, I'm using curl to make HTTP requests.

Designing The Init Script

The desired outcome is clear; now, I need to declare the actions that the init-script will perform when starting the NXRM container. Here's the list of actions (in order):

  1. Changes the initial random password that is in /nexus-data/admin.password to admin
  2. Enables anonymous access - allows anonymous users to access localhost:8081 with READ permissions
  3. Adds Docker Bearer Token Realm - allows anonymous pulls from local Nexus registry localhost:8081
  4. Creates two Docker repository of type proxy
    1. docker-hub - DockerHub
    2. docker-ecrpublic - AWS ECR Public
  5. Creates a Docker repository of type group
    1. docker-group - The above Docker repositories are members of this Docker group

Creating A Custom Docker Image

I've created a Docker image based on NXRM official Docker image.

Here's is how the Dockerfile looks like:


ARG NEXUS_VERSION="3.30.1"

FROM sonatype/nexus3:${NEXUS_VERSION} as app
USER root
RUN curl -L -o /usr/local/bin/jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 && \
    chmod +x /usr/local/bin/jq

USER nexus
ENV NEXUS_DATA_PATH="/nexus-data" \
    NEXUS_ADMIN_USERNAME="admin" \
    NEXUS_ADMIN_PASSWORD="admin" \
    NEXUS_API_PATH="service/rest/v1" \
    NEXUS_BASE_PATH="http://localhost:8081" \
    NEXUS_OPS_VERBOSE="false"
WORKDIR /"${NEXUS_DATA_PATH}/nexus-ops/"
COPY provision/ .
CMD /nexus-data/nexus-ops/entrypoint.sh
Enter fullscreen mode Exit fullscreen mode

Note: I added jq to the mix because I intend to use more APIs, and I'll need to analyze some JSON data. I find it best to analyze JSON data with jq when using Bash.

As you can see from the Dockerfile above, I'm copying the directory provision/ to the NXRM image, and instead of running /opt/sonatype/start-nexus-repository-manager.sh as the CMD, I wrapped it with the provision/entrypoint.sh script.

Bottom line, the whole logic is maintained in the init-script called entrypoint.sh.

Here's how the main function looks like

main(){
    start_nexus
    set_global_variables
    wait_for_healthy_response
    set_credentials
    change_initial_password
    enable_anonymous_access
    realms_enable_docker_token
    repositories_create_repository_wrapper "proxy" "docker-hub" "${_NEXUS_OPS_PATH}/repositories/docker-proxy-dockerhub.json"
    repositories_create_repository_wrapper "proxy" "docker-ecrpublic" "${_NEXUS_OPS_PATH}/repositories/docker-proxy-ecrpublic.json"
    repositories_create_repository_wrapper "group" "docker-group" "${_NEXUS_OPS_PATH}/repositories/docker-group.json"
    log_msg "Finished executing - ${_NEXUS_OPS_PATH}/entrypoint.sh"
}
Enter fullscreen mode Exit fullscreen mode

Final Result

Here's my project @ GitHub - unfor19/nexus-ops. To understand how it all works, check the provision/entrypoint.sh file; I tried to make it as neat as possible.

One more thing; you'll find the directory provision/repositories in my project. That directory contains the JSON structure of the provisioned repositories. As an example, here's the command for creating the DockerHub repository

repositories_create_repository_wrapper "proxy" "docker-hub" "${_NEXUS_OPS_PATH}/repositories/docker-proxy-dockerhub.json"
Enter fullscreen mode Exit fullscreen mode

Final Words

Initially, I was slightly intimidated by NXRM; it seemed complex to proxy Docker requests via NXRM. However, after creating this project, I think I got the idea, and I hope you did too.

Discussion (0)