質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

2回答

2997閲覧

dockerのコンテナの中身について

PartyKids

総合スコア65

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

0クリップ

投稿2017/05/20 03:06

編集2017/05/21 06:30

閲覧ありがとうございます!

『コンテナは、イメージから作成されたものであり、作業履歴を保存するもの』っと書かれていたので、作業履歴すべて(手で打ったコード等)を保存するものだと思っていました。
しかし実際、コンテナはコンテナを動かしたコマンド(作業履歴)を保存するものであるとdocker ps -aで分かったのですが、以下の疑問が出ました。

###環境
docker for Mac
docker version: 17.03.1-ce
Users/****/workspace下で、Quickstart: Compose and Railsリンク内容を構築

linux

1###Dockerfile 2FROM ruby:2.3.3 3RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs 4RUN mkdir /myapp 5WORKDIR /myapp 6ADD Gemfile /myapp/Gemfile 7ADD Gemfile.lock /myapp/Gemfile.lock 8RUN bundle install 9ADD . /myapp 10 11###docker-compose.yml 12version: '2' 13services: 14 db: 15 image: postgres 16 web: 17 build: . 18 command: bundle exec rails s -p 3000 -b '0.0.0.0' 19 volumes: 20 - .:/myapp 21 ports: 22 - "3000:3000" 23 depends_on: 24 - db

###疑問1:コンテナの中身の違い

linux

1$ docker-compose run web rails g contoller StaticPages home 2$ docker inspect [generate contoller container ID] 3"Cmd": [ 4 "rails", 5 "destroy", 6 "controller", 7 "StaticPages", 8 "home" 9 ] 10 11$ docker-compose run web rails g destroy StaticPages home 12$ docker inspect [destroy controller container ID] 13"Cmd": [ 14 "rails", 15 "destroy", 16 "controller", 17 "StaticPages", 18 "home" 19 ]

上記のコマンドより、各コンテナは、個々が独立しており、かつ、他のコンテナのコマンドを有していないと考えたのですが(destroyコンテナはgenerate controllerコマンドを有してない)
なぜdocker-compose run web **** で動くのですか?
generate controllerdestroy controllerをするには、まずrails newでアプリケーションを作成する必要があると思いますが、rails newコンテナは別にあります。
仮に、generateやdestroyをしたい場合には、rails newコンテナ(コマンド)を継承しなければ出来ないと思うのですが、『各コンテナは、個々が独立しており、かつ、他のコンテナのコマンドを有していない』と考えているため、rails new無しでgenerate & destroyが出来てしまうというおかしな考えになってしまいました。
私の考えがおかしいのは、間違いないのですが、どこが間違っているのかを調べても見つからないため、困っています。

###疑問2:localhost:3000で制作仮定がブラウザで見れる理由
rails tutorialを勉強している間、何も考えずにdocker-compose uplocalhost:3000をして、勉強過程をブラウザ確認していました。
勉強過程がブラウザで確認できたのは、volumeでホスト側のファイルをゲスト側にマウントしているからであり、実際に自分が打ったコードはコンテナ(ゲスト側)が有しているわけではない。っという事ですか?

説明が下手な、長い質問文になってしまいましたが、よろしくお願いいたします!

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

昨日私Dockerの基礎解説のようなものを他のご質問で書いたのですが、もしかしたらお役に立てるかもしれないので、リンクを貼りますね!
https://teratail.com/questions/76773

上記にはdocker-composeの解説が少ないので続きを書きますと、

dockerでは1つのコンテナしか動かせませんが、
docker-compose は、複数のコンテナを同時に動かすことができる仕組みで、その指令はdocker-compose.ymlというymlファイルに記載するのです。直観的にわかりやすい例としては


OSはUbuntuがよいので、Ubuntuコンテナを動かしつつ、
一方Ubuntu上でwebサーバーとしてnginxをつかいたいのでnxinxコンテナを動かしたいという
2つのコンテナを同時に動かし、連結したい場合

docker-compose.ymlの例(細かなセッティングは長くなりそうなので他の記事などでご確認ください)

ubuntu #ubuntuコンテナへの指示 image:****/****(ubuntuイメージの置いているリポジトリの場所docker hub等) (その他のセッティングについて指示を書く) nginx #nginxコンテナへの指示 image:****/****(nginxイメージの置いているリポジトリの場所docker hub等) (その他のセッティングについて指示を書く ubuntuとリンクさせるなど)

これで、例えばdocker-compose upとかコマンドを入れればdocker-compose.ymlに書いた指示を自動でdocker-composeが行い、複数のコンテナが連動して稼働するようになるという感じですね。

貢献できていれば幸いに存じます!

投稿2017/05/21 04:01

k_mawa82

総合スコア234

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

PartyKids

2017/05/21 06:28

回答ありがとうございます! 下手な質問文で申し訳ございませんでした。 なぜ、docker-composeで動くのか?という質問ではなく、各コンテナはそのコンテナを動かしたコマンドしか有しないのに、なぜgenerateやdestroyコンテナを動かせるのか?という質問です。 つまり、rails newをしてからじゃないと、コントローラーやモデルを作成することは出来ないと思いますが、コントローラー作成コンテナにはrails newコマンドを有していないのに作成出来てしまうのは、なぜですか?っという質問です。 説明が下手で勘違いさせて、申し訳ございませんでした。 よろしくお願いいたします!
k_mawa82

2017/05/21 06:54

ああ〜 なるほど・・・ご要望にお答えできなくてすみません・・・  私python-Djangoで開発しており、rubyーRubyonRailsはやったことがないのですがちらちらネットの記事などを見ると、モデルのマイグレーションはなんか似てるかもしれないのでヒントになるかまったくわかりませんがdocker-composeでのセットアップで似たセッティングの箇所があるので書いてみます。これは全然自信ないので的外れだったらゴメンナサイ 私のdocker-composeのセットアップでフレームワークのモデルやマイグレーションを行うのはdocker-compose.ymlそのものではなく、docker-compose.ymlのうちの自分のアプリコード+アプリケーションサーバー(railsだとUnicornなどです おそらく)のコンテナのイメージのセットアップ時に起動させるコマンドの中のDockerfileにマイグレーションのシェルスクリプトを実行するコマンドをかいておく(CMD ./server.sh のような形)ことでフレームワークも自動で動かせるという設定にしています。 あんまり役に立たない情報かもしれません・・・すみません・・・
PartyKids

2017/05/22 11:15

返信ありがとうございます! >ご要望にお答えできなくてすみません とんでもないです!助けて頂きありがとうございます! 私の質問の仕方が下手くそなばかりにご迷惑をおかけして申し訳ございません! 今後ともよろしくお願いいたします!
k_mawa82

2017/05/22 15:59

お気遣いありがとうございます!心が温かくなりました〜  またどこかでお会いしたらこちらこそお願いしますね〜
guest

0

ベストアンサー

まず少しDockerfileについて少し。
DockefileはFROMで指定されているイメージに対してシェル的に変更をして新しくイメージを作り出すものです。なのでこのDockerfileをcomposeで指定している時点で/myappが同梱された状態のイメージが生成されるはずです。しかしcomposeではそこにさらにvolumeを指定しています。
なので本来同梱したはずの/myappが同期フォルダによって上書きされています。
なのでどちらかを指定すれば良いと思います。

疑問1:なぜdocker-compose run web で動くのか

まず、dokcer-compose runコマンドは、docker-composeの特定のコンテナを起動させるものです。
なのでdockerのなかにdbとwebがありますが、その中でwebコンテナが生成されて立ち上げられます。またdepends(依存関係)にdbを指定しているのでdbも立ち上げられます。
本来はdocker-compose upコマンドでdockerを実行すべきですが、今回に限ってうまく動いています。
でもなるべくdocker-compose runではなくdocker-compose upを使うべきだと思います。

さらに、docker-compose runは、runのあとにcomposeに書いた名前だけではなくさらに何かを書いた場合そのコマンドが実行されるので、myappに対して動作を行っているのだと思われます。

疑問2:localhost:3000で制作仮定がブラウザで見れる理由

docker-compose.ymlでportを指定した場合、ホストのポートとコンテナのポートをつなげることができます。つまり、今回の場合はホストの3000版に来た通信はすべてwebコンテナの3000版へ転送されることになります。なのでローカルで起動しているrailsではなくコンテナの中で実行されているrailsへ正常にアクセスしているものだと思います。

投稿2017/05/21 06:39

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

PartyKids

2017/05/21 10:15

いつも丁寧に回答して頂きありがとうございます! 丁寧に説明して頂いたのに、私の説明が下手で、質問の趣旨とは異なる回答をさせてしまって、申し訳ございません。 dockerfileやdocker-composeについての質問ではなくコンテナの中身についてです。 rails newコマンドはweb_run_1コンテナ、rails g contollerコマンドはweb_run_4に属しています。 docker inspectで各コンテナの中身を調べると、各コンテナはコンテナを動かしたコマンドしか有していないことが分かりました。 つまり、web_run_4コンテナはアプリケーション作成コマンド(rails new)を有していない。 そのため、web_run_4コンテナはアプリケーション作成(rails new)をしなくても、rails g controllerでコントローラーを作成する事が出来たという考えに疑問を抱き質問させていただきました。 補足 docker ps -aをしてもwebコンテナは見つからず、web_run_1やweb_run_2といったコンテナが出来ています。 ご迷惑をおかけして申し訳ないですが、よろしくお願いいたします!
退会済みユーザー

退会済みユーザー

2017/05/21 15:10

なるほど。まずdocker-compose runというものは「docker-compose.ymlを元にして新しくコンテナを作る」コマンドです。なので「毎回コマンドごとに新しくコンテナが生成される」という現状になっています。 PartyKidsさんがしたいのは、おそらく「毎回同じコンテナに対してコマンドを実行したい」ということになると思うのですが、それで会っていますでしょうか? ちなみに、rails newをせずにrails gができたのは、コマンドがコンテナの/myappの中で実行されるため、成果物である/myappに対してコマンドが実行されているのが原因だと思われます。すでに成果物というプロジェクトがあるはずなので…。 と言う私はrailsの経験が少ししかないのでrailsに関しては完全に素人なのです…。すみません><
PartyKids

2017/05/22 11:33

返信ありがとうございます! >「毎回同じコンテナに対してコマンドを実行したい」ということ その逆なんです。。。毎回違うコンテナが作成されるのに、なぜコントローラーやモデルを作成することが出来るのか?です。毎回違うコンテナが作成されるため、コントローラーを作成したコンテナはrails new無しにコマンド実行させる事ができてしまう事に疑問を持っています。 >コマンドがコンテナの/myappの中で実行されるため 分からないながらも、この文がキーのような気がします。。。volumeでマウントをしていないなら、各コンテナは、そのコンテナで実行されたコマンドしか有していないため、多のコンテナに影響を与えない。しかし、マウントしている場合には、過去にコンテナで実行されたコマンドの結果をマウントする物が保有している事になるため、多のコンテナに影響を与える。ですかね? 私の質問文が下手で、勘違いをさせて申し訳ございますん。 ご迷惑をおかけしますがよろしくお願いいたします!
退会済みユーザー

退会済みユーザー

2017/05/22 13:34

はい。myappが同期されているため、おそらく毎回コマンドごとにコンテナを立ち上げてもmyappへの反映がすべてのコンテナで動悸されてしまうのだと思います。 なのでrails newをしなくても他のコンテナでrails newをしているため同期機能でrails gができるのだと思います。
PartyKids

2017/05/23 11:25

返信ありがとうございます! >rails newをしなくても他のコンテナでrails newをしているため同期機能でrails gができるのだと思います。 そういう事だったんですね! いつも助けて頂き、本当に有難うございます! 今後ともよろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2017/05/24 07:28

解決できてよかったです! こちらこそよろしくお願いします!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問