再利用可能なDocker開発環境
これまでのところ、私はWebアプリケーションの文脈での開発のためのDockerについて話していました.今日、私は反対側を見て、コンテナ化がどのように私が図書館で働くのを助けることができるかについて議論したいです.
わが社の最近の議論Evil Martians ) スラックは、私が最終的にこのポストを書くために私を引き起こしました:私の同僚は、複数のノードを管理する新しいツールについて議論しました.同じマシン上のJSバージョンwritten in Rust —ご存知のように、物事は錆で書き直されると涼しくなる😉).
私の最初の考えは次のとおりでした:“なぜ2020年に地球上で、我々はまだすべてのバージョン管理者、RBNV、NVM、ASDF、何が必要ですか?”私はほとんどそれらを使用する喜びを忘れてしまった:私のコンピュータは、これらのツールをもたらすすべての環境汚染なしで簡単に呼吸する.
ツイストをして、モノリシックなパソコン(またはラップトップ)について話しましょう.
私のスライドBetween monoliths and microservices Railsconf話
約1年前、新しいラップトップに切り替えました.私はバックアップや他のタイムマシンの大ファンではないので、私はゼロから快適な作業環境をクラフトする必要がありました.私は通常(Ruby、Golang、Erlang、ノード)を使用するすべてのランタイムをインストールする代わりに、私は実験とすべてのためにDockerと行くことを決めた:アプリケーションとライブラリ、商用およびオープンソースプロジェクト.言い換えれば、私はgitDip .
docker4 devの設定を保持していると考えますRuby on Whales すべての小さなライブラリのためのオーバーヘッドの束です.うん、それは本当だ.それで、私は共有で始めました
コンテナの起動は次のようになります.
RDEの考えは完全に必要性を排除することでした
このようにして、私はそれが働くことを想像しました.
複製問題を解決することは、さらに別のツールを構築することなく行うことができることがわかった😉). RDEコンセプトを議論した後Mikhail Merkushin , 我々は、同様の機能を達成することができた実現Dip いくつかの機能を追加すると、 親ディレクトリの設定を検索する 設定ディレクトリからカレントディレクトリへの相対パスを含む環境変数を提供します これらの機能はv5.0.0 (mishaに感謝)、そして私は新しい可能性を探求し始めた.
すべての中間の状態を飛ばして、最終的な構成を見てみましょう.
現在、私
私が持っている唯一の特別なトリックは
いくつかの例を考えよう.
あなたがVCコードユーザーであるなら、IntelliSenseの力を使いたいならば、あなたはこの方法を結合することができますRemote Containers : ジャストラン
Rubyの例を見てみましょうDocsify ドキュメントサーバー.
docsifyはJavaScript/ノードです.ドキュメントジェネレータ.私はusing it すべてのオープンソースプロジェクトのために.ノードが必要です.ジェイズアンドザ
まず、我々のベースノードサービスを宣言します
env varを定義できます.
今すぐdocsifyサーバーを実行するには
私が共有したい最終的な例はコンパイルされた言語の世界からである.
前と同様に、サービスを定義します
これは、ホスト(特にMacOSユーザーにとって有用である)に書くことによってコンパイルをスピードアップするのを助けます.
ディップを使用する1つの利点は、サービスを読み込むための複数のファイルを指定する機能です.それは私たちが自然によってグループサービスを可能にし、すべてを同じにするのを避けます
P . S .私は、ローカルマシンに何もインストールしなかった私の最初の計画が失敗したことを認めなければなりません
P . P . S .最近、私はGitHub Codespaces . 私はまだすべての詳細を把握していないが、それは将来的にライブラリ開発のための私の最初の選択肢になる可能性がありますように見える🙂).
昔々…。
わが社の最近の議論Evil Martians ) スラックは、私が最終的にこのポストを書くために私を引き起こしました:私の同僚は、複数のノードを管理する新しいツールについて議論しました.同じマシン上のJSバージョンwritten in Rust —ご存知のように、物事は錆で書き直されると涼しくなる😉).
私の最初の考えは次のとおりでした:“なぜ2020年に地球上で、我々はまだすべてのバージョン管理者、RBNV、NVM、ASDF、何が必要ですか?”私はほとんどそれらを使用する喜びを忘れてしまった:私のコンピュータは、これらのツールをもたらすすべての環境汚染なしで簡単に呼吸する.
ツイストをして、モノリシックなパソコン(またはラップトップ)について話しましょう.
私のスライドBetween monoliths and microservices Railsconf話
約1年前、新しいラップトップに切り替えました.私はバックアップや他のタイムマシンの大ファンではないので、私はゼロから快適な作業環境をクラフトする必要がありました.私は通常(Ruby、Golang、Erlang、ノード)を使用するすべてのランタイムをインストールする代わりに、私は実験とすべてのためにDockerと行くことを決めた:アプリケーションとライブラリ、商用およびオープンソースプロジェクト.言い換えれば、私はgitDip .
I decided to use Docker for everything: applications and libraries, commercial and open-source projects.
フェーズ0 :ユニバーサルDockerを構成します。気象研
docker4 devの設定を保持していると考えますRuby on Whales すべての小さなライブラリのためのオーバーヘッドの束です.うん、それは本当だ.それで、私は共有で始めました
docker-compose.yml
構成、プロジェクトごとのサービスを含んで、それらの間でボリュームを共有する(したがって、私はすべての依存関係を複数回インストールする必要はありませんでした).コンテナの起動は次のようになります.
docker-compose -f ~/dev/docker-compose.yml \
run --rm some_service
# we can omit -f if our project is somewhere inside the ~/dev folder: docker-compose tries to find the first docker-compose.yml up the tree
docker-compose run --rm some_service
# finally, using an alias
dcr some_service
それほど悪くない.唯一の問題は、私がDockerの中で新しいプロジェクトを実行するたびに、サービスを定義しなければならなかったということです.私は調査を続けて、再利用可能なDocker Environment(RDE)概念を思いつきました.フェーズ1 (破棄) : RDE
RDEの考えは完全に必要性を排除することでした
Dockerfile
and docker-compose.yml
ファイルを定義したテンプレートを使用してオンザフライで生成します.このようにして、私はそれが働くことを想像しました.
# Open the current folder within a Ruby executor
$ rde -e ruby
root@1123:/app#
# Execute a command within a JRuby executor
$ rde run -e jruby -- ruby -e "puts RUBY_PLATFORM"
java
この考えはAに残ったgist 塵を集める.フェーズ2(現在の):dockerの構成に戻ります。ディップ
複製問題を解決することは、さらに別のツールを構築することなく行うことができることがわかった😉). RDEコンセプトを議論した後Mikhail Merkushin , 我々は、同様の機能を達成することができた実現Dip いくつかの機能を追加すると、
~/dip.yml
すべてのプロジェクトについて).working_dir
). すべての中間の状態を飛ばして、最終的な構成を見てみましょう.
現在、私
~/dip.yml
ルビーやデータベースが異なるだけです.version: '5.0'
compose:
files:
- ./.dip/docker-compose.yml
project_name: shared_dip_env
interaction:
ruby: &ruby
description: Open Ruby service terminal
service: ruby
command: /bin/bash
jruby:
<<: *ruby
service: jruby
'ruby:latest':
<<: *ruby
service: ruby-latest
psql:
description: Run psql console
service: postgres
command: psql -h postgres -U postgres
createdb:
description: Run PostgreSQL createdb command
service: postgres
command: createdb -h postgres -U postgres
'redis-cli':
description: Run Redis console
service: redis
command: redis-cli -h redis
ルビーの宝石で仕事をしたいときはいつでもdip ruby
プロジェクトのディレクトリからすべてのコマンドを実行します.bundle install
, rake
) 容器の中~ $ cd ~/my_ruby_project
~/my_ruby_project $ dip ruby:latest
[../my_ruby_project] ruby -v
ruby 3.0.0dev (2020-10-20T12:46:54Z master 451836f582) [x86_64-linux]
参照してください、任意の手間をかけずにRuby 3を実行することができます🙂私が持っている唯一の特別なトリックは
docker-compose.yml
これによって、すべてのプロジェクトのために同じコンテナを再使用することができます.PWD
! はい、必要なのはPWD
, ホストマシン上のカレントワーキングディレクトリへの絶対パス.ここでは、この神聖な知識をどのように使用しますかversion: '2.4'
services:
ruby: &ruby
command: bash
image: ruby:2.7
volumes:
# That's all the magic!
- ${PWD}:/${PWD}:cached
- bundler_data:/usr/local/bundle
- history:/usr/local/hist
# I also mount different configuration files
# for better DX
- ./.bashrc:/root/.bashrc:ro
- ./.irbrc:/root/.irbrc:ro
- ./.pryrc:/root/.pryrc:ro
environment:
DATABASE_URL: postgres://postgres:postgres@postgres:5432
REDIS_URL: redis://redis:6379/
HISTFILE: /usr/local/hist/.bash_history
LANG: C.UTF-8
PROMPT_DIRTRIM: 2
PS1: '[\W]\! '
# Plays nice with gemfiles/*.gemfile files for CI
BUNDLE_GEMFILE: ${BUNDLE_GEMFILE:-Gemfile}
# And that's the second part of the spell
working_dir: ${PWD}
tmpfs:
- /tmp
jruby:
<<: *ruby
image: jruby:latest
volumes:
- ${PWD}:/${PWD}:cached
- bundler_jruby:/usr/local/bundle
- history:/usr/local/hist
- ./.bashrc:/root/.bashrc:ro
- ./.irbrc:/root/.irbrc:ro
- ./.pryrc:/root/.pryrc:ro
ruby-latest:
<<: *ruby
image: rubocophq/ruby-snapshot:latest
volumes:
- ${PWD}:/${PWD}:cached
- bundler_data_edge:/usr/local/bundle
- history:/usr/local/hist
- ./.bashrc:/root/.bashrc:ro
- ./.irbrc:/root/.irbrc:ro
- ./.pryrc:/root/.pryrc:ro
postgres:
image: postgres:11.7
volumes:
- history:/usr/local/hist
- ./.psqlrc:/root/.psqlrc:ro
- postgres:/var/lib/postgresql/data
environment:
PSQL_HISTFILE: /usr/local/hist/.psql_history
POSTGRES_PASSWORD: postgres
PGPASSWORD: postgres
ports:
- 5432
redis:
image: redis:5-alpine
volumes:
- redis:/data
ports:
- 6379
healthcheck:
test: redis-cli ping
interval: 1s
timeout: 3s
retries: 30
volumes:
postgres:
redis:
bundler_data:
bundler_jruby:
bundler_data_edge:
history:
ライブラリをビルドするためにPostgreSQLやREDISが必要な場合は、次のようにします.# Launch PostgreSQL in the background
dip up -d postgres
# Create a database
dip createdb my_library_db
# Run psql
dip psql
# And, for example, run tests
dip ruby -c "bundle exec rspec"
同じDockerネットワーク内の他のコンテナとしてのデータベースdocker-compose.yml
) そして、それらの名前を通してアクセス可能ですpostgres
and redis
). 私のコードはDATABASE_URL
and REDIS_URL
, それぞれ.いくつかの例を考えよう.
VSコードの使用
あなたがVCコードユーザーであるなら、IntelliSenseの力を使いたいならば、あなたはこの方法を結合することができますRemote Containers : ジャストラン
dip up -d ruby
そして、実行中の容器に付けてください!ノード。JSの例
Rubyの例を見てみましょうDocsify ドキュメントサーバー.
docsifyはJavaScript/ノードです.ドキュメントジェネレータ.私はusing it すべてのオープンソースプロジェクトのために.ノードが必要です.ジェイズアンドザ
docsify-cli
インストールするパッケージ.しかし、我々は何もインストールしないでください、覚えています?それをDockerに詰めましょう!まず、我々のベースノードサービスを宣言します
docker-compose.yml
:services:
# ...
node: &node
image: node:14
volumes:
- ${PWD}:/${PWD}:cached
# Where to store global packages
- npm_data:${NPM_CONFIG_PREFIX}
- history:/usr/local/hist
- ./.bashrc:/root/.bashrc:ro
environment:
NPM_CONFIG_PREFIX: ${NPM_CONFIG_PREFIX}
HISTFILE: /usr/local/hist/.bash_history
PROMPT_DIRTRIM: 2
PS1: '[\W]\! '
working_dir: ${PWD}
tmpfs:
- /tmp
それはrecommended 非依存のユーザディレクトリにグローバル依存関係を保持する.また、ボリュームに入れることでこれらのパッケージを「キャッシュする」ことを確認したい.env varを定義できます.
NPM_CONFIG_PREFIX
) ディップ設定で# dip.yml
environment:
NPM_CONFIG_PREFIX: /home/node/.npm-global
ドキュメントサイトにアクセスするにはDocsify Serverを実行したいので、portsを公開する必要があります.のために別のサービスを定義し、サーバを実行するコマンドを定義しましょう.services:
# ...
node: &node
# ...
docsify:
<<: *node
working_dir: ${NPM_CONFIG_PREFIX}/bin
command: docsify serve ${PWD}/docs -p 5000 --livereload-port 55729
ports:
- 5000:5000
- 55729:55729
インストールするdocsify-cli
パッケージについては、次のコマンドを実行します.dip compose run node npm i docsify-cli -g
コマンドを定義すると、コマンドを少し簡素化できますnode
コマンドでdip.yml
:interaction:
# ...
node:
description: Open Node service terminal
service: node
ここでは以下の文字を入力できます:dip node npm i docsify-cli -g
🙂今すぐdocsifyサーバーを実行するには
dip up docsify
プロジェクトのフォルダで.アーランの例:ビルドアーティファクトを維持する
私が共有したい最終的な例はコンパイルされた言語の世界からである.
前と同様に、サービスを定義します
docker-compose.yml
と対応するショートカットdip.yml
:# docker-compose.yml
services:
# ...
erlang: &erlang
image: erlang:23
volumes:
- ${PWD}:/${PWD}:cached
- rebar_cache:/rebar_data
- history:/usr/local/hist
- ./.bashrc:/root/.bashrc:ro
environment:
REBAR_CACHE_DIR: /rebar_data/.cache
REBAR_GLOBAL_CONFIG_DIR: /rebar_data/.config
REBAR_BASE_DIR: /rebar_data/.project-cache${PWD}
HISTFILE: /usr/local/hist/.bash_history
PROMPT_DIRTRIM: 2
PS1: '[\W]\! '
working_dir: ${PWD}
tmpfs:
- /tmp
# dip.yml
interactions:
# ...
erl:
description: Open Erlang service terminal
service: erlang
command: /bin/bash
この設定がRubyのものと異なるのは、私たちが同じpwd
依存関係を保存し、ファイルをビルドするトリックREBAR_BASE_DIR: /rebar_data/.project-cache${PWD}
デフォルトを変更する_build
マウントされたボリューム内のものへの場所${PWD}
我々は他のプロジェクトとの衝突がないことを保証します.これは、ホスト(特にMacOSユーザーにとって有用である)に書くことによってコンパイルをスピードアップするのを助けます.
ボーナス:複数のファイルを作成
ディップを使用する1つの利点は、サービスを読み込むための複数のファイルを指定する機能です.それは私たちが自然によってグループサービスを可能にし、すべてを同じにするのを避けます
docker-compose.yml
:# dip.yml
compose:
files:
- ./.dip/docker-compose.base.yml
- ./.dip/docker-compose.databases.yml
- ./.dip/docker-compose.ruby.yml
- ./.dip/docker-compose.node.yml
- ./.dip/docker-compose.erlang.yml
project_name: shared_dip_env
それだ!この例のセットアップはgist . お気軽に使用して、フィードバックを共有する!P . S .私は、ローカルマシンに何もインストールしなかった私の最初の計画が失敗したことを認めなければなりません
brew install ruby
(これはフェーズ2よりずっと前だった).P . P . S .最近、私はGitHub Codespaces . 私はまだすべての詳細を把握していないが、それは将来的にライブラリ開発のための私の最初の選択肢になる可能性がありますように見える🙂).
Reference
この問題について(再利用可能なDocker開発環境), 我々は、より多くの情報をここで見つけました https://dev.to/palkan_tula/reusable-docker-development-environment-81gテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol