freeCodeCamp/docs/i18n/japanese/devops.md

42 KiB

DevOps ハンドブック

このガイドは、インフラストラクチャスタックとプラットフォームをどのように維持するかを理解するのに役立ちます。 このガイドで、すべての操作について詳しく説明しているわけではありませんが、システムを理解する上での参考になります。

ご意見やご質問があれば、どうぞご連絡ください。喜んでご説明いたします。

フライトマニュアル - コードデプロイ

このリポジトリは、継続的に構築され、テストされ、インフラストラクチャの個別のセット (サーバー、データベース、CDNなど) にデプロイされます。

これには3つのステップが含まれます。

  1. 新規変更 (修正および機能変更の両方を含む) は、プルリクエストによりプライマリ開発ブランチ (main) にマージされます。
  2. これらの変更は、一連の自動テストで実行されます。
  3. テストに合格すると、インフラストラクチャ上でのデプロイメントに対して変更をリリースします(または必要に応じて更新します)。

コードベースのビルド - Git ブランチのデプロイメントへのマッピング

通常、main (デフォルトの開発ブランチ) は、prod-staging ブランチに 1 日 1 回マージされ、分離されたインフラストラクチャにリリースされます。

これは開発者とボランティアのコントリビューター用の中間リリースです。 「ステージング」または「ベータ」リリースとも呼ばれます。

それは freeCodeCamp.org のライブプロダクション環境と同じで、データベース、サーバー、Web プロキシなどの別々のセットを使用しています。 この分離により、freeCodeCamp.org の main プラットフォームの正規ユーザーに影響を与えることなく、「本番」のようなシナリオで継続的な開発と機能をテストすることができます。

開発者チーム @freeCodeCamp/dev-team が、ステージングプラットフォームでの変更に満足したら、これらの変更は数日ごとに prod-current ブランチに移されます。

これが freeCodeCamp.org で本番プラットフォームに変更を加えた最終リリースです。

変更のテスト - 統合テストとユーザー承認テスト

私たちは、コードの品質を確認するために、様々なレベルの統合と受け入れテストを採用しています。 すべてのテストは、GitHub Actions CIAzure Pipelines のようなソフトウェアにより実行されます。

私たちは、チャレンジソリューション、Server API、クライアントユーザーインターフェースをテストするための単体テストを行っています。 これらは、異なるコンポーネント間の統合をテストするのに役立ちます。

[!NOTE] また、メールの更新や API やサードパーティサービスへの呼び出しなど、現実世界のシナリオを再現するのに役立つエンドユーザーテストを作成中です。

これらのテストを組み合わせることで、問題が繰り返されるのを防ぎ、別のバグや機能の作業中にバグが発生しないようにします。

変更のデプロイ - 変更をサーバーにプッシュする

開発サーバーと本番サーバーに変更をプッシュする継続的デリバリーソフトウェアを設定しています。

保護されたリリースブランチに変更がプッシュされると、そのブランチに対してビルドパイプラインが自動的にトリガーされます。 ビルドパイプラインは、アーティファクトを構築し、後で使用するためにコールドストレージに保管する責任があります。

実行が正常に完了すると、ビルドパイプラインは対応するリリースパイプラインをトリガーします。 リリースパイプラインは、ビルドアーティファクトを収集し、それらをサーバーに移動し、稼働させる責任があります。

ビルドとリリースのステータスは こちら からご確認いただけます。

ビルドをトリガー・テスト・デプロイする

現時点では、開発チームのメンバーのみが本番ブランチにプッシュできます。 production-* ブランチへの変更は、upstream への早送りマージによってのみ可能です。

[!NOTE] 今後、アクセス管理と透明性を向上させるために、プルリクエストを介してこのフローを改善します。

ステージングアプリケーションに変更をプッシュする

  1. リモートを正しく構成します。

    git remote -v
    

    結果:

    origin   git@github.com:raisedadead/freeCodeCamp.git (fetch)
    origin   git@github.com:raisedadead/freeCodeCamp.git (push)
    upstream git@github.com:freeCodeCamp/freeCodeCamp.git (fetch)
    upstream git@github.com:freeCodeCamp/freeCodeCamp.git (push)
    
  2. main ブランチが初期状態であり、アップストリームと同期していることを確認してください。

    git checkout main
    git fetch --all --prune
    git reset --hard upstream/main
    
  3. GitHub CI がアップストリームの main ブランチを渡していることを確認してください。

    継続的インテグレーション テストは、main ブランチに関して、緑色であり PASSING でなければなりません。 main ブランチコードを表示する際、コミットハッシュの横にある緑色のチェックマークをクリックします。

    GitHub Actionsでステータスを確認する (スクリーンショット)
    ![Check build status on GitHub Actions](https://raw.githubusercontent.com/freeCodeCamp/freeCodeCamp/main/docs/images/devops/github-actions.png)

    これに失敗した場合は、停止してエラーの確認をします。

  4. リポジトリをローカルにビルドできることを確認します。

    npm run clean-and-develop
    
  5. 早送りマージにより、変更を main から prod-staging に移行します。

    git checkout prod-staging
    git merge main
    git push upstream
    

    [!NOTE] 強制的にプッシュすることはできません。履歴を書き直した場合、これらのコマンドはエラーになります。

    エラーになったとしたら、誤った操作をしたかもしれませんので、やり直します。

上記手順では、prod-staging ブランチのビルドパイプラインで自動的に実行がトリガーされます。 ビルドが完了すると、アーティファクトは .zip ファイルとしてコールドストレージで保存され、後で取り出され使用されます。

接続されたビルドパイプラインから新たなアーティファクトが利用可能になると、リリースパイプラインが自動的にトリガーされます。 ステージングプラットフォームでは、このプロセスに手動での承認は含まれません。また、アーティファクトは クライアント CDN および API サーバーにプッシュされます。

本番アプリケーションに変更をプッシュする

プロセスはほとんどステージングプラットフォームと同じですが、いくつかの追加のチェックが行われます。 これは、何百人ものユーザーが常に使用している freeCodeCamp.org 上で何も壊さないようにするためです。

すべてがステージングプラットフォームで動作していることを確認しない限り、これらのコマンドを実行しないでください。 先に進む前に、ステージング上のテストを回避またはスキップしないでください。
  1. prod-staging ブランチが初期状態であり、アップストリームと同期していることを確認してください。

    git checkout prod-staging
    git fetch --all --prune
    git reset --hard upstream/prod-staging
    
  2. 早送りマージにより、変更を prod-staging から prod-current に移行します。

    git checkout prod-current
    git merge prod-staging
    git push upstream
    

    [!NOTE] 強制的にプッシュすることはできません。履歴を書き直した場合、これらのコマンドはエラーになります。

    エラーになったとしたら、誤った操作をしたかもしれませんので、やり直します。

上記手順では、prod-current ブランチのビルドパイプラインで自動的に実行がトリガーされます。 ビルドアーティファクトの準備が完了すると、リリースパイプラインで実行がトリガーされます。

スタッフアクションの追加手順

リリースの実行がトリガーされると、開発者スタッフチームのメンバーは自動的に手動介入メールを受け取ります。 彼らはリリース実行を 承認、または 拒否 することができます。

変更がうまく動作し、ステージングプラットフォームでテストされている場合は、承認することができます。 承認は、自動的に拒否される前に、リリースがトリガーされてから4時間以内に行われる必要があります。 拒否された実行が拒否された場合、スタッフは手動でリリース実行を再トリガーするか、リリースの次のサイクルを待つことになります。

スタッフ用:

ビルドの実行が完了したら、直接リンクについて E メールを確認するか、リリースダッシュボードにアクセス してください。

スタッフがリリースを承認すると、パイプラインは freeCodeCamp.org の本番用 CDN および API サーバーにその変更を反映させます。

ビルド、テスト、デプロイスのテータス

ここでは、コードベースの現在のテスト、ビルド、およびデプロイの状況を示します。

ブランチ 単体テスト 統合テスト ビルド & デプロイ
main Node.js CI Cypress E2E Tests -
prod-staging Node.js CI Cypress E2E Tests Azure Pipelines
prod-current Node.js CI Cypress E2E Tests Azure Pipelines
prod-next (試験的、予定) - - -

早期アクセスとベータテスト

皆さんがこれらのリリースを "パブリックベータテスト" モードでテストし、プラットフォームの今後の機能に早期アクセスできるようにします。 これらの機能 / 変更は、次の、ベータ、ステージング などと呼ばれます。

フィードバックや Issue 報告を通じた貢献は、復元力一貫性 および 安定性 のある freeCodeCamp.org 本番プラットフォームを構築するのに役立ちます。

見つけたバグの報告や、freeCodeCamp.orgをより良くする支援に感謝します。 素晴らしい皆さんです!

プラットフォームの今後のバージョンを特定する

現在、パブリックベータテストバージョンは次の場所で利用できます。

アプリケーション 言語 URL
学習 英語 https://www.freecodecamp.dev
スペイン語 https://www.freecodecamp.dev/espanol
中国語 https://chinese.freecodecamp.dev
ニュース 英語 https://www.freecodecamp.dev/news
フォーラム 英語 https://forum.freecodecamp.dev
中国語 https://chinese.freecodecamp.dev/forum
API - https://api.freecodecamp.dev

[!NOTE] ドメイン名は freeCodeCamp.org とは異なります。 これは、検索エンジンのインデックス作成を防止し、プラットフォームの通常ユーザーの混乱を避けるための、意図的なものです。

上記リストは、提供するアプリケーションを包括したものではありません。 また、リソースを節約するために、すべての言語バリエーションがステージングにデプロイされるわけではありません。

プラットフォームの現在のバージョンを特定する

プラットフォームの現在のバージョンは freeCodeCamp.org で常に利用できます。

開発者チームは、リリース変更時に、prod-stageing ブランチから prod-current への変更をマージします。 トップコミットは、サイト上で表示されるもののはずです。

状況セクションにあるデプロイログおよびビルドにアクセスして、デプロイされた正確なバージョンを確認できます。 あるいは、contributors チャットルーム で確認することもできます。

既知の制限

プラットフォームのベータ版を使用する場合、いくつかの既知の制限とトレードオフがあります。

  • これらのベータプラットフォーム上のデータ / 個人的な進捗は、保存されたり本番環境に移行されることはありません。

    ベータ版のユーザーは本番とは異なるアカウントを持つことになります。 ベータ版は本番と物理的に分離されたデータベースを使用します。 これにより、偶発的なデータ損失や変更を防ぐことができます。 開発チームは、必要に応じてこのベータ版のデータベースを削除する可能性があります。

  • ベータ版プラットフォームの稼働時間と信頼性については保証はありません。

    デプロイは頻繁に行われ、時には非常に速いペースで 1 日に複数回行われることになります。 その結果、ベータ版において、不測のダウンタイムが発生したり機能が壊れることがあります。

  • 修正を確認する手段として、このサイトに一般ユーザーを送らないでください。

    ベータサイトは、ローカルの開発とテストを強化するためのものでしたし、今もそうです。 それはこれから起こることを約束するものではありませんが、取り組まれていることを垣間見るものです。

  • サインインページが本番環境とは異なる場合があります。

    Auth0 上で freeCodeCamp 開発用のテストテナントを使用しているため、カスタムドメインを設定することはできません。 そのため、すべてのリダイレクトコールバックとログインページが https://freecodecamp-dev.auth0.com/ のようなデフォルトドメインに表示されます。 This does not affect the functionality and is as close to production as we can get.

Issue の報告とフィードバック

ディスカッションやバグ報告をする場合、新しい Issue を開いてください。

ご質問があれば、dev[at]freecodecamp.org にメールをご送信ください。 セキュリティ脆弱性は、公開トラッカーやフォーラムではなく、security[at]freecodecamp.org に報告する必要があります。

フライトマニュアル - サーバーメンテナンス

[!WARNING]

  1. ガイドは、freeCodeCamp スタッフのみ に適用されます。
  2. インストラクションは包括的なものではありませんので、ご注意ください。

スタッフの一員として、Azure、Digital Ocean などのクラウドサービスプロバイダーへのアクセスが許可されている可能性があります。

仮想マシン (VM) で作業するために使用できる便利なコマンドをいくつか紹介します。例えばメンテナンスの更新や一般的なハウスキーピングの実行です。

VM のリストを取得する

[!NOTE] 既に VM へ SSH アクセスできるかもしれませんが、クラウドポータルへのアクセスが許可されていない限り VMを一覧表示することはできません。

Azure

Azure CLI のインストール az: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli

(一回のみ) homebrew で macOS にインストールします。

brew install azure-cli

(一回のみ) ログインします。

az login

VM 名と P アドレスのリストを取得します。

az vm list-ip-addresses --output table

Digital Ocean

Digital Ocean CLI のインストール doctl: https://github.com/digitalocean/doctl#installing-doctl

(一回のみ) homebrew で macOS にインストールします。

brew install doctl

(一回のみ) ログインします。

認証とコンテキストの切り替え: https://github.com/digitalocean/doctl#authenticating-with-digitalocean

doctl auth init

VM 名と IP アドレスのリストを取得します。

doctl compute droplet list --format "ID,Name,PublicIPv4"

新しいリソースをスピンする

私たちは IaC 設定の作成に取り組んでいます。そして、その作業中は Azure ポータルまたは Azure CLI を使用して、新しい仮想マシンやその他のリソースをスピンさせることができます。

[!TIP] スピニングリソースの選択に関係なく、docker のインストールや SSH キーの追加など基本的なプロビジョニングを行うのに役立つ 便利な cloud-init 設定ファイル がいくつかあります。

VM を最新に保つ

アップデートとアップグレードを行うことで、VM を最新の状態に保つ必要があります。 これにより、仮想マシンが最新のセキュリティ修正でパッチされるようになります。

[!WARNING] これらのコマンドを実行する前に下記を実行します。

  • VM が完全にプロビジョニングされており、インストール後の手順が実行されていないことを確認してください。
  • アプリケーションを既に提供している VM 上で、パッケージを更新する場合は、アプリが停止 / 保存されていることを確認してください。 パッケージ更新により、ネットワーク帯域幅や、メモリ、CPU の使用率が急増し、 実行中のアプリケーションが停止します。

パッケージ情報を更新する

sudo apt update

インストール済みパッケージをアップグレードする

sudo apt upgrade -y

未使用のパッケージをクリーンアップする

sudo apt autoremove -y

Web サーバーでの作業 (プロキシ)

Web サーバーのために、負荷分散 (Azure Load Balancer) インスタンスを実行しています。 これらのサーバーは NGINX を実行しています。NGINX は、独自インフラストラクチャで実行される様々なアプリケーションから freeCodeCamp.org へと、トラフィックを中継するリバースプロキシとして使用されます。

NGINX 設定は このリポジトリ で確認できます。

最初のインストール

コードを使用して VM をプロビジョニング

  1. NGINX をインストールし、リポジトリから設定します。

    sudo su
    
    cd /var/www/html
    git clone https://github.com/freeCodeCamp/error-pages
    
    cd /etc/
    rm -rf nginx
    git clone https://github.com/freeCodeCamp/nginx-config nginx
    
    cd /etc/nginx
    
  2. Cloudflare のオリジン証明書とアップストリームアプリケーション設定をインストールします。

    安全なストレージから Cloudflare のオリジン証明書を取得し、 必要な場所にインストールします。

    または

    既存の証明書上に移動します。

    # Local
    scp -r username@source-server-public-ip:/etc/nginx/ssl ./
    scp -pr ./ssl username@target-server-public-ip:/tmp/
    
    # Remote
    rm -rf ./ssl
    mv /tmp/ssl ./
    

    アップストリーム設定を更新します。

    vi configs/upstreams.conf
    

    ソース / オリジンアプリケーションの IP アドレスを追加 / 更新します。

  3. ネットワーキングとファイアウォールを設定します。

    必要に応じて、イングレスオリジンアドレスに Azure ファイアウォールと ufw を設定します。

  4. VM をロードバランサーバックエンドプールに追加します。

    必要に応じて、ロードバランサーにルールを設定し追加します。 バランサーバックエンドプールをロードするために、VM を追加する必要があるかもしれません。

ログとモニタリング

  1. 以下のコマンドを使用して NGINX サービスのステータスを確認します。

    sudo systemctl status nginx
    
  2. サーバーのログとモニタリングは以下で行います。

    現行の基本的なモニタリングダッシュボードは、NGINX Amplify (https://amplify.nginx.com) です。 監視向上のため、より細かいメトリックに取り組んでいます。

インスタンスの更新 (メンテナンス)

NGINX インスタンスへの設定変更は、GitHub 上でメンテナンスされています。これらは、以下のように各インスタンスにデプロイされる必要があります。

  1. SSH でインスタンスに接続し、sudo と入力します。
sudo su
  1. 最新の設定コードを取得します。
cd /etc/nginx
git fetch --all --prune
git reset --hard origin/main
  1. 設定 with Signals をテストして再度読み込みます。
nginx -t
nginx -s reload

API インスタンスでの作業

  1. ノードバイナリのビルドツール (node-gyp) をインストールします。
sudo apt install build-essential

最初のインストール

コードを使用して VM をプロビジョニング

  1. ノード LTS をインストールします。

  2. Update npm and install PM2 and setup logrotate and startup on boot

    npm i -g npm@8
    npm i -g pm2
    pm2 install pm2-logrotate
    pm2 startup
    
  3. Clone freeCodeCamp, setup env and keys.

    git clone https://github.com/freeCodeCamp/freeCodeCamp.git
    cd freeCodeCamp
    git checkout prod-current # or any other branch to be deployed
    
  4. Create the .env from the secure credentials storage.

  5. Create the google-credentials.json from the secure credentials storage.

  6. Install dependencies

    npm ci
    
  7. Build the server

    npm run create:config && npm run build:curriculum && npm run build:server
    
  8. Start Instances

    cd api-server
    pm2 start ./lib/production-start.js -i max --max-memory-restart 600M --name org
    

Logging and Monitoring

pm2 logs
pm2 monit

Updating Instances (Maintenance)

Code changes need to be deployed to the API instances from time to time. It can be a rolling update or a manual update. The later is essential when changing dependencies or adding environment variables.

[!ATTENTION] The automated pipelines are not handling dependencies updates at the minute. We need to do a manual update before any deployment pipeline runs.

1. Manual Updates - Used for updating dependencies, env variables.

  1. Stop all instances
pm2 stop all
  1. Install dependencies
npm ci
  1. Build the server
npm run create:config && npm run build:curriculum && npm run build:server
  1. Start Instances
pm2 start all --update-env && pm2 logs

2. Rolling updates - Used for logical changes to code.

pm2 reload all --update-env && pm2 logs

[!NOTE] We are handling rolling updates to code, logic, via pipelines. You should not need to run these commands. These are here for documentation.

Work on Client Instances

  1. Install build tools for node binaries (node-gyp) etc.
sudo apt install build-essential

First Install

Provisioning VMs with the Code

  1. Install Node LTS.

  2. Update npm and install PM2 and setup logrotate and startup on boot

    npm i -g npm@8
    npm i -g pm2
    npm install -g serve
    pm2 install pm2-logrotate
    pm2 startup
    
  3. Clone client config, setup env and keys.

    git clone https://github.com/freeCodeCamp/client-config.git client
    cd client
    

    Start placeholder instances for the web client, these will be updated with artifacts from the Azure pipeline.

    Todo: This setup needs to move to S3 or Azure Blob storage

       echo "serve -c ../../serve.json www -p 50505" >> client-start-primary.sh
       chmod +x client-start-primary.sh
       pm2 delete client-primary
       pm2 start  ./client-start-primary.sh --name client-primary
       echo "serve -c ../../serve.json www -p 52525" >> client-start-secondary.sh
       chmod +x client-start-secondary.sh
       pm2 delete client-secondary
       pm2 start  ./client-start-secondary.sh --name client-secondary
    

Logging and Monitoring

pm2 logs
pm2 monit

Updating Instances (Maintenance)

Code changes need to be deployed to the API instances from time to time. It can be a rolling update or a manual update. The later is essential when changing dependencies or adding environment variables.

[!ATTENTION] The automated pipelines are not handling dependencies updates at the minute. We need to do a manual update before any deployment pipeline runs.

1. Manual Updates - Used for updating dependencies, env variables.

  1. Stop all instances

    pm2 stop all
    
  2. Install or update dependencies

  3. Start Instances

    pm2 start all --update-env && pm2 logs
    

2. Rolling updates - Used for logical changes to code.

pm2 reload all --update-env && pm2 logs

[!NOTE] We are handling rolling updates to code, logic, via pipelines. You should not need to run these commands. These are here for documentation.

Work on Chat Servers

Our chat servers are available with a HA configuration recommended in Rocket.Chat docs. The docker-compose file for this is available here.

We provision redundant NGINX instances which are themselves load balanced (Azure Load Balancer) in front of the Rocket.Chat cluster. The NGINX configuration file are available here.

First Install

Provisioning VMs with the Code

NGINX Cluster:

  1. Install NGINX and configure from repository.

    sudo su
    
    cd /var/www/html
    git clone https://github.com/freeCodeCamp/error-pages
    
    cd /etc/
    rm -rf nginx
    git clone https://github.com/freeCodeCamp/chat-nginx-config nginx
    
    cd /etc/nginx
    
  2. Install Cloudflare origin certificates and upstream application config.

    Get the Cloudflare origin certificates from the secure storage and install at required locations.

    OR

    Move over existing certificates:

    # Local
    scp -r username@source-server-public-ip:/etc/nginx/ssl ./
    scp -pr ./ssl username@target-server-public-ip:/tmp/
    
    # Remote
    rm -rf ./ssl
    mv /tmp/ssl ./
    

    Update Upstream Configurations:

    vi configs/upstreams.conf
    

    Add/update the source/origin application IP addresses.

  3. Setup networking and firewalls.

    Configure Azure firewalls and ufw as needed for ingress origin addresses.

  4. Add the VM to the load balancer backend pool.

    Configure and add rules to load balancer if needed. You may also need to add the VMs to load balancer backend pool if needed.

Docker Cluster:

  1. Install Docker and configure from the repository

    git clone https://github.com/freeCodeCamp/chat-config.git chat
    cd chat
    
  2. Configure the required environment variables and instance IP addresses.

  3. Run rocket-chat server

    docker-compose config
    docker-compose up -d
    

Logging and Monitoring

  1. Check status for NGINX service using the below command:

    sudo systemctl status nginx
    
  2. Check status for running docker instances with:

    docker ps
    

Updating Instances (Maintenance)

NGINX Cluster:

Config changes to our NGINX instances are maintained on GitHub, these should be deployed on each instance like so:

  1. SSH into the instance and enter sudo

    sudo su
    
  2. Get the latest config code.

    cd /etc/nginx
    git fetch --all --prune
    git reset --hard origin/main
    
  3. Test and reload the config with Signals.

    nginx -t
    nginx -s reload
    

Docker Cluster:

  1. SSH into the instance and navigate to the chat config path

    cd ~/chat
    
  2. Get the latest config code.

    git fetch --all --prune
    git reset --hard origin/main
    
  3. Pull down the latest docker image for Rocket.Chat

    docker-compose pull
    
  4. Update the running instances

    docker-compose up -d
    
  5. Validate the instances are up

    docker ps
    
  6. Cleanup extraneous resources

    docker system prune --volumes
    

    Output:

    WARNING! This will remove:
      - all stopped containers
      - all networks not used by at least one container
      - all volumes not used by at least one container
      - all dangling images
      - all dangling build cache
    
    Are you sure you want to continue? [y/N] y
    

    Select yes (y) to remove everything that is not in use. This will remove all stopped containers, all networks and volumes not used by at least one container, and all dangling images and build caches.

Work on Contributor Tools

Deploy updates

ssh into the VM (hosted on Digital Ocean).

cd tools
git pull origin master
npm ci
npm run build
pm2 restart contribute-app

Updating Node.js versions on VMs

List currently installed node & npm versions

nvm -v
node -v
npm -v

nvm ls

Install the latest Node.js LTS, and reinstall any global packages

nvm install --lts --reinstall-packages-from=default

Verify installed packages

npm ls -g --depth=0

Alias the default Node.js version to the current LTS (pinned to latest major version)

nvm alias default 16

(Optional) Uninstall old versions

nvm uninstall <version>

[!ATTENTION] For client applications, the shell script can't be resurrected between Node.js versions with pm2 resurrect. Deploy processes from scratch instead. This should become nicer when we move to a docker based setup.

If using PM2 for processes you would also need to bring up the applications and save the process list for automatic recovery on restarts.

Get the uninstall instructions/commands with the unstartup command and use the output to remove the systemctl services

pm2 unstartup

Get the install instructions/commands with the startup command and use the output to add the systemctl services

pm2 startup

Quick commands for PM2 to list, resurrect saved processes, etc.

pm2 ls
pm2 resurrect
pm2 save
pm2 logs

Installing and Updating Azure Pipeline Agents

See: https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/v2-linux?view=azure-devops and follow the instructions to stop, remove and reinstall agents. Broadly you can follow the steps listed here.

You would need a PAT, that you can grab from here: https://dev.azure.com/freeCodeCamp-org/_usersSettings/tokens

Installing agents on Deployment targets

Navigate to Azure Devops and register the agent from scratch in the requisite deployment groups.

[!NOTE] You should run the scripts in the home directory, and make sure no other azagent directory exists.

Updating agents

Currently updating agents requires them to be removed and reconfigured. This is required for them to correctly pick up PATH values and other system environment variables. We need to do this for instance updating Node.js on our deployment target VMs.

  1. Navigate and check status of the service

    cd ~/azagent
    sudo ./svc.sh status
    
  2. Stop the service

    sudo ./svc.sh stop
    
  3. Uninstall the service

    sudo ./svc.sh uninstall
    
  4. Remove the agent from the pipeline pool

    ./config.sh remove
    
  5. Remove the config files

    cd ~
    rm -rf ~/azagent
    

Once You have completed the steps above, you can repeat the same steps as installing the agent.

Flight Manual - Email Blast

We use a CLI tool to send out the weekly newsletter. To spin this up and begin the process:

  1. Sign in to DigitalOcean, and spin up new droplets under the Sendgrid project. Use the Ubuntu Sendgrid snapshot with the most recent date. This comes pre-loaded with the CLI tool and the script to fetch emails from the database. With the current volume, three droplets are sufficient to send the emails in a timely manner.

  2. Set up the script to fetch the email list.

    cd /home/freecodecamp/scripts/emails
    cp sample.env .env
    

    You will need to replace the placeholder values in the .env file with your credentials.

  3. Run the script.

    node get-emails.js emails.csv
    

    This will save the email list in an emails.csv file.

  4. Break the emails down into multiple files, depending on the number of droplets you need. This is easiest to do by using scp to pull the email list locally and using your preferred text editor to split them into multiple files. Each file will need the email,unsubscribeId header.

  5. Switch to the CLI directory with cd /home/sendgrid-email-blast and configure the tool per the documentation.

  6. Run the tool to send the emails, following the usage documentation.

  7. When the email blast is complete, verify that no emails have failed before destroying the droplets.

Flight Manual - Adding news instances for new languages

Theme Changes

We use a custom theme for our news publication. Adding the following changes to the theme enables the addition of new languages.

  1. Include an else if statement for the new ISO language code in setup-locale.js
  2. Create an initial config folder by duplicating the assets/config/en folder and changing its name to the new language code. (en —> es for Spanish)
  3. Inside the new language folder, change the variable names in main.js and footer.js to the relevant language short code (enMain —> esMain for Spanish)
  4. Duplicate the locales/en.json and rename it to the new language code.
  5. In partials/i18n.hbs, add scripts for the newly created config files.
  6. Add the related language day.js script from cdnjs to the freeCodeCamp CDN

Ghost Dashboard Changes

Update the publication assets by going to the Ghost dashboard > settings > general and uploading the publications's icon, logo, and cover.