Private Repositories to store the artifacts (Nexus)
Partho Das
I help businesses design and automate their cloud infrastructure, streamline software deployment pipelines, and ensure they scale efficiently and securely.
What is an Artifacts
Why do we need a repository, we can directly push the artifacts to our deployment server?
- Configure users, provide RBAC to controll the access control
- It helps to store or retrieve any build artifacts
- It helps to create different types of Repositories (`3 types` - Proxy Repo, Hosted Repi, Group Repo )
- Repository Manager helps proxy any remote repositories & caches its content locally for further use by the internal orgs
- Maintains a repo for its own internal artifacts
What are the different types of Repositories Nexus has?
- Proxy repositories: Acts as a cache for public repositories like Dockerhub for Docker images.
- The public repo url https://hub.docker.com/ should be whitelisted in the proxy server
- Hosted repositories: Store build artifacts on Nexus, accessible only to the user with SSO, or Ldap or users from orgs. Not from outside world.
- Group repositories: Combines multiple hosted and proxy repositories into a single logical group,providing a unified view for clients.
Install Nexus on Ubuntu server
sudo apt install openjdk-17-jre-headless
sudo adduser --system --no-create-home --disabled-login --gecos "" nexus
cd /opt
sudo wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz
sudo tar -zxvf latest-unix.tar.gz
cd /opt
sudo mv nexus-3.* nexus
sudo mkdir -p /opt/sonatype-work
sudo chown -R nexus:nexus /opt/sonatype-work
sudo chown -R nexus:nexus /opt/nexus /opt/sonatype-work
sudo vim /opt/nexus/bin/nexus.rc
Add the following line:
run_as_user="nexus"
sudo -u nexus /opt/nexus/bin/nexus start
ps aux | grep nexus
Configuration of the Nexus Server
From the browser type this
Nexus_ip_address:8081 (Or DNS name, if the DNS entries are done with the org DNS)
User name : admin | Password - Need to ssh to the nexus server and find the password based on the location that the UI instructs.
What we can do with Nexus Repository and its facts?
- Support: Nexus supports various artifact formats, including Maven, npm, Docker, and more.
- Configuration: Configure specific settings for each format.
- Authentication: Configure authentication mechanisms like LDAP, Active Directory, or internal users.
- Authorization: Define roles and permissions for different users.
- Encryption: Protect sensitive data like passwords and credentials.
- There are two types of user we can create on Nexus
- 1. Anonymous user - They get only access to the repo contents (GET - Read only ), but they are restricted on other actions like create, delete, upload etc
领英推荐
- 2. Regular user - Each user can have different Roles with different privileges
- There are some default privilege available for Nexus see the lists here https://help.sonatype.com/en/privileges.html
- generally Jenkins integrations are pretty common, where we want the Jenkins to upload the artifacts into Nexus, so we have to create a user Jenkins and assign a role with privilege as create & read - but not delete
Is there any best practices to manage and maintain a private repository?
- Regular Cleanup: Regularly clean up old or unused artifacts to optimize storage.
- Security Audits: Conduct regular security audits to identify and address vulnerabilities.
- Performance Optimization: Monitor performance and optimize settings as needed.
- Version Control: Use version control for Nexus configuration to track changes and facilitate rollback.
- Backup and Recovery: Implement a robust backup and recovery plan to protect your repository data.
- Promotion of repository
- When we build an artifacts, that build does not get used in the production deployment
- First it stores itself into staging repository
- The tests are performed on the staging repo and if it passes all the tests, vulnerability tests,
- The artifacts gets promoted into production repository to be used by prod deployment
Let`s see an example of creating a private Repo for Docker images.
Create a Private Nexus Repo for Docker images
- Go to Nexus, click Create Repo
- Select Docker Hosted
- Update the Realm as active Docker Bearer Token Realm
- This is necessary for authentication when using Docker with Nexus.
To test the repository, we will mimic the stages of Jenkins
- This is often necessary when using HTTP instead of HTTPS.
- For production environments, it's recommended to secure the Nexus instance with HTTPS to avoid using insecure registries.
sudo vi /etc/docker/daemon.json
{
"insecure-registries" : ["https://3.16.26.143:8091"]
// "insecure-registries" : ["Nexus_URL:Port_mentioned_for_Docker_Repo"]
}
- Restart the Docker Daemon
systemctl restart docker
- verify the connectivity of client(Jenkins/Docker) & the Nexus
sudo docker login -u admin 3.16.26.143:8091
- Enter the password set for the Nexus
Note : Make sure to log out of Docker if the login test with the credentials are done to avoid potential security issues. sudo docker logout 3.16.26.143:8091
sudo git clone https://github.com/partho-dev/sample-code.git
sudo docker build -t 3.16.26.143:8091/express .
sudo docker build -t 3.16.26.143:8091/express:1.0 .
# For Prod, its good to use version in auto increment
- Verify if the image creation successfull
sudo docker images
sudo docker push 3.16.26.143:8091/express
The same above manual process can be automated by integrating Jenkins, and the declaritive pipeline can be somewhat like the below. I have added two more stages in that.
pipeline {
agent any #Good to add some agent to execute the jobs
environment {
imageName = "Give_Image_Name"
registryCredentials = "admin"
registry = "3.16.26.143:8091"
dockerImage = ''
}
stages {
stage('checkout') {
steps {
git url: 'https://github.com/partho-dev/sample-code.git', branch: 'main' }
}
// Docker images
stage('Docker image') {
steps{
script {
dockerImage = docker.build(imageName)
}
}
}
// Push the image from Jenkins to Nexus
stage('Push to Nexus') {
steps{
script {
docker.withRegistry('https://' + registry, registryCredentials) {
dockerImage.push('latest')
//or
//dockerImage.push("${env.BUILD_NUMBER}")
}
}
}
}
// Run the container - Stop the container if its running
stage('stop previous containers') {
steps {
sh 'docker ps -f name=container_name -q | xargs --no-run-if-empty docker container stop'
sh 'docker container ls -a -f name=container_name -q | xargs -r docker container rm'
}
}
stage('Docker Run') {
steps{
script {
sh 'docker run -d -p 3000:3000 --rm --name container_name ' + registry + '/' + imageName + ':latest'
}
}
}
}
}