Ruby: 高度な使用法

Rubyデプロイメントをさらに進める

👋 Stackheroのドキュメントへようこそ!

Stackheroは、数多くの利点を提供する、すぐに使えるRubyクラウドソリューションを提供しています。

  • シンプルなgit pushでアプリケーションを数秒でデプロイ
  • 独自のドメイン名を使用し、HTTPS証明書の自動設定による強化されたセキュリティを享受。
  • 自動バックアップワンクリック更新、そしてシンプルで透明性があり、予測可能な価格設定で安心を提供。
  • プライベートで専用のVMによる最適なパフォーマンスと強固なセキュリティを実現。

時間を節約し、生活を簡素化:StackheroのRubyクラウドホスティングソリューションを試すのに5分しかかかりません

これまで、mainブランチをプッシュしてRubyアプリケーションをデプロイしてきました。

git push stackhero main

別のブランチをデプロイしたい場合は、このコマンドを使用します。<BRANCH>をデプロイしたいブランチ名に置き換えてください。

git push stackhero <BRANCH>:main

例えば、productionという名前のブランチをデプロイするには、次のように実行します。

git push stackhero production:main

場合によっては、ブランチではなくタグをデプロイしたいことがあります。その場合は、次のコマンドを実行します。<TAG>をデプロイしたいタグに置き換えてください。

git push stackhero '<TAG>^{}:main'

例えば、タグv1.0.0をデプロイするには、次のように実行します。

git push stackhero 'v1.0.0^{}:main'

^{}構文は、タグが指すコミットを参照するために使用されます。

ブランチやタグに加えて、特定のコミットをデプロイすることもできます。以下のコマンドで<COMMIT_HASH>を目的のコミットのハッシュに置き換えてください。

git push -f stackhero <COMMIT_HASH>:main

例えば、ハッシュabcdeのコミットをデプロイするには、次のように実行します。

git push -f stackhero abcde:main

本番デプロイメントが期待通りに動作しない場合、古いコミットをデプロイすることでロールバックできます。まず、以下のコマンドを使用してコミット履歴を表示します。

git log

このコマンドは、リポジトリ内の各コミットの日付、コミットハッシュ、説明を表示します。例えば、次のような出力が表示されるかもしれません。

commit cccc8b3ebdccb9abc1926ef49ee589dae5c5fe06 (HEAD -> main, stackhero/main)
Author: Developer
Date:   Fri Apr 28 09:36:18 +0000

    Break the code

commit bbbb622301772072c3d82f3cc0d91e29e6e84901
Author: Developer
Date:   Wed Apr 26 12:49:28 +0000

    Update the code

commit aaaa1d8b06535b413e0df8298ccf52339dfef3ff
Author: Developer
Date:   Wed Apr 26 12:44:50 +0000

    Improve the code

メッセージ"Break the code"(ハッシュcccc...)のコミットが本番で実行されている場合、前のコミット"Update the code"(ハッシュbbbb...)にロールバックするには、次のように実行します。

git push -f stackhero bbbb622301772072c3d82f3cc0d91e29e6e84901:main

壊れたコードのデプロイを防ぎ、本番の安定性を高めるために、"staging"環境を持つことを強くお勧めします。

"development"環境と"production"環境の間に位置する"staging"環境は、本番環境のほぼ正確なレプリカを提供します。これにより、コードをテストし、本番にデプロイする前にその品質を確認できます。

ステージング環境を使用することで、コードの機能とパフォーマンスに自信を持ち、より信頼性の高い本番デプロイメントを確保できます。

このタイプの環境については、後のドキュメントで説明します。

ステージング環境は、開発および本番環境と並行して使用するためのベストプラクティスです。本番環境を再現し、更新や変更を本番に反映する前にテストできます。

ステージング環境は、本番環境を密接に反映する必要があります。

ただし、ステージング環境は本番データベースのクローンを使用し、本番データベース自体を使用しないようにしてください。

Rubyサービスがデータベースや他のサービスにリンクされている場合、新しい<Project> - Stagingスタックでそれらを再作成してください。

Stackheroでステージング環境を設定するには、次の手順に従ってください。

  1. Stackheroダッシュボードで、既存のスタックを<Project>から<Project> - Productionに名前を変更します。例えば、プロジェクトがChat Botと呼ばれる場合、スタックをChat Bot - Productionに名前を変更します。
  2. <Project> - Stagingという新しいスタックを作成します。前の例を使用すると、これはChat Bot - Stagingになります。
  3. ステージングスタック内でRubyサービスを開始します。
  4. git remoteコマンドの値を取得し、ステージング環境へのデプロイセクションの指示に従います。

これらの手順に従うことで、更新が本番に到達する前にテストと検証を行うための適切に構成されたステージング環境を得ることができます。

ステージング本番などの別々の環境を管理することは強く推奨されます。ステージング環境の設定で説明されているように、異なるGitリモートを使用して各環境にデプロイできます。

まず、現在のリモートリポジトリの名前を変更します。例えば、リモート"stackhero"を"stackhero-production"に次のコマンドで名前を変更します。

git remote rename stackhero stackhero-production

次に、ステージング環境用の新しいRubyサービスを作成します。提供された"git remote add"コマンドを使用し、次のように変更します(<XXXXXX>をサービスのドメインに置き換えます)。

  • 元のコマンド:

    git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git
    
  • 修正後のコマンド:

    git remote add stackhero-staging ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git
    

これで、次のコマンドを使用してステージングにデプロイできます。

git push stackhero-staging main

または、次のコマンドで本番にデプロイします。

git push stackhero-production main

デプロイプロセスをさらに簡素化するために、改良版Makefileの使用を検討してください。

この改良されたMakefileを使用すると、make deploy-productionまたはmake deploy-stagingを使用して簡単に本番またはステージングにデプロイできます。

以下は、一般的なタスクのための複数のルールをサポートする改良されたMakefileです。

  • make dev(または単にmake):開発モードでアプリケーションを開始します。
  • make deploystackheroという名前のリモートにアプリケーションをデプロイします(Stackheroインスタンスが1つだけの場合に最適)。
  • make deploy-productionstackhero-productionという名前のリモートにアプリケーションをデプロイします。
  • make deploy-stagingstackhero-stagingという名前のリモートにアプリケーションをデプロイします。

このMakefileは、コードがすでにデプロイされている場合に"Everything up-to-date"エラーを回避するように設計されています。

以下の内容を新しいMakefileにコピーして貼り付けてください。

# 引数なしで"make"を呼び出したときにデフォルトで実行されるルール
.DEFAULT_GOAL := dev


# Stackhero for Rubyは、インスタンスで"run"ルールを実行します。
# これは、本番およびステージングプラットフォームで実行するコマンドです。
run:
  rake assets:precompile
  rake db:migrate RAILS_ENV=production
  RAILS_ENV=production bundle exec puma -C config/puma.rb


# 開発環境で実行するコマンド
dev:
  RAILS_ENV=development rails server -b 0.0.0.0


# "deploy"ルールは、"stackhero"インスタンスにデプロイします。
# インスタンスが1つだけの場合に適しています。
deploy:
  @$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero DEPLOY_BRANCH=main


# "deploy-*"ルールは、"stackhero-*"インスタンスにデプロイします。
# 例えば、"make deploy-production"を実行して"stackhero-production"にデプロイするか、
# "make deploy-staging"を実行して"stackhero-staging"にデプロイします。
deploy-%:
  @$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero-$* DEPLOY_BRANCH=main


# 内部デプロイルール。変更しないでください。
deploy-script:
  @echo "ブランチ\"${DEPLOY_BRANCH}\"を\"${DEPLOY_REMOTE}\"にデプロイ中..."
  @echo

  @if [ -n "$$(git status --porcelain)" ]; then \
    echo "コミットされていない変更があるため、デプロイできません:"; \
    echo "\e[0m"; \
    git status -s; \
    echo ""; \
    echo "\e[0;31m"; \
    echo "このコマンドを使用して変更をコミットできます:"; \
    echo "git add -A . && git commit -m \"Your message\""; \
    echo "\e[0m"; \
    exit 1; \
  fi

  @git push --dry-run ${DEPLOY_REMOTE} ${DEPLOY_BRANCH} 2>&1 | grep -q -F "Everything up-to-date"; \
  EXIT_CODE=$$?; \
  if [ $$EXIT_CODE -eq 0 ]; then \
    echo -n "新しいものはありません... 強制デプロイしますか(これにより新しいコミットが作成されます)? (y/N) "; \
    read answer && \
    case $$answer in \
      y|Y|yes|YES) \
      git commit --allow-empty -m "Force update for deploy purpose to \"${DEPLOY_REMOTE}\"" ; \
      ;; \
      *) \
      echo "デプロイするものはありません!"; \
      exit 1; \
      ;; \
    esac \
  fi

  git push ${DEPLOY_REMOTE} ${DEPLOY_BRANCH}

データベースやサードパーティサービスのトークンやパスワードなどのシークレットを管理する必要がある時が来ます。これらのシークレットを安全に保管することが重要です。リポジトリやコードにシークレットを直接埋め込むことは、重大なセキュリティリスクをもたらすため避けてください。

環境変数には2つの大きな利点があります。

  1. シークレットがGitリポジトリに保存されないため、ソースコードにアクセスされた場合のリスクが軽減されます。
  2. 異なる環境で異なる資格情報を使用できます。例えば、本番環境では本番データベースに接続し、開発中は開発データベースを使用します。

開発用には、プロジェクトのルートに.envファイルを作成します。このファイルはGitから除外され、コミットされることはありません。dotenv gemを使用して.envファイルを自動的に読み込みます。

まず、dotenv-rails gemをGemfileに追加します。

# Gemfile
gem 'dotenv-rails', groups: [:development, :test]

次に、gemをインストールします。

bundle install

次に、プロジェクトのルートに.envファイルを作成し、変数を追加します。

RAILS_ENV="development"
DATABASE_PASSWORD="secretPassword"
THIRD_API_PRIVATE_KEY="secretKey"
# ...

最後に、.envファイルがGitで無視されることを確認します。

echo '.env*' >> .gitignore

ステージングおよび本番用には、.envファイルは安全でも実用的でもありません。Gitリポジトリに保存できないためです。代わりに、StackheroはRubyサービスの設定で環境変数を直接管理するための安全なソリューションを提供します。

これらの変数は、StackheroダッシュボードでRubyサービスを選択し、「設定」ボタンをクリックして設定できます。

Rubyでは、ENVを使用して環境変数に簡単にアクセスできます。例えば、DATABASE_PASSWORDを取得するには、次のように使用します。

ENV['DATABASE_PASSWORD'] # => 'secretPassword'

環境変数を使用してRabbitMQサーバーに接続する例を以下に示します。

require 'bunny'

class RabbitMQClient
  def initialize
    @connection = Bunny.new(hostname: ENV['RABBITMQ_HOST'],
                            username: ENV['RABBITMQ_USERNAME'],
                            password: ENV['RABBITMQ_PASSWORD'])
    @connection.start
  end

  def publish(queue_name, message)
    channel = @connection.create_channel
    queue = channel.queue(queue_name)
    channel.default_exchange.publish(message, routing_key: queue.name)
  end

  def close
    @connection.close
  end
end

開発プラットフォームでは、.envファイルに次のような内容が含まれるかもしれません。

RABBITMQ_HOST='127.0.0.1'
RABBITMQ_USERNAME='developmentUser'
RABBITMQ_PASSWORD='developmentPassword'

本番およびステージング用には、StackheroダッシュボードのRubyサービス設定で環境変数を以下のように定義します。

RABBITMQ_HOST='<XXXXXX>.stackhero-network.com'
RABBITMQ_USERNAME='production'
RABBITMQ_PASSWORD='secretProductionPassword'

Rubyアプリケーションは、通常、ポート80(HTTP)および443(HTTPS)でHTTPプロトコルを使用します。追加のポートや異なるプロトコル(TCPまたはUDP)が必要な場合は、StackheroダッシュボードでRubyサービスの「ポートリダイレクション」設定を構成します。

公開されるエントリーポート、Rubyサービス内で開かれる宛先ポート、およびプロトコル(TCPまたはUDP)を指定する必要があります。

ユーザーの写真やドキュメントなどのファイルを保存するには、オブジェクトストレージソリューションを使用することを強くお勧めします。オブジェクトストレージは、複数のサービスやインスタンス間でファイルを共有でき、ストレージ層をコードから分離します。これはベストプラクティスとされています。

MinIOは、Amazon S3プロトコルと互換性があり、簡単で高速かつ強力なソリューションとして推奨されます。

ローカルファイルストレージを選択する場合は、Rubyインスタンスに提供される永続ストレージを使用できます。このローカルストレージは、ディレクトリ/persistent/storage/の下にあります。

ただし、ローカルファイルストレージは、長期的なスケーラビリティと信頼性のためのベストプラクティスではないため、一般的には推奨されません。

警告:データを/persistent/storage/フォルダの外に保存しないでください!

永続ストレージフォルダ以外の場所にデータを保存すると、インスタンスが再起動、更新、または新しいコードをプッシュしたときにデータが失われる可能性があります。

macOSを使用している場合、コードをプッシュするたびにSSHプライベートキーのパスワードを入力するのが不便に感じるかもしれません。セキュリティは重要ですが、Appleのキーチェーンにパスワードを安全に保存することで利便性を向上させることができます。

SSHプライベートキーのパスワードを削除するのは魅力的かもしれませんが、これは推奨されません。

代わりに、次のコマンドを使用して、id_ed25519という名前のキーのパスワードをキーチェーンに保存します。

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

このコマンドを実行した後、キーのパスワードを再度求められることはありません。RSAキーを使用している場合は、id_ed25519id_rsaに置き換えて次のようにします。

ssh-add --apple-use-keychain ~/.ssh/id_rsa