最近、自分のユニットに CI/CD をセットアップし、開発者の git コードをビルドしてデプロイするように依頼しました。CI/CD をゼロから勉強したのはこれが初めてで、本当に多くの落とし穴を踏んでしまいました。デプロイの部分で、3 日間行き詰まってしまいました。
起因
環境:
ubuntu 物理マシンは CI/CD ツール マシンとして特別に使用され、gitlab と gitlab-runner を同時にインストールするために docker-compose が使用されています。
gitlab はコードのホスティングに使用され、gitlab-runner は gitlab-ci の実行に使用されます。これにより、自動コンパイル、テスト、デプロイが 1 ステップで実現されます。
リモートWEBサーバー、本番環境
質問:
gitlab-runner は docker 上で実行され、gitlab-runner が使用する実行環境も docker であるため、問題が発生します。コンパイルされたファイルを物理マシンに直接コピーすることはできません。Docker は完全に分離されたサンドボックスであり、docker もCI/CD が完了したらすぐに破棄します。幸いなことに、docker CI/CD タスクが完了する前にビルド ファイルを取得できます。
jar パッケージや bin パッケージなど、デプロイする必要があるファイルをサーバーにデプロイするにはどうすればよいですか? 私は多くのオプションを検討しました:
- リモートへのコピーを使用します
scp
。失敗: アカウントのパスワードが必要です。gitlab-ci では入力する機会がありません。 sshpass
+を使用するscp
とパスワードを渡すことができますが、処理が面倒で、権限の問題も残るため、深くは説明しませんでした- を使用してください
ftp
。FTP の古いものはパッシブ モードまたはアクティブ モードで双方にランダムなポートを開くため、安全ではないと思います。あきらめてください。 - を使用するには
rsync
、サーバーとクライアントを同時に設定するのが非常に面倒で、見たくない - 最終的に
sftp
、サーバーに付属のsshユーザーを使用して、それを使用することにしました(新しい安全なユーザーを作成し、ディレクトリを指定する必要があります) - jekenis、これは非常に強力で重く、さまざまなサービスをデプロイするには長い学習期間が必要ですが、私たちのプロジェクトは小さいため、今は考慮せず、軽量の sftp を優先します
上記は、私が多くのオンラインドキュメントやブログを参照し、最終的に docker での独自の sftp デプロイメソッドのセットをまとめたものです。
ここでは例として、ノード配下の vue プロジェクトを使用します。たとえば、ビルド後の vue プロジェクトは dist ディレクトリを生成します。次に、これ以下のすべてのファイルを Web サーバーに公開したいとします。
始める
まず第一に、実行する前にランナーを gitlab に追加する必要があります。これについては、docker-compose を使用した gitlab の構築に関する最後の 2 つの記事で説明されています。ここで注意してください: gilab でプロジェクトを開き、[設定]-[CI] に移動します。左側のメニュー バーの /CD をクリックし、ランナーをプルダウンし、URL とトークンを見つけて、gitlab-runner register を介して登録します。登録後、新しいランナーが緑色の利用可能なステータスを示していることがわかります。
次のステップでは、gitlab-ci.yml とdeploy.sh を記述する必要があります。もちろん、これらを一緒に gitlab-ci.yml に記述することもできます。シェルを書くのが大好きなので、分割しました。
私の.gitlab-ci.yml
stages:
- build
- deploy
cache:
key:
files:
- package.json
paths:
- node_modules
build:
stage: build
before_script:
- npm config set registry https://registry.npm.taobao.org
script:
- npm install
- npm run build
artifacts:
expire_in: 1 day
paths:
- dist
deploy:
stage: deploy
image: ubuntu:20.04
before_script:
- rm /etc/apt/sources.list
- echo 'deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse' >> /etc/apt/sources.list
- echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse' >> /etc/apt/sources.list
- echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse' >> /etc/apt/sources.list
- mkdir ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >~/.ssh/config
- 'which lftp || ( apt-get update -y && apt-get install lftp -y )'
script:
- bash ./deploy.sh
gitlab-ci の yml スクリプトについては、私がたくさんの落とし穴を踏んで書き上げたエッセンスがたくさん含まれていることを具体的に説明しなければなりません。
公式文書は次のとおりです。
GitLab CI/CD での SCP 経由のデプロイによる Composer および NPM スクリプトの実行
焦点は before_script にあります。
- まず、速度を上げるには、ubuntu の適切なソースを中国に置き換える必要があります。そうしないと、CI/CD が非常に遅くなります。
- npm を China に変更しないと、非常に遅くなります。
- 次に、ssh 検証をオフにする必要があります。これは非常に複雑です。docker の下のランナー システムは毎回尋ねます (実行するたびに新しい環境になります)。ただし、「yes」と入力することはできないため、StrictHostKeyChecking をオフにする必要があります。オフにしないと失敗します。通常、.ssh の下にある既知のホストを確認するため、ローカルでエラーを報告することはありません。あなたはそれを許可しました!
- lftp をインストールし、このツールを使用して sftp にアップロードしてください。とても便利!
配備.sh
#!/bin/bash
#指定对端FTP服务器的用户名和密码
USER="xxxx"
PASSWD="xxxx"
IP='xxx.xxx.xxx.xxxx'
P='22'
DIR='example.com'
targetDay=$(date -d "-1 days" +"%Y-%m-%d")
lftp -u $USER,$PASSWD sftp://$IP:$P <<EOM
mirror -R dist $DIR
bye
EOM
[ $? -eq 0 ] && echo "Upload SFTP server successful [$targetDay]"
gitlab-ci.yml はもともとシェルスクリプトを簡略化したものなので、ここでのdeploy.shは実際にはymlにマージできますが、gitlab-ciの場合は別途シェルを書く必要がなく、分けたほうがわかりやすいと思います。ここでは、その内容について説明します。
- まず、ユーザー名やパスワードなど、SFTP サーバーに接続するための変数を定義します。将来的には、これらをgitlab-runner の変数に入れておいたほうが安全です。 そうしないと、git を送信する人が本番サーバーをデプロイするためのアカウントのパスワードを知ることになりますが、これは大企業では絶対に許可されていません。
- 前の記事のユーザーについてですが、root の使用は決して推奨されません。useradd で新しいユーザーを作成し、www ディレクトリを割り当てることができます。私は新しいデプロイ ユーザーを作成しました。デプロイ ディレクトリを追加するのが最善です。ウェブサイト、そうでない場合は
chmod 777
「許可が拒否されました」問題が発生する可能性があります - ディレクトリ全体が lftp でアップロードされるため、
mirror
コマンドを使用する必要があります。ではないことに注意してくださいput
。いわゆる は使用できませんput -r
。すべて不正行為です。不正行為のせいで泣いています。
その仕事が成功したのを見て、私は非常に興奮し、ついにピットから這い上がりました。