Twitterで冬休みの間にポートフォリオを作ると宣言して一応設計書までは準備したのだが、
dockerでLaravel環境を作ろうとして結局挫折した。
とはいえ作らないとポートフォリオ自体いつまでも作れないので、docker自体を勉強し直すことに。
(冬休みには作れなかったけど、せっかく設計書書いたのでポートフォリオ自体は最後まで作成します)
詰まったのはどこかというと、
DockerFileを作るまでは良かったけど、そこから docker-compose
コマンドを実行しようとしたところ。
そんなわけで復習も兼ねて上のコマンドを実行できるようになるまでここに書き連ねたい。
基本的なコマンド
dockerをnginx環境で起動(例)
※nginx ・・・エンジンエックスと読む。いわゆるWebサーバーの一種
えーとニジンクスかなと推測して読んでたら全く違う読み方だった。。。
apacheもアパッチェと思ったらアパッチだったし(ただし、コマンド上はhttpd
)
nginxの場合
docker run -p nginx
Apacheの場合
docker run -p httpd
>>> dockerドキュメント
※ -p(ポートの略、ポート公開ということ)とかのオプションの説明はドキュメントを見た方が早い。
※ どの環境でrunできるかは、dockerhubで検索しよう(ついでにログインもできるように新規登録もしておこう)
※ https://labs.play-with-docker.com/ で、dockerの実験ができるので、勉強がてら触れる(docker-hubのログイン必須)
docker 停止
コマンドライン上で ctrl
(Macだとcontrol
) + c
で停止
コマンド上でもshutting downなどの反応があり、閉じてることがわかる
Docker imageをpullしてdocker上で動かす
Docker imageはdockerに入れるOSとかソフトウェアとかPHPとかのランタイムを全てをパッケージ化して保存したようなもので環境のスナップショットというらしい。
つまりこれをpullしたらdockerでインストールが始まり、その後は何も設定しなくても動かせるようになるというもの。
前に紹介したDocker Hubでは、こういうDockerimageがたくさん公開されている。
例えば php だったり、ubuntuだったりもDockerHub上から取得できるが、Webサイトにいかなくてもコマンド上でもpullできる。(docker pull (取得したいツール名)
)
見つからない場合はdocker search (取得したいツール名)
で検索
(OFFICIALにOKとあるのがDocker公式のもの)
例えばphpならこれ
docker pull php
ubuntuを検索するならこれ
docker search ubuntu
OSでもランタイムでもソフトウェアでもいける。(ubuntuとか)
Dockerfileを作成してアップロードして動かす
さてある意味本題。
DockerfileとはDockerImageを作るための設計書みたいなもの。
これを自分で作って実際にやってみてOKかどうか確認しながら調整していく。
ここで色々躓いているので、躓きやすいポイントから。
まずそもそも、Dockerは1つの大きなフォルダ単位のフォルダで、
その中でOSなり、ソフトウェアなり、ランタイムなどが動く。
そのためフォルダ内にOSのフォルダだったりランタイムのフォルダがサブフォルダとして置かれている。
dockerが動かない原因で一番多いのは dockerFileが置かれているフォルダを間違えていること。
Laravelと同じで、置かれているフォルダにdockerFileがないとdocker自体が動かない。
ディレクトリの位置だったり、パスだったりが重要。
1. ディレクトリ周りの整理
とりあえずubuntu環境作ってコマンドでhello dockerworld!と出力するまでやる
というわけでいきなりコマンド(macなのでWindowsは適宜読み替えてください)
1行ずつやってもいいし、全部コピペして貼り付けてもOK
cd ~
mkdir -p DockerOS/ubuntu
cd DockerOS/ubuntu
echo "hello dockerworld !" > helloworld.txt
vi Dockerfile
(説明)
1行目: cdでホームティレクトりに移動
2行目: mkdirはディレクトリを作るコマンド、-pはサブディレクトリも作っちゃうオプション、
というわけで、dockerフォルダ、その中にubuntuフォルダも一気に作っちゃう
3行目: 一気にubuntuフォルダまで移動
4行目: (コマンド) > helloworld.txtというファイルに(コマンド)を記載
5行目: Dockerfileを作り、さらにviを起動(コマンドライン上のエディタ)
(実行後)
viが起動し、コマンド上でDockerfileの編集画面になる
普段のコマンドラインと違うところとしては、左端に行番号が現れるところ。
****
次に、Dockerfileの編集画面で、
FROM ubuntu
COPY helloworld.txt /tmp/helloworld.txt
CMD ["cst" , "/tmp/helloworld.txt"]
とうち終わったらesc
を押して編集終了し、
さらにshift
を押したまま、 z
を2回押せば(つまり大文字のZ
キーを2回押すということ)
上書き保存して終了し、元のコマンドラインに戻る。
編集できているのを確認する。
※もしescを押しても返答がない場合はやり直した方がいいかもしれません。
私の場合はやり直していけました
※viの操作がわからなければ、普通に新規テキストファイルで上の文章を入れて保存する、でも良いです。でも慣れれば短い場合はこっちの方が早くできるので、練習の意味でもやってみた方がいいかと。
これでディレクトリの準備はOK
2.Dockerimageの作成(ビルド)と、実行
いきなりコマンドから。
※cdはDockerOS/ubuntuのところにいる状態のまま。もし他の場所に移動してしまったら、cdでubuntuのところまで移動しておく。
docker build -t helloworld .
Dockerfileから作るDockerImageを「helloworld」にするという意味で、
最後の「.」は打ち間違いではなく、COPYコマンドを実行するときにどのディレクトリを起点にするかを指定するもの。
この場合、dockerfileがあるフォルダということになる
実行してerrorが出なかったら、dockerimageがビルドできたか確かめる
docker images
リストにあったらOK
次に、イメージからコンテナ作成実行
docker run の後に追加したRepository名を入れる(上のdocker imagesで出てきたもの)
docker run helloworld
そうすると、
hello dockerworld!というのがコマンドラインに出力され、完了
3.DockerHubへのアップ
ローカルで開発したイメージをステージングや本番環境で動かすには、DockerHubにアップして置かないといけない。ログインとか新規登録したのはこのため。
※クラウドの場合だとどうやらレジストリサービスがあるので、AWSとかGCPではマニュアルをみたほうがいい。後で確認する
docker login
でユーザ名とパスを入れてログイン。
(メールアドレスだとダメでユーザ名でないといけないらしいです。マイページに出てくるアカウントの名前を入れればOK。)
Docker hubにアップロードするときには、下記のようにする
docker tag helloworld <ユーザ名>/helloworld
例)ユーザ名が999hogehogeだったら
docker tag helloworld 999hogehoge/helloworld
dockerimageの確認=>コマンドは? わからなければ上を見て復習
次に、アップロード
docker push <ユーザ名>/helloworld
例)ユーザ名が999hogehogeだったら
docker push 999hogehoge/helloworld
終わったら、Docker Hubの確認
レポジトリにアップしたのがあるか見ておく
Docker HubにアップしたDocker Imageの実行
→ 現在のローカルイメージを削除しないとDockerHubから取得ができないため
docker container ls -a
docker container prune
docker image prune -a
lsは参照、-aは全てという意味。
pruneは削除.(2行目はコンテナ、3行目はイメージから)
dockerのイメージがもう全部残ってないか確かめるには?
わからない時は上を見て復習
次にDocker Hubから作成したイメージを取得するには
docker pull <ユーザ名>/helloworld
次にdockerイメージの実行
docker run <ユーザ名>/helloworld
Hello, dockerworld!
が表示される
ここで基本的な流れは完了
Dockerfileで使うコマンド
17コマンドしかない
中でもよく使うのは7つぐらい
基本的にベースとなるDockerImageをDockerHubから調べて持ってきて、その上にCOPYやRUNを加えてDockerImageを使う。
FROM
ベースとなるDocker Image(例:node/php/ignix/httpdとか)
COPY
ホストのファイル・ディレクトリをコピー 引数1がホスト側ディレクトリ(docker build .
で指定したディレクトリ)、引数2がDocker側ディレクトリ(WORKDIR
で定義したディレクトリ)
RUN
コマンド実行(コンテナへ依存するライブラリ、パッケージのインストール・ユーザ設定などの処理)
CMD
Docker起動時にデフォルトで実行されるコマンドを定義。なお、フォアグラウンドで実行するように定義しなければならない。(バックだとすぐ止まるため)
WORKDIR
コマンドを実行する時基準となるディレクトリを設定。存在しなければ作成する。
→既存のディレクトリを上書きする場合もあるので注意
ENV
Docker内での環境変数を定義
USER
作成したDockerImageを起動ときにログインするユーザーを指定。デフォルトがroot
なので他のユーザーを指定すること。
ADD
COPYの拡張版。COPYと同じく指定したパスをコンテナ内にコピー、URLを指定したらそのURLからファイルをDL,コンテナ内にコピー、コピーされたパスが.tar系
だったら解凍するという3つの役割がある 第1引数はコピーしたいファイル名、第2引数はコピー先のパス。コピーしたいファイル名
それ以外だと
EXPOSE
コンテナ起動時に公開することを想定しているポートを記述しておく。
また、EXPOSEで指定されたポートを公開するには run -P ...
とする
AGES
Dockerfileのビルド時に変数を使用するためのコマンド。基本的に使用しない
ENTRYPOINT
指定されたコマンドを実行。docker run
時に指定したコマンドをこのコマンドの引数として使用。普通の場合、CMDを使うので、そうでないと初心者が混乱するため使用しない方がいい
VOLUME
Data Volumeを作成するコマンド。
以下は必要になった時、見た時に覚えよう
ONBUILD
LABEL
STOPSIGNAL
MAINTAINER
HEALTHCHECK
USER
SHELL
では今回の原因になったDockerfileの中身は
FROM php:7.4-apache
# 設定ファイルをdockerコンテナ内のPHP、Apacheに読み込ませる
# ADD:ローカルのファイルをDockerコンテナ内にコピーする
ADD php.ini /usr/local/etc/php/
ADD 000-default.conf /etc/apache2/sites-enabled/
# Composerのインストール
# RUN:コンテナ内でコマンド実行する
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
# ミドルウェアのインストール
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim \
libpng-dev \
libpq-dev \
&& docker-php-ext-install pdo_mysql
# Laravelで必要になるmodRewriteを有効化する
RUN mv /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled
RUN /bin/sh -c a2enmod rewrite
問題となった箇所だが、ファイルのパスが怪しい気がする。
そもそもの原因
とりあえず、phpのパスを確認しようと思って
php -v
と打ってみたが、phpがなかった。。
Macには必ず入っているはずなのに、、、と思っていたら、どうやら、いつのバージョンかわからないか自動ではインストールされなくなったらしい。なるほど。
だとしたらそもそもphp.iniがないからコピーできなかっただけやんこれ。
原因判明。
phpをダウンロードするとなって、はたと気づいた。
元々、phpは8.0以上だったので、そもそもこのdockerfileじゃだめだった。
全部ダメじゃん。。。
気を取り直して、
dockerhubで、docker laravelで検索したら、
公式のいいdockerfileが出てきたので、このイメージを使ってインストールして、
LaravelでWebサーバーが立ち上がったので、URL(localhostのやつ)
に繋いだら、いつものLaravelのロゴが出てきた。
これにて完了。
まあ、遠回りしたけど、dockerのことが学習できたし、わかっただけでもよしとしよう。
原因と今後の課題
・dockerfileの各文章の意味が分かってなかった
・ローカルPCにphpが入っていないことに気づいてなかった(普段ローカルPCでなくてテスト環境で開発してたので。。。それそもそもあかんけど。。。)
・何よりdockerに慣れてなかった
ということで。dockerは便利なのでエンジニアは一緒に使えるようになろうぜ。
と何気にカッコつけてみる。
以上。