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:
- Automated Setup of Sonatype Nexus Repository Manager
- NXRM Integration API Scripting Examples
- Nexus Community - Automated provisioning of nexus
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):
- Changes the initial random password that is in
/nexus-data/admin.password
toadmin
- Enables anonymous access - allows anonymous users to access
localhost:8081
withREAD
permissions - Adds Docker Bearer Token Realm - allows anonymous pulls from local Nexus registry
localhost:8081
- Creates two Docker repository of type proxy
-
docker-hub
- DockerHub -
docker-ecrpublic
- AWS ECR Public
-
- Creates a Docker repository of type group
-
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
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 usingBash
.
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"
}
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"
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.
Top comments (0)