verdaccio で社内 npm レジストリを立てる
目標
npmの社内レジストリを立てて、接続されている間に埋め、上位への接続を切断したあとも、ロックファイルのとおりにインストールできることを確認します。外部で作ったロックファイルのアドレスが、どう解決されるかも、直接測ります。
なぜ重要なのか
node_modulesを丸ごと圧縮して持ち込む方式は、nodeのバージョンが違うと壊れ、何が入ったかが残りません。社内レジストリは、パッケージ単位で積み上がり、ロックファイルは、「何をどのハッシュで」を書きます。2つがかみ合えば、エアギャップ環境の中でも、npm ciが外部と同じツリーを作ります。このPodは、インターネット(80/443)に届くので、ダウンロード側の役割を果たし、エアギャップ環境側の確認は、採点が、外部へ向かうHTTP(S)を閉じたプロキシ(127.0.0.1:9)に向けてふさいだ状態で行います。
ステップ
/opt/verdaccioで、verdaccio@6.1.6をインストールしてください(バージョンを正確に固定し、ロックファイルが残る必要があります)。/root/npm/config.yamlを書いてください。ストレージは/root/npm/storage、uplinknpmjsはhttps://registry.npmjs.org/、パターン'**'は、誰でも読めて、npmjsをproxyとし、待ち受けるアドレスは127.0.0.1:4873、ログは/root/npm/verdaccio.logファイルです。/etc/hostsに127.0.0.1 npm.airgap.internalを追加して、その設定でverdaccioを起動してください。- プロジェクト
/root/npm/app(package.jsonが必要です)の.npmrcに、registry=http://npm.airgap.internal:4873/を書いてください。 /root/npm/appにchalk@4.1.2をインストールして、社内レジストリが上位から引いて埋めるようにしてください。'**'パターンからproxyを外して、上位への接続を切断し、verdaccioを再起動してください。/root/npm/app2に、appのpackage.json・package-lock.jsonをコピーして、新しいキャッシュ(/root/npm/cache2)でnpm ciを実行してください。- 外部のレジストリで作ったロックファイルを
/root/npm/outlock/に作成して(chalk 4.1.2)、外部がふさがれた状態で、社内レジストリでnpm ciを、replace-registry-hostのデフォルトとneverのそれぞれで実行し、結果を/root/npm/lockhost.txtに、default=ok|fail・never=ok|failの2行で書いてください。
参考
- 今適用されている値:
npm config get registry(プロジェクトディレクトリの中で) - verdaccioが生きているか:
curl http://npm.airgap.internal:4873/-/ping・再起動:pkill -x verdaccioのあとで、同じコマンド - 外部をふさいで測る:
HTTPS_PROXY=http://127.0.0.1:9 HTTP_PROXY=http://127.0.0.1:9 NO_PROXY=127.0.0.1,localhost,.airgap.internal npm ci ... - よくある間違い1:
npm install -gでverdaccioをインストールしてしまうこと。このPodでは、グローバルディレクトリに書き込めず、失敗します。ディレクトリを決めてインストールしてください。 - よくある間違い2: uplinkを切断したあと、キャッシュが残ったまま試すこと。キャッシュが受け付けてしまえば、レジストリを試したことになりません。新しいキャッシュディレクトリを使ってください。
持ち込み物その1: verdaccioをバージョン固定で
/opt/verdaccioで、verdaccio@6.1.6をインストールしてください(ロックファイルが残る必要があります)。
npmは、ディレクトリの中でインストールすると、そのディレクトリのnode_modulesとpackage-lock.jsonを作成します。グローバルインストールは、このPodでは権限のために失敗します。バージョンは、@の後ろに正確に書いてください。
上位(uplink)を置いたプロキシレジストリの設定
/root/npm/config.yamlに、ストレージ・uplink・パターン・待ち受けるアドレス・ログファイルを書いてください。
uplinksに、上位レジストリの名前とアドレスを書き、packagesの'**'パターンで、その名前をproxyとして指します。listenは、ホスト:ポートの1行です。ログは、type: fileでパスを指定します。
社内の名前でレジストリを起動する
/etc/hostsに127.0.0.1 npm.airgap.internalを追加して、/root/npm/config.yamlでverdaccioを起動してください。
verdaccioは、--configで設定ファイルを受け取ります。ターミナルを閉じても生き続けるように、バックグラウンドで起動し、レジストリのpingアドレスで、生きているかを確認してください。
プロジェクトの.npmrcで指し示す
プロジェクト/root/npm/app(package.jsonを含む)の.npmrcに、registry=http://npm.airgap.internal:4873/を書いてください。
プロジェクトディレクトリの.npmrcは、ユーザーやグローバルの設定より優先されます。書いたあと、そのディレクトリの中で、npmが実際にどの値を使うかを、config getで確認してください。
接続されている間に一度引いて埋める
/root/npm/appにchalk@4.1.2をインストールして、社内レジストリが上位から引いて、ストレージに残すようにしてください。
プロジェクトの.npmrcが社内レジストリを指しているので、いつもどおりにインストールすれば済みます。インストール後、ロックファイルのresolvedアドレスがどこを指しているか、レジストリのストレージディレクトリに何ができたかを、見てください。
上位への接続を切断して、エアギャップ環境のレジストリにする
'**'パターンからproxyを外して、verdaccioを再起動してください。
proxyがないパターンは、ローカルのストレージにあるものだけを返します。設定は起動時に読まれるので、プロセスを停止して、起動し直す必要があります。ストレージにないパッケージをリクエストして、404になるかを見てください。
新しいキャッシュで、ロックファイルのとおりにインストールする
/root/npm/app2に、appのpackage.json・package-lock.json・.npmrcをコピーして、新しいキャッシュ/root/npm/cache2でnpm ciを実行してください。
npm ciは、ロックファイルが必ず必要で、そのとおりにインストールします。キャッシュディレクトリを新しく指定すれば、以前に取得しておいたものが役に立たないので、レジストリだけでできるかを試すことになります。
外部のロックファイルのアドレスは、どう解決されるのか
/root/npm/outlock/に、外部のレジストリでchalk 4.1.2のロックファイルを作成して、外部をふさいだ状態で、社内レジストリでnpm ciを、デフォルトと--replace-registry-host=neverで実行し、/root/npm/lockhost.txtに、default=・never=の結果(okまたはfail)を書いてください。
ロックファイルのresolvedに埋め込まれたホストが、デフォルトのレジストリのとき、npmが何をするかは、replace-registry-host設定が決めます。2回とも、新しいキャッシュと新しいディレクトリで、外部をふさいだまま実行しないと、公平な比較になりません。結果は、コマンドの終了コードで判断してください。