初めてDockerを使った(備忘録)

2023/03/21に公開

Dockerを使った感想

  • もっとDockerを知りたい
  • 超便利

あまり知らなかったLinuxコマンド

/bin/bashコマンド

  • Linuxでコマンドなどの命令文を記述したシェルを実行するために使われます。
  • 以下のコマンドでコンテナ内のbashを起動します。
コマンド
docker exec -it my-server /bin/bash

apt-getコマンド

  • ATPライブラリを最新版へ更新(update)
  • -y インタラクティブ(ユーザーへの問い合わせ)に「yes」と答えます。
コマンド
apt-get [スイッチ] [オプション] [パッケージ]
apt-get update -y

永続化問題

  • 仮想環境はディスク上にあるが、dockerはメモリ上にあるためパソコンの再起動で消える
    • 特にDBなどが課題になるが永続化は可能
    • ホストマシンのディスクに書き込めばいい
    • この時二重管理になるのか?書き込みが2倍になって処理が重たくなるのか?

Windows環境でインストールできるDocker

  • 「Docker Desktop(Windows)」もしくは「Docker Toolbox」
  • Docker Desktop(Windows)はHyper-Vを使用したOSネイティブで動作する

https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v

Dockerベストプラクティス

https://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html

Dockerfile内でのコマンド

  • RUN:Dockerfile→image

  • CMD:iage→コンテナ

  • MySQL のデフォルト設定は/etc/mysql/my.cnfにある

  • カスタムMySQL構成ファイルを使用したいときはCOPYやvolumeで定義する必要がある

コマンド
COPY my.conf /etc/mysql/conf.d

https://hub.docker.com/_/mysql

するとこんなエラーが...

エラー
error during connect: This error may indicate that the docker daemon is not running.

Docker Desktopを起動したら治りました。

dockerの起動

imageの作成

コマンド
docker build -t [タグ名] [指定したDockerfileのあるディレクトリ名]

コンテナの起動

  • 特にPortの指定はなし
  • 今回はポートフォワーディングする必要がないため
コマンド
docker run --name [コンテナ名] [imageのタグ名]
  • コンテナの中に入り、ログインする
コマンド
docker exec -it [コンテナ名] /bin/bash
mysql -u [ユーザ名] -p

docker-composeからbuildする時

  • Dockerfileがあるディレクトリ指定
コマンド
services:
  app:
    build: ./dir
  • 特定のDockerfileを指定したい時
コマンド
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile

Dockerfileで詰まったところ

Dockerfileにenvを記述しているのに読み込んでくれない...

Dockerfile
ENV DISCORD_TOKEN = xxxxx
ENV OPRNAI_ORG = xxxxx
ENV OPENAI_KEY = xxxxx
エラー
(node:1) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
/usr/src/node_modules/discord.js/src/client/websocket/WebSocketManager.js:134
  const invalidToken = new DiscordjsError(ErrorCodes.TokenInvalid);
                       ^
Error [TokenInvalid]: An invalid token was provided.
  at WebSocketManager.connect (/usr/src/node_modules/discord.js/src/client/websocket/WebSocketManager.js:134:26)
  at Client.login (/usr/src/node_modules/discord.js/src/client/Client.js:226:21)
  at Object.<anonymous> (/usr/src/index.js:72:8)
  at Module._compile (node:internal/modules/cjs/loader:1101:14)
  at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
  at Module.load (node:internal/modules/cjs/loader:981:32)
  at Function.Module._load (node:internal/modules/cjs/loader:822:12)
  at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
  at node:internal/main/run_main_module:17:47 {
code: 'TokenInvalid'
}

Dockerfileに記述されたenvはコンテナ起動時には読み込んでくれなさそう...
起動時にenv情報を渡してみると無事に起動

コマンド
docker run --env DISCORD_TOKEN=xxxxx --env OPRNAI_ORG=xxxxx --env OPENAI_KEY=xxxxx [イメージ名]
起動

このままだと面倒なのでenvファイルを渡すことに...
しかし、以下のようなエラーがでてきました

コマンド
docker run --env-file .env chatbot-demo-sub
docker: poorly formatted environment: variable 'OPRNAI_ORG ' contains whitespaces.
See 'docker run --help'.

emvの=の左右にスペース入れちゃだめなんですね...いままで気にしたことがなかった...
以下のように修正して起動

.env
DISCORD_TOKEN=xxxxx
OPRNAI_ORG=xxxxx
OPENAI_KEY=xxxxx
コマンド
docker run --env-file .env chatbot-demo-sub
起動

DockerのWORKDIR

WORKDIR命令は、Dockerfile 内で以降に続くRUN/CMD/ENTRYPOINT/COPY/ADD 命令の処理時に(コマンドを実行する場所として)使う 作業ディレクトリworking directory を指定します。
https://docs.docker.jp/engine/reference/builder.html#workdir

相対パスで指定すると、/usr/src内にCOPYされます。
「.」と書かれているので/usrに入ると思いがちなので注意。
CMDの./index.jsもWORKDIRで指定したパスからの相対パスでしていするので、./index.jsでOK

Dokcerfile
WORKDIR /usr/src
COPY . .
CMD [ "node", "./index.js" ]

下のような例が分かりやすいかも
/usr/src/data/index.jsの配置になります。

Dokcerfile
WORKDIR /usr/src
COPY . data
CMD [ "node", "data/index.js" ]

docker-composeの起動

あとはdocker-composeを作成して起動

docker-compose.yaml
version: "3.0"
services:
  chatbot:
    build: .
    image: chatbot-demo
    container_name: chatbot
    env_file: .env
コマンド
docker-cmpose up
[+] Running 2/1
 - Network chatgpt-chatbot_default  Created
       0.6s
 - Container chatbot                Created
       0.1s                                                                                                          0.6s 
Attaching to chatbot                                                                                                 0.1s
chatbot  | ChatGPT Bot is Online on Discord
chatbot  | (node:1) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time                                                                                                       ny time
chatbot  | (Use `node --trace-warnings ...` to show where the warning was created)

一通り軽くDockerに触れることができました。
びっくりするくらい便利だったのでもっと使えるようになりたいです。

Discussion