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

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

新規登録して質問してみよう
ただいま回答率
85.49%
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Docker

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

3044閲覧

(Docker)nodeを用いたフロントエンド用のコンテナが起動しない

hoboki

総合スコア52

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Docker

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2022/03/30 05:45

DockerでNode.js用のコンテナを作成しようとしていますが、コンテナの起動が上手くいきません。
要素を最小限にしてもだめでした。
Docker Desktopに何もエラーログが出ないので、原因の特定に難を要しています。

ご意見いただきたく存じます。

project/docker/front/Dockerfile

Dockerfile

1FROM node:17-alpine 2 3WORKDIR /var/www/js

project/docker-compose.yml

yml

1version: "3.8" 2 3services: 4 front: 5 build: 6 context: ./ 7 dockerfile: ./docker/front/Dockerfile 8 restart: always 9 volumes: 10 - ./src:/var/www/:cached 11 working_dir: 12 /var/www/js/ 13 ports: 14 - "3000:3000" 15 16volumes: 17 db-store:

実行コマンド

bash

1docker-compose up -d front

環境情報

Windows10 Home
Docker version 19.03.13, build 4484c46d9d
Docker Desktop 2.5.0.1
WSL2 Ubuntu18.04

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

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

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

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

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

guest

回答2

0

ベストアンサー

駄目な箇所を箇条書きにしていきます。

  1. 実行コマンドがない
  2. srcディレクトリだけがNode.jsのプロジェクトではない
  3. フロントってなんだよ

1つずつ見ていきましょう。


Dockerは単なる仮想環境ではありません。
「ターミナルの1コマンドのみを確実に実行させる為にディレクトリ構造を整えて動かす仮想環境」です。
なのでその「実行すべき1コマンド」はなんぞや?がとても重要になります。

次に/srcディレクトリだけを中身として突っ込んでいるのが問題です。
Node.jsのプロジェクトというのはプロジェクトルートにpackage.jsonというプロジェクトの概要を説明するファイルが存在し、
npm installコマンドを実行すると、package.jsonを読み込んで依存モジュールをダウンロードし、/node_modulesディレクトリに保管してくれます。
その後、/srcのJavaScriptファイルがrequire("モジュール名")でモジュールを読み込む事を指定したら
プロジェクトルートにある/node_modulesからJavaScriptファイルを探してきてロードしてくれます。

また1コマンドの方に着目した場合、
package.jsonファイル内にコマンドを登録してnpm run xxxで呼び出すnpm-scripts
Gulp等のタスクランナーといったプロジェクトを実現する為のファイル群もプロジェクトルートにあるでしょう。
これを使って1コマンドの動作を担保すべきなので、/srcディレクトリだけが内部にコピーされて実行されるなんて絶対にありえないのです。

この2項目を加味した場合のdocker-compose.ymlファイルは下記のようになってることかと思います。

yaml

1version: "3.8" 2 3services: 4 front: 5 build: 6 context: ./ 7 dockerfile: ./docker/front/Dockerfile 8 restart: always 9 volumes: 10 - .:/var/www/:cached 11 working_dir: 12 /var/www/js/ 13 ports: 14 - "3000:3000" 15 command: "npm start" 16 17volumes: 18 db-store:

まぁ、それでは1ミリも解決しないと思うので最後の項目に行きましょう。


フロントってなんだよ

質問文からは読み取れない項目です。
なのでエスパー回答するので、照らし合わせながらdocker-compose.yml等を作り込んでください。

volumesの:/var/www/:cached

/var/wwwってなんやねん?
これはApacheを起動させてWebサーバとして稼働させた時にデフォルトのルートディレクトリです。
なので、Apacheで動作してほしいんですよね。
(その他の、例えばNginxなりExpressjsを想定しているかもしれないけど)

前項で散々「実行したい1コマンドが大事なんだよ」と説明しましたが、
ApacheやNginx、MySQLの既製品サーバが前提となっているなら話は別。
最初からそのサーバーソフトウェアを実行する為のコマンドがイメージ内に注入されてるので、新しく何かする必要はありません。

今回説明したのは、それがない実行ファイル&環境だけが入っているNode.jsを指定しているからです。
勘違いしないようにしてくださいね。

DockerfileのFROM node:17-alpine
このイメージ(仮想マシン)にはNode.jsの実行ファイルしか入ってないので、
これにApache入っとるんか?って言われても入ってるわけないですよ。

だから、回答者のわたしが質問文を読み取った感じでゴールを設定すると、
「SASSやPugなどのテンプレート言語で書かれたファイル、Node.jsのしきたりで書かれたJavaScriptファイル
これらを静的なHTML、CSS、JSファイルにコンパイルしてから、Apacheで実行したい!」
となるわけです。

Node.jsとApacheが同居してるイメージなんてなので、一見困ったとなるのですが、
Dockerが考えてないわけないじゃないですか。
ちゃんと「マルチステージビルド」という形で用意されています。

参考記事

このマルチステージを使うと、
一度Node.jsのイメージを起動させてGulpやWebpack等を実行して静的ファイル達にコンパイルして
Node.jsのマシンで出来上がった静的ファイルをApacheだけが入っているイメージにコピー
その後Apacheだけが入っているイメージのみを保存

こういう形でフロントエンドのイメージを作成する事が可能となります。
Apacheで調べたらhttpdという名前だったのでそれを使いますかね。

Dockerfile

1FROM node:17-alpine AS build-env 2ADD . /work 3WORKDIR /work 4RUN gulp build # ここに静的ファイル群を生成する為の実行コマンドを記述する 5 6FROM httpd:2.4-alpine 7COPY --from=build-env /work/dist /usr/local/apache2/htdocs/

一般的にsrc(ソース)、コンパイル前のファイルを指す言葉であり、
生成されたファイルはdist(ディスティネーション)、コンパイル等を行ったあとに生成される成果物を指します。
なのでプロジェクトルートにdistディレクトリをつくって、それをApacheイメージが「個々に保存しろ」と指定したディレクトリにコピーするというDockerfileを作りました。

yaml

1version: "3.8" 2 3services: 4 front: 5 build: 6 context: ./ 7 dockerfile: ./docker/front/Dockerfile 8 restart: always 9 volumes: 10 - ./dist:/usr/local/apache2/htdocs:cached 11 ports: 12 - "3000:3000" 13 14volumes: 15 db-store:

これである程度進むんじゃないですかね。


最後に

dockerfile: ./docker/front/Dockerfile

これ絶対社内に詳しい仕事できるエンジニアいるでしょ。

知らない事を聞けないのはチームである意味がないので、
ある程度勉強するのは良いと思いますが、
実際問題どうするか、最終的な判断はその人に相談してください。

投稿2022/03/30 07:02

編集2022/03/30 07:06
miyabi-sun

総合スコア21158

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

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

hoboki

2022/03/30 07:40

ご回答ありがとうございます。しがない大学院生の個人開発で申し訳ありません。 実際にはDjango, Nginx, Mysqlコンテナも併用しています。 端的にお伺いしたいのですが、このコマンドだけでコンテナが落ちる原因は何でしょうか? サーバーがないとかの話以前に、コンテナが起動してくれないのです。
miyabi-sun

2022/03/30 11:45

Dockerは1コマンドを実行するだけで、そのコマンドの実行が終わったら正常終了します。 今まで立ち上げたDockerのコンテナは「たまたま」Django、Nginx、MySQL等といった 「終了させない限り一生動作し続ける」サーバーソフトウェアの実行というコマンドが注入されていたようです。 なのでコンテナが一度起動したらエラー等で死なない限りずっと実行し続ける仮想マシンなんだ?と勘違いしてしまってたのでしょう。 フォローしておくと、多くのケースでサーバの動作目当てにDockerを使うものなので そういう動作を期待するのは当然で、リアクションとして間違ってはいません。 知識として「1コマンド実行して正常終了してしまうものなんだ」という事は知っておいてください。 というわけで`docker-compose ps`等で確認してみてください。 特別な実行し続けろ命令等がないようなので、正常終了のステータス0等で終わってると思います。 または`docker-compose logs`などで動作ログの確認をしてみるのも良いと思います。 標準出力した内容が残っていると思います。 もし、これからDockerfileを書くために `docker-compose exec -it front sh`等で入ってソフトウェア等の実行検証したいんだ だからサーバーを継続動作するようなコマンドが注入されてないからといって、勝手に終了してもらっては困るんだ。 こういうフェイズだった場合は`tty`を使うと勝手に終了せず起動しっぱなしにできます。 (もちろんメモリやストレージを消費しちゃうので、作業後は忘れずにコンテナを潰しましょう) commandの部分には`sh`等の中に入ってそうなコマンドを適当に設定しておいてあげてください。 https://qiita.com/sekitaka_1214/items/2af73d5dc56c6af8a167
hoboki

2022/04/14 00:40

返信遅れて申し訳ありません。 なるほど、コマンド次第では正常終了するものなのですね、、、 様々学ばせていただきました。ありがとうございます。
guest

0

一般的にnode.jsの場合、コンテナが起動したら実行するファイルをdockerfileならCMD [ "node", "app.js" ]、docker-composeならcommand: node app.jsで指定するはずです。
今回何か実行するファイルを用意していますか?
用意していない場合、コンテナはnode.jsの実行環境が整っているコンテナ(サーバー)なので、起動しても何も起こらないと思います。

投稿2022/03/30 06:54

YuuT

総合スコア673

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

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

hoboki

2022/03/30 07:43

ご回答ありがとうございます。 何も起こらないならまだしも、コンテナが落ちてしまいます。 こちらの原因はわかりますでしょうか?他のコンテナと一緒に立ち上げないと落ちるなんてことありますか?
YuuT

2022/03/31 00:14

既に回答ありますが、dockerの仕組みについて理解したほうが良いと思います。 今回コンテナが落ちるのは正しい動作です。 コンテナはvirtualboxの様な仮想マシンとは異なり、コンテナという枠の中に基本は1プロセスを動かすように設計されています。 プロセスはlinuxの場合psコマンドでものや、今回の場合例で挙げたnode app.jsで実行したプログラムです。 コンテナのライフサイクル(起動から停止まで)は、コンテナを立ち上げ、指定されたコマンド(CMDやcommand)を実行し、そのプロセスが終了するとコンテナは終了します。 (仕組みとしてコンテ内のプロセスの数が0になるとコンテナは終了します) 例えば、hello worldと表示するapp.jsを作成してコンテナを起動した場合、hello worldを表示した後app.jsのプログラム(プロセス)は終了するので、コンテナも終了します。 今回の場合、何もコマンドを指定していない(起動するプロセスを指定していない)ので、コンテナ立ち上げ後すぐにコンテナが停止、理解している人からすると正常終了しているわけです。 他の回答者の内容は、起動時にshellのプロセスを立ち上げることで、コンテナ内のプロセスを1つ立ち上げコンテナを起動し続けさせる方法です。(docker-compose exec -it front sh) これはshellが停止するとコンテナはプロセスがなくなるので終了します。 ttyはコンテナが勝手に落ちるのが困る場合に、他のプログラムに影響がなく、停止しないプロセス(tty)を1つ立ち上げることでコンテナの起動を維持する方法です。 最後に、デフォルトのnode:17-alpineではnodejsの対話モードが起動するように設定されているようですが、この辺り詳しくないので時間があれば動きを確認してみます。
hoboki

2022/04/14 00:42

返信遅れて申し訳ありません。 確かにdocker-compose exec -it front shでコマンドを確認できることを失念しておりました。 学ばせていただきました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問