搭建本地Maven仓库Nexus

使用 Docker 安装

docker volume create --name nexus_data
docker run -d -p 8081:8081--name nexus -v nexus_data://nexus-data sonatype/nexus3

使用 Docker Compose 安装

services:
nexus:
image: sonatype/nexus3
platform: linux/amd64
ports:
- "8081:8081"
volumes:
- nexus_data://nexus-data
- /etc/localtime://etc/localtime:ro
volumes:
nexus_data:

访问并配置 Nexus

访问 http://127.0.0.1:8081/ 或者是 http://<your IP>:8081,用户名为 admin ,初始密码在容器里的 /nexus-data/admin.password 文件

docker ps
# docker-nexus-1 为容器名称
docker exec -it docker-nexus-1 cat /nexus-data/admin.password

登录之后,将密码修改为自己的密码,比如:admin。

开启匿名访问权限

依次点击【Security】—【Realms】,将【Docker Bearer Token Tealm】添加到右侧,然后保存。

创建 Maven 仓库

Nexus 提供三种类型的仓库:

创建一个 maven(proxy) 仓库,名称:aliyun,Version Policy 选择 Mixed,URL 地址:https://maven.aliyun.com/nexus/content/groups/public/,并修改 maven-public 仓库,将 aliyun 加入 maven-public 的 Group 中。

注意:保持 hosted 仓库在 proxy 仓库之前,这样方便下载依赖时先从本地查找。

创建 Docker 仓库

先创建一个 blob store 用于存储 docker 文件。

然后,创建三个仓库:

修改 docker 配置:

vim /etc/docker/daemon.json
{
"registry-mirrors" : [
"https://docker-registry.chensoul.cc"
]
}

重启 docker。

配置反向代理

  1. 准备好 SSL 文件,放置 /etc/nginx/ssl 目录

  2. 使用源码编译安装 nignx,安装目录 /usr/local/nginx

  3. 修改 /usr/local/nginx/conf/nginx.conf 文件,添加 include /etc/nginx/conf.d/*.conf

    #user nobody;
    worker_processes 1;
    events {
    worker_connections 1024;
    }
    http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    include /etc/nginx/conf.d/*.conf;
    }
  4. 为 nexus 配置反向代理

    /etc/nginx/conf.d/ 目录下添加 nexus.conf 文件:

    server {
    listen 80;
    server_name nexus.chensoul.cc;
    rewrite ^ https://$http_host$request_uri? permanent;
    }
    server {
    listen 443 ssl;
    server_name nexus.chensoul.cc;
    ssl_certificate /etc/nginx/ssl/all.crt;
    ssl_certificate_key /etc/nginx/ssl/all.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    client_max_body_size 1g;
    access_log /var/log/nginx/nexus.log;
    location / {
    proxy_pass http://192.168.1.107:8081;
    proxy_read_timeout 90;
    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 $scheme;
    }
    }
    • 192.168.1.107 为 nexus 所在服务器的 IP 地址
  5. 为 docker 注册中心配置反向代理

    参考 https://gist.github.com/abdennour/74c5de79e57a47f3351217d674238da8 ,在 /etc/nginx/conf.d/ 目录下添加 docker-registry.conf 文件:

    server {
    listen 80;
    server_name docker-registry.chensoul.cc;
    rewrite ^ https://$http_host$request_uri? permanent;
    }
    server {
    listen 443 ssl;
    server_name docker-registry.chensoul.cc;
    ssl_certificate /etc/nginx/ssl/all.crt;
    ssl_certificate_key /etc/nginx/ssl/all.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    access_log /var/log/nginx/docker-registry.log;
    # disable any limits to avoid HTTP 413 for large image uploads
    client_max_body_size 0;
    # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
    chunked_transfer_encoding on;
    location ~ ^/(v1|v2)/[^/]+/?[^/]+/blobs/ {
    if ($request_method ~* (POST|PUT|DELETE|PATCH|HEAD) ) {
    rewrite ^/(.*)$ /repository/docker-local/$1 last;
    }
    rewrite ^/(.*)$ /repository/docker/$1 last;
    }
    location ~ ^/(v1|v2)/ {
    if ($request_method ~* (POST|PUT|DELETE|PATCH) ) {
    rewrite ^/(.*)$ /repository/docker-local/$1 last;
    }
    rewrite ^/(.*)$ /repository/docker/$1 last;
    }
    location / {
    proxy_pass http://192.168.1.107:8081/;
    proxy_read_timeout 90;
    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 "http";
    }
    }

如果使用 docker 中的 nginx 配置反向代理,则 docker-compose 文件如下:

services:
nginx:
image: nginx:1.27-alpine
volumes:
- ./nginx.conf://etc/nginx/nginx.conf
ports:
- "80:80"
nexus:
image: sonatype/nexus3
platform: linux/amd64
ports:
- "8081:8081"
volumes:
- nexus_data://nexus-data
- /etc/localtime://etc/localtime:ro
volumes:
nexus_data:

./nginx.conf 文件见上面。

测试

Maven 测试

配置maven的配置文件settings.xml:

<?xml version="1.0" encoding="UTF-8"?>
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 http://maven.apache.org/xsd/settings-1.2.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<servers>
<server>
<username>nexus-release</username>
<password>admin</password>
<id>central</id>
</server>
<server>
<username>nexus-snapshot</username>
<password>admin</password>
<id>snapshots</id>
</server>
</servers>
<mirrors>
<mirror>
<id>nexus</id>
<name>nexus repository</name>
<url>https://nexus.chensoul.cc/repository/maven-public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>nexus-release</name>
<url>https://nexus.chensoul.cc/repository/maven-release</url>
</repository>
<repository>
<snapshots />
<id>snapshots</id>
<name>nexus-snapshot</name>
<url>https://nexus.chensoul.cc/repository/maven-snapshot</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>nexus-release</name>
<url>https://nexus.chensoul.cc/repository/maven-release</url>
</pluginRepository>
<pluginRepository>
<snapshots />
<id>snapshots</id>
<name>nexus-snapshot</name>
<url>https://nexus.chensoul.cc/repository/maven-snapshot</url>
</pluginRepository>
</pluginRepositories>
<id>nexus</id>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>

docker 测试

登录:

docker login docker-registry.chensoul.cc

拉取镜像:

$ docker pull alpine:3.14
3.16: Pulling from library/alpine
550f8bf8502c: Pull complete
Digest: sha256:452e7292acee0ee16c332324d7de05fa2c99f9994ecc9f0779c602916a672ae4
Status: Downloaded newer image for alpine:3.16
docker.io/library/alpine:3.16

从日志可以看到是从 docker.io 下载镜像。

接下来,试试从 docker-registry.chensoul.cc 下载镜像

$ docker pull docker-registry.chensoul.cc/alpine:3.16
3.16: Pulling from alpine
Digest: sha256:452e7292acee0ee16c332324d7de05fa2c99f9994ecc9f0779c602916a672ae4
Status: Downloaded newer image for docker-registry.chensoul.cc/alpine:3.16
docker-registry.chensoul.cc/alpine:3.16

从日志可以看到是从 docker-registry.chensoul.cc 下载镜像,并且在 https://nexus.chensoul.cc/#browse/browse:docker 可以看到下载的镜像。

推送镜像:

$ docker tag alpine:3.16 docker-registry.chensoul.cc/alpine:3.16-custom
$ docker push docker-registry.chensoul.cc/alpine:3.16-custom
The push refers to repository [docker-registry.chensoul.cc/alpine]
edbfd2db8ef2: Pushed
3.16-custom: digest: sha256:4bdb4ac63839546daabfe0a267a363b3effa17ce02ac5f42d222174484c5686c size: 528

参考文章

Gitlab安装和部署-使用Docker
搭建本地 Maven 仓库 Artifactory 开源版