2021年4月26日月曜日

docker Node.jsの実行環境完成

 dockerを使ったNode.jsの実行環境を作りました。

実際には、データベースも含みますが、それは省略して、このようなフォルダ構成にしました。

フォルダ構成は、実行環境、開発環境により、様々な方法がありますが、VSCodeでの開発を前提にして、このようにしてみました。


MyApp

├─ .devcontainer

│   ├─ devcontainer.json

│   ├─ docker-compose.yml

│   └─ Dockerfile

├─ src

│   └─ 

├─ docker-compose.yml

├─ Dockerfile

├─ app.env

└─ .dockerignone



開発環境のdocker(.devcontainerフォルダ内)は、まだ、未完成ですから、ファイル構成のみ、書き残します。


プログラムのソースは、srcフォルダに置くことにしました。



docker-compose.yml


version: '3.8'

services:

  app:

    build:

      context: .

      args: 

        - NODE_ENV=production

    container_name: tp_app_container

    env_file: ./app.env

    environment:

      - TZ=Asia/Tokyo

    ports:

      - '80:3000'

    restart: always

    working_dir: /app

    command: npm start



Dockerfile


FROM node:14-slim


ARG NODE_ENV=production

ENV NODE_ENV $NODE_ENV


ARG PORT=3000

ENV PORT $PORT

EXPOSE $PORT


WORKDIR /app


RUN chown node:node /app

USER node


COPY --chown=node:node ./src/package*.json ./

RUN npm install

COPY --chown=node:node ./src .



.dockerignone


.git

*Dockerfile*

*docker-compose*

node_modules



狙いとしては、

・Node.jsのエラー時の再起動の管理は、dockerに任せる

・実行は、nodeユーザー

・ソースは、コンテナ内にコピーして実行する



この構成にたどり着くまでに苦労したのは、フォルダ、ファイルの権限です。

rootで実行するなら悩むことはありませんが、nodeユーザーで実行するために試行錯誤しました。

RUN chown node:node /app

がポイントです。

COPY --chown=node:node ./src/package*.json ./

の--chown=node:nodeは、この場合、不要だと思いますが、今後、Dockerfileを修正したときに忘れないように、残しておきました。

2021年4月25日日曜日

docker ファイル権限に悩む

 dockerのファイル権限に悩みました。


node.jsの実行環境を作っています。

参考にするべきは、node.jsの公式HPです。

こちらに、方法が書かれているので、これが正解です。

横着しようと、google検索で調べたために、遠回りしました。

rootユーザーで実行するなら、これで終わりです。


nodeユーザーで実行しようとしたのが、今回の迷走の原因でした。

nodeユーザーで実行しようとすると、volumeのファイルの権限を意識する必要がありました。


例えば、このようなエラーが発生しました。

npm WARN checkPermissions Missing write access to


公式のHPのように、ソースをコンテナ内の/usr/src/appに置くなら、Dockerfileに、

RUN chmod node:node /usr/src/app

を追加することで解決しました。


これを行わないと、npm install時に、アクセス権限のないフォルダ内で、フォルダの作成を行おうとすることになり、エラーとなります。


こう書くと、単純な話ですが、これに、volumeのバインドが絡んでいたため、非常に苦労しました。

結局、volumeをバインドする必要はないと気づき、コンテナ内にファイルをコピーすること(公式HPのまま)で解決しました。



プログラムの開発時は、volumeのバインドが必要になるため、もっと、ややこしいことになります。

gitの管理をコンテナの中で行うのか、外で行うのか。

gitの管理をコンテナ内で行うなら、完全に、外と分離するのか。

それとも、ローカルとのファイル共有を行うなら、競合を発生させないために、どうするべきか。

開発マシンが、linuxでもwindowsでも動くようにするには、どうするのか。

コンテナ内では、rootで実行するのか、あるいは、nodeかvscodeか。


これらを考えて、試行錯誤すると、ソースのファイル権限の関係で、エラーが発生します。

発生するのは、npm installの行ですが、他にも、WORKDIRで指定したフォルダがないというエラーが発生したりします。

buildの1回目にエラーが出て、2回目はエラーが出ないという現象にも遭遇し、頭の中は、大混乱です。


とりあえず、実行環境が完成したので、一歩前進です。

2021年4月21日水曜日

w2ui 不具合に悩む

 w2uiライブラリを使っています。

しばらく前から、奇妙な不具合に遭遇し困っていました。

データが、13行以上なら表示されるが、13行未満の場合、表示されません。

どうやら、1ページに表示できる範囲のデータの場合、表示されないようでした。


ライブラリのバージョンを、1.4から、1.5に上げることで解決しました。


2021年4月11日日曜日

WSL docker ubuntuを入れる意味

 Windows10に、WSLを入れて、dockerを使っています。

この環境で、疑問に思っていたのは、なぜ、別途、ubuntuを入れる例が多いのかでした。


WSL2を入れれば、dockerは動きます。

WSLのubuntuを、別途、導入しなくても、問題はありません。

VSCodeを使い、新たに、コンテナを起動し、その中で開発を進めれば良いだけです。


ubuntuを導入する例が多いのは、昔の名残なのかなと思っていました。


ubuntuを導入する意味が理解できたのは、Windows10で作成したdockerを、linux上で実行したときでした。

動きません。

ファイルの権限の問題で、コンテナの実行に失敗しました。

Windowsのファイル権限の仕組みと、linuxでのファイル権限の仕組みが異なるために、ソースをWindows側に置き、コンテナ内から利用する設定にしていると、windowsでは動くのに、linuxでは動かないということになります。


過去の日記

https://cikou.blogspot.com/2021/04/dockervolume.html



ここで、ubuntuを導入する意味が分かりました。

ubuntu側に、dockerのソースを置いておけば、dockerの開発時も、dockerの本番時も、同様に扱えるのだと理解できました。


このためには、dockerの設定で、「WSL INTEGRATION」から、ubuntuを有効にする必要がありました。


これで、Dockerfileは、ubuntuシステム内に置いて、ubuntu内のVSCodeを起動。

そのVSCodeを、Windowsからリモートで操作。

つまり、WindowsのVSCodeから、ubuntun内のVSCodeを操作する。

ここで、開発に使うコンテナを起動し、その中で、VSCodeを使うことができました。

Windows、ubuntu、コンテナ内と、3箇所に、VSCodeを入れる流れになりますが、後者の2つは、ほぼ、自動的に入りますから、面倒ではありません。


これで、ようやく、WSLとdockerの関係性が理解できました。


2021年4月5日月曜日

docker 少し、理解が進んだ

 dockerの理解が、少しだけ、進みました。

VSCodeのdocker向けの拡張を利用すると、開発環境の構築が簡単になります。


しかし、これが、悩みの元で、試行錯誤しました。

今、思えば、単純な話でした。

思い違いしたのは、市販の本は、開発環境の構築に、dockerを使っている例が多かったので、それを見習ったことでした。

これ自体は間違いではありません。

開発環境を構築した後、本番向けの環境を構築しようという順番に、意識が向いてしまったのが問題でした。

本番向けの環境を構築し、それを開発環境にアレンジする流れが正解でした。

VSCodeでは、本番向けのDockerfileを含んだフォルダを、reopen in containerを選ぶことで、開発環境向けのDockerfileを作ってくれました。(厳密にいうと違いますが)

この流れで良かったのです。


開発環境の構築関係の情報は、この最後に作られたDockerfileを含んだ環境を説明しているので、先に、これを作るのだと勘違いして、頭が混乱していました。

もちろん、場合によっては、開発環境を先に作っておいて、プログラムをテストしてみるという場合もありますから、逆の流れもあります。

このあたりの位置づけが理解できて、すっきりしました。

2021年4月1日木曜日

dockerに悩む volumeの権限の問題

 docker、難しいです。

希望する動作があるとして、それを実現する手段は、複数あります。

現時点で、どの手段が最適なのかを考えると、なかなか選べません。


仮想マシンであれば、仮想イメージを、windowsでもlinuxでもコピーすれば動きます。

しかし、dockerは、そうはいきません。

異なるホストOSでも動くように、dockerの環境を構築していれば問題ないのかもしれませんが、その方法は勉強しないとわかりません。まだ、その域に至っていません。

現在、はまっているのが、volumeの権限です。

ホストのファイルを、コンテナからでも利用できるようにすると、これが、ファイル権限の問題でエラーになります。

windowsなら、問題になりません。

linuxに持っていくと、エラーになります。

コンテナ内のユーザーと、ホストのユーザーが異なることが原因です。


chmod 777にするのは、今後の管理を考えるとやりたくありません。

コンテナに特権を与えるのは、なんだか怖い。

両者で共通のユーザーを作るのも、今後の管理を考えるとやりたくありません。

コンテナ内のユーザーのuid、gidを変えるのが良さそうですが、ホストのuid、gidを取得して、コンテナに与える部分を、簡単にできないか、検討中です。