web-dev-qa-db-ja.com

GemfileなしでDockerfileにgemをインストールする

私のチームはDockerfileからRailsアプリケーションをホストしています。ビルドが実際に遅くなっている遅いgemがいくつかあります(私はyou grpcを見ています。??? ?)

GemfileをDockerfileにコピーする前にいくつかのgemをインストールすることは可能ですか?これにより、Dockerがそれらのビルドステップをキャッシュできるようになるため、Gemfileが変更されるたびに遅いgemを再インストールする必要はありません。

私はこれを試しましたが、bundle installはまだgrpcsasscnokogiriをインストールしています。

RUN gem install grpc --version 1.28.0
RUN gem install sassc --version 2.2.1
RUN gem install nokogiri --version 1.10.9

WORKDIR /app

ADD Gemfile Gemfile.lock .Ruby-version /app/
RUN bundle install
4
LandonSchropp

オプションバンドルのインストール--deploymentまたは--pathを使用して、gemsをインストールできるフォルダーを指定できます(この目的のためにのみコンテナーを構築し、そのフォルダーをdocker外にコピーします)。次に、このディレクトリをコンテナ内のボリュームとしてマッピングし、マッピングが完了した後でバンドルインストールを実行します...または単にフォルダをコピーします

# outside actual image

bundle install --path=vendor/cache

# actual docker image
COPY . /app
COPY vendor/cache /app/vendor/cache
COPY .bundle /app/.bundle 

WORKDIR /app

RUN bundle install --path=vendor/cache

--path = vendor/cacheを指定したコマンドは、次のようにバンドル構成を生成します。

---
BUNDLE_DEPLOYMENT: "true"
BUNDLE_PATH: "vendor/cache"

コンパイルされた拡張機能のgemsバージョンがGemfileで変更されない限り、それらを再インストールしないでください。

ベンダー/キャッシュフォルダーをソースファイルにコミットしないようにするには、どこかにホストし、開発者にダウンロードしてもらうことができます。このフォルダをどこに残して、どのように画像にコピーするかは、かなり自由度の高い問題であり、何かを推奨するには、セットアップに関する詳細情報が必要です。アプリを実際にどこで本番環境にデプロイしていますか?

例:

ネイティブ拡張を備えたAWSラムダgemには問題があります。OSシステム内にインストールすることはできますが、ラムダ環境と互換性がありません。

機能するgemバンドルを作成する方法は、次のとおりです。

1-ラムダと互換性のある方法でネイティブ拡張を使用してgemをインストールするコンテナーを使用します。

docker run --rm -v "$PWD":/var/task lambci/lambda:build-Ruby2.7 bundle install --deployment

2-次に、別のコンテナでGEMSをボリュームとしてマップするか、コピーして、アプリケーションを実行します

docker run --rm --env-file=.env -v $PWD:/var/task:ro,delegated lambci/lambda:Ruby2.7 send.lambda_handler

ここでは、アプリケーションに対して同様のことを行うことをお勧めします。1つのイメージを使用してプラットフォームの宝石を構築し、次に別のイメージを使用してアプリケーションを実行し、これらの宝石をアプリケーションに渡します。 これら2つのイメージが同じOSである限り、gemは互換性があります。

これと同様の設定が、Docker以外のデプロイメントパイプラインで私のチームに機能しており、新しいバージョンをプッシュする前にgemをプリインストールし、そこからgemを取得するためにバンドルをセットアップします。

0
cesartalves