Install Nexus Repository Manager on Ubuntu 20.04
Run System Update
Update system package cache;
apt update
Install Java on Ubuntu 20.04
Nexus repository manager requires Java 8 Runtime Environment (JRE). You can install full JDK or just the JRE.
You can simply run the command below to install Java 8 on Ubuntu 20.04;
apt update
Then install Java 8;
apt install openjdk-8-jdk
Confirm the installed version of Java;
java -version
openjdk version "1.8.0_282" OpenJDK Runtime Environment (build 1.8.0_282-8u282-b08-0ubuntu1~20.04-b08) OpenJDK 64-Bit Server VM (build 25.282-b08, mixed mode)
Create Dedicated Nexus System Account
As a security precaution, Nexus Repository Manager should NOT be run as the root user. Instead, create a system account for Nexus;
useradd -M -d /opt/nexus -s /bin/bash -r nexus
Allow the nexus user to run all commands with sudo without password.
echo "nexus ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/nexus
Download Nexus Repository OSS Tarball
Next, navigate to Nexus repository OSS downloads page, register for an account and download Nexus repository OSS for Unix tarball.
You can simply obtain the link and pull the tarball using wget command as shown below. Note that this downloads the current stable release version of Nexus, 3.81.1-01, as of this writing. Be sure to get the link to the latest version from downloads page.
wget https://download.sonatype.com/nexus/3/nexus-3.38.1-01-unix.tar.gz
Install Nexus Repository Manager on Ubuntu 20.04
Extract Nexus Repository OSS tarball
Navigate to the directory where you downloaded the Nexus tarball and extract it to the nexus user home directory, which in this guide is /opt/nexus.
mkdir /opt/nexus
tar xzf nexus-3.38.1-01-unix.tar.gz -C /opt/nexus --strip-components=1
Checking the contents of the /opt/nexus directory;
ls /opt/nexus
bin deploy etc lib nexus3 NOTICE.txt OSS-LICENSE.txt PRO-LICENSE.txt public system
Set the proper ownership of the nexus directory;
chown -R nexus: /opt/nexus
Adjust the Nexus Memory Heap Size
The default minimum JVM heap for Nexus is 2037MB with maximum recommended being 4G. If you have less memory, you can reduce it by editing the file /opt/nexus/bin/nexus.vmoptions and setting a lower value, for demo purposes.
vim /opt/nexus/bin/nexus.vmoptions
Replace the default values for the lines;
-Xms2703m -Xmx2703m -XX:MaxDirectMemorySize=2703m ...
To for example, to set it to 1024MB;
-Xms1024m -Xmx1024m -XX:MaxDirectMemorySize=1024m
Save and exit the file once you have made the changes.
Running Nexus Repository on Ubuntu 20.04
Nexus provides a startup script at /opt/nexus/bin/nexus.
To run Nexus in standalone mode, you can run this command. However, you need to ensure that Nexus is run as nexus user.
Therefore, edit the file /opt/nexus/bin/nexus.rc and uncomment the line, #run_as_user=”” and add nexus as the value.
sed -i 's/#run_as_user=""/run_as_user="nexus"/' /opt/nexus/bin/nexus.rc
Change the location of the Sonatype Work directory (Nexus data directory) to a location where nexus user has permissions to write.
For example, in our setup, we set the home directory for Nexus as /opt/nexus and we gave nexus user ownership of this directory.
By default, sonatype-work data directory is moved one directory up, hence, it is expected to be created under /opt, which the nexus user has no permissions to write.
Therefore, edit the /opt/nexus/bin/nexus.vmoptions and adjust the path of the Nexus directory (in the below settings, the directory is changed from ../sonatype-work to ./sonatype-work).
vim /opt/nexus/bin/nexus.vmoptions
-XX:LogFile=./sonatype-work/nexus3/log/jvm.log -XX:-OmitStackTraceInFastThrow -Djava.net.preferIPv4Stack=true -Dkaraf.home=. -Dkaraf.base=. -Dkaraf.etc=etc/karaf -Djava.util.logging.config.file=etc/karaf/java.util.logging.properties -Dkaraf.data=./sonatype-work/nexus3 -Dkaraf.log=./sonatype-work/nexus3/log -Djava.io.tmpdir=./sonatype-work/nexus3/tmp ...
Next, you can then run Nexus;
sudo -u nexus /opt/nexus/bin/nexus start
It might take sometime for Nexus to start. While starting, tail the logs;
tail -f /opt/nexus/sonatype-work/nexus3/log/nexus.log
2021-02-15 17:10:56,914+0000 INFO [jetty-main-1] *SYSTEM org.sonatype.nexus.siesta.SiestaServlet - Initialized
2021-02-15 17:10:56,920+0000 INFO [jetty-main-1] *SYSTEM org.sonatype.nexus.repository.httpbridge.internal.ViewServlet - Initialized
2021-02-15 17:10:56,962+0000 INFO [jetty-main-1] *SYSTEM org.eclipse.jetty.server.handler.ContextHandler - Started o.e.j.w.WebAppContext@3b390334{Sonatype Nexus,/,file:///opt/nexus/public/,AVAILABLE}
2021-02-15 17:10:57,082+0000 INFO [jetty-main-1] *SYSTEM org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@75763136{HTTP/1.1, (http/1.1)}{0.0.0.0:8081}
2021-02-15 17:10:57,083+0000 INFO [jetty-main-1] *SYSTEM org.eclipse.jetty.server.Server - Started @182105ms
2021-02-15 17:10:57,083+0000 INFO [jetty-main-1] *SYSTEM org.sonatype.nexus.bootstrap.jetty.JettyServer -
-------------------------------------------------
Started Sonatype Nexus OSS 3.29.2-02
-------------------------------------------------
Nexus listens on TCP port 8081 by default;
netstat -altnp | grep :8081
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 2113/java
You should now be able to access Nexus web interface from browser.
Create Nexus Repository Systemd Service
In order to easily manage Nexus repository service, create a systemd service unit for it as shown below;
cat > /etc/systemd/system/nexus.service << 'EOL'
[Unit]
Description=nexus service
After=network.target
[Service]
Type=forking
LimitNOFILE=65536
ExecStart=/opt/nexus/bin/nexus start
ExecStop=/opt/nexus/bin/nexus stop
User=nexus
Restart=on-abort
[Install]
WantedBy=multi-user.target
EOL
Next, stop Nexus if you already started it with startup script above.
/opt/nexus/bin/nexus stop
Reload the systemd manager configuration;
systemctl daemon-reload
Start and enable Nexus service to run on system reboot;
systemctl enable --now nexus.service
Check the service status;
systemctl status nexus
● nexus.service - nexus service
Loaded: loaded (/etc/systemd/system/nexus.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2021-02-15 17:14:49 UTC; 5s ago
Process: 67085 ExecStart=/opt/nexus/bin/nexus start (code=exited, status=0/SUCCESS)
Main PID: 67277 (java)
Tasks: 41 (limit: 4620)
Memory: 442.9M
CGroup: /system.slice/nexus.service
└─67277 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java -server -Dinstall4j.jvmDir=/usr/lib/jvm/java-8-openjdk-amd64/jre -Dexe4j.moduleName=/opt/nexus/bin/nexu>
Feb 15 17:14:48 ubuntu20 systemd[1]: Starting nexus service...
Feb 15 17:14:49 ubuntu20 nexus[67085]: Starting nexus
Feb 15 17:14:49 ubuntu20 systemd[1]: Started nexus service.
You can as well check the logs for verification;
tail -f /opt/nexus/sonatype-work/nexus3/log/nexus.log
Accessing Nexus Repository Web Interface
You can now access Nexus repository from browser using the address http://server-IP-or-resolvable-hostname:8081.
If UFW is running, you need to open port 8081 to allow external access.
ufw allow 8081/tcp
Setup Nexus Repository Manager
Click the sign in button at the top right corner. Login as admin. The password is located on the file, /opt/nexus/sonatype-work/nexus3/admin.password. To get the password, just print the contents of the file.
cat /opt/nexus/sonatype-work/nexus3/admin.password
Once you logged in, click next to proceed to setup Nexus.
- Reset Nexus repository admin password
- Configure anonymous access. You can choose to disable the anonymous access to secure Nexus repositories by requiring user to authenticate before they can browse through the repositories.
- Finish the setup
Run Nexus Repository Behind Nginx Reverse Proxy
In all the above tutorials, Nexus port 8081 is exposed to the external networks as can be seen on Nexus URL, http://server-IP:8081.
When you run Nexus repository behind a reverse proxy, you can access it without having to specify its port on the URL.
Bind Nexus Repository to Localhost Interface
NOTE: if your Nexus instance is already listening on a loopback address, then skip this step.
When you check, by default, at least in the guides above, Nexus is not bound to specific interface on a server on which it is running and hence listens on all interfaces on port 8081.
ss -altnp | grep 8081
LISTEN 0 50 0.0.0.0:8081 0.0.0.0:* users:(("java",pid=663,fd=691))
Before you can proceed to run Nexus repository manager behind Nginx reverse proxy, first configure Nexus to bind it to a loopback interface, 127.0.0.1.
As shown by the ss command output above, Nexus listens on all interfaces on port 8081/tcp.
grep application- /opt/nexus/etc/nexus-default.properties
application-port=8081 application-host=0.0.0.0
To bind Nexus to localhost interface, replace the 0.0.0.0 address in the configuration file above with the specific server loopback IP address;
sed -i 's/0.0.0.0/127.0.0.1/' /opt/nexus/etc/nexus-default.properties
Once you have made the changes, restart Nexus;
systemctl restart nexus
Once Nexus starts, you can confirm the address it is bind to again;
ss -altnp | grep 8081
Sample output;
LISTEN 0 50 127.0.0.1:8081 0.0.0.0:* users:(("java",pid=2711,fd=699))
Install Nginx Web Server
Next, install Nginx Web server;
apt install nginx -y
Run Nexus Repository Manager Behind Nginx Reverse Proxy
Once Nginx Web server is installed, create Nexus site.
Any requests that comes to this site will be forward to the Nexus repository running on the same host and listening on loopback interface.
Create Nginx Nexus Site Configuration
To create the Nexus site configuration, /etc/nginx/sites-available/nexus, you can simply copy and paste the content below on the terminal.
Replace the names of the site accordingly.
cat > /etc/nginx/sites-available/nexus << 'EOL'
server {
listen *:80 default_server;
server_name nexus.kifarunix-demo.com;
access_log /var/log/nginx/nexus.access.log;
error_log /var/log/nginx/nexus.error.log;
location / {
proxy_pass http://127.0.0.1:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
proxy_request_buffering off;
keepalive_timeout 5 5;
tcp_nodelay on;
proxy_connect_timeout 90;
proxy_send_timeout 120;
proxy_read_timeout 300;
client_max_body_size 10m;
}
}
EOL
Verify Nginx Syntax;
nginx -t
If the output is, similar to below;
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
then you are good to proceed. Otherwise fix any errors before you can proceed.
Disable default Nginx site;
unlink /etc/nginx/sites-enabled/default
rm /etc/nginx/sites-available/default
Enable Nginx Nexus site;
ln -s /etc/nginx/sites-available/nexus /etc/nginx/sites-enabled/
Restart Nginx;
systemctl restart nginx
Secure NGINX With LetsEncrypt SSL
Step 1 — Installing Certbot
The first step to using Let’s Encrypt to obtain an SSL certificate is to install the Certbot software on your server.
Install Certbot and it’s Nginx plugin with apt:
sudo apt install certbot python3-certbot-nginx
Certbot is now ready to use, but in order for it to automatically configure SSL for Nginx, we need to verify some of Nginx’s configuration.
Step 2 — Allowing HTTPS Through the Firewall
If you have the ufw firewall enabled, as recommended by the prerequisite guides, you’ll need to adjust the settings to allow for HTTPS traffic. Luckily, Nginx registers a few profiles with ufw upon installation.
You can see the current setting by typing:
sudo ufw status
It will probably look like this, meaning that only HTTP traffic is allowed to the web server:
OutputStatus: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6)
To additionally let in HTTPS traffic, allow the Nginx Full profile and delete the redundant Nginx HTTP profile allowance:
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
Your status should now look like this:
sudo ufw status
OutputStatus: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6)
Next, let’s run Certbot and fetch our certificates.
Step 4 — Obtaining an SSL Certificate
Certbot provides a variety of ways to obtain SSL certificates through plugins. The Nginx plugin will take care of reconfiguring Nginx and reloading the config whenever necessary. To use this plugin, type the following:
sudo certbot --nginx -d example.com -d www.example.com
This runs certbot with the –nginx plugin, using -d to specify the domain names we’d like the certificate to be valid for.
If this is your first time running certbot, you will be prompted to enter an email address and agree to the terms of service. After doing so, certbot will communicate with the Let’s Encrypt server, then run a challenge to verify that you control the domain you’re requesting a certificate for.
If that’s successful, certbot will ask how you’d like to configure your HTTPS settings.
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel):
Select your choice then hit ENTER. The configuration will be updated, and Nginx will reload to pick up the new settings. certbot will wrap up with a message telling you the process was successful and where your certificates are stored:
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on 2020-08-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Your certificates are downloaded, installed, and loaded. Try reloading your website using https:// and notice your browser’s security indicator. It should indicate that the site is properly secured, usually with a lock icon. If you test your server using the SSL Labs Server Test, it will get an A grade.
Let’s finish by testing the renewal process.
Step 5 — Verifying Certbot Auto-Renewal
Let’s Encrypt’s certificates are only valid for ninety days. This is to encourage users to automate their certificate renewal process. The certbot package we installed takes care of this for us by adding a systemd timer that will run twice a day and automatically renew any certificate that’s within thirty days of expiration.
You can query the status of the timer with systemctl:
sudo systemctl status certbot.timer
Output● certbot.timer - Run certbot twice daily
Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Mon 2020-05-04 20:04:36 UTC; 2 weeks 1 days ago
Trigger: Thu 2020-05-21 05:22:32 UTC; 9h left
Triggers: ● certbot.service
To test the renewal process, you can do a dry run with certbot:
sudo certbot renew --dry-run
If you see no errors, you’re all set. When necessary, Certbot will renew your certificates and reload Nginx to pick up the changes. If the automated renewal process ever fails, Let’s Encrypt will send a message to the email you specified, warning you when your certificate is about to expire.
