オンプレGitLabでgit+CI+npmサーバー2024 の変更点
更新- 追加された行はこの色です。
- 削除された行はこの色です。
- オンプレGitLabでgit+CI+npmサーバー2024 へ行く。
- オンプレGitLabでgit+CI+npmサーバー2024 の差分を削除
#author("2024-09-08T05:25:56+00:00","default:administrator","administrator") #author("2024-09-08T05:33:23+00:00","default:administrator","administrator") [[プログラミング/svelte]] * 自前サーバーで GitLab を動かしてプライベートな npm プロジェクトなどを置きたい [#p3da9108] GitLab は、 - GitHub のように使える git 利用開発支援機能 - テストやビルドやデプロイを自動化する CI サーバー機能 - npm パッケージサーバー機能 など、さまざまな機能を兼ね備えるフリーソフト。 自前のサーバーにインストールして動かせる。 GitLab を動かすには 4GB 以上のメモリが必要で、しばらく前だと二の足を踏んでいたのだけれど今なら軽いはず。 Docker を使ってサクッと動かす。(動かせるといいな) 今のところ、 - docker で GitLab を動かす - ホストの apache2 をプロキシサーバーとして外からの接続を docker との間で中継する - docker で GitLab Runner を動かす - GitLab に Runner を登録する(shell モード) - CI/CD で成果物を .zip としてダウンロード可能にする ところまで基本を押さえることができました。 - GitLab に Runner を登録する(docker モード) - GitLab の npm パッケージサーバーへパッケージを Deploy する はこれからです。 ** 目次 [#xea030b5] #contents * GitLab サーバーを docker compose で動かす [#bf994d2a] https://gitlab-docs.creationline.com/ee/install/docker.html#install-gitlab-using-docker-compose を見ながら docker イメージで動作するよう設定する。 - ホストサーバーには docker 環境があって、自分が管理者である -- gitlab は docker 内で動かす - ホストサーバーには apache2 が https://myserver.com/ への通信を受け付ける状況になっている - https://myserver.com/gitlab/ というアドレスへの通信を docker 内の gitlab サーバーへ繋ぐ という形で GitLab を動かします。 LANG:console $ cd ~ $ mkdir gitlab $ cd gitlab $ echo GITLAB_HOME=`pwd` > .env $ cat <<"EOS" > docker-compose.yml services: web: image: 'gitlab/gitlab-ce:latest' restart: always environment: GITLAB_OMNIBUS_CONFIG: | external_url 'https://myserver.com/gitlab' nginx['listen_port'] = 80 nginx['listen_https'] = false gitlab_rails['gitlab_shell_ssh_port'] = 2224 ports: - '8980:80' volumes: - '$GITLAB_HOME/etc:/etc/gitlab' - '$GITLAB_HOME/log:/var/log/gitlab' - '$GITLAB_HOME/data:/var/opt/gitlab' shm_size: '256m' EOS $ docker compose up -d [+] Running 10/10 ✔ web Pulled 58.2s ✔ 857cc8cb19c0 Pull complete 2.1s ✔ 28812802a434 Pull complete 2.1s ✔ 54e2e989e54c Pull complete 3.0s ✔ abb7892b26dc Pull complete 3.0s ✔ e9d667f5a8c1 Pull complete 3.0s ✔ a8891519352d Pull complete 3.1s ✔ 8b624a00a604 Pull complete 3.1s ✔ 0cf3370d74b6 Pull complete 3.1s ✔ 3253094bd895 Pull complete 55.9s [+] Running 2/2 ✔ Network gitlab_default Created 0.0s ✔ Container gitlab-web-1 Started 0.7s これで docker 内で GitLab サーバーが立ち上がる。 ** 全体としての注意 [#o2bf1916] 上記のようにして動かすと、etc/ フォルダに etc/gitlab.rb というのができて、 これを書き換えれば設定を変えられる。 設定項目についてはこちらに説明がある。~ https://gitlab-docs.creationline.com/omnibus/settings/configuration.html また、ファイルの冒頭には以下の注意書きがある。 ## GitLab configuration settings ##! This file is generated during initial installation and **is not** modified ##! during upgrades. ##! Check out the latest version of this file to know about the different ##! settings that can be configured, when they were introduced and why: ##! https://gitlab.com/gitlab-org/omnibus-gitlab/blame/master/files/gitlab-config-template/gitlab.rb.template ##! Locally, the complete template corresponding to the installed version can be found at: ##! /opt/gitlab/etc/gitlab.rb.template ##! You can run `gitlab-ctl diff-config` to compare the contents of the current gitlab.rb with ##! the gitlab.rb.template from the currently running version. ##! You can run `gitlab-ctl show-config` to display the configuration that will be generated by ##! running `gitlab-ctl reconfigure` ##! In general, the values specified here should reflect what the default value of the attribute will be. ##! There are instances where this behavior is not possible or desired. For example, when providing passwords, ##! or connecting to third party services. ##! In those instances, we endeavour to provide an example configuration. ## GitLab URL ##! URL on which GitLab will be reachable. ##! For more details on configuring external_url see: ##! https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-the-external-url-for-gitlab ##! ##! Note: During installation/upgrades, the value of the environment variable ##! EXTERNAL_URL will be used to populate/replace this value. ##! On AWS EC2 instances, we also attempt to fetch the public hostname/IP ##! address from AWS. For more details, see: ##! https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html # external_url 'GENERATED_EXTERNAL_URL' ## Roles for multi-instance GitLab ##! The default is to have no roles enabled, which results in GitLab running as an all-in-one instance. ##! Options: ##! redis_sentinel_role redis_master_role redis_replica_role geo_primary_role geo_secondary_role ##! postgres_role consul_role application_role monitoring_role ##! For more details on each role, see: ##! https://docs.gitlab.com/omnibus/roles/index.html#roles ##! # roles ['redis_sentinel_role', 'redis_master_role'] ## Legend ##! The following notations at the beginning of each line may be used to ##! differentiate between components of this file and to easily select them using ##! a regex. ##! ## Titles, subtitles etc ##! ##! More information - Description, Docs, Links, Issues etc. ##! Configuration settings have a single # followed by a single space at the ##! beginning; Remove them to enable the setting. ##! **Configuration settings below are optional.** 一方、例えば data/nginx/conf/gitlab-http.conf に nginx 関連の設定ファイルが見つかるのだけれど、 こちらの設定ファイルはサーバーを立ち上げ直すと gitlab.rb の内容を元に自動的に生成されるものなので、 手で書きかえてはいけない。 ちゃんと冒頭に # This file is managed by gitlab-ctl. Manual changes will be # erased! To change the contents below, edit /etc/gitlab/gitlab.rb # and run `sudo gitlab-ctl reconfigure`. などと書かれている。 etc/gitlab.rb を書き換えてしまうと設定情報が docker-compose.yml と gitlab.rb とに分かれてしまうので、どちらか一方にまとめた方がいいのかもしれない。 単純な見やすさからすると docker-compose.yml に書く方が良さそうなのだけれど、 gitlab-ctl diff-config を使うなら gitlab.rb でもいいのかもしれない。 docker コンテナの外から確認するなら: LANG:console $ docker compose exec web gitlab-ctl diff-config ** ポートの指定 [#i42dc48e] 外からの接続を受ける apache2 と同じマシンに置くのであれば docker-compose.yml の ports: - '8980:80' のところは ports: - '127.0.0.1:8980:80' として、外からの接続が直接 docker へ行かないようにする。 docker でポートを開けると ufw などのファイアウォールで許可してなくても 外向きにポートが開いてしまうので十分注意する。 ** https を名乗りつつ http で待ち受ける [#z2f50ccd] gitlab の設定で GITLAB_OMNIBUS_CONFIG: | external_url 'https://myserver.com/gitlab' nginx['listen_port'] = 80 nginx['listen_https'] = false としている理由は以下の通り。 この docker イメージは external_url の設定を見て、内部の nginx で 80 番で http を待つか、443 番で https を待つかを決めている。 「どちらか片方しか有効にならない」というのが重要な点。 今実現したい構成では、外部から見た gitlab サーバーのアドレスは https://myserver.com/gitlab で https 接続になるのだけれど、その暗号化通信は間に入る apache2 が受け持つので docker 内の nginx への接続は http になる。 external_url を https としてしまうと gitlab docker は nginx を 443 番で https を待つように設定してしまい 80 番の http では繋がらなくなってしまう。 そこで 80 番で http を待つように設定しているのがこの部分だ。 サーバーに繋ぎに行って「接続をリセットされました」みたいになるときは、 LANG:console $ sudo less data/nginx/conf/gitlab-http.conf として gitlab 関連の nginx の設定を確かめるといい。 (これに気付くのにかなり時間がかかりました・・・) ** GITLAB_OMNIBUS_CONFIG で指定可能なその他の設定 [#d7e481ac] GITLAB_OMNIBUS_CONFIG では LANG:console $ sudo less etc/gitlab.rb として表示される設定項目に値を指定できるので、 「こんなことできないのかな」と思ったときにはじっくり読むといい。 * apache2 をプロキシサーバーとして接続を中継させる [#g1e47924] ホストマシンの /etc/apache2/sites-enabled/default-ssl.conf に <IfModule mod_proxy.c> ProxyRequests Off <Proxy *> Require all granted </Proxy> AllowEncodedSlashes NoDecode <Location /gitlab> Order deny,allow Allow from all </Location> RequestHeader set X_FORWARDED_PROTO 'https' ProxyPass /gitlab http://localhost:8980/gitlab ProxyPassReverse /gitlab http://localhost:8980/gitlab </IfModule> と設定して、 LANG:console $ sudo a2enmod proxy $ sudo service apache2 reload とすることで apache2 がプロキシサーバーとして振る舞い、 https://myserver.com/gitlab 以下へのアクセスを http://localhost:8929/gitlab へ転送してくれる。 ここで重要なのが AllowEncodedSlashes NoDecode だ。 これをしておかないと、後々 GitLab を npm パッケージサーバーとして使おうとした際に、パッケージリポジトリへの PUT が 404 で失敗する。 https://stackoverflow.com/questions/20496963/avoid-nginx-decoding-query-parameters-on-proxy-pass-equivalent-to-allowencodeds LANG: console $ npm publish # 他の設定が終わってからの話 ... npm error code E404 npm error 404 Not Found - PUT https://myserver.com/gitlab/api/v4/projects/1/packages/npm/@myscope%2fmypackage npm error 404 npm error 404 '@myscope/mypackage@0.0.1' is not in this registry. npm error 404 npm error 404 Note that you can also install from a npm error 404 tarball, folder, http url, or git url. のように、npm publish で認証は通過しているのに、そして、アップロードしようとしているのに 404 で落ちるていたらこの設定を見直すといい。 * メールを送れるように設定する [#aa2a5159] GITLAB_OMNIBUS_CONFIG に gitlab_rails['gitlab_email_from'] = 'gitlab@myserver.com' gitlab_rails['gitlab_email_display_name'] = 'GitLab' gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.server" gitlab_rails['smtp_port'] = 465 gitlab_rails['smtp_user_name'] = "smtp user" gitlab_rails['smtp_password'] = "smtp password" gitlab_rails['smtp_domain'] = "example.com" gitlab_rails['smtp_authentication'] = "login" gitlab_rails['smtp_enable_starttls_auto'] = true gitlab_rails['smtp_tls'] = false gitlab_rails['smtp_pool'] = false あたりを追加する。 設定の仕方はこちらを参照:~ https://gitlab-docs.creationline.com/omnibus/settings/smtp.html * root でログインする [#u468af48] 初期設定で root という管理者ユーザーが登録されているので、 ウェブサーバーから https://myserver.com/gitlab へアクセスして root でログインする。 管理者 root の初期パスワードは gitlab の docker-compose.yml を作ったフォルダの下の etc フォルダを調べるとわかる。 LANG:console $ sudo cat etc/initial_root_password ** 普段使いのユーザーを作っておく [#i200c3a4] この root ユーザーを使って普段使いのユーザー(以下では "myname" とする)を作っておく。 ** 自分で変更した root のパスワードを忘れてしまった場合 [#p77da698] root のパスワードを自分で変更して、その後忘れてしまうと困ったことになる。 そんな時は、 https://blog.k-bushi.com/post/tech/environment/construct-gitlab-runner-docker/#gitlab%E3%81%B8%E3%81%AE%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3 にあるように、 LANG:console $ docker compose exec web gitlab-rake "gitlab:password:reset" Enter username: root Enter password: Confirm password: Password successfully updated for user with username root. とすればパスワードを設定しなおせるらしい。 * GitLab Runner も docker で動かす [#a35f227c] CI で実際にジョブを実行するサーバーは GitLab Runner と呼ばれる。 同時に使用する人数と比較すると今使っている物理サーバーには余裕があるので、 CI サーバーも同じ物理サーバーで動かしてしまうことにした。 先の docker-compose.yml に以下を追加する。 runner: image: 'gitlab/gitlab-runner:latest' restart: unless-stopped volumes: - '$GITLAB_HOME/runner:/etc/gitlab-runner' - /var/run/docker.sock:/var/run/docker.sock ports: - '8093:8093' そして、 LANG:console $ sudo docker compose up -d * Runner を GitLab に追加する [#k5e1dceb] ** GitLab 画面で新しい Runner インスタンスを作成 [#k2bc716a] https://myserver.com/gitlab/admin/runners から右上の [New Instance Runner] を押す。 ここでは特別な設定をしないごく一般的な shell の動くサーバーを建てるので、 x Run untagged jobs のチェックを付けて [Create runner] とする。 ** docker で動かした Runner と対応付ける [#ka34cbec] 次の画面の Step 1 となっているところで $ gitlab-runner register --url https://myserver.com/gitlab --token glrt-iqghvxb-GLHJG9WsFPT6 のようなところをコピーする。 ちょっと手直しをして次の形にして Runnner を起動した docker-compose.yml のあるフォルダで実行。 $ docker compose exec runner \ gitlab-runner register \ --url https://myserver.com/gitlab \ --token glrt-iqghvxb-GLHJG9WsFPT6 コマンドを起動するといくつか質問に答えることになる。 - GitLab instance URL には指定した https://myserver.com/gitlab が入っているのでそのまま ENTER - Enter a name for the runner にはこの Runner を識別する名前を付ける - Enter an executor には shell を指定 これで Runner 一覧に正しく追加される。 ** ERROR: Verifying runner... failed → extra_hosts の設定が必要? [#kde9fa35] 何らかの事情で Runner の docker 内部から myserver.com で apache2 の動くサーバーへ到達できない場合には(LAN 内で ローカル IP を持っている場合など)、 $ docker compose exec runner \ gitlab-runner register \ --url https://myserver.com/gitlab \ --token glrt-iqghvxb-GLHJG9WsFPT6 Enter the GitLab instance URL (for example, https://gitlab.com/): [https://myserver.com/gitlab]: <ENTER> ERROR: Verifying runner... failed runner=yFiGd5DTA status=couldn't execute POST against https://myserver.com/gitlab/api/v4/runners/verify: Post "https://myserver.com/gitlab/api/v4/runners/verify": dial tcp xx.xx.xx.xx:443: connect: connection refused PANIC: Failed to verify the runner. のように connection refused というエラーが出て失敗する。 このときは docker-compose.yml 内で runner に extra_hosts: - myserver.com:192.168.0.2 のようなのを追加して https://myserver.com/gitlab でサーバーへ到達できるようにしておく必要がある。 * CI 動作を試してみる [#jb5189f3] LANG: console $ mkdir ~/gitlab-ci-hello $ cd ~/gitlab-ci-hello $ cat <<"EOS" > .gitlab-ci.yml build: script: - echo hello `pwd` - ls -la EOS $ git init $ git add . $ git commit -m "Initial commit" として .gitlab-ci.yml だけをコミットした git リポジトリを作成する。 GitLab 上でブランクプロジェクトを作ってそこへコミットしてみる。 https://myserver.com/gitlab/projects/new#blank_project - Project name: gitlab-ci-hello - Project url: https://myserver.com/gitlab/myname/gitlab-ci-hello - Visibility Level: private - Project Configuration: README のチェックを外す そして Create Project 次のページの Push an existing Git repository の手順で push する。 LANG:console $ git remote add origin https://myserver.com/gitlab/myname/gitlab-ci-hello.git $ git push --set-upstream origin --all Username for 'https://myserver.com': myname Password for 'https://myname@myserver.com': xxxxxx Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Delta compression using up to 4 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 266 bytes | 266.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To https://myserver.com/gitlab/myname/gitlab-ci-hello.git * [new branch] master -> master branch 'master' set up to track 'origin/master'. $ git push --set-upstream origin --tags Username for 'https://myserver.com': myname Password for 'https://myname@myserver.com': xxxxxx Everything up-to-date push 時には gitlab サーバーのユーザー名とパスワードを聞かれるので入力する。 GitLab の画面で確認すると、 &ref(jobs-success.png,,50%); こちらのようにコミット番号の隣に緑のチェックマークがついて、 ジョブが成功したことを確認できる。 このチェックをクリックして中を見ると、 LANG:console Running with gitlab-runner 17.3.1 (66269445) on myrunnner1 t2X9wkLjw, system ID: r_FoHQflE05Zou Preparing the "shell" executor 00:00 Using Shell (bash) executor... Preparing environment 00:00 Running on 8163caea6de5... Getting source from Git repository 00:00 Fetching changes with git depth set to 20... Initialized empty Git repository in /home/gitlab-runner/builds/t2X9wkLjw/0/gitlab/myname/gitlab-ci-hello/.git/ Created fresh repository. Checking out cc71a4d9 as detached HEAD (ref is master)... Skipping Git submodules setup Executing "step_script" stage of the job script 00:00 $ echo hello `pwd` hello /home/gitlab-runner/builds/t2X9wkLjw/0/gitlab/myname/gitlab-ci-hello $ ls -la total 16 drwxrwxr-x 3 gitlab-runner gitlab-runner 4096 Sep 7 13:03 . drwxrwxr-x 4 gitlab-runner gitlab-runner 4096 Sep 7 13:03 .. drwxrwxr-x 6 gitlab-runner gitlab-runner 4096 Sep 7 13:03 .git -rw-rw-r-- 1 gitlab-runner gitlab-runner 53 Sep 7 13:03 .gitlab-ci.yml Cleaning up project directory and file based variables 00:00 Job succeeded のようにして、 LANG:console $ echo hello `pwd` と LANG:console $ ls -la が正しく実行されていることを確認できる。 ワーキングフォルダが /home/gitlab-runner の下にあることからもわかるとおり、 このシェルは gitlab-runner というユーザー権限で実行される。 そのままでは sudo は使えないので、システムに変更を加えるようなコマンドは実行できない。 Runner の Dockerfile はこちらにある:~ https://hub.docker.com/r/gitlab/gitlab-runner/dockerfile 中身はものすごく古い ubuntu を元にしている? なんでこんなに古いんだろう??? ** CI スクリプトの書き方 [#q6b58aca] 概要:~ https://gitlab-docs.creationline.com/ee/ci/yaml/gitlab_ci_yaml.html リファレンス:~ https://gitlab-docs.creationline.com/ee/ci/yaml/index.html 用語の整理: - パイプラインは複数のステージから構成される - 個々のステージは並列実行可能な複数のジョブから構成される - 個々のステージは前のステージのジョブがすべて成功してから次へ進む ** node 環境を準備&ビルド&テスト [#d1c57aa0] 例えば、以下の .gitlab_ci.yml と package.json をコミットしてみる。 .gitlab_ci.yml variables: NODE_VERSION: 22 NVM_VERSION: v0.40.0 stages: - build - test - package cache: paths: - dist/* # common setting for each job default: before_script: - ls -d "$HOME/.nvm" || (curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh | bash) - export NVM_DIR="$HOME/.nvm" - \[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - nvm --version - nvm use ${NODE_VERSION} || nvm install ${NODE_VERSION} # each job is associated to a stage build: stage: build script: - echo $CI_PIPELINE_SOURCE - echo $CI_COMMIT_REF_NAME - echo $CI_COMMIT_TAG - echo $CI_COMMIT_BRANCH - npm run lint - npm run build environment: production test: stage: test script: - npm run test:unit --run package: stage: package only: - tags except: - branches script: - ls dist artifacts: name: mypackage-${CI_COMMIT_TAG}.tar.gz paths: - dist/* package.json LANG:console { "name": "mypackage", "version": "0.0.1", "scripts": { "lint": "echo 'lint - success!'", "build": "mkdir -p dist && (echo 'Hello!' > dist/hello.txt) && echo 'build - success!'", "test:unit": "echo 'test:unit - success!'" } } すると build と test に成功して、 build の結果: LANG:console Running with gitlab-runner 17.3.1 (66269445) on bee01 t2X9wkLjw, system ID: r_FoHQflE05Zou Preparing the "shell" executor 00:00 Using Shell (bash) executor... Preparing environment 00:00 Running on 8163caea6de5... Getting source from Git repository 00:00 Fetching changes with git depth set to 20... Reinitialized existing Git repository in /home/gitlab-runner/builds/t2X9wkLjw/0/gitlab/osamu/gitlab-ci-hello/.git/ Checking out 504e92af as detached HEAD (ref is master)... Skipping Git submodules setup Executing "step_script" stage of the job script 00:07 $ ls -d "$HOME/.nvm" || (curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh | bash) ls: cannot access '/home/gitlab-runner/.nvm': No such file or directory % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 16555 100 16555 0 0 59336 0 --:--:-- --:--:-- --:--:-- 59336 => Downloading nvm from git to '/home/gitlab-runner/.nvm' => Cloning into '/home/gitlab-runner/.nvm'... * (HEAD detached at FETCH_HEAD) master => Compressing and cleaning up git repository => Profile not found. Tried ~/.bashrc, ~/.bash_profile, ~/.zprofile, ~/.zshrc, and ~/.profile. => Create one of them and run this script again OR => Append the following lines to the correct file yourself: export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm => Installing Node.js version 22 Downloading and installing node v22.8.0... Downloading https://nodejs.org/dist/v22.8.0/node-v22.8.0-linux-x64.tar.gz... ######################################################################## 100.0% Computing checksum with sha256sum Checksums matched! Now using node v22.8.0 (npm v10.8.2) Creating default alias: default -> 22 (-> v22.8.0 *) => Node.js version 22 has been successfully installed => Close and reopen your terminal to start using nvm or run the following to use it now: export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm $ export NVM_DIR="$HOME/.nvm" $ \[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" $ nvm --version 0.40.0 $ nvm use ${NODE_VERSION} || nvm install ${NODE_VERSION} Now using node v22.8.0 (npm v10.8.2) $ npm run lint > mypackage@0.0.1 lint > echo 'lint - success!' lint - success! $ npm run build > mypackage@0.0.1 build > mkdir -p dist && (echo 'Hello!' > dist/hello.txt) && echo 'build - success!' build - success! Cleaning up project directory and file based variables 00:00 Job succeeded test の結果: LANG:console Running with gitlab-runner 17.3.1 (66269445) on bee01 t2X9wkLjw, system ID: r_FoHQflE05Zou Preparing the "shell" executor 00:00 Using Shell (bash) executor... Preparing environment 00:00 Running on 8163caea6de5... Getting source from Git repository 00:01 Fetching changes with git depth set to 20... Reinitialized existing Git repository in /home/gitlab-runner/builds/t2X9wkLjw/0/gitlab/osamu/gitlab-ci-hello/.git/ Checking out ae25c69e as detached HEAD (ref is master)... Removing dist/ Skipping Git submodules setup Executing "step_script" stage of the job script 00:00 $ ls -d "$HOME/.nvm" || (curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh | bash) /home/gitlab-runner/.nvm $ export NVM_DIR="$HOME/.nvm" $ \[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" $ nvm --version 0.40.0 $ nvm use ${NODE_VERSION} || nvm install ${NODE_VERSION} Now using node v22.8.0 (npm v10.8.2) $ npm run test:unit --run > mypackage@0.0.1 test:unit > echo 'test:unit - success!' test:unit - success! Cleaning up project directory and file based variables 00:00 Job succeeded となる。 ちゃんと初回に node がインストールされて、2回目はそれが再利用されている。 ちゃんと test をするときは report を作成するといいらしい~ https://docs.gitlab.com/17.3/ee/ci/testing/unit_test_reports.html ** パッケージング [#u55ac843] まず、上で cache: paths: - dist/* をしておかないと build で作成したファイルが package に引き継がれないので注意が必要だ。 そして package ステージには only: - tags except: - branches がついているので、tag を付けたときで、なおかつそのタグがデフォルトブランチ(ここでは master)についてないとスクリプトは実行されない。 - https://stackoverflow.com/questions/42796018/how-to-run-a-gitlab-ci-yml-job-only-on-a-tagged-branch - https://stackoverflow.com/questions/69199614/ci-commit-tag-in-if-statemets-of-regular-job あたりを参照。 試してみよう GitLab 画面のプロジェクトページの左上 "+" のドロップダウンから New Tag を選んで、 https://myserver.com/gitlab/myname/mypackage/-/tags/new から 0.0.1 というタグを作成する。 ・・・ん? 新しいパイプラインが生成されないような??? > > https://forum.gitlab.com/t/pipeline-not-executed-after-commit/87173/6 > > によると GitLab と Runner のバージョンを合わせた方がいいと書かれてる? > > GitLab のバージョンは、 > > $ docker compose exec web gitlab-rake gitlab:env:info > > とするか、GitLab 画面左下の Help ボタンを押すことで確認できる。 > > ここでは 17.3.1 だった。 > > Runner のバージョンは GitLab の admin メニューから CI/CD - Runners で > > https://myserver.com/gitlab/admin/runners > > ここから個々の Runner をクリックして show detail すると、、、17.3.1 なので問題なし。 > ああ、違った。 ちゃんと動いているけれど、トップ画面の緑色のチェックマークはあくまでコミットに対する CI/CD の結果で、タグに対する CI/CD の結果は Tags のページでタグの横に現れるのか。 個別のタグのページに CI/CD の結果を表示してくれないので混乱した。 https://myserver.com/gitlab/myname/gitlab-ci-hello/-/tags/0.0.1 パイプラインがすべて正しく実行されると、 https://myserver.com/gitlab/myname/gitlab-ci-hello/-/tags のタグの横に緑のチェックが出て、その右のダウンロードメニューに artifact - package が現れる。 選択すると mypackage-0.0.1.tar.gz を落とせた。 メニュー自体の表示を mypackage-0.0.1.tar.gz にすることはできないのかな??? TODO: リリース時にこのアーティファクトを参照する方法も調べる * GitLab に Runner を登録する(docker モード) [#k3e6874a] node は sudo の必要なくインストールできるので shell モードで簡単に動かせたけれど、 例えば playwright を動かそうとすると apt などでネイティブなパッケージをいろいろ入れなければならず、 困ってしまう。 そういう時は https://qiita.com/yusayoshi/items/6b48bca5b5c0a17cd40e#gitlab-cicd のように runner を docker モードで動かしてやればいいいいみたい。 これは、docker の中で走っている Runner が、さらに docker を起動して ci スクリプトをその docker の中で実行させるというもの。いわゆる dind (docker-in-docker) という技術らしい。Runner の docker コンテナを作る際に /var/run/docker.sock を受け渡しているおかげでそういうことができるのだとか。 Runner を docker モードで動かすには 上記手順で Runner を GitLab へ追加する際に Executor を shell ではなく docker とする。 すると、デフォルトで使う docker image を聞かれる。 ここでは主に node 上での開発を考えているので playwright が使えるようリンク先にあった mcr.microsoft.com/playwright:focal を指定した。 ci スクリプトから image を指定されないときにはこれが使われることになる。 スクリプトで image 指定すれば別の image を使うこともできる。 ** extra_hosts を設定する [#dc5bb821] 上で runner に extra_hosts を追加している場合には、 runner/config.toml に、 [[runners]] [runners.docker] extra_hosts = ["myserver.com:192.168.0.2"] の設定をしないと、runner docker 内部で作成される docker コンテナに hosts の設定が引き継がれないことに注意が必要。 ** 試してみる [#p08621ae] これで始めから npm や playwright の使える環境で ci スクリプトを走らせることができるようになったはず。 上のスクリプトの before_script をバージョン確認だけにしてみた。 default: before_script: - node --version - npm --version すると、 LANG:console $ node --version v20.16.0 $ npm --version 10.8.1 と表示され、残りのスクリプトも正しく実行された。 * GitLab の npm パッケージサーバーへパッケージを Deploy する [#fbffbb3a] GitLab には npm パッケージサーバーの機能があるので、 そこへパッケージを Deploy してみよう。 ** GitHub のプロジェクトをクローンして GitLab へ登録する [#vc66bcf0] まず、こちらで作った typescript-vitest-skeleton という GitHub プロジェクトをクローンして、 GitLab へ登録しなおす https://dora.bk.tsukuba.ac.jp/~takeuchi/?typescript+%2B+vitest+%E3%81%A7+npm+%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E9%96%8B%E7%99%BA+2024 GitLab 上で typescript-vitest-skeleton という空のプロジェクトを作成しておいて、 LANG:console $ git clone https://github.com/osamutake/typescript-vitest-skeleton.git Cloning into 'typescript-vitest-skeleton'... $ cd typescript-vitest-skeleton/ $ npm i $ git remote add origin2 https://myserver.com/gitlab/myname/typescript-vitest-skeleton.git $ git push origin2 --all 左のメニューの Deploy - Package Registray からこの GitLab プロジェクトのパッケージレジストリを確認できる。 https://myserver.com/gitlab/myname/typescript-vitest-skeleton/-/packages 当然今は空だ。 ここに上記 npm パッケージを登録したい。 ** パッケージ名のスコープ [#eca37037] GitLab プロジェクトのパッケージレジストリへパッケージを登録するには、 https://myserver.com/gitlab/api/v4/projects/(project id)/packages/npm/@(scope_name)/(package_name) のようなアドレスへパッケージを PUT することになる。 ここで、 - project id : この GitLab サーバーのプロジェクトにつけられた通し番号 -- プロジェクトのトップページ https://myserver.com/gitlab/myname/typescript-vitest-skeleton の右上の縦に3つ並んだ点のアイコン(More actions)をクリックして "Copy Project ID: 9" をクリックするとコピーできる - scope_name : npm ではパッケージ名の前に @ユーザー名 を付けることでスコープ付きにして、他のパッケージと名前が被らないようにしますが、それと似たような識別子 -- GitLab で使うときは GitLab サーバーを識別するために使うことになるみたい? - package_name : 例えば上の typescript-vitest-skeleton まだよくわかっていないのだけれど、どうやら GitLab の提供する npm パッケージサーバーからパッケージをダウンロードさせたい場合「"@osamu_takeuchi/*" のように @osamu_takeuchi というスコープがついているパッケージは npm ではなく特定の GitLab サーバーを探しに行け」という設定をすることになるみたいなので、パッケージ名を例えば @myserver/typescript-vitest-skeleton というような、分かりやすいスコープ付きにしておくのが良さそう? LANG:console $ git remote remove origin $ git remote remove origin2 $ git remote add origin https://myserver.com/gitlab/myname/typescript-vitest-skeleton.git $ sed -i.bak s/@osamu_takeuchi/@myserver/ package.json $ git add package.json $ git commit -m "Scope of package is changed" $ git push origin ** デプロイ用のトークンを発行して .npmrc を設定する [#k4264fcf] パッケージのアップロードには個々のプロジェクトからのアクセス許可が必要なので、 プロジェクトの Settings - Repository - Deploy Tokens - Add token からトークンを発行する。 https://myserver.com/gitlab/myname/typescript-vitest-skeleton/-/settings/repository &ref(add-deploy-token.png,,50%); GitLab はいろんなところでいろんな用途のトークンを発行できるので、 違うところで違う用途のトークンを発行して設定して、動かないなあ、となることが多い(汗 - Name を npm push とする - write_package_registry にチェックを入れる - [Create deploy token] を押す - 次の画面で gldt-XXXXXXXXXXXXXXXX のようなトークンをコピーする プロジェクトのフォルダーにこのトークンを指定した .npmrc を作成する。 LANG:console $ echo ".npmrc" >> .gitignore $ cat <<"EOS" >.npmrc //myserver.com/gitlab/api/v4/projects/9/packages/npm/:_authToken=gldt-XXXXXXXXXXXXXXXXX @myserver:registry=https://myserver.com/gitlab/api/v4/projects/9/packages/npm/ EOS このファイルを GitLab へアップロードしてしまうと誰でもデプロイできるようになってしまうので、 必ず .gitignore に追加しておく必要がある。 ** 手動でデプロイする [#xbeab9f0] 後は普通に npm publish すればいい。 LANG:console $ npm publish npm notice Publishing to https://myserver.com/gitlab/api/v4/projects/9/packages/npm/ with tag latest and default access + @myserver/mypackage@0.0.1 これでパッケージがデプロイされ、Package Registry に @myserver/mypackage (latest) 0.0.1 npm のような項目が現れる。 TODO: プロジェクトじゃなくグループ単位のレジストリを使った方が良いのかも? TODO: ci スクリプトから自動的にデプロイする方法は? 特に Deploy Token をどのように CI スクリプトに渡せばいいのかが想像つかない??? ** Package Registry のパッケージを npm install する [#fcdddf1c] こちらでは読み取りのみの権限があればいいので、 https://myserver.com/gitlab/myname/typescript-vitest-skeleton/-/packages の一覧から先にデプロイした 0.0.1 をクリックすると、 LANG:console $ echo @myserver:registry=https://myserver.com/gitlab/api/v4/packages/npm/ >> .npmrc $ npm i @myserver/mypackage のようにすればインストールできると書かれていた。 ただし認証が必要になると。 ここでは読み取りのみの権限があればいいので、 トップページのサイドバーの右上アイコンから Edit Profile、サイドバーの User settings - Access Tokens - Add new token を選択。 https://myserver.com/gitlab/-/user_settings/personal_access_tokens - Token name を例えば npm install とかにして - read_api だけチェックして - Expiration date を適当に延ばして [Create personal access token] - 次のページでトークンをコピーする (glpat-XXXXXXXX みたいなの) そして、 https://docs.gitlab.com/ee/user/packages/npm_registry/#authenticate-to-the-package-registry を見ながら、 LANG:console $ npm config set @myserver:registry https://myserver.com/api/v4/packages/npm/ $ npm config set -- //myserver.com/api/v4/packages/npm/:_authToken=glpat-XXXXXXXX $ cat ~/.npmrc @myserver:registry=https://myserver.com/api/v4/packages/npm/ //myserver.com/api/v4/packages/npm/:_authToken=glpat-XXXXXXXX これらは ~/.npmrc に書き込まれるのでその後は自由に npm i が使えるはず。 これらが ~/.npmrc に書き込まれるのでその後は自由に npm i が使えるはず。 試しに、 LANG:console $ mkdir ~/test_npm_install $ cd ~/test_npm_install $ npm init { "name": "test_npm_install", "version": "1.0.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "description": "" } $ npm install @myserver/mypackage npm error code E404 npm error 404 Not Found - GET https://myserver.com/api/v4/packages/npm/@myserver%2fmypackage npm error 404 npm error 404 '@myserver/mypackage@*' is not in this registry. npm error 404 npm error 404 Note that you can also install from a npm error 404 tarball, folder, http url, or git url. ん?そうでもないぞ。 そんなパッケージは見つからないと言われる・・・って URL を指定し間違っていた。 今は gitlab/ というサブフォルダで gitlab を動かしているので 今は gitlab/ というサブフォルダで gitlab を動かしているので GitLab が教えてくれていた通り、 LANG:console $ npm config set @myserver:registry https://myserver.com/gitlab/api/v4/packages/npm/ $ npm config set -- //myserver.com/gitlab/api/v4/packages/npm/:_authToken=glpat-XXXXXXXX $ npm config set -- //myserver.com/gitlab:_authToken=glpat-XXXXXXXX が正しい。 でもそうしたら今度は LANG:console $ npm install @myserver/mypackage npm error code E404 npm error 404 Not Found - GET https://registry.npmjs.org/@takenchi%2fmypackage - Not found npm error 404 npm error 404 '@takenchi/mypackage@*' is not in this registry. npm error 404 npm error 404 Note that you can also install from a npm error 404 tarball, folder, http url, or git url. となってしまった。 URL のパスが api から始まっていないと認識してくれない??? ・・・どうやらそうじゃなくて、myserver.com の API が registry.npmjs.org へのリダイレクトを返しているらしい。適当なパッケージ名を与えても同じ動作をするので、恐らく自分が持っていないパッケージに対するフォールバック動作がこれみたい。 ・・・どうやらそうじゃなくて、myserver.com の API が registry.npmjs.org へのリダイレクトを返しているらしい。適当に、絶対存在しないパッケージ名を与えても同じ動作をするので、恐らく自分が持っていないパッケージに対するフォールバック動作がこれみたい。 つまり、プロジェクトへ Deploy したパッケージはここには見つからない?? つまり、プロジェクトへ Deploy したパッケージがここに見つからない?? なんでだろう???
Counter: 49 (from 2010/06/03),
today: 19,
yesterday: 30