- 投稿日:2022-04-02T21:23:28+09:00
Proxy環境下のWSL2でDockerを動かす
企業によっては社外リソースへのアクセスはプロキシサーバー経由という決まりがあり,開発環境の構築に苦労されている方も少なくないかと思います. 今やWSL2やDockerはWindows PCで開発する上で欠かせないものとなっており,開発メンバーにも設定をお願いするのですが,プロキシに阻まれ上手くいかないといった場面に遭遇することが中々減らないの悩みの種だったりします. プロキシ設定に関する記事はQiitaの中にも数多くあるのですが,手順通りに進めても上手くいかない,別のトラブルに遭遇して解決方法を更に探さないといけないことがあったため, 私の環境で上手くいった手順を1つの記事としてまとめてみました. WSL2のインストール Microsoftのページに日本語で手順が記載されているため, この記事では手順の詳細は書きません.Windowsのバージョンによって手順が異なることもあって余計な混乱の元になるかと思います. 皆さんのPCのWindowsのバージョンを確認し, 対応する手順を公式ページで確認することが一番良いと思います. 少ないとは思いますが, Microsoft Storeへのアクセスも禁止されているケースもあるでしょう. その場合はWindows Serverへのインストールの手順でWSLを入れることができます. 以前の私の環境では以前このような状況に会っていて,これで無理やりデスクトップPCにWSLを入れていました. WSL2のプロキシ設定 まずはaptやcurlといった基本的なコマンドのプロキシ認証を突破するため, .bashrcに次の項目を追記します. ~/.bashrc export HTTP_PROXY=http://<ユーザー名>:<パスワード>@proxysrv:port/ export HTTPS_PROXY=${HTTP_PROXY} ユーザー名, パスワード, propxysrv, portの部分は皆さんの環境に合わせて置き換えてください.私が所属する会社ではHTTP_PROXY, HTTPS_PROXYどちらも同じ設定にする必要があるため上記のような書き方となっています.間違ってhttps://...と書き始めてしまう人がいたのでこのような記述を推奨しています. また,ユーザー名, パスワードが不要なケースもあると思います.その時はhttp://<ユーザー名>:<パスワード>@proxysrv:port/をhttp://proxysrv:port/と置き換えてください. 設定ができたら次のコマンドを実行して, .bashrcのプロキシ設定を読み込みましょう. source ~/.bashrc 上手くいっているか心配な場合はecho $HTTP_PROXYで確認しましょう. これでDockerをインストールする準備が整いました. Dockerのインストール 基本的には公式ドキュメント通りに進めれば良いのですが, sudoで外部リソースにアクセスする場合は現在の環境変数を保持してコマンドを実行する-Eオプションをつける必要があります.そのため実行するコマンドには若干の差異が出てきます. まずはDockerのインストールに必要なパッケージを取得します. $ sudo -E apt update $ sudo -E apt install \ ca-certificates \ curl \ gnupg \ lsb-release 次にDockerの公式GPGキーを追加します. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg aptでDockerをインストールするため, アクセスするリポジトリを追加します. echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 最後にDockerエンジンをインストールします. $ sudo -E apt update $ sudo -E apt install docker-ce docker-ce-cli containerd.io バージョン確認を行い, 以下のように表示されればインストール成功です. $ sudo docker --version Docker version 20.10.14, build a224086 sudoなしでのDocker実行設定 DockerデーモンはUnixソケットに紐づいているため, dockerコマンドを実行するときはsudoを基本的につける必要があります. sudoをつけずにdockerコマンドを実行したい場合は以下のコマンドを実行しましょう. $ sudo groupadd docker $ sudo usermod -aG docker $USER この後の手順は上記のコマンドを実行したものとして記述しています. 設定しなくても残りの設定は進めることはできますが,dockerコマンドの実行は適時読み替えてください. Dockerのプロキシ設定 Dockerクライアントのプロキシ設定 ~/.docker/config.jsonを作成し, .bashrcと同じプロキシ設定を記述しましょう. ~/.docker/config.json { "proxies": { "default": { "httpProxy": "http://<ユーザー名>:<パスワード>@proxysrv:port/", "httpsProxy": "http://<ユーザー名>:<パスワード>@proxysrv:port/", } } } Dockerクライアントのプロキシ設定 /etc/systemd/system/docker.service.d/override.confファイルを作成し, こちらも .bashrcと同じプロキシ設定を記入します. /etc/systemd/system/docker.service.d/override.conf [Service] Environment = 'http://<ユーザー名>:<パスワード>@proxysrv:port/' Environment = 'http://<ユーザー名>:<パスワード>@proxysrv:port/' sudo systemctl edit dockerで記入するという方法もあるのですが, WSLで実行すると以下のようなエラーが出てしまいます. $ sudo systemctl edit docker System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down systemdがPID1で動作していないというエラーなのですが,これはWSL特有の問題となっており, systemctlコマンドが使えないだけでなく, dockerにプロキシ設定が反映されないことに繋がっています. 私の環境ではserviceコマンドを使ってdockerを起動してもプロキシ設定が反映されず, genieというパッケージを使うことで解決を図りました. ここではgenieの詳細については触れませんが, 興味があればGitHubリポジトリのREADME.mdやWikiを覗いてみてください. genieのインストール こちらもDocker同様, 公式ドキュメントの手順をベースにsudo使用時の違いに気を付けながらコマンドを実行していきます. 公式ドキュメントでは最初にlsb-releaseのインストールが必要となっていますが, Dockerインストール時にすでに入っているので作業は不要です. まずは次のコマンドを使ってaptがアクセスするリポジトリを追加します. ここではsudo -E -sを実行し, 現在の環境変数を使用しつつrootユーザーへと切り替えてから実行してください.(確認が面倒で私はこのような手順で実行してしまいました) wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg chmod a+r /etc/apt/trusted.gpg.d/wsl-transdebian.gpg cat << EOF > /etc/apt/sources.list.d/wsl-transdebian.list deb https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main EOF apt update ここからは元のユーザーで実行しています. aptコマンドでgenieをインストールしましょう. sudo -E apt update sudo -E apt install -y systemd-genie インストールが成功していれば下記のようにバージョンが確認できます. $ genie --version genie 2.3 genieコマンド実行時には起動までに時間がかかります. そこで/etc/genie.iniを編集し, systemd-timoutを書き換えます(この場合は240秒から10秒へと変更). /etc/genie.ini [genie] #systemd-timeout=240 systemd-timeout=10 clone-env=WSL_DISTRO_NAME,WSL_INTEROP,WSLENV,DISPLAY,WAYLAND_DISPLAY,PULSE_SERVER secure-path=/lib/systemd:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin clone-path=false target-warning=true update-hostname=true update-hostname-suffix=-wsl resolved-stub=false genieの実行に時間がかかるのは, 1つ以上のサービスが正常に起動しなかったことを意味するのですが,今回の内容からは話がそれてしまうのでここでは深く入り込みません. とにかく,これでProxy環境下でDockerを実行する準備は整いました. Proxy環境下でDockerの動作手順 以下のコマンドでgenieを実行します. genie -s 初回は起動に時間がかかるので, 気長に待ちましょう. また,警告メッセージがいくつか出ますが, Dockerを動かすことには支障がないので無視してもらって大丈夫です. 起動に成功すると以下のように表示が切り替わります. username@hostname:~$ #genie 実行前 username@hostname-wsl:~$ #genie 実行後 次にdockerを起動し, プロキシ設定が反映されているか確認しましょう. $ sudo service docker start $ docker info (略) HTTP Proxy: http://xxxxx:xxxxx@proxysrv:port HTTPS Proxy: http://xxxxx:xxxxx@proxysrv:port (略) 最後にdockerイメージを取得して実行できるか確認しましょう $ docker run hello-world genieを実行してからの動作がおかしいと感じた場合は, Windows側から一度WSLを止めてから再度実行すると良いと思います. wsl --shutdown 参考URL WSLのインストール UbuntuでのDockerエンジンのインストール Dockerエンジンインストール後の設定 プロキシサーバーを使用するためのDockerの設定 genieのGitHubリポジトリ genieのインストール準備
- 投稿日:2022-04-02T19:30:08+09:00
[Terraform+Docker(+NewRelic)]環境変数のおすすめ設定方法
この記事を3行で ①Gitに載せられないセンシティブな環境変数(API KEYとか)はローカルで設定しコンテナに渡す設定にする ②Gitに載せられるような環境変数は *.tfvars ファイルに記載 ③各環境ごとのディレクトリを作り、そのディレクトリでTerraformコマンドを叩くことで同一ソースを複数環境でデプロイしよう 前提 次の過去記事で構築した環境を前提としています Terraform+Docker 環境構築 - Qiita NewRelicをTerraformでIaC(Infrastructure as Code)化するプロジェクトを想定しています 環境 macOS Big Sur v11.6.1(Intel) Docker for Mac v4.3.1 Docker v20.10.11 docker-compose v1.29.2 本題 ディレクトリ構成 ---- terraform │ └ src │ │ └ environment │ │ │ └ prod │ │ │ │ └ prod.tf │ │ │ └ dev │ │ │ └ dev.tf │ │ └ main │ │ │ └ main.tf │ │ │ └ その他もろもろ // Terraform関連ソース(docker-composeでマウントする) │ └ home │ │ └ entrypoint.sh // TerraformコンテナのENTRYPOINTに指定するシェルコマンド │ └ root │ │ └ .bashrc // bashのエイリアスなどをここに記載 │ └ Dockerfile └ docker-compose.yaml ①Gitに載せられないセンシティブな環境変数(API KEYとか)はローカルで設定しコンテナに渡す設定にする ここでの環境変数は環境間で変更する必要はない想定で話を進めます 変更の必要がある場合、この章に記載されているやり方でローカルの環境変数を変更した上で各環境のコンテナを立ち上げる必要があるかと思います 上でも挙げた、下記の過去記事に記載がありますが、改めて要点を記載しておきます Terraform+Docker 環境構築 - Qiita docker-compose.tml environmentでローカルで設定された環境変数をコンテナ環境内に反映させる docker-compose.tml version: "3.8" services: terraform: container_name: tf build: ./terraform environment: // コンテナ内の環境変数を指定する => 導入するプロバイダーや求める環境次第 - NEW_RELIC_API_KEY=${NEW_RELIC_API_KEY} - NEW_RELIC_ACCOUNT_ID=${NEW_RELIC_ACCOUNT_ID} - NEW_RELIC_REGION=US volumes: - ./terraform/src:/terraform/src ローカルでの環境変数設定 CLIで設定する場合 $ NEW_RELIC_API_KEY=xxxx-xxxxxxxxxxxxxxxxxxxxxxx \ && echo ${NEW_RELIC_API_KEY} xxxx-xxxxxxxxxxxxxxxxxxxxxxx .zshenvで設定する場合 ~/.zshenv export NEW_RELIC_API_KEY=xxxx-xxxxxxxxxxxxxxxxxxxxxxx ※ターミナルを開き直し、正しく環境変数が設定されていることを確認すること echo ${NEW_RELIC_API_KEY} xxxx-xxxxxxxxxxxxxxxxxxxxxxx ②Gitに載せられるような環境変数は *.tfvars ファイルに記載 ここについては、実際のTerraform開発時の流れにのって紹介していきます terraform/home/entrypoint.sh (いきなり蛇足ですが、ここでterraform initしておくといい感じなので載せておきます) entrypoint.sh #!/bin/bash echo -e '\n\n//==========================================='; echo -e '// START_[$ terraform init(prod)]'; echo -e '//==========================================='; cd terraform/src/environment/prod; terraform init; cd ../../../.. echo -e '\n\n//==========================================='; echo -e '// START_[$ terraform init(stg2)]'; echo -e '//==========================================='; cd terraform/src/environment/stg2; terraform init; cd ../../../.. echo -e '\n\n//==========================================='; echo -e '// SHOW_environment'; echo -e '//==========================================='; echo '$NEW_RELIC_API_KEY=' $NEW_RELIC_API_KEY; echo '$NEW_RELIC_REGION=' $NEW_RELIC_REGION; echo '$NEW_RELIC_ACCOUNT_ID=' $NEW_RELIC_ACCOUNT_ID; tail -f /dev/null DockerfileのENTRYPOINTに指定しているファイルです (今回の構成に合わせて書き換えてますが、仕組みなどについてはこれも過去記事を参照してください) やっていること コンテナ起動時、各環境でterraform initコマンドを叩いている ローカルで定義した環境変数をコンテナに反映している(docker-compose.ymlに記載)ので、正常に反映されているかチェックしている terraform/root/.bashrc .bashrc alias ll='ls -la --color' # これは便利なのでおまけ alias tf='terraform' # これは便利なのでおまけ # plan alias plan:dev="cd /terraform/src/environment/dev && terraform plan -var-file ./dev.tfvars && cd ../../../.." alias plan:prod="cd /terraform/src/environment/prod && terraform plan -var-file ./prod.tfvars && cd ../../../.." # apply alias apply:dev="cd /terraform/src/environment/dev && terraform apply -var-file ./dev.tfvars && cd ../../../.." alias apply:prod="cd /terraform/src/environment/prod && terraform apply -var-file ./prod.tfvars && cd ../../../.." # tmt alias fmt="terraform fmt -recursive" # これは便利なのでおまけ やっていること 各環境のディレクトリに移動 Terraformコマンド起動 -var-fileオプションで各環境ごとの環境変数ファイルを定義している コンテナのルートディレクトリに移動 各環境のディレクトリへの移動は絶対パスで指定しているのでコンテナのどこにいてもコマンドは叩ける 「terraform initが必要」という旨のエラーが現れた場合 各環境のディレクトリに移動した状態でコマンドが中断されているはずなので、そこでinitをすればOK terraform/src/environment/prod & dev/*.tfvars ex. prod *.tfvars env = "prod" domain = "www.example_prod.com" 上記****.****bashrc内エイリアスの-var-fileオプションにて指定されている環境変数の定義ファイル これでplan, applyしたディレクトリ内の.tfファイル内でvariableとして取得し、使用することができる terraform/src/environment/prod & dev/*.tf *.tf //------------------------------------- // variable //------------------------------------- variable "env" { type = string } variable "domain" { type = string } //------------------------------------- // modules //------------------------------------- module "main" { source = "../../main" env = var.env domain = var.domain } //------------------------------------- // terraform //------------------------------------- terraform { required_version = "~> 1.0" required_providers { newrelic = { source = "newrelic/newrelic" } } } variableブロックで環境変数を取得している modulesブロックで環境変数を”main”としているmoduleに渡している あとは”main”のmoduleから使いたいところまで環境変数をパスしていく (参考)以降の環境変数のリレーの仕方 terraform/src/main/modules.tf modules.tf module "urls" { source = "./modules/output/urls" ++ domain = var.domain } ↓ terraform/src/modules/output/urls/urls-table.tf urls-table.tf //------------------------------------- // variable //------------------------------------- ++ variable "domain" { ++ type = string ++ } //------------------------------------- // output //------------------------------------- output "urls" { value = { -- "https://example.aaaa.com/path/to/hoge" : { ++ "https://${var.domain}:443//path/to/hoge" : { url_name = "ほげ" } ︙ } } //------------------------------------- // terraform //------------------------------------- terraform { required_version = "~> 1.0" required_providers { newrelic = { source = "newrelic/newrelic" } } } ③各環境ごとのディレクトリを作り、そのディレクトリでTerraformコマンドを叩くことで同一ソースを複数環境でデプロイ ここまでで 各環境ごとのディレクトリ構成ができており それぞれの環境で環境変数を定義できていて (terraform/src/environment/prod & dev****/.tfvars)*** それぞれの環境でTerraformコマンドを叩く準備 (terraform/root/.bashrc) ができています ---- terraform │ └ src │ │ └ environment │ │ │ └ prod │ │ │ │ └ prod.tf │ │ │ └ dev │ │ │ └ dev.tf ︙ あとはコンテナ内でコマンドをたたけばOKです $ plan:dev $ apply:prod 終わりに 無事、各環境ごとでリソースをapplyすることができましたでしょうか? 記事にするためなるべく無駄を省いて記載してますので、もしかしたら必要な部分まで省いてしまっているかもしれませんし、自分の中で当たり前なつもりで書いてない事項があるかもしれません。 何か問題があったり、どこかで詰まったなどありましたらコメントなどぜひよろしくお願いします!
- 投稿日:2022-04-02T17:45:18+09:00
Docker+Ubuntu+PostgreSQL セットアップ〜動作確認
公式 Ubuntuイメージに PostgreSQLなどをつめこんでみます 参考ページ docker docs 公式サイト https://matsuand.github.io/docs.docker.jp.onthefly/ インストールバージョン Docker Desktop 4.6.1 Ubuntu 20.04 LTS PostgreSQL 14.2 Docker Desktop のセットアップ Mac / Windows 共通 https://www.docker.com/products/docker-desktop/ Windowsのみ WSL2 for x64 https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi 初回動作確認 コマンドラインから動作テスト /bin/bash # 公式イメージを取得 docker pull hello-world # コンテナを作成 docker run -it --name hello-world hello-world Hello from Docker! This message shows that your installation appears to be working correctly. (中略) コンテナ操作 /bin/bash # コンテナ一覧 docker ps -a # コンテナ開始 docker start コンテナID or コンテナ名 # コンテナ停止 docker stop コンテナID or コンテナ名 イメージ操作 /bin/bash # イメージ一覧 docker images # イメージ削除 docker rm イメージ名[:タグ] イメージのカスタマイズ 公式で提供されるイメージをベースとして、追加アプリや設定を記述 以下、/Users/ユーザ名/Docker/Ubuntu 配下での作成を想定 Dockerfile #--------------------------------- # For Docker #--------------------------------- FROM ubuntu:20.04 #--------------------------------- # For Ubuntu #--------------------------------- #シェル指定 SHELL ["/usr/bin/bash", "-l", "-c"] #初回のアップデートを強制 RUN apt update && apt upgrade -y #最低限のメンテナンスツール #2回目以降のapt installでも毎回updateをして、dockerの差分buildによるキャッシュの悪さを回避する RUN apt update && apt install -y vim net-tools #--------------------------------- # For PostgreSQL #--------------------------------- RUN apt update && apt install -y lsb-release locales-all curl ca-certificates gnupg ENV TZ=Asia/Tokyo ENV LANG=ja_JP.UTF-8 ENV LANGUAGE=ja_JP:ja ENV LC_ALL=ja_JP.UTF-8 #無人インストール ARG DEBIAN_FRONTEND=noninteractive RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' RUN apt update && apt install -y postgresql-14 #初期設定 USER postgres RUN /etc/init.d/postgresql start && \ psql -c "alter user postgres with encrypted password 'postgres'" && \ psql -c "create user docker with password 'docker' superuser;" && \ psql -c "create role readonly with login password 'readonly';" && \ psql -c "grant pg_read_all_data to readonly;" && \ psql -c "create database docker owner docker;" && \ psql -d docker -c "create schema authorization docker;" RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/14/main/pg_hba.conf RUN echo "listen_addresses='*'" >> /etc/postgresql/14/main/postgresql.conf USER root #ポート解放 EXPOSE 5432 #--------------------------------- # For OpenJDK #--------------------------------- ENV TZ=Asia/Tokyo #無人インストール ARG DEBIAN_FRONTEND=noninteractive RUN apt update && apt install -y openjdk-17-jdk #--------------------------------- # For Nginx #--------------------------------- RUN apt update && apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring RUN curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null RUN echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | tee /etc/apt/sources.list.d/nginx.list RUN apt update && apt install -y nginx #ポート解放 EXPOSE 80 #--------------------------------- # For Node.js #--------------------------------- RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - RUN apt update && apt install -y nodejs #ポート解放 EXPOSE 8888 #--------------------------------- # For Docker #--------------------------------- #コンテナ起動時に各サービス・プロセスを起動 COPY ./sh/startup.sh /startup.sh RUN chmod +x /startup.sh STOPSIGNAL SIGINT ENTRYPOINT /startup.sh 起動・終了スクリプトを startup.sh として作成 startup.sh #!/bin/sh #終了処理 handle(){ /etc/init.d/postgresql stop exit 0 } trap handle TERM INT #起動処理 /etc/init.d/postgresql start /bin/bash イメージ構築 /bin/bash docker build -t イメージ名[:タグ] . コンテナ作成 /bin/bash docker run -it -d -p ホストポート1:コンテナポート1 -p ホストポート2:コンテナポート2 -p ホストポート3:コンテナポート3 --mount type=bind,source=/Users/ユーザ名/Docker/Ubuntu/mnt,target=/mnt --name コンテナ名 イメージ名:タグ 動作確認 Docker 上の Ubuntu へ接続し、さらに PostgreSQL へ接続してバージョン情報などを確認 /bin/bash # コンテナ一覧 docker ps -a # コンテナ情報 docker inspect コンテナ名 # コンテナ情報 (マウント情報) docker inspect --format='{{.Mounts}}' コンテナ名 # コンテナ情報 (IP情報) docker inspect --format='{{.NetworkSettings.IPAddress}}' コンテナ名 # コンテナ情報 (ポートフォーワード情報) docker inspect --format='{{.NetworkSettings.Ports}}' コンテナ名 # コンテナログ docker logs コンテナ名 # Ubuntu 接続 docker exec -it コンテナ名 bash # PostgreSQL 接続 psql -h 127.0.0.1 -U docker Password for user docker: docker psql -- ここから PostgreSQL コマンドラインインターフェース -- バージョン情報 select version(); version ------------------------------------------------------------------ PostgreSQL 14.2 (Ubuntu 14.2-1.pgdg20.04+1) on x86_64-pc-linux-gnu (1 row) -- 現在のデータベース select current_database(); current_database ------------------ docker (1 row) -- 現在のスキーマ select current_schema; current_schema ---------------- docker (1 row) -- 終了 \q /bin/bash -- ここから /bin/bash -- 終了 exit
- 投稿日:2022-04-02T17:45:18+09:00
Docker+Ubuntu+PostgreSQL セットアップ
公式 Ubuntuイメージに PostgreSQLなどをつめこんでみます 参考ページ docker docs 公式サイト https://matsuand.github.io/docs.docker.jp.onthefly/ インストールバージョン Docker Desktop 4.6.1 Ubuntu 20.04 LTS PostgreSQL 14.2 Docker Desktop のセットアップ Mac / Windows 共通 https://www.docker.com/products/docker-desktop/ Windowsのみ WSL2 for x64 https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi 初回動作確認 コマンドラインから動作テスト /bin/bash # 公式イメージを取得 docker pull hello-world # コンテナを作成 docker run -it --name hello-world hello-world Hello from Docker! This message shows that your installation appears to be working correctly. (中略) コンテナ操作 /bin/bash # コンテナ一覧 docker ps -a # コンテナ開始 docker start コンテナID or コンテナ名 # コンテナ停止 docker stop コンテナID or コンテナ名 イメージ操作 /bin/bash # イメージ一覧 docker images # イメージ削除 docker rm イメージ名[:タグ] イメージのカスタマイズ 公式で提供されるイメージをベースとして、追加アプリや設定を記述 以下、/Users/ユーザ名/Docker/Ubuntu 配下での作成を想定 Dockerfile #--------------------------------- # For Docker #--------------------------------- FROM ubuntu:20.04 #--------------------------------- # For Ubuntu #--------------------------------- #シェル指定 SHELL ["/usr/bin/bash", "-l", "-c"] #初回のアップデートを強制 RUN apt update && apt upgrade -y #最低限のメンテナンスツール #2回目以降のapt installでも毎回updateをして、dockerの差分buildによるキャッシュの悪さを回避する RUN apt update && apt install -y wget curl gnupg gnupg2 vim net-tools lsb-release ca-certificates #--------------------------------- # For PostgreSQL #--------------------------------- ENV TZ=Asia/Tokyo ENV LANG=ja_JP.UTF-8 ENV LANGUAGE=ja_JP:ja ENV LC_ALL=ja_JP.UTF-8 #無人インストール化 ARG DEBIAN_FRONTEND=noninteractive RUN apt update && apt install -y locales-all RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' RUN apt update && apt install -y postgresql-14 #初期設定 USER postgres RUN /etc/init.d/postgresql start && \ psql -c "alter user postgres with encrypted password 'postgres'" && \ psql -c "create user docker with password 'docker' superuser;" && \ psql -c "create role readonly with login password 'readonly';" && \ psql -c "grant pg_read_all_data to readonly;" && \ psql -c "create database docker owner docker;" && \ psql -d docker -c "create schema authorization docker;" RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/14/main/pg_hba.conf RUN echo "listen_addresses='*'" >> /etc/postgresql/14/main/postgresql.conf USER root #ポート解放 EXPOSE 5432 #--------------------------------- # For OpenJDK #--------------------------------- ENV TZ=Asia/Tokyo #無人インストール化 ARG DEBIAN_FRONTEND=noninteractive RUN apt update && apt install -y openjdk-17-jdk #環境変数 #/etc/environmentに書き込んでもログイン時にsourceしてないため、Dockerfileで変数セットする #RUN echo "JAVA_HOME=\"/usr/lib/jvm/java-17-openjdk-amd64\"" >> /etc/environment ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 #--------------------------------- # For TomCat #--------------------------------- RUN apt update && apt install -y tomcat9 tomcat9-admin ENV CATALINA_HOME=/usr/share/tomcat9 ENV CATALINA_BASE=/var/lib/tomcat9 COPY ./mnt/tomcat9/var/lib/tomcat9/conf/web.xml /var/lib/tomcat9/conf COPY ./mnt/tomcat9/var/lib/tomcat9/webapps/ROOT/index.txt /var/lib/tomcat9/webapps/ROOT #ポート解放 EXPOSE 8080 #--------------------------------- # For Nginx #--------------------------------- RUN apt update && apt install -y ubuntu-keyring RUN curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null RUN echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | tee /etc/apt/sources.list.d/nginx.list RUN apt update && apt install -y nginx fcgiwrap spawn-fcgi COPY ./mnt/nginx/etc/nginx/nginx.conf /etc/nginx COPY ./mnt/nginx/usr/share/nginx/html/* /usr/share/nginx/html RUN chmod 755 /usr/share/nginx/html/index.sh COPY ./mnt/fcgiwrap/etc/init.d/fcgiwrap /etc/init.d #ポート解放 EXPOSE 8000 #--------------------------------- # For Node.js #--------------------------------- RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - RUN apt update && apt install -y nodejs #ポート解放 EXPOSE 8888 #--------------------------------- # For MongoDB #--------------------------------- RUN wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | apt-key add - RUN echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list RUN apt update && apt install -y mongodb-org EXPOSE 27017 #--------------------------------- # For Docker #--------------------------------- #コンテナ起動時に各サービス・プロセスを起動 COPY ./startup.sh /startup.sh RUN chmod 744 /startup.sh STOPSIGNAL SIGINT ENTRYPOINT /startup.sh 起動・終了スクリプトを startup.sh として作成 startup.sh #!/bin/sh #終了処理 handle(){ /etc/init.d/fcgiwrap stop /etc/init.d/ngix stop /etc/init.d/postgresql stop exit 0 } trap handle TERM INT #起動処理 /usr/libexec/tomcat9/tomcat-start.sh & /usr/bin/node /mnt/bind/nodejs/webserver.js & /etc/init.d/fcgiwrap start /etc/init.d/nginx start /etc/init.d/postgresql start /bin/bash イメージ構築 /bin/bash docker build -t イメージ名[:タグ] . コンテナ作成 /bin/bash docker run -it -d -p ホストポート1:コンテナポート1 -p ホストポート2:コンテナポート2 -p ホストポート3:コンテナポート3 --mount type=bind,source=/Users/ユーザ名/Docker/Ubuntu/mnt,target=/mnt --name コンテナ名 イメージ名:タグ 動作確認 Docker 上の Ubuntu へ接続し、さらに PostgreSQL へ接続してバージョン情報などを確認 /bin/bash # コンテナ一覧 docker ps -a # コンテナ情報 docker inspect コンテナ名 # コンテナ情報 (マウント情報) docker inspect --format='{{.Mounts}}' コンテナ名 # コンテナ情報 (IP情報) docker inspect --format='{{.NetworkSettings.IPAddress}}' コンテナ名 # コンテナ情報 (ポートフォーワード情報) docker inspect --format='{{.NetworkSettings.Ports}}' コンテナ名 # コンテナログ docker logs コンテナ名 # Ubuntu 接続 docker exec -it コンテナ名 bash # PostgreSQL 接続 psql -h 127.0.0.1 -U docker Password for user docker: docker psql -- ここから PostgreSQL コマンドラインインターフェース -- バージョン情報 select version(); version ------------------------------------------------------------------ PostgreSQL 14.2 (Ubuntu 14.2-1.pgdg20.04+1) on x86_64-pc-linux-gnu (1 row) -- 現在のデータベース select current_database(); current_database ------------------ docker (1 row) -- 現在のスキーマ select current_schema; current_schema ---------------- docker (1 row) -- 終了 \q /bin/bash -- ここから /bin/bash -- 終了 exit
- 投稿日:2022-04-02T17:34:00+09:00
【Next.js / TypeScript】ホットリロードを有効にする方法
Docker composeを使ってNext.jsの開発を進めていたのですが、ある日JavaScriptから TypeSriptに切り替えてから、それまで使えていたホットリロードが効かなくなってしまいました。 JavaScriptのままでNext.jsの開発をしていた時には、docker-compose.yamlの中でCHOKIDAR_USEPOLLING=trueと設定をしていればホットリロードが効いていたのですが... 下記が使っていたdocker-compose.yamlの中身です。 frontend: build: ./frontend container_name: frontend_ultimate_timer hostname: frontend volumes: - ./frontend/ultimate_timer:/app tty: true environment: - CHOKIDAR_USEPOLLING=true ports: - "3000:3000" 解決策としては、environmentのところにWATCHPACK_POLLING=trueという記載をすることでホットリロードがTypeScriptでも効くようになりました。 frontend: build: ./frontend container_name: frontend_ultimate_timer hostname: frontend volumes: - ./frontend/ultimate_timer:/app tty: true environment: # - CHOKIDAR_USEPOLLING=true - WATCHPACK_POLLING=true ports: - "3000:3000" めでたしめでたし
- 投稿日:2022-04-02T12:14:29+09:00
Dockerの volume trick を試してみる
はじめに ReactをDockerで使ってみようとした際に、Reactのアプリケーションディレクトリを丸ごとバインドマウントしたところ、コンテナ側でインストールしたnode_modulesがホスト側にもマウントされてしまう、という問題にぶち当たりました。 その解消方法として、volume trick というものがあったので、少し試してみた記事になります。 volume trick とは バインドマウントするフォルダ内にマウントさせたくないフォルダが存在する場合に、そのフォルダをマウント対象から除外する方法。 参考: https://jdlm.info/articles/2016/03/06/lessons-building-node-app-docker.html ※ Dockerfile内の COPY や ADD でコンテナ内にファイルを配置する場合は .dockerignore が使えるので、わざわざ volume trick を使う必要はありません。(参考) リポジトリ ファイル構造 今回試してみた際のファイル構造は下記の通りです。 . ├── docker-compose.yml ├── Dockerfile └── src ├── target │ └── inHost.txt // コンテナ側にマウントされないことを確認したい └── index.html この構造で、src はバインドマウントするが、src/target はマウントしないようにします。 ファイル記述 Dockerfile FROM nginx:latest WORKDIR /usr/share/nginx/html RUN mkdir target \ && echo touch in image > target/inImage.txt # ホスト側にマウントされないことを確認したい docker-compose.yml version: "3.8" services: server: build: . ports: - 80:80 volumes: - ./src:/usr/share/nginx/html # バインドマウント - exception-volumes:/usr/share/nginx/html/target # バインドマウントするフォルダ中のtargetフォルダのみvolumeマウントの対象とする volumes: exception-volumes: # volume trick用のダミーのvolume 動かしてみる コンテナ起動 $ docker compose up -d --build コンテナ内のファイル構造確認 $ docker compose exec server ls index.html target $ docker compose exec server ls target inImage.txt ホスト側のファイル構造確認 $ ls src index.html target $ ls src/target inHost.txt 動かしてみた結果、下記のことを確認することができました。 ホスト側の target/inHost.txt がコンテナ側にない イメージビルド時に作成した target/inImage.txt がコンテナ側にはあるが、ホスト側にはない 図で表すと下記のような差分があります。 コンテナ側のファイル構造(ホストと比べた差分を表示) . ├── target + │ └── inImage.txt - │ └── inHost.txt └── index.html コンテナとボリュームのイメージとしては、下記になります。 (こちらのページのイメージ図がわかりやすかったので、参考にしています。) +--<Host>--+ +--<Docker>-----------------------------------------------------------------+ | | | +--<Container:c1>-------------------+ +--<Volume:exception-volumes>--+ | | | | | | | | | | ./src/------------> /usr/share/nginx/html | | | | | | | | /usr/share/nginx/html/target <---------/ | | | | | | | | | | | | | +-----------------------------------+ +------------------------------+ | +----------+ +---------------------------------------------------------------------------+ 結果 対象のフォルダをバインド対象から外すことができました! 参考 Lessons from Building a Node App in Docker - jdlm.info DockerでVolumeをマウントするとき一部を除外する方法 - Qiita Docker と node_modules と Volume Trick - Hatena Blog VSCode&Docker Volumeにおけるnode_modules問題を解決する - Zenn Docker、ボリューム(Volume)について真面目に調べた - Qiita
- 投稿日:2022-04-02T03:47:28+09:00
【インフラ構築】MENTAにてフォローしていただいた事を振り返ります
背景 Laravelで作成したポートフォリオのAWSデプロイに苦労していた時、MENTAにて@adachin0817さんよりお声がけいただき、インフラ構築のフォローをしていただきました。 以下のプランよりフォローしていただきました。 構築過程 まず最初に開発環境構築に使用すたDockerの設定があまりよろしくなかったので、 開発環境の再構築から始めました。 (本番環境と設定を合わせる目的もあります) 開発環境 開発環境にはDockerを使用しています Docker 20.10.12 Docker Compose v2.2.3 Docker image laravel-app(appコンテナ) php7.4-fpm-alpine(nginx,php-fpm,supervisor) Laravel 6.20.34 laravel-db(mysqlコンテナ) MySQL 8.0.27 以下構成図です。 具体的な構成、構築内容は以下の記事にまとめました。 【Docker+Laravel6】開発環境構築についてまとめてみました 本番環境 本番環境はAWSを使用し、CircleCIで自動デプロイを可能にしています AWS:EC2, RDS, VPC, Route 53, ALB, ACM, S3, CloudWatch EC2 : nginx, php-fpm RDS : mysql 8.0.27 CircleCI deploy job : git pullデプロイ自動化 slack orb : Slackデプロイ結果通知 以下構成図です。 具体的な構成、構築内容は以下の記事にまとめました。 【AWS+Laravel】本番環境構築についてまとめてみました 身についたこと Docker, AWSのインフラの構造とCircleCIの設定・操作の理解 構成を理解し構成図として表記できる能力 公式ドキュメントを軸に、あらゆる記事を読み、最適な実装方法を導き出せる能力 自走力 実装中に意識したこと 後で見返してもわかりやすいように、タグや説明をその都度付け加える。 各サービス同士の繋がりを意識しながら構築していく。 とにかく諦めないこと。 振り返り ちょうど1ヶ月でのデプロイ完了でした。技術力のみならず質問力も鍛えられました。 まだまだ理解不足なところもあるので、普段の学習と実務経験で、もっと対応できる幅を広げていきたいです。 最後に @adachin0817さんのMENTAプランについて紹介します。 初学者が一番悩むであろう構築までのロードマップを速攻で作っていただき、構築完成まで手厚いサポートをしていただきました。 とにかく質問への回答が早く、問題を素早く解決できます。 また、実務レベルのフォローで、メンティー自身が解決までたどり着けるよう導いてくださるので、自走力爆上がりすると思います! 初学者にとっては決して甘くはないですが、インフラの知識のみならずエンジニアとしての心得を学ぶにおいて、@adachin0817さんのサポートは最高です。 おすすめです!!
- 投稿日:2022-04-02T02:50:39+09:00
【Docker】NameError: uninitialized constant Gem::Source 解消法【Rails】
はじめに 本記事は、プログラミング初学者、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。 そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。 間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。 NameError: uninitialized constant Gem::Source 解消法 状況 以下の内容のDockerfileでdocker build -t <イメージ名> .実行後、docker run <イメージ名> rails new .したところ以前は発生しなかったNameError: uninitialized constant Gem::Sourceが発生しました。 Dockerfile FROM ruby:3.1.1 ENV APP_NAME=myapp ENV USER_NAME=myuser ENV TZ=Asia/Tokyo WORKDIR /${APP_NAME} COPY Gemfile /${APP_NAME}/Gemfile COPY Gemfile.lock /${APP_NAME}/Gemfile.lock RUN bundle install COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] RUN adduser ${USER_NAME} && \ chown -R ${USER_NAME} /${APP_NAME} && \ chown -R ${USER_NAME} ${GEM_HOME} USER ${USER_NAME} EXPOSE 3000 CMD ["rails", "server", "-b", "0.0.0.0"] ターミナル [12, #<Thread:0x0000ffffa5667c90 run>, #<NameError: uninitialized constant Gem::Source (defined?(@source) && @source) || Gem::Source::Installed.new ^^^^^^^^ Did you mean? Gem::SourceList>, ["/usr/local/lib/ruby/3.1.0/bundler/rubygems_ext.rb:18:in `source'", "/usr/local/lib/ruby/3.1.0/bundler/rubygems_ext.rb:50:in `extension_dir'", "/usr/local/lib/ruby/3.1.0/rubygems/basic_specification.rb:339:in `have_file?'", "/usr/local/lib/ruby/3.1.0/rubygems/basic_specification.rb:86:in `contains_requirable_file?'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:1038:in `block (2 levels) in find_in_unresolved_tree'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2555:in `block (2 levels) in traverse'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2550:in `each'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2550:in `block in traverse'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2548:in `each'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2548:in `traverse'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:1034:in `block in find_in_unresolved_tree'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:1033:in `each'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:1033:in `find_in_unresolved_tree'", "<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:114:in `require'", "/usr/local/lib/ruby/3.1.0/bundler/rubygems_ext.rb:18:in `source'", "/usr/local/lib/ruby/3.1.0/bundler/rubygems_ext.rb:50:in `extension_dir'", "/usr/local/lib/ruby/3.1.0/rubygems/basic_specification.rb:339:in `have_file?'", "/usr/local/lib/ruby/3.1.0/rubygems/basic_specification.rb:86:in `contains_requirable_file?'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:1038:in `block (2 levels) in find_in_unresolved_tree'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2555:in `block (2 levels) in traverse'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2550:in `each'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2550:in `block in traverse'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2548:in `each'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:2548:in `traverse'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:1034:in `block in find_in_unresolved_tree'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:1033:in `each'", "/usr/local/lib/ruby/3.1.0/rubygems/specification.rb:1033:in `find_in_unresolved_tree'", "<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:114:in `require'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb:1:in `<top (required)>'", "/usr/local/lib/ruby/3.1.0/bundler/vendored_persistent.rb:11:in `require_relative'", "/usr/local/lib/ruby/3.1.0/bundler/vendored_persistent.rb:11:in `<top (required)>'", "/usr/local/lib/ruby/3.1.0/bundler/fetcher.rb:3:in `require_relative'", "/usr/local/lib/ruby/3.1.0/bundler/fetcher.rb:3:in `<top (required)>'", "<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'", "<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'", "/usr/local/lib/ruby/3.1.0/bundler/cli/install.rb:50:in `run'", "/usr/local/lib/ruby/3.1.0/bundler/cli.rb:255:in `block in install'", "/usr/local/lib/ruby/3.1.0/bundler/settings.rb:131:in `temporary'", "/usr/local/lib/ruby/3.1.0/bundler/cli.rb:254:in `install'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'", "/usr/local/lib/ruby/3.1.0/bundler/cli.rb:31:in `dispatch'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor/base.rb:485:in `start'", "/usr/local/lib/ruby/3.1.0/bundler/cli.rb:25:in `start'", "/usr/local/lib/ruby/gems/3.1.0/gems/bundler-2.3.7/libexec/bundle:48:in `block in <main>'", "/usr/local/lib/ruby/3.1.0/bundler/friendly_errors.rb:103:in `with_friendly_errors'", "/usr/local/lib/ruby/gems/3.1.0/gems/bundler-2.3.7/libexec/bundle:36:in `<main>'"]] [12, #<Thread:0x0000ffffa5667c90 run>, #<RuntimeError: CRITICAL: RUBYGEMS_ACTIVATION_MONITOR.owned?: before false -> after true>, ["<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:167:in `ensure in require'", "<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:167:in `require'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb:1:in `<top (required)>'", "/usr/local/lib/ruby/3.1.0/bundler/vendored_persistent.rb:11:in `require_relative'", "/usr/local/lib/ruby/3.1.0/bundler/vendored_persistent.rb:11:in `<top (required)>'", "/usr/local/lib/ruby/3.1.0/bundler/fetcher.rb:3:in `require_relative'", "/usr/local/lib/ruby/3.1.0/bundler/fetcher.rb:3:in `<top (required)>'", "<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'", "<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'", "/usr/local/lib/ruby/3.1.0/bundler/cli/install.rb:50:in `run'", "/usr/local/lib/ruby/3.1.0/bundler/cli.rb:255:in `block in install'", "/usr/local/lib/ruby/3.1.0/bundler/settings.rb:131:in `temporary'", "/usr/local/lib/ruby/3.1.0/bundler/cli.rb:254:in `install'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'", "/usr/local/lib/ruby/3.1.0/bundler/cli.rb:31:in `dispatch'", "/usr/local/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor/base.rb:485:in `start'", "/usr/local/lib/ruby/3.1.0/bundler/cli.rb:25:in `start'", "/usr/local/lib/ruby/gems/3.1.0/gems/bundler-2.3.7/libexec/bundle:48:in `block in <main>'", "/usr/local/lib/ruby/3.1.0/bundler/friendly_errors.rb:103:in `with_friendly_errors'", "/usr/local/lib/ruby/gems/3.1.0/gems/bundler-2.3.7/libexec/bundle:36:in `<main>'"]] /usr/local/lib/ruby/3.1.0/bundler/rubygems_ext.rb:18:in `source': uninitialized constant Gem::Source (NameError) (defined?(@source) && @source) || Gem::Source::Installed.new ^^^^^^^^ Did you mean? Gem::SourceList from /usr/local/lib/ruby/3.1.0/bundler/rubygems_ext.rb:50:in `extension_dir' from /usr/local/lib/ruby/3.1.0/rubygems/basic_specification.rb:339:in `have_file?' from /usr/local/lib/ruby/3.1.0/rubygems/basic_specification.rb:86:in `contains_requirable_file?' from /usr/local/lib/ruby/3.1.0/rubygems/specification.rb:1038:in `block (2 levels) in <省略> run bundle binstubs bundler Could not find gem 'sprockets-rails' in locally installed gems. rails importmap:install Could not find gem 'sprockets-rails' in locally installed gems. Run `bundle install` to install missing gems. rails turbo:install stimulus:install Could not find gem 'sprockets-rails' in locally installed gems. Run `bundle install` to install missing gems. 解決した方法 Bundlerをアップデートするために、Dockerfileを以下のように修正し、再度docker build -t <イメージ名> .実行後、docker run <イメージ名> rails new .することで解消しました。 Dockerfile FROM ruby:3.1.1 ENV APP_NAME=myapp ENV USER_NAME=myuser ENV TZ=Asia/Tokyo ENV BUNDLER_VERSION=2.3.10 WORKDIR /${APP_NAME} COPY Gemfile /${APP_NAME}/Gemfile COPY Gemfile.lock /${APP_NAME}/Gemfile.lock RUN gem install bundler -v ${BUNDLER_VERSION} && \ bundle install # Bundlerをアップデートできれば良いので # gem install bundler -v ${BUNDLER_VERSION}は以下のどちらかでも対応可能です。 # gem update --system (RubyGemsをアップデート) # gem update bundler (Bundlerを最新バージョンにアップデート) COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] RUN adduser ${USER_NAME} && \ chown -R ${USER_NAME} /${APP_NAME} && \ chown -R ${USER_NAME} ${GEM_HOME} USER ${USER_NAME} EXPOSE 3000 CMD ["rails", "server", "-b", "0.0.0.0"] ちなみに修正前のBundlerのバージョンは2.3.7でした。 ターミナル $ docker run <イメージ名> bundler -v Bundler version 2.3.7 どうやら、Bundlerのバージョンが2.3.7だとNameError: uninitialized constant Gem::Sourceが発生するようです。 また、2.3.8でも同様のエラーが発生しました。 2.3.6や2.3.9、2.3.10ではエラーは発生しませんでした。