This is my life.

There are many like it, but this one is mine.

Nginx の Webdav でデプロイ時のみパスワードが必要な Mavenリポジトリ を立てる

前回の記事で JitPack を使えば Mavenリポジトリ を立てる必要すらないっていう話を書いたのですが、 クローズドな環境では外部サービスの利用が難しい場合があります。

そこで、今回は Nginx を使ってサクッと Mavenリポジトリ を立ててみます。
さらにリポジトリは誰でも見られるようにして、デプロイ時はパスワード認証をかけます。

CentOS 7系でやってみましょう。
ここでは、使い捨てのDockerコンテナを立ち上げて試します。

docker run --rm -it -p 80:80 centos:7 bash 

Nginxのインストール

CentOS 7 にインストールするためには、yumリポジトリを追加する必要があります。

vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

リポジトリを追加したら yum コマンドでインストールしましょう。

yum install -y nginx

インストールをしたら起動します。 nginx  コマンドはバックグラウンドで実行されます。

nginx 

Dockerコンテナでなく実際のサーバーで実行する場合は

systemctl start nginx

で開始することができます。

起動した状態で、ブラウザで以下にアクセスしてみましょう。

http://localhost/

以下のような画面が表示されれば Nginx が起動しています。

f:id:duck8823:20171224095744p:plain

確認が済んだらプロセスを終了します。
コンテナで起動している場合は pid を取得して kill します。

ps x | grep [n]ginx | awk '{print $1}' | xargs kill

実際のサーバーの場合は以下で終了することができます。

systemctl stop nginx

Basic認証できるようにする

ライブラリの利用時は認証せず、デプロイ時にはユーザー名とパスワードで認証するようにします。
Nginx でBasic認証を利用する場合ために httpd-tools をインストールします。

yum install -y httpd-tools

Basic認証のユーザーファイルを作成しましょう。

htpasswd -c /etc/nginx/.htpasswd ユーザー名

画面の指示に従ってパスワードを入力します。

作成された /etc/nginx/.htpasswdBasic認証用のファイルとなります。

Mavenリポジトリの設定を追加する

Maven用の Webdav 設定を追加します。

vi /etc/nginx/conf.d/maven.conf
server {
  # localhost でアクセスすると default.conf が優先される。
  # 以下の設定で 127.0.0.1 にアクセスするとこちらが優先される。 
  listen 80 default;
  server_name _;

  # アクセスする際のパス 以下の場合 http://サーバー名/maven/
  location /maven/ {
    
    # この場合 /var + /mavan/ で Mavenリポジトリの root は /var/maven
    root /var;

    # デプロイ時の一時ディレクトリ
    client_body_temp_path /tmp/maven;
    # ディレクトリを作成するか
    create_full_put_path on;

    # ブラウザでディレクトリにアクセスした際に一覧が表示されるようにする
    autoindex on;
    autoindex_exact_size off;
    autoindex_localtime on;

    # webav を有効にする
    dav_access group:r all:r;
    dav_methods PUT DELETE MKCOL COPY MOVE;

    # GET 以外に制限(Basic認証)をかける
    limit_except GET {
      auth_basic "Maven Repo";
      auth_basic_user_file "/etc/nginx/.htpasswd";
    }
  }
}

設定を作成したら、必要なディレクトリを作成しましょう。
プロセスは nginx ユーザーで実行されるため、作成したディレクトリのオーナーを nginx に変更しておきます。

mkdir -p /var/maven /tmp/maven
chown nginx:nginx /var/maven /tmp/maven
nginx

/etc/nginx/conf.d/default.confserver_name localhost; が設定されているため、 http://localhost/maven/ にアクセスしても default.conf が適用されます。 よって、 404 エラーが返ってきてしまいます。

http://127.0.0.1/maven/ にアクセスすることで /etc/nginx/conf.d/macen.conf が適用され、 /var/maven/ 以下を参照することができます。

ライブラリをデプロイする

Maven

デプロイしたいプロジェクトの pom.xml を編集します。

distributionManagementリポジトリ情報を追記します。
Dockerホストからデプロイする場合、 http://127.0.0.1/maven/ です。
webdav を利用してアップロードするので、 dav:http://127.0.0.1/maven/ となります。

<project>
    ...
    <distributionManagement>
        <repository>
            <id>docker.maven</id>
            <name>Maven Repo</name>
            <url>dav:http://127.0.0.1/maven/</url>
        </repository>
    </distributionManagement>
    ...
    <build>
        <extensions>
            <extension>
                <groupId>org.apache.maven.wagon</groupId>
                <artifactId>wagon-webdav-jackrabbit</artifactId>
                <version>3.0.0</version>
            </extension>
        </extensions>
        ...
    </build>
    ...
</project>

webadv で GET 以外のメソッドにはBasic認証をかけているので、 この状態では ` 401 Unauthorized デとなりプロイできません。

認証情報は $HOME/.m2/settings.xml に記述します。

<settings>
    <servers>
        <server>
            <!-- pom.xml の distributionManagement/repositoryの id と一致させる -->
            <id>docker.maven</id>
            <username>ユーザー名</username>
            <password>パスワード</password>
        </server>
    </servers>
</settings>

下記のコマンドでデプロイすることができます。

mvn deploy

Gradle

build.gradle を編集します。

apply plugin: 'maven'

configurations {
    deployerJars
}

repositories {
    mavenCentral()
}

dependencies {
    deployerJars 'org.apache.maven.wagon:wagon-webdav-jackrabbit:3.0.0'
}

uploadArchives {
    repositories.mavenDeployer {
        configuration = configurations.deployerJars
        repository(url: "http://127.0.0.1/maven/") {
            authentication(userName: "ユーザー名", password: "パスワード")
        }
    }
}

コマンドは以下の通りです。

./gradlew uploadArchives

これによりJarファイル や pom.xml も自動的に生成され、サーバーにアップロードされます。

ライブラリの利用

デプロイ後にブラウザでアクセスしてみると、ディレクトリが増えていると思います。

f:id:duck8823:20171224100130p:plain

Mavenリポジトリは URL を指定するだけで追加できます。
リポジトリを追加したら、通常のライブラリと同じように dependency を記述します。

Maven

<project>
    <repositories>
        ...
        <repository>
            <id>maven.docker</id>
            <name>Maven Repo</name>
            <url>http://127.0.0.1/maven/</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>example-maven</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

Gradle

repositories {
    maven { url 'http://127.0.0.1/maven/' }
}
dependenciea {
    implementation 'com.example:example-maven:0.0.1-SNAPSHOT'
}

おわり

Nginx で webdav を利用して Mavenリポジトリ を立てて、Basic認証でデプロイ(アップロード)を制限する方法を記述しました。
社内ネットワークでライブラリを配布したいけど、webdavでなんでもデプロイされるのはちょっと...ていう場合には使えるかもしれないです。かなりニッチ...

お試しが終わったらコンテナを終了させましょう。
最初の docker コマンドで --rm オプションを指定しているので、コンテナから抜ければ自動的に削除されます。
まっさらな環境で試す場合に Docker 非常に便利ですね。

exit