Docker Repository Reverse Proxy Strategies
Set up a reverse proxy to avoid Docker port scalability issues. This topic covers intended use cases and implementation steps for setting up a reverse proxy.
Intended Use Cases
Using a reverse proxy in front of Nexus Repository for Docker repositories is recommended for the following use cases:
Multiple connectors inside of Eclipse Jetty or Nexus Repository cause performance issues. When using more than 20 connectors you must use a reverse proxy
You need to limit the number of open ports for infrastructure or security reasons
Managing secure connectors/ports/hosts inside an external reverse proxy aligns with organizational goals and infrastructure
Implementation Overview
Once implemented as described in this topic, Nexus Repository listens at a non-HTTPS connector such as the default 8081.
You can add Docker repositories into Nexus Repository as normal but do not configure them with any connector port values.
In the simple example, the following Docker repository hierarchy would exist inside the Nexus Repository per project team:
docker-group-project
docker-hosted-project
docker-hub
Based on the hostname or port of the request to a reverse proxy, the reverse proxy decides where to reverse proxy the request into Nexus Repository.
Limitations
A wildcard TLS certificate is needed for the hostname mapping scenario if you intend to have more than one project team-specific hostname.
Examples
Docker Push Port Mapping Example
In the following Docker push port mapping example, the reverse proxy would direct Docker push
commands received at https://project.example.com:8086
to http://nexus.example.com:8081/repository/docker-hosted-project
.
docker login project.example.com:8086 docker push project.example.com:8086
Docker Pull Port Mapping Example
In the following Docker pull port mapping example, the reverse proxy would direct Docker pull
commands received at https://project.example.com:8087
to http://nexus.example.com:8081/repository/docker-group-project
.
docker login project.example.com:8087 docker pull project.example.com:8087
Docker Push Host Mapping Example
In the following Docker push host mapping example, the reverse proxy would direct Docker push
commands received at https://project-push.example.com
to http://nexus.example.com:8081/repository/docker-hosted-project
.
docker login project-push.example.com docker push project-push.example.com
Docker Pull Host Mapping Example
In the following Docker pull host mapping example, the reverse proxy would direct Docker pull
commands received at https://project.example.com
to http://nexus.example.com:8081/repository/docker-group-project
.
docker login project.example.com docker pull project.example.com
Apache Port Mapping Reverse Proxy Example
The following example Apache HTTP Server configuration port maps https://project.example.com:8087
to http://nexus.example.com:8081/repository/docker-repo
.
Listen 8087 https <VirtualHost *:8087> ServerName project.example.com ServerAdmin admin@example.com AllowEncodedSlashes NoDecode ProxyRequests Off ProxyPreserveHost On SSLEngine ON SSLCertificateFile "/path/to/ssl/server.crt" SSLCertificateKeyFile "/path/to/ssl/server.key" ProxyTimeout 300 ProxyPass / http://nexus.example.com:8081/repository/docker-repo/ nocanon ProxyPassReverse / http://nexus.example.com:8081/repository/docker-repo/ RequestHeader set X-Forwarded-Proto "https" </VirtualHost>
Nginx Host Mapping Reverse Proxy Example
The following example Nginx configuration host maps https://project.example.com
to http://nexus.example.com:8081/repository/docker-repo
.
This Nginx host mapping example uses the same server for both Docker and regular Nexus Repository requests; it also uses location directives to proxy /v2 or /v1 requests to the Docker repository. Docker automatically adds these v1/v2 paths to the requests and does not require users to add them directly to the Docker commands.
http { proxy_send_timeout 120; proxy_read_timeout 300; proxy_buffering off; proxy_request_buffering off; keepalive_timeout 5 5; tcp_nodelay on; server { listen 443 ssl; server_name project.example.com ssl on; ssl_certificate /path/to/ssl/server.crt; ssl_certificate_key /path/to/ssl/server.key; # Docker /v2 and /v1 (for search) requests location /v2 { proxy_set_header Host $host:$server_port; 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"; proxy_pass http://nexus.example.com:8081/repository/docker-repo/$request_uri; } location /v1 { proxy_set_header Host $host:$server_port; 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"; proxy_pass http://nexus.example.com:8081/repository/docker-repo/$request_uri; } # Regular Nexus requests location / { proxy_set_header Host $host:$server_port; 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"; proxy_pass http://nexus.example.com:8081; } }}