Solving Access Challenges: Building Your Own Docker Image Proxy Acceleration Service with Nexus 3

Publish: 2024-06-09 | Modify: 2024-06-09

Recently, there have been rumors that many public Docker image acceleration addresses have been taken offline one after another due to mysterious factors. Prior to this, the official Docker image source was also blocked in China, making it extremely difficult to pull Docker images from within the country. Now, it is particularly important to establish your own Docker image proxy. This article will detail how to use Nexus 3 to set up a Docker image proxy. The content of the article contains a lot of professional knowledge and is mainly aimed at operations or development personnel. It may not be very friendly to novice users.

![47dfe7ab8ab8639b.png](https://img.rss.ink/imgs/2024/06/09/47dfe7ab8ab8639b.png)

### About Nexus 3

Nexus 3 is a powerful package management and repository tool developed by Sonatype. It supports multiple package formats, including Maven, Docker, npm, NuGet, etc., and is suitable for dependency management and repository hosting in software development. Here are some key features of Nexus 3:

- **Multiple Format Support**: Nexus 3 can manage various formats of binary files, including Java's jar and war files, JavaScript's npm packages, Python's PyPi packages, and more.
- **Proxy and Hosted Repositories**: Nexus 3 allows users to create proxy repositories to cache components from remote repositories, as well as create hosted repositories to store internally generated components.
- **Security and Permission Management**: It provides granular permission control, supports integration with external user management systems (such as LDAP), and ensures secure access to repositories.
- **High Availability and Support for Large-Scale Deployment**: Nexus 3 supports high availability deployment configurations, can handle a large number of requests, and store a large number of components, making it suitable for large-scale enterprise environments.
- **Repository Health Check and Optimization**: It provides repository health check tools and data optimization tools to help maintain the stability and efficiency of repositories.
- **Interface and Integration**: It provides a user-friendly interface for managing repositories and components. Meanwhile, Nexus 3 can be integrated with continuous integration/continuous deployment (CI/CD) tools such as Jenkins, Bamboo, etc., to optimize the development process.

Nexus 3 is an indispensable tool for development and DevOps teams in building and maintaining software projects, especially in scenarios where multiple dependencies need to be managed and their security needs to be ensured.

### Prerequisites

- A foreign VPS with at least 4GB of memory
- Docker service installed on the server
- Nginx installed
- A domain name and SSL certificate obtained

The reason for choosing a foreign VPS is that the official Docker image source is blocked in China, preventing servers in China from accessing these images. Therefore, it is necessary to use a foreign VPS for proxying to ensure smooth pulling of the required Docker images.

### Use Cases

Next, xiaoz will detail this process based on my personal use case.

- Using Nexus 3 to set up a Docker image proxy
- Configuring Nexus 3 Docker image proxy
- Allowing anonymous PULL operations for the image proxy, but not allowing PUSH operations
- For security considerations and to avoid excessive use by multiple users, I only proxy and cache my own image `helloz` (my Docker official username), and do not allow pulling of other images.

### Installing Nexus 3 using Docker Compose

Create a `docker-compose.yaml` file with the following content:

```yaml
version: "3.8"
services:
  nexus:
    image: sonatype/nexus3
    container_name: nexus
    ports:
      - "8081:8081"
    volumes:
      - ./data:/nexus-data
    restart: always

The ./data is the Nexus 3 persistent storage data directory. It is recommended to change it to the absolute path of the host, and do not modify the internal container path /nexus-data.

Then use the command docker-compose up -d to start the Nexus 3 container. The first start requires an initialization operation, which may take a little while, so you may need to wait a few minutes for it to start completely.

Configuring Nexus 3

After the startup, access Nexus 3 by entering http://IP:8081 in the browser, then click on the top right to log in, with the username as admin and the password obtained by viewing the admin.password file in the mounted directory.

137cffcef57090ab.png

Follow the prompts to change the admin password.

856386691d1ac016.png

Here, I choose to enable anonymous access.

efa13775bc2df4ff.png

Setting up Docker Image Proxy through Nexus 3

Open "Settings >> Security >> Roles >> Create Role"

5db475d4b2057a8e.png

Then fill in the following:

  • Role ID: Fill in DockerPullAnonymous (you can also modify the ID yourself)
  • Role Name: DockerPullAnonymous (can be modified as needed)
  • Applied Privileges
    • nx-repository-view-docker-*-browse
    • nx-repository-view-docker-*-read
    • nx-repository-view-docker-docker-browse
    • nx-repository-view-docker-docker-read
  • Applied Roles: nx-anonymous

As shown in the screenshot:

3799b66af3402962.png

Continue to open "Settings >> Security >> Users", find the Anonymous User, and edit it to add the DockerPullAnonymous permission.

f86732998a8d735d.png

Continue to open "Settings >> Security >> Realms", add the Docker Bearer Token Realm permission and save.

e48aaed59c8323d8.png

The purpose of the above steps is to add Docker anonymous PULL permissions. If not configured, when pulling an image, it will prompt: Error response from daemon: unauthorized: authentication required

Continue to open "Settings >> Routing Rules" and add a new rule:

  • Name: Allow_helloz (you can choose your own name)
  • Mode: Allow
  • Matchers: ^/v2/helloz/.* (here I only configure to allow pulling images of the helloz user; multiple users can be written as ^/v2/(helloz|user2|user3)/.*)

ce9d38c1679e60ae.png

The purpose of this step is to prevent anonymous users from pulling all Docker images. Therefore, I only configure to allow pulling images of my own helloz (the official Docker registered username).

Open "Settings >> Repositories >> Create repository" to start creating a Docker image repository.

77573247631b22e4.png

Then select docker(proxy).

6931f5e839c29141.png

Pay attention to the area marked in red at the bottom (Fill in Remote storage with https://registry-1.docker.io).

6a109566d552904e.png

Choose the previously added Allow_helloz for Routing Rule and keep the rest as default.

911af2c01ced50b1.png

Setting up Nginx Reverse Proxy

When executing docker pull, Docker officially requires the target image address to be an HTTPS link. To meet this requirement, we can use Nginx as a reverse proxy to connect to Nexus 3, and set up the image address through the domain name to support HTTPS access. The specific Nginx configuration is as follows:

server {
    listen 80;
    server_name hub.xxx.com; # Fill in your own domain name

    rewrite ^(.*) https://hub.xxx.com$1 permanent;
}
server {
    listen 443 ssl http2;

    server_name hub.xxx.com; # Fill in your own domain name

    ssl_certificate /data/ssl/hub.xxx.com.crt; # Change to your own SSL certificate
    ssl_certificate_key /data/ssl/hub.xxx.com.key; # Change to your own SSL private key
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
    ssl_session_tickets off;

    # intermediate configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    location / {
          client_max_body_size  64m;
          proxy_http_version 1.1;
          proxy_pass http://IP:8081/repository/docker/;  # Change to the Docker image address on your Nexus 3
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $remote_addr;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_connect_timeout 60s;
          proxy_send_timeout 60s;
          proxy_read_timeout 300s;
          send_timeout 60s;

          proxy_buffers 16 32k;
          proxy_buffer_size 64k;

          proxy_set_header Connection "";
   }
}

Testing

Next, test pulling an image using the command docker pull hub.xxx.com/helloz/onenav:0.9.33 on the server in China. If the image is successfully pulled, it indicates that the configuration is successful.

10f5e0bc3a32948c.png

Continue to test pulling an image using the command docker pull hub.xxx.com/baiyuetribe/zdir:latest. If it prompts that permission is denied, it meets our expected situation.

180974dc82ff7443.png

Conclusion

In this article, we have thoroughly discussed how to use Nexus 3 to set up a Docker image proxy. It is worth noting that everyone's use cases are different, but the flexibility of Nexus 3 allows users to configure different rules according to their specific needs, achieving fine-grained permission control. This feature not only makes Nexus 3 an ideal choice for managing Docker images but also applies to other types of package management such as npm, maven, and more.

Finally, thanks to ChatGPT for guiding me through the permission settings of Nexus 3 and assisting me in troubleshooting the errors encountered!

For paid deployment of Nexus 3, please contact me on WeChat: xiaozme


Comments