Infrastructure Reinstall
The final step of our Infrastructure Seed process creates the "infrastructure grade" Nexus3 Docker images that are based off assets coming from our own DML. The following images will now be created:
- (prior step) Ubuntu Base Image with APT template
- (prior step) OpenJDK8 with our own copy of the JDK and APT proxy
- Nexus3 with our own copy of the install package and APT proxy
Nexus3 Image
This being our third Nexus3 image as part of this lab, it is finally considered our Production grade image that will be used as a baseline for Nexus3 updates in the future.
version: '3.3'
services:
nexus:
image: infra/sonatype/nexus3:1.0.0
build:
context: .
network: host
args:
ARG_ART_URL: http://d1i-doc-ngbuild:3001
extra_hosts:
- "d1i-doc-ngbuild:172.22.90.2"
FROM infra/java/openjdk-8:1.0.0
ARG CONTAINER_UID=2001
ARG CONTAINER_GID=2001
ARG CONTAINER_USER=nexus
ARG CONTAINER_GROUP=nexus
RUN groupadd -g ${CONTAINER_GID} ${CONTAINER_GROUP} \
&& useradd -d /home/${CONTAINER_USER} -u ${CONTAINER_UID} -g ${CONTAINER_GROUP} -m -s /bin/bash ${CONTAINER_USER}
RUN mkdir -p /opt/sonatype/nexus /opt/sonatype/sonatype-work/nexus3 \
&& ln -s /opt/sonatype/sonatype-work/nexus3 /nexus-data \
&& chown -R nexus:nexus /opt/sonatype /nexus-data
ARG NEXUS_VERSION=3.41.0-01
ARG ARG_ART_URL
RUN curl $ARG_ART_URL/repository/dml/docker/nexus/nexus-${NEXUS_VERSION}-unix.tar.gz -o /tmp/nexus-${NEXUS_VERSION}-unix.tar.gz \
&& tar -xvzf /tmp/nexus-${NEXUS_VERSION}-unix.tar.gz --strip-components=1 -C /opt/sonatype/nexus \
&& rm -rf /tmp/*
USER nexus
CMD ["/opt/sonatype/nexus/bin/nexus","run"]
NGINX as Reverse Proxy
Before completing the Nexus3 Repository installation, we want to change our run behavior to ensure its SSL protected by running it behind nginx. As the name of the image suggests, it is considered a base image that can be used to dynamically adjust containers we want to run behind this nginx generally via a subdomain.acme.com. This is accomplished via a wildcard config include inside the nginx.conf.
daemon off;
worker_processes 1;
#error_log /var/log/nginx/error.log warn;
#pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
proxy_send_timeout 120;
proxy_read_timeout 300;
proxy_buffering off;
keepalive_timeout 5 5;
tcp_nodelay on;
include /etc/nginx/conf.d/*.conf;
}
version: '3.3'
services:
nginx:
image: infra/nginx/base:1.0.0
build:
context: .
network: host
args:
ARG_ART_URL: http://d1i-doc-ngbuild:3001
extra_hosts:
- "d1i-doc-ngbuild:172.22.90.2"
FROM infra/ubuntu/focal:1.0.0
ARG ARG_ART_URL
RUN sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.base > /etc/apt/sources.list \
&& apt-get update \
&& apt-get install -y nginx=1.18.* \
&& apt-get clean \
&& rm /etc/apt/sources.list
# Add default configuration
COPY conf/nginx.conf /etc/nginx/nginx.conf
CMD ["nginx"]
Next, we want to use a wildcard self signed SSL for *.acme.com, allowing us to run many of our DevOps apps behind the same nginx as we continue. As you should always try to externalize your ssl, we are going to use a ssl generator tool image.
version: '3.3'
services:
ssl-cert:
image: tools/ssl-cert:1.0.0
build:
context: .
network: host
args:
ARG_ART_URL: http://d1i-doc-ngbuild:3001
extra_hosts:
- "d1i-doc-ngbuild:172.22.90.2"
FROM infra/ubuntu/focal:1.0.0
ARG ARG_ART_URL
RUN sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.base > /etc/apt/sources.list \
&& apt-get update \
&& apt-get install -y openssl dos2unix \
&& apt-get clean \
&& rm /etc/apt/sources.list
COPY init.sh /init/init.sh
RUN chmod +x /init/init.sh \
&& dos2unix /init/init.sh
ENTRYPOINT ["/init/init.sh"]
#!/bin/bash
# fail if anything errors
set -e
openssl req -x509 -newkey rsa:4096 \
-subj "/C=XX/ST=XXXX/L=XXXX/O=XXXX/CN=${CERT_CN}" \
-keyout "/ssl/${KEY_NAME}" \
-out "/ssl/${CERT_NAME}" \
-days 365 -nodes -sha256
We will be creating the wildcard certificate using the following compose file. Once generated, the certificate will be placed into the nginx compose location.
version: '3.3'
services:
ssl-cert:
image: tools/ssl-cert:1.0.0
volumes:
- ./ssl:/ssl
environment:
- CERT_CN=*.acme.com
- KEY_NAME=key.pem
- CERT_NAME=cert.pem
networks:
- ops-network
networks:
ops-network:
name: ops-network
Building & Running the Final Images
Build the Nexus3 and NGINX. Remember we still rely on our Nginx build proxy for the docker compose build files.
docker-compose -f images/nexus/docker-compose.yml build
docker-compose -f images/nginx-base/docker-compose.yml build
docker-compose -f tools/ssl-cert/docker-compose.yml build
Next is adding both nexus and nginx as individual compose files. Note, we are adding a specific IP address for the nginx as we want to leverage hostfile additions to other docker containers in other parts of the lab to simplify DNS.
version: '3.3'
services:
nexus:
image: infra/sonatype/nexus3:1.0.0
volumes:
- nexus-data:/nexus-data
ports:
# this is for HTTP web interface
- 8081:8081
# this is for HTTP docker combined registry
- 8082:8082
# this is for HTTP docker private registry
- 8083:8083
hostname: d1i-doc-nexus01
networks:
- ops-network
networks:
ops-network:
name: ops-network
volumes:
nexus-data:
name: nexus-data
server {
listen *:443 ssl;
server_name "nexus.acme.com";
ssl_certificate /etc/nginx/external/cert.pem;
ssl_certificate_key /etc/nginx/external/key.pem;
client_max_body_size 1G;
location / {
proxy_pass http://d1i-doc-nexus01: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_set_header X-Forwarded-Proto https;
}
}
server {
listen *:443 ssl;
server_name "docker.acme.com";
ssl_certificate /etc/nginx/external/cert.pem;
ssl_certificate_key /etc/nginx/external/key.pem;
client_max_body_size 1G;
location / {
proxy_pass http://d1i-doc-nexus01:8082;
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_set_header X-Forwarded-Proto https;
}
}
server {
listen *:443 ssl;
server_name "docker-private.acme.com";
ssl_certificate /etc/nginx/external/cert.pem;
ssl_certificate_key /etc/nginx/external/key.pem;
client_max_body_size 1G;
location / {
proxy_pass http://d1i-doc-nexus01:8083;
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_set_header X-Forwarded-Proto https;
}
}
version: '3.3'
services:
nginx:
image: infra/nginx/base:1.0.0
volumes:
- ./ssl/cert.pem:/etc/nginx/external/cert.pem
- ./ssl/key.pem:/etc/nginx/external/key.pem
- ./nginx/nexus.conf:/etc/nginx/conf.d/nexus.conf
ports:
- 443:443
hostname: d1i-doc-ng01
networks:
ops-network:
ipv4_address: 172.22.90.1
networks:
ops-network:
name: ops-network
driver: bridge
ipam:
driver: default
config:
- subnet: 172.22.90.0/16
Stop the running non-nginx Nexus3 (http access based), our nginx build proxy and start the new SSL based Nexus3 containers (nginx + nexus3 + nginx-build).
# stop the seed
docker-compose -f composed/docker-compose-seed.yml stop
# generate wildcard cert
docker-compose -f composed/docker-compose-ssl-cert-wildcard.yml up
# start nexus
docker-compose -f composed/docker-compose-nexus.yml up --no-start
docker-compose -f composed/docker-compose-nexus.yml start
# start behind nginx
docker-compose -f composed/docker-compose-nginx-nexus.yml up --no-start
docker-compose -f composed/docker-compose-nginx-nexus.yml start
# check logs until started
docker-compose -f composed/docker-compose-nexus.yml logs -f --tail="50"
As the DML is using an nginx config with acme, ensure to change your host file to point nexus.acme.com to 127.0.0.1. After that change, your nexus installation is available at https://nexus.acme.com/.