tag:crieit.net,2005:https://crieit.net/tags/docker-compose/feed
「docker-compose」の記事 - Crieit
Crieitでタグ「docker-compose」に投稿された最近の記事
2022-05-31T00:00:59+09:00
https://crieit.net/tags/docker-compose/feed
tag:crieit.net,2005:PublicArticle/18203
2022-05-31T00:00:59+09:00
2022-05-31T00:00:59+09:00
https://crieit.net/posts/docker-compose-conditional-branch-volume-mount-20220531
Docker Compose で条件に応じてマウントするボリュームを切り替える
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>Docker Compose を使って複数の似たようなユースケースで検証を繰り返している中で、</p>
<ul>
<li>この検証では Apache のドキュメントルートと MySQL のデータを永続化して試験したい</li>
<li>その検証ではどちらも永続化しないで試験したい</li>
<li>あの検証ではファイル数が膨大な上にオペレーションでその膨大なファイルに変更ををかけるので Apache のファイル永続化をしているとディスクIOがボトルネックになって検証に時間がかかり過ぎる</li>
</ul>
<p>という具合に、同じ Docker Compose のベースを使いつつもユースケースに応じてボリュームをマウントするかどうかを条件によって切り分けたくなりました。</p>
<p>検証ごとに別リポジトリにフォークなりブランチなり切っていくと数が多くなってしまい管理しきれなくなる恐れがあるので、なるべくベースのコードは共通にしておきたいところです。</p>
<p>そこで、「同じ Docker Compose のコードで、条件に応じて処理を変化させる(今回はマウントするボリュームを切り替える)」ということが必要になりました。</p>
<h2 id="結果"><a href="#%E7%B5%90%E6%9E%9C">結果</a></h2>
<p>最初に結果を記すと、今回は <code>docker-compose</code> を <code>up</code> する際に <code>-f</code>オプション を付ける、という方法を選択しました。</p>
<h3 id="ボリュームをマウントしない場合"><a href="#%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%A0%E3%82%92%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88%E3%81%97%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88">ボリュームをマウントしない場合</a></h3>
<pre><code class="bash">> docker-compose up -d
</code></pre>
<h3 id="ボリュームをマウントする場合"><a href="#%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%A0%E3%82%92%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88">ボリュームをマウントする場合</a></h3>
<pre><code class="bash">> docker-compose -f docker-compose.yml -f docker-compose.volumes.yml up -d
</code></pre>
<p>このように使い分けるイメージです。</p>
<h2 id="コード"><a href="#%E3%82%B3%E3%83%BC%E3%83%89">コード</a></h2>
<p>上述で指定した各 <code>yml</code> ファイルは次のようになっています。</p>
<h3 id="docker-compose.yml"><a href="#docker-compose.yml">docker-compose.yml</a></h3>
<pre><code class="yml">version: '3.8'
services:
web:
build:
context: ./apache/docker
dockerfile: Dockerfile
args:
WEB_ROOT_DIRECTORY: $WEB_ROOT_DIRECTORY
## 略
volumes:
# workspace
- ./workspace:/workspace
# docker settings template
- ./template:/template
## 略
db:
build:
context: ./mysql/docker
dockerfile: Dockerfile
## 略
volumes:
# workspace
- ./workspace:/workspace
# docker settings template
- ./template:/template
## 略
</code></pre>
<p>オプションなしで使用するデフォルトの <code>docker-compose.yml</code> はエントリポイントのシェルスクリプトや設定、ログの置き場所など最低限のディレクトリをマウントするに留めています。</p>
<h3 id="docker-compose.volumes.yml"><a href="#docker-compose.volumes.yml">docker-compose.volumes.yml</a></h3>
<pre><code class="yml">version: '3.8'
services:
web:
volumes:
# apache virtual host
- ./apache/www:/var/www/$WEB_ROOT_DIRECTORY/web
db:
volumes:
# mysql data
- ./mysql/data:/var/lib/mysql/data
</code></pre>
<p>一方、ボリュームマウント用の <code>yml</code> ファイルでは冒頭の通り Apache のドキュメントルート想定のディレクトリや MySQL のデータファイルのディレクトリをマウントするようにしています。</p>
<p>これにより、オプション指定のない場合は後者のファイルが読み込まれないことによりドキュメントルートやデータファイルをマウントせず、オプションを付けるとマウントする、というように挙動を切り替えられる、という寸法です。</p>
<p>ただし、このくらいで済むのでまだ良いですがこれが複雑化すると大量の <code>-f</code>オプション と Composeファイル による長大なコマンドになってしまう恐れがあるのでその点は要改善ですかね。現時点でも <code>readme.md</code> とかにコマンドを書いておかないと一々打ち込んでいられないレベルですし。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<h3 id="-f オプション"><a href="#-f+%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3">-f オプション</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/reireias/items/ecb81e248314253eb156">docker-compose.ymlをDRYに書くテクニック2選 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.ykicchan.dev/posts/2020-07-13">docker-compose.yml を環境ごとに分割する - yKicchan's blog</a></li>
</ul>
<h3 id="-f オプションの先"><a href="#-f+%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E5%85%88">-f オプションの先</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://suin.io/535">docker-compose.ymlが環境別に複数ある場合はCOMPOSE_FILEを定義しておくと幸せになれる</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://ikasamak503.hatenablog.com/entry/dry-docker-compose-yaml">docker-compose で複数環境を構築するときの設定をなるべく DRY に書く - ikasama over technology</a></li>
</ul>
<h3 id="Compose ファイルの指定"><a href="#Compose+%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E6%8C%87%E5%AE%9A">Compose ファイルの指定</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://docs.docker.jp/compose/reference/envvars.html#compose-file">Compose CLI 環境変数 — Docker-docs-ja 20.10 ドキュメント</a></li>
</ul>
<h3 id="(未使用) 環境変数"><a href="#%28%E6%9C%AA%E4%BD%BF%E7%94%A8%29+%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0">(未使用) 環境変数</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://matsuand.github.io/docs.docker.jp.onthefly/compose/environment-variables/#the-env-file">Compose における環境変数 | Docker ドキュメント</a></li>
</ul>
<h3 id="ボリュームのマウント"><a href="#%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%A0%E3%81%AE%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88">ボリュームのマウント</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/randd/articles/84ac7de7f22800">Dockerのマウントについて</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/18196
2022-05-23T23:59:20+09:00
2022-05-23T23:59:20+09:00
https://crieit.net/posts/docker-compose-set-default-enviroment-variables-20220522
Docker Compose で使用する環境変数にデフォルト値を設定する
<p>Docker Compose で使用する <code>.env</code> の環境変数にデフォルト値を設定する方法についてメモ。</p>
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>PHP Webアプリケーション用のコンテナからDB用のコンテナに接続する際、DB名やユーザ名・パスワードを任意の値に設定したい。</p>
<p>ただし <code>.env</code> は Git 管理にはしたくないので標準では <code>sample.env</code> 等に逃がしており、うっかりファイルをコピー・リネームし忘れていたり、あるいはキー名をタイポして値が消えてしまったりすると困る……ということでデフォルト値を設定できないか、と考えました。</p>
<h2 id="コード"><a href="#%E3%82%B3%E3%83%BC%E3%83%89">コード</a></h2>
<h3 id="docker-compose.yml"><a href="#docker-compose.yml">docker-compose.yml</a></h3>
<pre><code class="yml">version: '3.7'
volumes:
logs:
driver: local
services:
php:
build:
context: ./_docker/dockerfiles/
dockerfile: Dockerfile
working_dir: /var/www
command: php -S 0.0.0.0:8080 -t public
ports:
- 8080:8080
db:
image: mariadb
restart: always
ports:
- ${MYSQL_PORT:-3306}:${MYSQL_PORT:-3306}
environment:
- MYSQL_ROOT_PASSWORD=pwd
- MYSQL_DATABASE=${MYSQL_DBNAME:-test}
- MYSQL_USER=${MYSQL_USER:-user}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-pwd}
</code></pre>
<h3 id=".env (サンプル)"><a href="#.env+%28%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%29">.env (サンプル)</a></h3>
<pre><code class="env">MYSQL_DBNAME=foo_db
MYSQL_USER=foo_user
MYSQL_PASSWORD="Password-1234"
MYSQL_HOST=192.0.2.1
MYSQL_PORT=3306
</code></pre>
<p>早速ですが用意したコード。</p>
<p>まず基本的に <code>.env</code> を用意すれば、 <code>${HOGE}</code> の形式で環境変数をセットできます。</p>
<p>今回はそこに <code>${HOGE:-FUGA}</code> と、コロン(<code>:</code>)とハイフン(<code>-</code>)を付けた値を追加しました。これにより、「<code>.env</code> に <code>HOGE=PIYO</code> のように <code>HOGE</code> に値がセットされていれば <code>PIYO</code> を、そうでなければデフォルト値として <code>:-</code> の後の文字列 (この場合は <code>FUGA</code>) をセット」となります。</p>
<p>例えば上述の <code>- MYSQL_DATABASE=${MYSQL_DBNAME:-test}</code> の部分では、 MariaDB のコンテナイメージに対して <code>MYSQL_DATABASE</code> キーへ <code>.env</code> の <code>MYSQL_DBNAME</code> に値がセットされていればその値を、そうでなければ <code>test</code> をセット、となります。</p>
<p>なお <code>-</code> がない場合は empty も許容されるので、空文字列が環境変数にセットされるようです。今回はどれも空文字列では都合が宜しくないので全てハイフンありで統一。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<h3 id="デフォルト値"><a href="#%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E5%80%A4">デフォルト値</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/fagai/items/b944950b26af19453c02">案外知られてないdocker-composeの環境変数定義の記法 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://docs.docker.com/compose/compose-file/#interpolation">Compose specification | Docker Documentation</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://matsuand.github.io/docs.docker.jp.onthefly/compose/environment-variables/">Compose における環境変数 | Docker ドキュメント</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/18195
2022-05-23T23:58:56+09:00
2022-05-23T23:58:56+09:00
https://crieit.net/posts/docker-compose-change-enviroment-variables-file-20220523
Docker Compose に渡す環境変数ファイルを変更する
<p>Docker Compose に渡す環境変数に .env 以外のファイルから渡したいと考えたのでメモしておきます。</p>
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>アプリケーション開発環境等で開発環境用の <code>.development.env</code> と本番環境用の <code>.production.env</code> を用意したとして、この2つのどちらかから Docker Compose に環境変数を渡したい。</p>
<p>開発環境なのでアプリ側で使用する環境変数と Dockerコンテナ 内で使用する環境変数を統一したい、と。</p>
<p>ただし、デフォルトでは Docker Compose は <code>.env</code> からしか環境変数を読み取ってくれません。これをどうにかしたい。</p>
<h2 id="コマンド"><a href="#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89">コマンド</a></h2>
<pre><code class="bash">> docker-compose --env-file .development.env up -d
</code></pre>
<p>ということでコマンドですが、 <code>docker-compose</code> コマンドに <code>--env-file</code> でパラメータを渡してあげると <code>.env</code> 以外のファイルも環境変数のソースとして渡すことができます。</p>
<h2 id="(余談) コマンド実行時の --env-file パラメータと .envファイル と docker-compose.yml の env_file キー"><a href="#%28%E4%BD%99%E8%AB%87%29+%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E5%AE%9F%E8%A1%8C%E6%99%82%E3%81%AE+--env-file+%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%A8+.env%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB+%E3%81%A8+docker-compose.yml+%E3%81%AE+env_file+%E3%82%AD%E3%83%BC">(余談) コマンド実行時の --env-file パラメータと .envファイル と docker-compose.yml の env_file キー</a></h2>
<p>さて、ここから少しややこしい話を。</p>
<p>Docker Compose 周りでは環境変数関連で見出しに挙げた3つの方法があるようです。</p>
<p><code>.env</code> については Docker Compose で使用できる環境変数ファイル。これは良いですね。</p>
<p>この <code>.env</code> をそれ以外のファイル名・ディレクトリのファイルから読み取るように変更できるのが <code>docker-compose</code>コマンド 実行時の <code>--env-file</code> パラメータ。</p>
<p>ここまでは <strong><code>docker-compose.yml</code> 内で使用できる</strong> 環境変数です。</p>
<p>それでは最後、 <code>docker-compose.yml</code> の <code>env_file</code>キー は何か。</p>
<pre><code>version: '3.7'
services:
db:
env_file:
- .dvelopment.env
</code></pre>
<p>最後の <code>env_file</code> は <code>docker-compose.yml</code> 内に記述できるパラメータで、これを使って環境変数のファイルを指定することができます。</p>
<p>ただし、このパラメータで指定した環境変数は、 <strong>起動したコンテナ内からは参照できますが、 <code>docker-compose.yml</code> 内からは参照できません</strong>。</p>
<p>ということで、今回やりたいこととはマッチしません。そもそもの目的が異なる、ということですね。</p>
<p>過去の先人達のように自分も嵌まったのでこのことも併せてメモしておきます。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/rhene/scraps/781fdbecd340d3">docker-composeで環境変数が読み込まれない?</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/SolKul/items/989727aeeafcae28ecf7">docker-composeのenv_fileと.envファイルの違い - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://docs.docker.jp/compose/environment-variables.html">Compose における環境変数 — Docker-docs-ja 19.03 ドキュメント</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://docs.docker.com/compose/environment-variables/">Environment variables in Compose | Docker Documentation</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/18125
2022-02-25T22:46:15+09:00
2022-02-25T22:46:15+09:00
https://crieit.net/posts/change-timzezone-in-docker-for-wordpress-post-failed-20220224
Docker 上の Almalinux のタイムゾーン設定について
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>AlmaLinux ベースの自作LAMP環境構築用 Docker で WordPress を動かしたところ、投稿が「予約投稿の失敗」となってしまい正常に投稿できない現象に遭遇したため対処。</p>
<h2 id="現象"><a href="#%E7%8F%BE%E8%B1%A1">現象</a></h2>
<p><a href="https://crieit.now.sh/upload_images/49f0d2b150a7b5d422313af680baf9ae62124ffe1e1d2.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/49f0d2b150a7b5d422313af680baf9ae62124ffe1e1d2.jpg?mw=700" alt="今までの設定で発生していた現象" /></a></p>
<p>今までの Docker Compose 環境で発生していた現象が上述の画像。普通に投稿したにも関わらず、「予約投稿の失敗」となってしまいます。</p>
<p>困ったことに WordPress の管理画面で見ると日時はずれていない (WordPress インストール時のサンプル投稿「Hello World!」の投稿日時とほぼ同じ) ので、ぱっと見原因が掴みづらいところ。</p>
<p>ちなみに、 <code>wp_posts</code> のテーブルを直接見たところ、 <code>post_date</code>, <code>post_date_gmt</code>, <code>post_modified</code>, <code>post_modified_gmt</code> が全て同じ日時になっていました。</p>
<p>……あれ、 <code>_gmt</code> 系はグリニッジ標準時刻なので日本の時刻とは9時間ずれるはずでは……。ということで、どうもこの辺りが宜しくなさそうです。</p>
<p>なお、この時の Dockerfile 等の各種設定は次のようになっていました。</p>
<h3 id="Dockerfile (共通)"><a href="#Dockerfile+%28%E5%85%B1%E9%80%9A%29">Dockerfile (共通)</a></h3>
<pre><code class="dockerfile">RUN \cp -pf /usr/share/zoneinfo/Japan /etc/localtime
</code></pre>
<h3 id="php.ini"><a href="#php.ini">php.ini</a></h3>
<pre><code class="ini">[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =
date.timezone = 'Asia/Tokyo'
</code></pre>
<h3 id="my.cnf 等"><a href="#my.cnf+%E7%AD%89">my.cnf 等</a></h3>
<p>MySQL 側では特に指定なし。</p>
<h2 id="変更"><a href="#%E5%A4%89%E6%9B%B4">変更</a></h2>
<p>これらの設定を次のようにしました。</p>
<h3 id="Dockerfile (共通)"><a href="#Dockerfile+%28%E5%85%B1%E9%80%9A%29">Dockerfile (共通)</a></h3>
<pre><code class="dockerfile">RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux \
&& dnf -y update && dnf -y install \
# 略
# timezone
glibc-locale-source \
# locale, timezone
&& localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 \
&& ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# local & timezone
ENV LANG="ja_JP UTF-8" \
LANGUAGE="ja_JP:ja" \
LC_ALL="ja_JP.UTF-8" \
TZ="Asia/Tokyo"
</code></pre>
<p>やり方を大幅に変更。強制コピーで localtime ファイルを上書きするのではなく、段取りを踏んで設定するようにしました。</p>
<h3 id="php.ini"><a href="#php.ini">php.ini</a></h3>
<pre><code class="ini">[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =
date.timezone = 'Asia/Tokyo'
</code></pre>
<p>変わらず。</p>
<h3 id="my.cnf 等"><a href="#my.cnf+%E7%AD%89">my.cnf 等</a></h3>
<p>こちらも変わらず。</p>
<h3 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h3>
<p><a href="https://crieit.now.sh/upload_images/d64288e5b382b9fe2564274e8237a20c6212500befe90.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d64288e5b382b9fe2564274e8237a20c6212500befe90.jpg?mw=700" alt="新しい設定方法で投稿した場合の挙動" /></a></p>
<p>新しい方法で設定した Docker 環境上に先程と同様 WordPress をインストールして記事を投稿すると、無事投稿が公開されました。</p>
<p>このとき、 <code>wp_posts</code> のテーブルを直接見ると、 <code>post_date</code>, <code>post_modified</code> は同じ日時、 <code>post_date_gmt</code>, <code>post_modified_gmt</code> は -9時間の日時になっていました。</p>
<p>やはりここがおかしかったようです。</p>
<h2 id="続・検証"><a href="#%E7%B6%9A%E3%83%BB%E6%A4%9C%E8%A8%BC">続・検証</a></h2>
<p>さて、それではこの時刻の狂いはどこに起因しているのでしょうか。</p>
<p><a href="https://crieit.now.sh/upload_images/67aea8dcc499e2cd3be8f9a4698e5de1621250140823c.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/67aea8dcc499e2cd3be8f9a4698e5de1621250140823c.jpg?mw=700" alt="Webサーバのみ新しい設定方法で投稿した場合の挙動" /></a></p>
<p>Webサーバの Dockerコンテナ のみ今回の新しい方法で localtime を設定した場合。OKですね。</p>
<p><a href="https://crieit.now.sh/upload_images/35de93c1057c97f109f3c8e152c7ec526212501e5c450.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/35de93c1057c97f109f3c8e152c7ec526212501e5c450.jpg?mw=700" alt="DBサーバのみ新しい設定方法で投稿した場合の挙動" /></a></p>
<p>DBサーバの Dockerコンテナ のみ今回の新しい方法で localtime を設定した場合。NGです。</p>
<p>ということで、原因は Webサーバ 側にありそうです。</p>
<h3 id="Webサーバでの date"><a href="#Web%E3%82%B5%E3%83%BC%E3%83%90%E3%81%A7%E3%81%AE+date">Webサーバでの date</a></h3>
<p>ただ、 Webサーバ のコンテナで <code>date</code> コマンドを打っても日時は正しい日時が返ってくるのですよね。</p>
<h4 id="設定方法が未変更の状態の Webサーバ コンテナ"><a href="#%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95%E3%81%8C%E6%9C%AA%E5%A4%89%E6%9B%B4%E3%81%AE%E7%8A%B6%E6%85%8B%E3%81%AE+Web%E3%82%B5%E3%83%BC%E3%83%90+%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A">設定方法が未変更の状態の Webサーバ コンテナ</a></h4>
<pre><code class="bash"># php -r 'echo date_default_timezone_get() . PHP_EOL; echo date("y-m-d H:i:s") . PHP_EOL;'
Asia/Tokyo
22-02-13 19:06:21
# date
Thu Feb 13 19:06:28 JST 2022
</code></pre>
<h4 id="設定方法を変更した状態の Webサーバ コンテナ"><a href="#%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%97%E3%81%9F%E7%8A%B6%E6%85%8B%E3%81%AE+Web%E3%82%B5%E3%83%BC%E3%83%90+%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A">設定方法を変更した状態の Webサーバ コンテナ</a></h4>
<pre><code class="bash"># php -r 'echo date_default_timezone_get() . PHP_EOL; echo date("y-m-d H:i:s") . PHP_EOL;'
Asia/Tokyo
22-02-13 19:16:50
# date
2022年 2月 13日 日曜日 19:16:56 JST
</code></pre>
<p>ご覧の通り時刻は正常……ってあれ、確かに日時は正常ですが、出力フォーマットが異なっています。</p>
<p>どうやら今までの設定変更ではやはり不完全な部分があるようです。どこが、というところまでは追い切れていないですが、ここまでの検証で確かに今までの設定方法では宜しくないであろう、ということが断片的に表われているので、ここは大人しく新しい設定方法に変更していった方が良さそうです。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/rururu_kenken/items/972314402d588e073d40">Dockerコンテナのタイムゾーン変更方法 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/jeffi7/items/9d4c85cf049644f711b8">Docker で \/etc\/localtime をホストに volume マウントしてハマった話 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://saito-shion-technology.hatenablog.jp/entry/2020/02/27/115040">Docker : コンテナのタイムゾーンを変更する - saito-shion technology diary</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/polarbear08/items/e5c00869c7566db5f7b8">CentOS7・CentOS8のDockerコンテナの日本語化および日本時間設定 - Qiita</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/18121
2022-02-23T00:12:52+09:00
2022-02-23T00:12:52+09:00
https://crieit.net/posts/error-at-install-mysql-community-server-import-rpm-pgp-key-20220223
Docker で MySQL の community版をインストールしようとした際に Failing package is: ... エラー
<p>Docker の MySQL コンテナを構築する Dockerfile を走らせようとしたところ、</p>
<blockquote>
<p>The GPG keys listed for the "MySQL 8.0 Community Server" repository are already installed but they are not correct for this package.</p>
</blockquote>
<p>や</p>
<blockquote>
<p>Public key for mysql-community-client-8.0.28-1.el8.x86_64.rpm is not installed. Failing package is: mysql-community-client-8.0.28-1.el8.x86_64</p>
</blockquote>
<p>というエラーが発生してしまったので対処。</p>
<h3 id="改修前の Dockerfile"><a href="#%E6%94%B9%E4%BF%AE%E5%89%8D%E3%81%AE+Dockerfile">改修前の Dockerfile</a></h3>
<pre><code class="dockerfile">RUN dnf -y localinstall https://dev.mysql.com/get/mysql80-community-release-el8-2.noarch.rpm
</code></pre>
<p>コミュニティ版の MySQL8 をインストールしようとしています。</p>
<h3 id="改修後の Dockerfile"><a href="#%E6%94%B9%E4%BF%AE%E5%BE%8C%E3%81%AE+Dockerfile">改修後の Dockerfile</a></h3>
<pre><code class="dockerfile">RUN rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022 && dnf -y localinstall https://dev.mysql.com/get/mysql80-community-release-el8-2.noarch.rpm
</code></pre>
<p>エラー文で検索したところ、</p>
<pre><code class="bash">rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
</code></pre>
<p>を追加すると良い、という記事を見かけたので追加したところ、エラーが発生しなくなったのでこれで対処。</p>
<h3 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://support.cpanel.net/hc/en-us/articles/4419382481815-MySQL-GPG-keys-expired-preventing-installation-upgrade-of-MySQL-packages-from-the-official-repository-">MySQL GPG keys expired, preventing installation\/upgrade of MySQL packages from the official repository. – cPanel</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://support.cpanel.net/hc/en-us/articles/4419382481815-Installer-fails-due-to-The-GPG-keys-listed-for-the-MySQL-repository-are-already-installed-but-they-are-not-correct-for-this-package-">MySQL GPG keys expired, preventing installation\/upgrade of MySQL packages from the official repository. – cPanel</a></li>
</ul>
<p>URLは異なりますがどちらも同じ内容の模様。</p>
arm-band
tag:crieit.net,2005:PublicArticle/17932
2022-01-12T00:06:20+09:00
2022-01-12T00:06:20+09:00
https://crieit.net/posts/centos-onelinear-ternary-and-compoare-operator-20220112
CentOS の bash で比較演算と三項演算子的な処理を使って変数に代入する値を分岐するワンライナー
<p><a href="https://crieit.net/posts/diverting-date-as-args-in-dockerfile-20211230">Dockerfile 内でコンテナの時刻を変数として流用し、年に対応した rpmパッケージ の GPG署名 をインストールする</a>で試験した内容の続きとなります。</p>
<ul>
<li><code>http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021</code>: OK</li>
<li><code>http://rpms.famillecollet.com/RPM-GPG-KEY-remi2022</code>: Not Found.</li>
</ul>
<p>remiリポジトリのGPG署名が2022年版が存在しないので、条件分岐で2021を最大値とするように処理を書いてみました。</p>
<h2 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h2>
<pre><code class="bash"># date
2022年 1月 11日 火曜日 20:42:53 JST
</code></pre>
<p>今回の検証環境はこのような表示がされる CentOS の日本語版の環境。</p>
<pre><code class="bash"># NOWYEAR=$(sudo date | sudo awk 'END{print $1}' | sudo sed -e 's/年//g') && [ ${NOWYEAR} -gt 2021 ] && ALTERYEAR=2021 || ALTERYEAR=${NOWYEAR} && echo ${ALTERYEAR}
2021
</code></pre>
<p>早速完成したワンライナーですが、このようになりました。</p>
<h2 id="説明"><a href="#%E8%AA%AC%E6%98%8E">説明</a></h2>
<p>わりと複雑になってしまったので順番に読んでいきます。</p>
<pre><code class="bash">NOWYEAR=$(sudo date | sudo awk 'END{print $1}' | sudo sed -e 's/年//g') \ # date コマンドの結果から、 awk でスペース区切り1つ目の値(2022年) を抽出し、 `sed -e` で`年`を落とす。結果、`2022`が得られる
&& [ ${NOWYEAR} -gt 2021 ] && ALTERYEAR=2021 || ALTERYEAR=${NOWYEAR} \ # 三項演算子的な処理。 {コマンドとして実行可能な式} && {前述式が true の場合の処理} || {前述式が false の場合の処理} 。今回は得られた現在の年が2021年以降ならば2021を変数に代入、そうでなければ現在の年を変数代入
&& echo ${ALTERYEAR} # 上の三項演算子的な処理で代入された変数の値を echo
</code></pre>
<p>こんな感じです。</p>
<pre><code class="dockerfile">RUN MELUSINE=$(sudo date | sudo awk 'END{print $6}') \
&& [ ${NOWYEAR} -gt 2021 ] && ALTERYEAR=2021 || ALTERYEAR=${NOWYEAR} \
&& rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm \
&& rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi${ALTERYEAR}
</code></pre>
<p>今回はこんな感じで <code>http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021</code> か、 <code>http://rpms.famillecollet.com/RPM-GPG-KEY-remi{2020以下}</code> かを読み込む分岐に。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.pmi-sfbac.org/arithmetic-comparison/">【Shellスクリプト】演算子「算術演算子」「比較演算子」について! | Beエンジニア</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://eng-entrance.com/linux-shellscript-replacement">【Linux】シェルスクリプトによる文字列処理:置換や削除をする方法</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17901
2021-12-30T01:05:47+09:00
2021-12-30T01:07:46+09:00
https://crieit.net/posts/diverting-date-as-args-in-dockerfile-20211230
Dockerfile 内でコンテナの時刻を変数として流用し、年に対応した rpmパッケージ の GPG署名 をインストールする
<p>Dockerコンテナ をビルドする際にコンテナ内の時刻(年)を他のコマンドに流用したくなりました。その方法をいくつか試したのでメモしておきます。</p>
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>AlmaLinux で PHP7.4系 をインストールする際に Remiリポジトリ からインストールしようとしました。</p>
<pre><code class="dockerfile">RUN rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm && \
rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021
# disable default module
RUN dnf module reset -y php
# install php 7.4
RUN dnf module install -y php:remi-7.4
</code></pre>
<p><code>rpm</code> を使用して Remiリポジトリ をインストールしています。</p>
<p><code>rpm</code> ではパッケージインストールではパッケージが破損していないか、改ざんされていないかをチェックするために GPG署名 を用いています。</p>
<p>その公開鍵の取得も、 Remiリポジトリ のインストールと同時に行っています。</p>
<pre><code class="dockerfile">RUN rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm && \
rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021
</code></pre>
<p>ここでふと思ったのは、URLに年が入っていること。2022年になったら</p>
<pre><code class="dockerfile">RUN rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm && \
rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2022
</code></pre>
<p>に変えたい。かといってそれを毎年手動で更新するのは面倒なので、自動化したい。</p>
<p>であれば、 <code>date</code> コマンドの値を <code>awk</code> に通すなどして年だけ取り出し、それを上述コマンドに流用できないか、と。</p>
<h2 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h2>
<p>まずは AlmaLinux のコンテナをビルド・起動します。</p>
<pre><code class="bash">docker run --name yeartest -it almalinux:8 /bin/bash
</code></pre>
<pre><code class="bash"># \cp -pf /usr/share/zoneinfo/Japan /etc/localtime
## タイムゾーン変更
# dnf -y update && yum -y install sudo epel-release
## 略
</code></pre>
<p>パッケージを入れたり前準備。</p>
<h3 id="date から年のみ取り出す"><a href="#date+%E3%81%8B%E3%82%89%E5%B9%B4%E3%81%AE%E3%81%BF%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99">date から年のみ取り出す</a></h3>
<pre><code class="bash"># date
Wed Dec 29 22:28:18 JST 2021
</code></pre>
<p>普通に <code>date</code> を叩きます。ふむ、6番目ですね……。</p>
<pre><code class="bash"># sudo date | sudo awk '{print $6}'
2021
</code></pre>
<p>そこでパイプで繋いで <code>awk</code> に渡します。無事、年のみを取り出せました。</p>
<h3 id="rpm の GPG署名 について"><a href="#rpm+%E3%81%AE+GPG%E7%BD%B2%E5%90%8D+%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">rpm の GPG署名 について</a></h3>
<p>一応インポートされている GPG署名 について確認しておきます。</p>
<pre><code class="bash"># rpm -qa 'gpg-pubkey*'
gpg-pubkey-3abb34f8-5ffd890e
</code></pre>
<p>まずデフォルトの状態。1つのみインポートされていますね。</p>
<pre><code class="bash"># rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021
# rpm -qa 'gpg-pubkey*'
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5
</code></pre>
<p>次に <code>RPM-GPG-KEY-remi2021</code> をインポートします。増えました。</p>
<pre><code class="bash"># rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
# rpm -qa 'gpg-pubkey*'
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5
gpg-pubkey-00f97f56-467e318a
</code></pre>
<p>さらに <code>RPM-GPG-KEY-remi</code> をインポートすると増えました。</p>
<h2 id="検証2"><a href="#%E6%A4%9C%E8%A8%BC2">検証2</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/test-docker-tychedight">Tychedight</a></li>
</ul>
<p>以上を踏まえて、 Docker Compose からの Dockerfile ビルドで試験。</p>
<pre><code class="dockerfile">FROM almalinux:8
RUN \cp -pf /usr/share/zoneinfo/Japan /etc/localtime
RUN dnf -y update && yum -y install \
sudo \
epel-release
RUN mkdir /home/temp/
# パターン1
RUN GEOFFROY=$(sudo date | sudo awk 'END{print $6}') \
&& sudo echo ${GEOFFROY} >> /home/temp/geoffroy.txt
# パターン2
RUN FROMONT=$(sudo date | sudo awk 'END{print $6}')
RUN sudo echo ${FROMONT} >> /home/temp/fromont.txt
# パターン3
RUN sudo echo \
| sudo date \
| sudo awk 'END{print $6}' \
>> /home/temp/carillon.txt
</code></pre>
<p>一応3つパターンを試してみます。さあ、それぞれのファイルには何が出力されるのか……。</p>
<pre><code class="dockerfile"># パターン1
RUN GEOFFROY=$(sudo date | sudo awk 'END{print $6}') \
&& sudo echo ${GEOFFROY} >> /home/temp/geoffroy.txt
# 2021
# パターン2
RUN FROMONT=$(sudo date | sudo awk 'END{print $6}')
RUN sudo echo ${FROMONT} >> /home/temp/fromont.txt
#
# パターン3
RUN sudo echo \
| sudo date \
| sudo awk 'END{print $6}' \
>> /home/temp/carillon.txt
# 2021
</code></pre>
<p>結果、意図した出力になったのは1つ目と3つ目のパターンでした。 <code>RUN</code> ごとにコンテナが変わるとのことなので2は望み薄だと思っていましたが……。</p>
<p>そこで、パターン1を使って次のように組んでみます。</p>
<pre><code class="dockerfile">FROM almalinux:8
RUN \cp -pf /usr/share/zoneinfo/Japan /etc/localtime
RUN dnf -y update && yum -y install \
sudo \
epel-release
RUN mkdir /home/temp/
# args
RUN MELUSINE=$(sudo date | sudo awk 'END{print $6}') \
&& rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm \
&& rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi${MELUSINE}
</code></pre>
<p>これでビルド・起動したコンテナに bash で入って確認。</p>
<pre><code class="bash"># rpm -qa 'gpg-pubkey*'
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5
</code></pre>
<p>内容的にデフォルトと2021の公開鍵が入っているように見えます。</p>
<pre><code class="bash"># rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
# rpm -qa 'gpg-pubkey*'
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5
gpg-pubkey-00f97f56-467e318a
</code></pre>
<p>手動で <code>RPM-GPG-KEY-remi</code> を入れると増えました。</p>
<pre><code class="bash"># rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021
# rpm -qa 'gpg-pubkey*'
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5
gpg-pubkey-00f97f56-467e318a
</code></pre>
<p>ついでに手動で <code>RPM-GPG-KEY-remi2021</code> を入れようとしましたが、数は増えませんでした。先のコードで <code>RPM-GPG-KEY-remi2021</code> がインストールできていることが確認できました。OKです。</p>
<h2 id="余談"><a href="#%E4%BD%99%E8%AB%87">余談</a></h2>
<p>実は上述の通り年指定のない <code>http://rpms.famillecollet.com/RPM-GPG-KEY-remi</code> があるので、それを入れてしまえば終わりのような気もするのですが……折角なのでチャレンジしてみた次第です。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<h3 id="PHP インストール"><a href="#PHP+%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">PHP インストール</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.tsuda1.com/%E6%9C%AA%E5%88%86%E9%A1%9E/php%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/">PHPインストール PHP7.4 CentOS8 | AlmaLinux 自宅サーバ</a></li>
</ul>
<p>もしかして、そもそもいらない……?</p>
<h3 id="rpm と GPG署名"><a href="#rpm+%E3%81%A8+GPG%E7%BD%B2%E5%90%8D">rpm と GPG署名</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/s1-check-rpm-sig">B.3. パッケージの署名確認 Red Hat Enterprise Linux 6 | Red Hat Customer Portal</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/aosho235/items/9ba95b6b8fb1ce8ac580">CentOS 7 インストールされている全パッケージのrpmをダウンロードする - Qiita</a>
<ul>
<li>インポートされた公開鍵の確認</li>
</ul></li>
<li>参考:
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.kakiro-web.com/linux/centos6-remi-install.html">CentOS6.7 64bitのyumリポジトリにRemiを追加 - Kakiro-Web カキローウェブ</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://pentan.info/server/linux/yum/remi.html">Remi 基本リポジトリで提供されていないパッケージのyumインストール - [yum/Linux [Red Hat/CentOSなど]] ぺんたん info</a></li>
</ul></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17898
2021-12-29T00:16:11+09:00
2021-12-29T00:17:49+09:00
https://crieit.net/posts/test-centos8-lamp-for-almalinux-in-docker-20211229
(Docker) Almalinux を見据えて CentOS8 での環境構築を試験してみる
<p>手前味噌で恐縮ですが、自作の LAMP環境 を検証する Docker Compose について。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/docker_compose_ambergrease">GitHub - arm-band/docker_compose_ambergrease</a></li>
</ul>
<p>イメージを CentOS7 ベースで構築しているので、いずれは AlmaLinux なり Rocky Linux なりに移行しなければならないことは分かっていました。</p>
<p>そこで、その以降を見据えて残り数日の命の CentOS8 で試験してみることにしました。なぜ AlmaLinux や Rocky Linux ではなくわざわざ CentOS8 かというと、いきなりそれらのOSに飛びついて何らかの不具合が発生したときに原因の切り分けで苦労するならば、まだ同じシリーズで差分が少ない (と想定される) CentOS8 で試験して、問題なければ次に進もう、という段階的な試験を想定したためです。</p>
<h2 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h2>
<pre><code class="bash">docker run --name php7_cent8 -it centos:centos8 /bin/bash
</code></pre>
<p>まずはイメージを取得し、 bash に入ります。</p>
<h3 id="Apache + PHP"><a href="#Apache+%2B+PHP">Apache + PHP</a></h3>
<p>最初は Apache + PHP 。こちらについては、以前 <a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/02/23/centos8-lamp-install-note/">CentOS8 をインストールして遊んだとき</a>にremiリポジトリの入り方が CentOS7 とは異なることが分かっていたので、多少手を加える必要があるだろう、と踏んでいました。</p>
<pre><code class="bash"># \cp -pf /usr/share/zoneinfo/Japan /etc/localtime
#
</code></pre>
<p>これは問題なし。</p>
<pre><code class="bash"># dnf -y update && yum -y install epel-release sudo less iproute httpd-devel zip unzip openssl mod_ssl
## 略
Installed:
apr-1.6.3-12.el8.x86_64 apr-devel-1.6.3-12.el8.x86_64
apr-util-1.6.1-6.el8.x86_64 apr-util-bdb-1.6.1-6.el8.x86_64
apr-util-devel-1.6.1-6.el8.x86_64 apr-util-openssl-1.6.1-6.el8.x86_64
brotli-1.0.6-3.el8.x86_64 centos-logos-httpd-85.8-2.el8.noarch
cyrus-sasl-2.1.27-5.el8.x86_64 cyrus-sasl-devel-2.1.27-5.el8.x86_64
epel-release-8-11.el8.noarch expat-devel-2.2.5-4.el8.x86_64
groff-base-1.22.3-18.el8.x86_64 httpd-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_64
httpd-devel-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_64 httpd-filesystem-2.4.37-43.module_el8.5.0+1022+b541f3b1.noarch
httpd-tools-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_64 libdb-devel-5.3.28-42.el8_4.x86_64
libpath_utils-0.2.1-39.el8.x86_64 libpkgconf-1.4.2-1.el8.x86_64
libtalloc-2.3.2-1.el8.x86_64 mailcap-2.1.48-3.el8.noarch
mod_http2-1.15.7-3.module_el8.4.0+778+c970deab.x86_64 mod_ssl-1:2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_64
ncurses-6.1-9.20180224.el8.x86_64 openldap-devel-2.4.46-18.el8.x86_64
perl-Carp-1.42-396.el8.noarch perl-Data-Dumper-2.167-399.el8.x86_64
perl-Digest-1.17-395.el8.noarch perl-Digest-MD5-2.55-396.el8.x86_64
perl-Encode-4:2.97-3.el8.x86_64 perl-Errno-1.28-420.el8.x86_64
perl-Exporter-5.72-396.el8.noarch perl-File-Path-2.15-2.el8.noarch
perl-File-Temp-0.230.600-1.el8.noarch perl-Getopt-Long-1:2.50-4.el8.noarch
perl-HTTP-Tiny-0.074-1.el8.noarch perl-IO-1.38-420.el8.x86_64
perl-IO-Socket-IP-0.39-5.el8.noarch perl-IO-Socket-SSL-2.066-4.module_el8.3.0+410+ff426aa3.noarch
perl-MIME-Base64-3.15-396.el8.x86_64 perl-Mozilla-CA-20160104-7.module_el8.3.0+416+dee7bcef.noarch
perl-Net-SSLeay-1.88-1.module_el8.3.0+410+ff426aa3.x86_64 perl-PathTools-3.74-1.el8.x86_64
perl-Pod-Escapes-1:1.07-395.el8.noarch perl-Pod-Perldoc-3.28-396.el8.noarch
perl-Pod-Simple-1:3.35-395.el8.noarch perl-Pod-Usage-4:1.69-395.el8.noarch
perl-Scalar-List-Utils-3:1.49-2.el8.x86_64 perl-Socket-4:2.027-3.el8.x86_64
perl-Storable-1:3.11-3.el8.x86_64 perl-Term-ANSIColor-4.06-396.el8.noarch
perl-Term-Cap-1.17-395.el8.noarch perl-Text-ParseWords-3.30-395.el8.noarch
perl-Text-Tabs+Wrap-2013.0523-395.el8.noarch perl-Time-Local-1:1.280-1.el8.noarch
perl-URI-1.73-3.el8.noarch perl-Unicode-Normalize-1.25-396.el8.x86_64
perl-constant-1.33-396.el8.noarch perl-interpreter-4:5.26.3-420.el8.x86_64
perl-libnet-3.11-3.el8.noarch perl-libs-4:5.26.3-420.el8.x86_64
perl-macros-4:5.26.3-420.el8.x86_64 perl-parent-1:0.237-1.el8.noarch
perl-podlators-4.11-1.el8.noarch perl-threads-1:2.21-2.el8.x86_64
perl-threads-shared-1.58-2.el8.x86_64 pkgconf-1.4.2-1.el8.x86_64
pkgconf-m4-1.4.2-1.el8.noarch pkgconf-pkg-config-1.4.2-1.el8.x86_64
sscg-2.3.3-14.el8.x86_64 sudo-1.8.29-7.el8_4.1.x86_64
unzip-6.0-45.el8_4.x86_64 zip-3.0-23.el8.x86_64
Complete!
</code></pre>
<p>OK。</p>
<pre><code class="bash"># dnf -y upgrade
## 略
Upgraded:
epel-release-8-13.el8.noarch
Complete!
</code></pre>
<p>特に大きな差分もなさそうです。OK。</p>
<h3 id="remiリポジトリ"><a href="#remi%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA">remiリポジトリ</a></h3>
<pre><code class="bash"># rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm
Retrieving http://rpms.famillecollet.com/enterprise/remi-release-8.rpm
warning: /var/tmp/rpm-tmp.hlvLxe: Header V4 RSA/SHA256 Signature, key ID 5f11735a: NOKEY
Verifying... ################################# [100%]
Preparing... ################################# [100%]
Updating / installing...
1:remi-release-8.5-2.el8.remi ################################# [100%]
# rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021
#
</code></pre>
<p>OK。 CentOS8 用のリポジトリに切り替えました。鍵についてはすぐ <code>RPM-GPG-KEY-remi2022</code> にしなければならないでしょうけど。</p>
<h4 id="dnf"><a href="#dnf">dnf</a></h4>
<pre><code class="bash"># dnf config-manager --enable remi && dnf config-manager --enable remi-php74
No such command: config-manager. Please use /usr/bin/dnf --help
It could be a DNF plugin command, try: "dnf install 'dnf-command(config-manager)'"
</code></pre>
<p><code>remi-php74</code> に指定で躓くかと思いきや、そもそも <code>config-manager</code> がない、と?</p>
<p>元々は <code>yum-config-manager</code> だったのですが、 CentOS8 であれば <code>dnf</code> ベースの方が良いだろう、ということで置き換えてはみましたが、ダメですか……。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.trippyboy.com/2021/terraform/almalinux%E3%81%ABterraform%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92yum%E3%81%A7%E5%B0%8E%E5%85%A5%E3%81%99%E3%82%8B%E3%81%AE%E5%B7%BB/">Almalinuxにterraformコマンドをyumで導入するの巻 - TrippyBoyの愉快な日々</a></li>
</ul>
<p>こちらより <code>dnf install -y dnf-plugins-core</code> してみます。</p>
<pre><code class="bash"># dnf install dnf-plugins-core
## 略
Installed:
dbus-glib-0.110-2.el8.x86_64 dnf-plugins-core-4.0.21-3.el8.noarch python3-dateutil-1:2.6.1-6.el8.noarch
python3-dbus-1.2.4-15.el8.x86_64 python3-dnf-plugins-core-4.0.21-3.el8.noarch python3-six-1.11.0-8.el8.noarch
Complete!
</code></pre>
<p>OK。</p>
<h4 id="remi + PHP"><a href="#remi+%2B+PHP">remi + PHP</a></h4>
<pre><code class="bash"># dnf config-manager --enable remi && dnf config-manager --enable remi-php74
Error: No matching repo to modify: remi-php74.
</code></pre>
<p>……やはり <code>remi-php74</code> で引っかかりましたか。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://mebee.info/2020/03/12/post-7365/">CentOs8 php7.4をインストールする | mebee</a></li>
</ul>
<p>……想定していたものとは少し違うやり方ですが、試してみましょう。</p>
<pre><code class="bash"># dnf module reset php
## 略
Remi's RPM repository for Enterprise Linux 8 - x86_64 598 kB/s | 3.9 MB 00:06
Last metadata expiration check: 0:00:03 ago on DDD dd mmm yyyy hh:ii:ss AM UTC.
Dependencies resolved.
Nothing to do.
Complete!
</code></pre>
<p>OK。</p>
<pre><code class="bash"># dnf module install -y php:remi-7.4
## 略
Installed:
libedit-3.1-23.20170329cvs.el8.x86_64 libxslt-1.1.32-6.el8.x86_64
nginx-filesystem-1:1.14.1-9.module_el8.0.0+184+e34fea82.noarch oniguruma5php-6.9.7.1-1.el8.remi.x86_64
php-cli-7.4.27-1.el8.remi.x86_64 php-common-7.4.27-1.el8.remi.x86_64
php-fpm-7.4.27-1.el8.remi.x86_64 php-json-7.4.27-1.el8.remi.x86_64
php-mbstring-7.4.27-1.el8.remi.x86_64 php-xml-7.4.27-1.el8.remi.x86_64
Complete!
# php --version
PHP 7.4.27 (cli) (built: Dec 14 2021 17:17:06) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
</code></pre>
<p>OK。入りましたね。これに従い該当箇所を書き換えます。</p>
<pre><code class="dockerfile"># enable repository remi & remi-php74
#RUN dnf config-manager --enable remi && dnf config-manager --enable remi-php74
# disable default module
RUN dnf module reset -y php
RUN dnf module install -y php:remi-7.4
## 略
# disable repository remi & remi-php74
#RUN dnf config-manager --disable remi && dnf config-manager --disable remi-php74
</code></pre>
<p><code>config-manager</code> によるリポジトリ使用のオン・オフの切り替えを削除しました。</p>
<pre><code class="bash"># dnf -y install php php-devel php-pdo php-mysqlnd php-mbstring php-gd php-pear php-pecl-apc-devel zlib-devel php-xml php-mcrypt php-pecl-xdebug
## 略
Installed:
autoconf-2.69-29.el8.noarch automake-1.16.1-7.el8.noarch
cmake-filesystem-3.20.2-4.el8.x86_64 cpp-8.5.0-4.el8_5.x86_64
dejavu-fonts-common-2.35-7.el8.noarch dejavu-sans-fonts-2.35-7.el8.noarch
emacs-filesystem-1:26.1-7.el8.noarch fontconfig-2.13.1-4.el8.x86_64
fontpackages-filesystem-1.44-22.el8.noarch freetype-2.9.1-4.el8_3.1.x86_64
fribidi-1.0.4-8.el8.x86_64 gcc-8.5.0-4.el8_5.x86_64
gcc-c++-8.5.0-4.el8_5.x86_64 gd3php-2.3.3-4.el8.remi.x86_64
glibc-devel-2.28-164.el8.x86_64 glibc-headers-2.28-164.el8.x86_64
graphite2-1.3.10-10.el8.x86_64 harfbuzz-1.7.5-3.el8.x86_64
isl-0.16.1-6.el8.x86_64 jbigkit-libs-2.1-14.el8.x86_64
kernel-headers-4.18.0-348.2.1.el8_5.x86_64 keyutils-libs-devel-1.5.10-9.el8.x86_64
krb5-devel-1.18.2-14.el8.x86_64 libX11-1.6.8-5.el8.x86_64
libX11-common-1.6.8-5.el8.noarch libXau-1.0.9-3.el8.x86_64
libXpm-3.5.12-8.el8.x86_64 libcom_err-devel-1.45.6-2.el8.x86_64
libimagequant-2.12.5-1.el8.x86_64 libjpeg-turbo-1.5.3-12.el8.x86_64
libkadm5-1.18.2-14.el8.x86_64 libmcrypt-2.5.8-26.el8.x86_64
libmpc-1.1.0-9.1.el8.x86_64 libpng-2:1.6.34-5.el8.x86_64
libraqm-0.7.0-4.el8.x86_64 libselinux-devel-2.9-5.el8.x86_64
libsepol-devel-2.9-3.el8.x86_64 libsodium-1.0.18-2.el8.x86_64
libstdc++-devel-8.5.0-4.el8_5.x86_64 libtiff-4.0.9-20.el8.x86_64
libtool-2.4.6-25.el8.x86_64 libverto-devel-0.3.0-5.el8.x86_64
libwebp-1.0.0-5.el8.x86_64 libxcb-1.13.1-1.el8.x86_64
libxcrypt-devel-4.1.1-6.el8.x86_64 libxml2-devel-2.9.7-9.el8_4.2.x86_64
m4-1.4.18-7.el8.x86_64 make-1:4.2.1-10.el8.x86_64
openssl-devel-1:1.1.1k-5.el8_5.x86_64 pcre2-devel-10.32-2.el8.x86_64
pcre2-utf16-10.32-2.el8.x86_64 pcre2-utf32-10.32-2.el8.x86_64
perl-Thread-Queue-3.13-1.el8.noarch php-7.4.27-1.el8.remi.x86_64
php-devel-7.4.27-1.el8.remi.x86_64 php-fedora-autoloader-1.0.1-2.el8.remi.noarch
php-gd-7.4.27-1.el8.remi.x86_64 php-mysqlnd-7.4.27-1.el8.remi.x86_64
php-opcache-7.4.27-1.el8.remi.x86_64 php-pdo-7.4.27-1.el8.remi.x86_64
php-pear-1:1.10.13-1.el8.remi.noarch php-pecl-apcu-5.1.21-1.el8.remi.7.4.x86_64
php-pecl-apcu-devel-5.1.21-1.el8.remi.7.4.x86_64 php-pecl-mcrypt-1.0.4-1.el8.remi.7.4.x86_64
php-pecl-xdebug-2.9.8-1.el8.remi.7.4.x86_64 php-process-7.4.27-1.el8.remi.x86_64
php-sodium-7.4.27-1.el8.remi.x86_64 xz-devel-5.2.4-3.el8.x86_64
zlib-devel-1.2.11-17.el8.x86_64
Complete!
</code></pre>
<p>OK。</p>
<pre><code class="bash"># php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php && php -r "unlink('composer-setup.php');" && mv composer.phar /usr/local/bin/composer
All settings correct for using Composer
Downloading...
Composer (version 2.2.1) successfully installed to: /etc/yum.repos.d/composer.phar
Use it: php composer.phar
# composer --version
Composer version 2.2.1 2021-12-22 22:21:31
</code></pre>
<p>Composer も入りました。</p>
<pre><code class="bash"># mkdir /var/log/php
# chown apache /var/log/php
# chmod 755 /var/log/php
# mkdir -p /etc/ssl/private
</code></pre>
<p>まあこの辺りは普通に。</p>
<h3 id="SSL"><a href="#SSL">SSL</a></h3>
<pre><code class="bash"># openssl req -new -newkey rsa:2048 -nodes -out /etc/ssl/private/server.csr -keyout /etc/ssl/private/server.key -subj "/C=/ST=/L=/O=/OU=/CN=*.lvh.me"
## 略
# openssl x509 -days 365 -req -signkey /etc/ssl/private/server.key -in /etc/ssl/private/server.csr -out /etc/ssl/private/server.crt
Signature ok
subject=CN = *.lvh.me
Getting Private key
</code></pre>
<p>OK。</p>
<h3 id="Apache の設定ファイル"><a href="#Apache+%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB">Apache の設定ファイル</a></h3>
<h4 id="ssl.conf"><a href="#ssl.conf">ssl.conf</a></h4>
<pre><code class="bash"># cat /etc/httpd/conf.d/ssl.conf
## 略
</code></pre>
<p>表示させたSSL用の設定を現行のものと差し替えます。ただし、現行の設定をなるべく引き継ぐように。これは他の設定ファイルも同様です。</p>
<pre><code class="conf">- SSLRandomSeed startup file:/dev/urandom 256
- SSLRandomSeed connect builtin
- SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
</code></pre>
<p>現行にあったこれらの行は削除。</p>
<pre><code class="conf">+ SSLHonorCipherOrder on
</code></pre>
<p>これは新しく追加されていました。</p>
<pre><code class="conf">SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
</code></pre>
<p>プロトコルについては念のため現行の設定を引き継ぎ。流石にもう SSLv2 なんて存在しないでしょうけど……。</p>
<pre><code class="conf">- <Files ~ "\.(cgi|shtml|phtml|php3?)$">
+ <FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
- </Files>
+ </FilesMatch>
</code></pre>
<p>微妙にディレクティブの表現が変わっていますが、影響はなさそうなので変更を受け入れます。</p>
<h4 id="php.conf"><a href="#php.conf">php.conf</a></h4>
<pre><code class="bash"># cat /etc/httpd/conf.d/php.conf
## 略
# Redirect to local php-fpm if mod_php (5 or 7) is not available
<IfModule !mod_php5.c>
<IfModule !mod_php7.c>
# Enable http authorization headers
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
<FilesMatch \.(php|phar)$>
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>
</IfModule>
</IfModule>
</code></pre>
<p>こちらは最後の部分に追記がありますね。これはそのまま受け入れ。</p>
<h4 id="php.ini"><a href="#php.ini">php.ini</a></h4>
<pre><code class="bash"># cat /etc/php.ini
## 略
</code></pre>
<p>こちらも設定を引き継ぎ、といっても現行の設定と変更点はなく(自前の設定を引き継いだ) 差分としてはコメントの文字列くらい。</p>
<h3 id="AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.0.2.1. Set the 'ServerName' directive globally to suppress this message"><a href="#AH00558%3A+httpd%3A+Could+not+reliably+determine+the+server%27s+fully+qualified+domain+name%2C+using+192.0.2.1.+Set+the+%27ServerName%27+directive+globally+to+suppress+this+message">AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.0.2.1. Set the 'ServerName' directive globally to suppress this message</a></h3>
<p>Apache を起動しようとしたところ、</p>
<blockquote>
<p>AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.0.2.1. Set the 'ServerName' directive globally to suppress this message</p>
</blockquote>
<p>のエラーメッセージがログに記録されて起動してこない現象に遭遇。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sachiko-kame/items/a6deebbad207d627b598">[Docker]AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using ***.***.*.*. Set the 'ServerName' directive globally to suppress this message - Qiita</a></li>
</ul>
<p>そういえば元々の Dockerfile には記述していましたが、 <code>httpd.conf</code> への追記をしていませんでした。</p>
<pre><code class="bash">echo ServerName www.example.com:80 >> /etc/httpd/conf/httpd.conf
</code></pre>
<p>これでOK。</p>
<pre><code class="bash"># httpd -v
Server version: Apache/2.4.37 (centos)
Server built: Nov 12 2021 04:57:27
</code></pre>
<p>バージョンも拾えました。</p>
<h3 id="(2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/php-fpm/www.sock (*) failed"><a href="#%282%29No+such+file+or+directory%3A+AH02454%3A+FCGI%3A+attempt+to+connect+to+Unix+domain+socket+%2Frun%2Fphp-fpm%2Fwww.sock+%28%2A%29+failed">(2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/php-fpm/www.sock (*) failed</a></h3>
<p>これで Apache も起動してきたのでブラウザで表示確認、ということで <code>phpinfo()</code> でも表示させようかとファイルを用意して <code>curl</code> してみると……</p>
<blockquote>
<p>Service Unavailable</p>
<p>The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.</p>
</blockquote>
<p>503エラーが出てしまいました。</p>
<blockquote>
<p>(2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/php-fpm/www.sock (*) failed</p>
</blockquote>
<p>Apache のエラーログには上述のログが記録されていました。</p>
<p>今までとは異なる方法で PHP をインストールしたら、どうやら php-fpm (CGIモード) で動作しようとしてしまっているようです。</p>
<p>今回の環境ではCGI版かモジュール版かはあまり考慮しておらず、Webサーバも Apache のためモジュール版でも良いと判断。</p>
<p>動作を切り替えます。</p>
<pre><code class="bash"># less /etc/httpd/conf/httpd.conf
## 略
Include conf.modules.d/*.conf
</code></pre>
<p>念のためモジュール読み込みの記述があることを確認。</p>
<pre><code class="bash"># ls /etc/httpd/conf.modules.d/
00-base.conf 00-lua.conf 00-optional.conf 00-ssl.conf 01-cgi.conf 10-proxy_h2.conf README
00-dav.conf 00-mpm.conf 00-proxy.conf 00-systemd.conf 10-h2.conf 15-php.conf
</code></pre>
<p>関係しそうなのは <code>00-mpm.conf</code>, <code>01-cgi.conf</code>, <code>15-php.conf</code> 辺りでしょうか。</p>
<pre><code class="bash"># less /etc/httpd/conf.modules.d/15-php.conf
# Cannot load both php5 and php7 modules
<IfModule !mod_php5.c>
<IfModule prefork.c>
LoadModule php7_module modules/libphp7.so
</IfModule>
</IfModule>
</code></pre>
<p>ここはそのまま。</p>
<pre><code class="bash"># less /etc/httpd/conf.modules.d/01-cgi.conf
# This configuration file loads a CGI module appropriate to the MPM
# which has been configured in 00-mpm.conf. mod_cgid should be used
# with a threaded MPM; mod_cgi with the prefork MPM.
<IfModule mpm_worker_module>
LoadModule cgid_module modules/mod_cgid.so
</IfModule>
<IfModule mpm_event_module>
LoadModule cgid_module modules/mod_cgid.so
</IfModule>
<IfModule mpm_prefork_module>
LoadModule cgi_module modules/mod_cgi.so
</IfModule>
</code></pre>
<p>ここもそのまま。</p>
<pre><code class="bash"># less /etc/httpd/conf.modules.d/00-mpm.conf
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines. See the httpd.conf(5) man
# page for more information on changing the MPM.
# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#
# NOTE: If enabling prefork, the httpd_graceful_shutdown SELinux
# boolean should be enabled, to allow graceful stop/shutdown.
#
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
LoadModule mpm_event_module modules/mod_mpm_event.so
</code></pre>
<p>変更するのはここ。</p>
<pre><code>- #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
+ LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
- LoadModule mpm_event_module modules/mod_mpm_event.so
# LoadModule mpm_event_module modules/mod_mpm_event.so
</code></pre>
<p>上述のうち2ヶ所を反転させます。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.out48.com/archives/5636/">CentOSにApacheとPHP入れてPHPファイルを表示しようとしたら503エラー Output48</a></li>
</ul>
<p>これでOK。起動も確認できました。</p>
<p>テンプレートとして上述を反転させた <code>00-mpm.conf</code> を用意し、エントリポイントでファイルコピーして設定を上書きすることで対処しました。</p>
<p><a href="https://crieit.now.sh/upload_images/abe7eb81a2b7f6580feb784cb81cdf1361cb21ea49eef.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/abe7eb81a2b7f6580feb784cb81cdf1361cb21ea49eef.jpg?mw=700" alt="最終的に AlmaLinux の Docker Compose で起動、確認した phpinfo() の画面" /></a></p>
<p>最終的に AlmaLinux の Docker Compose を作成して起動し、ブラウザで該当の PHPファイル にアクセスし、 <code>phpinfo()</code> の画面が表示されることを確認できました。OK。</p>
<h3 id="SSLCertificateFile: file '/etc/pki/tls/certs/localhost.crt' does not exist or is empty"><a href="#SSLCertificateFile%3A+file+%27%2Fetc%2Fpki%2Ftls%2Fcerts%2Flocalhost.crt%27+does+not+exist+or+is+empty">SSLCertificateFile: file '/etc/pki/tls/certs/localhost.crt' does not exist or is empty</a></h3>
<p>上述のエラーの他に</p>
<blockquote>
<p>SSLCertificateFile: file '/etc/pki/tls/certs/localhost.crt' does not exist or is empty</p>
</blockquote>
<p>localhost のSSL証明書がない、というエラーにも遭遇しました。</p>
<p>なければ作れば良いだけ、上述で</p>
<pre><code class="bash">echo ServerName www.example.com:80 >> /etc/httpd/conf/httpd.conf
</code></pre>
<p>としているので、このダミードメインを使います。</p>
<pre><code class="bash"># openssl req -new -newkey rsa:2048 -nodes -out /etc/pki/tls/certs/localhost.csr -keyout /etc/pki/tls/private/localhost.key -subj "/C=/ST=/L=/O=/OU=/CN=www.example.com"
## 略
# openssl x509 -days 365 -req -signkey /etc/pki/tls/private/localhost.key -in /etc/pki/tls/certs/localhost.csr -out /etc/pki/tls/certs/localhost.crt
Signature ok
subject=CN = www.example.com
Getting Private key
</code></pre>
<p>これでOK。 <code>ssl.conf</code> には記述はあるのですが……。</p>
<h3 id="MySQL"><a href="#MySQL">MySQL</a></h3>
<p>次に MySQL 側を。こちらはほぼ手を加える必要はないという想定です。</p>
<pre><code class="bash"># dnf localinstall https://dev.mysql.com/get/mysql80-community-release-el8-2.noarch.rpm
## 略
Package mysql80-community-release-el8-2.noarch is already installed.
Dependencies resolved.
Nothing to do.
Complete!
</code></pre>
<p>CentOS8 用ということでリポジトリの入れ方を少し変更。</p>
<pre><code class="bash"># ls /etc/yum.repo.d/
CentOS-Linux-AppStream.repo CentOS-Linux-Media.repo epel-testing.repo
CentOS-Linux-BaseOS.repo CentOS-Linux-Plus.repo mysql-community.repo
CentOS-Linux-ContinuousRelease.repo CentOS-Linux-PowerTools.repo mysql-community-source.repo
CentOS-Linux-Debuginfo.repo CentOS-Linux-Sources.repo remi-modular.repo
CentOS-Linux-Devel.repo epel-modular.repo remi.repo
CentOS-Linux-Extras.repo epel-playground.repo remi-safe.repo
CentOS-Linux-FastTrack.repo epel.repo
CentOS-Linux-HighAvailability.repo epel-testing-modular.repo
</code></pre>
<p><code>mysql-community.repo</code>, <code>mysql-community-source.repo</code> の2つが追加されたことを確認。</p>
<pre><code class="bash"># dnf module disable mysql
## 略
Complete!
</code></pre>
<p>デフォルトの MySQL がいると邪魔になるので無効化して</p>
<pre><code class="bash"># dnf -y install mysql-community-devel mysql-community-server
## 略
Installed:
mysql-community-client-8.0.27-1.el8.x86_64 mysql-community-client-plugins-8.0.27-1.el8.x86_64
mysql-community-common-8.0.27-1.el8.x86_64 mysql-community-devel-8.0.27-1.el8.x86_64
mysql-community-libs-8.0.27-1.el8.x86_64 mysql-community-server-8.0.27-1.el8.x86_64
net-tools-2.0-0.52.20160912git.el8.x86_64
Complete!
</code></pre>
<p>インストール完了。</p>
<pre><code class="bash"># mysqld --version
/usr/sbin/mysqld Ver 8.0.27 for Linux on x86_64 (MySQL Community Server - GPL)
</code></pre>
<p>デフォルトでは <code>8.0.26</code> だったバージョンが地味に <code>8.0.27</code> に上がりました。</p>
<pre><code class="bash"># grep 'temporary password' /var/log/mysqld.log
yyyy-mm-ddThh:ii:ss.zzzzzzZ 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: XXXXXXXXXXXX
</code></pre>
<p>初期パスワードの出現位置が半角スペース区切りで13番目であることを確認。これはエントリポイントで <code>awk</code> を使って抽出、初期パスワードを環境変数の値で書き換える処理で使用するため個人的には重要ポイント。ここは変更しなくて良さそうです。</p>
<pre><code class="bash"># cat /etc/my.cnf
[mysqld]
## 略
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
</code></pre>
<p>デフォルトで4つパラメータが指定されています。うち3つはテンプレートの設定ファイルに記述がされているので不要、 <code>pid-file</code> だけ現時点では指定がないため、これだけ <code>base.cnf</code> に移植します。</p>
<p><code>/etc/my.cnf</code> には上述4つを削除した代わりに <code>!includedir /etc/my.cnf.d</code> を末尾に追加したものを現行の <code>my.cnf</code> と差し替え。</p>
<p>これで MySQL 側は良さそうです。</p>
<p>なお、 phpMyAdmin は公式イメージをそのまま使っているので変更なし。</p>
<p>以上で一通り動作検証できたので、これをベースに AlmaLinux 用に書き換えれば良さそうです。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<h3 id="Docker"><a href="#Docker">Docker</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://hub.docker.com/_/almalinux?tab=tags">almalinux Tags | Docker Hub</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://hub.docker.com/_/centos?tab=tags">centos Tags | Docker Hub</a></li>
</ul>
<h3 id="AlmaLinux"><a href="#AlmaLinux">AlmaLinux</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.apar.jp/linux/15554/">AlmaLinux 8.4 LAMPサーバインストールメモ【Apache2.4+MySQL8.0+PHP7.4】 | あぱーブログ</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yamada-hakase/items/17b41d33e30232b69fe2">AlmaLinuxを使ってみた(後編) - Qiita</a></li>
</ul>
<h3 id="dnf"><a href="#dnf">dnf</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.trippyboy.com/2021/terraform/almalinux%E3%81%ABterraform%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92yum%E3%81%A7%E5%B0%8E%E5%85%A5%E3%81%99%E3%82%8B%E3%81%AE%E5%B7%BB/">Almalinuxにterraformコマンドをyumで導入するの巻 - TrippyBoyの愉快な日々</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/40937056/dnf-missing-config-manager-command">linux - DNF missing config-manager command - Stack Overflow</a></li>
</ul>
<h3 id="remi"><a href="#remi">remi</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="http://rpms.remirepo.net/">Remi's RPM repository</a></li>
</ul>
<h3 id="AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.0.2.1. Set the 'ServerName' directive globally to suppress this message"><a href="#AH00558%3A+httpd%3A+Could+not+reliably+determine+the+server%27s+fully+qualified+domain+name%2C+using+192.0.2.1.+Set+the+%27ServerName%27+directive+globally+to+suppress+this+message">AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.0.2.1. Set the 'ServerName' directive globally to suppress this message</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sachiko-kame/items/a6deebbad207d627b598">[Docker]AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using ***.***.*.*. Set the 'ServerName' directive globally to suppress this message - Qiita</a></li>
</ul>
<h3 id="PHP"><a href="#PHP">PHP</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://mebee.info/2020/03/12/post-7365/">CentOs8 php7.4をインストールする | mebee</a></li>
</ul>
<h3 id="(2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/php-fpm/www.sock (*) failed"><a href="#%282%29No+such+file+or+directory%3A+AH02454%3A+FCGI%3A+attempt+to+connect+to+Unix+domain+socket+%2Frun%2Fphp-fpm%2Fwww.sock+%28%2A%29+failed">(2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/php-fpm/www.sock (*) failed</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/58365479/no-such-file-or-directory-ah02454-fcgi-attempt-to-connect-to-unix-domain-sock">apache - No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /var/run/php/php5.6-fpm.sock (*) failed - Stack Overflow</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.out48.com/archives/5636/">CentOSにApacheとPHP入れてPHPファイルを表示しようとしたら503エラー Output48</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://ja.stackoverflow.com/questions/46727/amazon-linux2%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BCah02454%E3%82%84ah01079%E3%81%AA%E3%81%A9%E3%81%8C%E5%87%BA%E3%81%A6httpd%E3%81%8C%E3%81%86%E3%81%BE%E3%81%8F%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%BE%E3%81%9B%E3%82%93">php - amazon-linux2でエラーAH02454やAH01079などが出てhttpdがうまく起動しません - スタック・オーバーフロー</a></li>
</ul>
<h3 id="php-fpm"><a href="#php-fpm">php-fpm</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/kotarella1110/items/634f6fafeb33ae0f51dc">nginx と PHP-FPM の仕組みをちゃんと理解しながら PHP の実行環境を構築する - Qiita</a></li>
</ul>
<h3 id="SSLCertificateFile: file '/etc/pki/tls/certs/localhost.crt' does not exist or is empty"><a href="#SSLCertificateFile%3A+file+%27%2Fetc%2Fpki%2Ftls%2Fcerts%2Flocalhost.crt%27+does+not+exist+or+is+empty">SSLCertificateFile: file '/etc/pki/tls/certs/localhost.crt' does not exist or is empty</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://daredemose.com/linux/ssl/">SSL/TLS | 初心者向けプログラミング講座</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://hacknote.jp/archives/51779/">いつの間にか作られてる /etc/pki/tls/certs/localhost.crt と /etc/pki/tls/private/localhost.key の謎 | ハックノート</a></li>
</ul>
<h3 id="MySQL"><a href="#MySQL">MySQL</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yasushi-jp/items/1579c301075d693a2a36">MySQL 8.0 を CentOS 8.1 にインストールする手順 - Qiita</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17849
2021-12-13T23:56:29+09:00
2021-12-13T23:56:29+09:00
https://crieit.net/posts/awk-only-match-last-line-for-mysql-init-password-20211213
awk で条件に合致する最後の行のみ処理する
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>次のようなシチュエーションを考えます。</p>
<ul>
<li>Docker 環境で MySQL の初期パスワードを変更するシェルスクリプトをエントリポイントで実行</li>
<li>MySQL のログ (特に <code>mysql-error.log</code>) をボリュームマウントしてファイルの永続化を実施している</li>
<li>このプロジェクトでディレクトリを使い回して1回目の MySQL のログを削除せずに2回目のビルドを実行する</li>
</ul>
<p>このとき、 <code>mysql-error.log</code> 内に初期パスワードが2回記録されることになります。</p>
<p>すると、条件に合致する最初の行(1回目の初期パスワード)を処理しようとした際に(2回目のパスワードが設定されているため)パスワードが合致せず、処理が失敗してしまう遭遇したので対処しました。</p>
<h2 id="対処"><a href="#%E5%AF%BE%E5%87%A6">対処</a></h2>
<pre><code>- DB_INIT_PASSWORD=$(sudo grep 'temporary password' /var/log/mysql/mysql-error.log | sudo awk '{print $13}')
+ DB_INIT_PASSWORD=$(sudo grep 'temporary password' /var/log/mysql/mysql-error.log | sudo awk 'END{print $13}')
</code></pre>
<p>エントリポイントのシェルスクリプトで、 <code>awk</code> に <code>END</code> を付け加えました。処置としてはこれだけ。</p>
<h2 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h2>
<p>試しに、中身のシェルスクリプトを該当環境で手動で実行してみます。</p>
<h3 id="変更前"><a href="#%E5%A4%89%E6%9B%B4%E5%89%8D">変更前</a></h3>
<pre><code class="bash"># sudo grep 'temporary password' /var/log/mysql/mysql-error.log | sudo awk '{print $13}'
XXXXXXXXXXXX
YYYYYYYYYYYY
</code></pre>
<p>変更前では複数マッチしていることが確認できます。このうち、最初のパスワード <code>XXXXXXXXXXXX</code> で認証をくぐって理しようとすると冒頭のようにパスワードが合致せず失敗します。</p>
<h3 id="変更後"><a href="#%E5%A4%89%E6%9B%B4%E5%BE%8C">変更後</a></h3>
<pre><code class="bash"># sudo grep 'temporary password' /var/log/mysql/mysql-error.log | sudo awk 'END{print $13}'
YYYYYYYYYYYY
</code></pre>
<p>そこで変更後。今度は1回目のパスワード <code>XXXXXXXXXXXX</code> がヒットせず、2回目のパスワード <code>YYYYYYYYYYYY</code> のみがヒットするようになりました。</p>
<p>これで Docker Compose 全体のビルドもコケなくなりました。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://orebibou.com/ja/home/201607/20160725_001/">awkで最後の行(最終行)のみ処理を行わせる | 俺的備忘録 -なんかいろいろ-</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17843
2021-12-10T23:34:08+09:00
2021-12-10T23:34:08+09:00
https://crieit.net/posts/ssh-login-by-password-in-docker-container-20211210
Dockerコンテナ に SSHログイン できるようにする(パスワード方式)
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>Dockerコンテナ でファイル永続化をすると便利ではあるのですが、 Windows-Linux間 だと異なるファイルシステム間で整合性を保つ処理でもたつき、大量のファイルがある場合は体感的には加速度的に遅延がひどくなってしまいます。</p>
<p>一時的な試験であれば、ファイル永続化を捨てるという選択肢を取ることができると思います。</p>
<p>そこで課題となるのは、ファイルをどうやってコンテナの中に持ち込むか。</p>
<p>そのための一つの方法として、 SFTP を採ることにしました。通常のサーバと同様に、 SFTP で接続してファイルをアップロードする、と。</p>
<p>であれば、 SSHログイン できなければ話が成立しないので、 SSHログイン できるようにしてみたいと思います。</p>
<h2 id="コード"><a href="#%E3%82%B3%E3%83%BC%E3%83%89">コード</a></h2>
<ul>
<li>ベース: <a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/docker_compose_ambergrease">arm-band/docker_compose_ambergrease</a></li>
</ul>
<p>例によって Ambergrease をベースに使います。</p>
<h3 id=".env"><a href="#.env">.env</a></h3>
<pre><code class="env"># 略
WEB_HOST_PORTSSH=2222
WEB_CONTAINER_PORTSSH=22
WEB_SSH_USER=root
WEB_SSH_PASSWORD=Password-1234
# 略
</code></pre>
<p>今回はWebサーバのコンテナに SSHログイン したいので、必要なパラメータを追加します。</p>
<p>管理者権限ユーザもハードコーディングはしたくないので一緒に変数にしておきます。ただ、 Docker で一時的な試験環境なので SSH はパスワード認証方式で良いかな、と。</p>
<h3 id="docker-compose.yml"><a href="#docker-compose.yml">docker-compose.yml</a></h3>
<pre><code class="yml"> web:
build:
context: ./apache/docker
dockerfile: Dockerfile
args:
# 略
WEB_HOST_PORTSSH: $WEB_HOST_PORTSSH
WEB_CONTAINER_PORTSSH: $WEB_CONTAINER_PORTSSH
WEB_SSH_USER: $WEB_SSH_USER
WEB_SSH_PASSWORD: $WEB_SSH_PASSWORD
# 略
volumes:
# 略
# apache virtual host
# - ./apache/www:/var/www/$WEB_ROOT_DIRECTORY/web
# 略
ports:
# 略
- "$WEB_HOST_PORTSSH:$WEB_CONTAINER_PORTSSH"
entrypoint: bash -c "bash /workspace/entrypoint_web.sh $WEB_ROOT_DIRECTORY $WEB_DOMAIN $WEB_HOST_PORTNUM $WEB_CONTAINER_PORTNUM $WEB_HOST_PORTSSL $WEB_CONTAINER_PORTSSL $WP_CLI $WEB_SSH_USER $WEB_SSH_PASSWORD && /bin/bash"
# 略
</code></pre>
<p>主に変更した部分のみ掲載。</p>
<ul>
<li><code>args</code>: <code>.env</code> で追加したホスト・コンテナ双方のポート番号を引数に追加</li>
<li><code>volumes</code>: 今回の本題。ファイル数が多いと激重になってしまうので仮想ホストのファイル永続化を切っています</li>
<li><code>ports</code>: <code>.env</code> で追加したホスト・コンテナ双方のポート番号を紐付け</li>
<li><code>entrypoint</code>: エントリポイントとして実行するシェルスクリプトに渡す引数に <code>.env</code> で追加した <code>$WEB_SSH_USER</code>, <code>$WEB_SSH_PASSWORD</code> (SSHログインユーザ名・パスワード)を追加</li>
</ul>
<h3 id="Dockerfile"><a href="#Dockerfile">Dockerfile</a></h3>
<pre><code class="dockerfile"># 略
# yum install
RUN yum -y update && yum -y install \
# 略
# network ss (instaed of netstat)
iproute \
# SSH
openssh-server
# 略
# SSH
RUN mkdir /var/run/sshd
</code></pre>
<p>追加した項目は <code>openssh-server</code> のインストールと、ディレクトリ <code>/var/run/sshd</code> の作成のみ。それ以外の処理はエントリポイント側に投げました。</p>
<h3 id="entrypoint_web.sh"><a href="#entrypoint_web.sh">entrypoint_web.sh</a></h3>
<pre><code class="sh"># 略
# SSH
sed -ri 's/^#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config
echo "${8}:${9}" | chpasswd
ssh-keygen -t rsa -N "" -f /etc/ssh/ssh_host_rsa_key
/usr/sbin/sshd -D &
</code></pre>
<p>先程述べた通り、 SSHサーバ についての主な処理はこちらに追加しました。</p>
<ol>
<li>管理者権限のログインを有効化し</li>
<li>パスワードを上述の Docker Compose から引数で渡された <code>.env</code> の値に書き換え</li>
<li>使用しないものの存在しないとエラーになるので秘密鍵を生成</li>
<li>最後にフォアグラウンドで SSHサーバ を起動</li>
</ol>
<p><a href="https://crieit.now.sh/upload_images/cd8f856540941fe0320d9bb4443a1b6561b0d2f9345c0.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/cd8f856540941fe0320d9bb4443a1b6561b0d2f9345c0.jpg?mw=700" alt="TeraTerm で SSH ログイン" /></a></p>
<p><a href="https://crieit.now.sh/upload_images/9cd07317d7e8c28ade7e61b9c5fa91ed61b0d308ce42f.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9cd07317d7e8c28ade7e61b9c5fa91ed61b0d308ce42f.jpg?mw=700" alt="TeraTerm で SSH ログイン" /></a></p>
<p><a href="https://crieit.now.sh/upload_images/fe8fed10666c348a7e780afb22263ab161b0d324ef9d5.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/fe8fed10666c348a7e780afb22263ab161b0d324ef9d5.jpg?mw=700" alt="TeraTerm で SSH ログイン" /></a></p>
<p>これで SSHサーバ が起動し、 <code>.env</code> でアクセスできるようになりました。</p>
<p>なお、ポート番号は <code>.env</code> のホスト用のポートなので接続する際は注意。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://nxmnpg.lemoda.net/ja/8/sshd">sshd(8) manページ</a>: <code>-D</code> について</li>
<li><a target="_blank" rel="nofollow noopener" href="https://pocketcode.net/docker-centos7-ssh-connect">Dockerで構築したCentOS7にSSH接続する | ポケットコード</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://genchan.net/it/virtualization/docker/8547/">【Docker】CentOS7,8をコンテナ上で動作とSSHアクセスまで | インフラエンジニアの技術LOG</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17841
2021-12-09T00:28:54+09:00
2021-12-09T00:28:54+09:00
https://crieit.net/posts/memory-limit-up-of-phpmyadmin-docker-compose-20211209
Docker の phpMyAdmin公式イメージ でメモリ上限等を増やす (Docker Compose 使用)
<p>表題の通り、 phpMyAdmin公式イメージ でメモリ上限等を増やす方法をメモ。</p>
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>phpMyAdmion で大量のデータをインポートしようとしたら、以下のエラーが出て失敗してしまいました。</p>
<blockquote>
<p>Fatal error: Allowed memory size of XXXXXXXXX bytes exhausted (tried to allocate 16 bytes) in ......</p>
</blockquote>
<p>メモリ不足ですね……そのため、 phpMyAdmin の設定を変更します。</p>
<h2 id="対処"><a href="#%E5%AF%BE%E5%87%A6">対処</a></h2>
<h3 id="docker-compose.yml"><a href="#docker-compose.yml">docker-compose.yml</a></h3>
<pre><code class="yml"> phpmyadmin:
image: phpmyadmin/phpmyadmin
volumes:
# sessions
- ./phpmyadmin/sessions:/sessions
- ./phpmyadmin/conf/phpmyadmin-misc.ini:/usr/local/etc/php/conf.d/phpmyadmin-misc.ini
</code></pre>
<p><code>docker-compose.yml</code> でこのようにします。</p>
<p>ディレクトリ・ファイルは次の2つをボリュームマウントして永続化しています。</p>
<ul>
<li><code>/phpmyadmin/sessions</code></li>
<li><code>/phpmyadmin/conf/phpmyadmin-misc.ini</code></li>
</ul>
<h3 id="/phpmyadmin/conf/phpmyadmin-misc.ini"><a href="#%2Fphpmyadmin%2Fconf%2Fphpmyadmin-misc.ini">/phpmyadmin/conf/phpmyadmin-misc.ini</a></h3>
<pre><code class="ini">allow_url_fopen = Off
max_execution_time = 600
memory_limit = 64M
post_max_size = 64M
upload_max_filesize = 64M
</code></pre>
<p>後は <code>phpmyadmin-misc.ini</code> でパラメータを記述してあげればOK。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://deep-blog.jp/engineer/1887/">PHPのメモリー不足(Allowed memory size) | エンジニア足立のコーディング日記</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.yuulinux.tokyo/16613/">docker-compose phpmyadmin アップロード制限緩和設定 | 優技録</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17771
2021-11-20T17:13:30+09:00
2021-11-20T17:13:30+09:00
https://crieit.net/posts/mysql-on-docker-error-lower-case-table-names-20211120
Docker から MySQL 用のコンテナで初期化・起動しようとしたら The server option 'lower_case_table_names' is configured ... エラーで失敗する
<h2 id="現象"><a href="#%E7%8F%BE%E8%B1%A1">現象</a></h2>
<p>Docker から自作の MySQL 用のコンテナで初期化・起動しようとしたら MySQL が起動しておらず、手動で初期化コマンドを実行したら以下のエラーで失敗する現象に遭遇しました。</p>
<blockquote>
<p>[ERROR] The server option 'lower_case_table_names' is configured to use case sensitive table names but the data directory is on a case-insensitive file system which is an unsupported combination. Please consider either</p>
<p>using a case sensitive file system for your data directory or switching to a case-insensitive table name mode.</p>
</blockquote>
<h2 id="環境"><a href="#%E7%92%B0%E5%A2%83">環境</a></h2>
<p>環境としては以下の自作の LAMP環境 作成用の Docker Compose を使用しました。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/docker_compose_ambergrease/tree/afa8c12e3dff1ec435643bcd8c9a3215d1409a25">GitHub - arm-band/docker_compose_ambergrease</a></li>
</ul>
<p>MySQL5.7系 で、 entrypoint で</p>
<ul>
<li>設定ファイルをテンプレートからコピーして配置</li>
<li><code>/usr/sbin/mysqld --user=mysql --initialize &</code> で初期化コマンド実行</li>
<li><code>/usr/sbin/mysqld --user=mysql &</code> で MySQL 起動</li>
<li>MySQL のログから初期パスワードを見つけ出し、環境変数で設定された値に管理者パスワードを変更</li>
</ul>
<p>をしています。</p>
<p>このうち、2つ目の <code>/usr/sbin/mysqld --user=mysql --initialize &</code> で上述のエラーが発生していました。</p>
<h2 id="対処"><a href="#%E5%AF%BE%E5%87%A6">対処</a></h2>
<p>エラー文は「 MySQL の設定では大文字小文字を区別する設定になっているが、 <code>data</code>ディレクトリ のファイルシステムは大文字小文字を区別しない環境になっていて不一致を起こしているので、どちらかに統一してね」ということのようです。</p>
<p>今回は Docker for Windows 利用で、 <code>data</code>ディレクトリ はホスト側の Windows のフォルダにボリュームをマウントしています。また、データはコンテナを落としても保持していてほしいので Windows とのボリュームマウントを解除する方向性はなし。</p>
<p>そのため、ファイルシステムは Windows 依存になるので、大文字小文字を区別するファイルシステムに寄せるのは厳しい。したがって、 MySQL 側の設定を調整することにします。</p>
<pre><code class="conf">[mysqld]
## 略
# not only lowercase characters in tablename
# lower_case_table_names = 0
lower_case_table_names = 1
</code></pre>
<p>該当の設定は <code>lower_case_table_names</code> 。この値<code>0</code>だと大文字小文字を区別する、<code>1</code>だと小文字に変換、<code>2</code>だと大文字小文字を区別してディスクに保存するが MySQL からのルックアップ時に小文字に変換、という挙動になるようです。</p>
<p>今回はシンプルに全て小文字変換で<code>1</code>とすることにしました。</p>
<p>これで問題が解決されたことを確認。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://teratail.com/questions/131905">MySQL - MySQLが起動しない(mac)|teratail</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://dev.mysql.com/doc/refman/5.6/ja/identifier-case-sensitivity.html">MySQL :: MySQL 5.6 リファレンスマニュアル :: 9.2.2 識別子の大文字と小文字の区別</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17496
2021-07-11T01:08:30+09:00
2021-07-11T01:08:30+09:00
https://crieit.net/posts/listing-github-repository-in-docker-20210711
Github で特定ユーザの publicリポジトリ の名前の一覧を生成する Docker Compose
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>自分のあるリポジトリを clone しようとして、名前を失念。探すのに手間取ったのでリポジトリの名前の一覧を生成するスクリプトが欲しくなりました。</p>
<h2 id="調査"><a href="#%E8%AA%BF%E6%9F%BB">調査</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/emergent/items/a557246a0c0bf9d50a11">GitHubのリポジトリを一覧化する(public/private両対応) - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://rcmdnk.com/blog/2017/10/03/computer-github/">GitHubのレポジトリ一覧を取ってくるワンライナー</a></li>
</ul>
<p>調べたら Linuxコマンド でどうにかなりそうだったので、 Docker で Linux環境 を用意してごにょごにょしよう、と思い立ちました。</p>
<h2 id="成果物"><a href="#%E6%88%90%E6%9E%9C%E7%89%A9">成果物</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/docker_list_of_hirokawa">GitHub - arm-band/docker_list_of_hirokawa: Github の特定ユーザの public リポジトリの一覧を生成する Docker Compose 設定集。</a></li>
</ul>
<h2 id="構成"><a href="#%E6%A7%8B%E6%88%90">構成</a></h2>
<h3 id="ディレクトリ構造"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E6%A7%8B%E9%80%A0">ディレクトリ構造</a></h3>
<pre><code>PROJECT_ROOT/
├ docker/
│ └ Dockerfile
│
├ entrypoint/
│ └ entrypoint.sh
│
├ template/
│ └ script.sh // コンテナ内で実行したいスクリプトのテンプレート。一部変数をエントリポイントで置換
│
├ workspace/ // リポジトリ名一覧のテキストファイルのダンプ先
│
├ .env // docker-compose.yml 用の環境変数
└ docker-compose.yml
</code></pre>
<p>今回はこんなディレクトリ構造に。</p>
<h3 id="docker-compose.yml"><a href="#docker-compose.yml">docker-compose.yml</a></h3>
<pre><code class="yml">version: '3.8'
services:
hirokawa:
build:
context: ./docker
dockerfile: Dockerfile
args:
USER_NAME: $USER_NAME
FILE_NAME: $FILE_NAME
volumes:
# entrypoint
- ./entrypoint:/entrypoint
# workspace
- ./workspace:/workspace
# docker settings template
- ./template:/template
tty: true
entrypoint: /bin/sh -c "/bin/sh /entrypoint/entrypoint.sh $USER_NAME $FILE_NAME && /bin/sh"
</code></pre>
<p>リポジトリ名の一覧を取得したい対象ユーザ名とダンプ先ファイル名を <code>.env</code> で指定しています。</p>
<h3 id=".env"><a href="#.env">.env</a></h3>
<pre><code class="env">USER_NAME=saigyo
FILE_NAME=repository_list.txt
</code></pre>
<p>上述の通り。</p>
<h3 id="docker/Dockerfile"><a href="#docker%2FDockerfile">docker/Dockerfile</a></h3>
<pre><code class="Dockerfile">FROM alpine:latest
RUN apk update && \
apk upgrade && \
apk add --no-cache \
jq \
bash \
sed \
curl
RUN mkdir /var/script
RUN chmod 777 /var/script
</code></pre>
<p>必要なパッケージのインストールとスクリプトの生成先のディレクトリの作成。</p>
<p>今回はやることが最小限なので alpine を使用。</p>
<h3 id="entrypoint/entrypoint.sh"><a href="#entrypoint%2Fentrypoint.sh">entrypoint/entrypoint.sh</a></h3>
<pre><code class="sh">sed -e "s/USER_NAME/${1}/gi" -e "s/FILE_NAME/${2}/gi" /template/script.sh > /var/script/script.sh
</code></pre>
<p>一部変数名を <code>.env</code> の値で置換。一行しかないので command でも良かったかも。</p>
<h3 id="template/script.sh"><a href="#template%2Fscript.sh">template/script.sh</a></h3>
<pre><code class="sh">for page in $(seq 1 10);
do result=$(curl -s "https://api.github.com/users/USER_NAME/repos?page=$page&per_page=100"|jq -c '[.[] .name]'|jq -c '.[]');
if [ -z "$result" ];
then break;
fi;
formatted_result=$(echo "$result"|sed -e "s/\"//gi");
echo "$formatted_result" > "/workspace/FILE_NAME";
done
</code></pre>
<p>実行するスクリプトのテンプレート。個人ユーザ対象で <code>curl</code> で Github API を叩いて100個(指定可能な最大数)ずつ出力、 <code>jq</code> でフィルタリングして、 <code>workspace</code> にファイルとしてダンプ。</p>
<hr />
<p>これでやりたいことは実現できました。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<h3 id="サンプル"><a href="#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB">サンプル</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/emergent/items/a557246a0c0bf9d50a11">GitHubのリポジトリを一覧化する(public/private両対応) - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://rcmdnk.com/blog/2017/10/03/computer-github/">GitHubのレポジトリ一覧を取ってくるワンライナー</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://deep.tacoskingdom.com/blog/11">[Shell script] Alpine LinuxのDockerコンテナ内で使うjqをインストールする方法</a></li>
</ul>
<h3 id="jq"><a href="#jq">jq</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://jqplay.org/#">jq play</a></li>
</ul>
<h2 id="alpine で bash"><a href="#alpine+%E3%81%A7+bash">alpine で bash</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yumenomatayume/items/b28edbaf40a293519b8a">【docker alpine linux】でbashの使用方法 - Qiita</a></li>
</ul>
<h3 id="starting container process caused: exec: "bash": executable file not found in $PATH: unknown"><a href="#starting+container+process+caused%3A+exec%3A+%26quot%3Bbash%26quot%3B%3A+executable+file+not+found+in+%24PATH%3A+unknown">starting container process caused: exec: "bash": executable file not found in $PATH: unknown</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://kaoru2012.blogspot.com/2017/11/docker-executable-file-not-found-in-path.html">プログラマーの雑記: docker コンテナにログイン時に、「executable file not found in $PATH」エラーの対応</a></li>
</ul>
<h3 id="alpineイメージ への entrypoint 指定"><a href="#alpine%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8+%E3%81%B8%E3%81%AE+entrypoint+%E6%8C%87%E5%AE%9A">alpineイメージ への entrypoint 指定</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://cpoint-lab.co.jp/article/202009/16844/">【Docker】ENTRYPOINT と CMD の仕組みと小技 – 株式会社シーポイントラボ | 浜松のシステム・RTK-GNSS開発</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17486
2021-07-05T23:53:53+09:00
2021-07-05T23:53:53+09:00
https://crieit.net/posts/build-enviroment-node-version-switch-by-docker-20210706
Docker で Node.js のバージョン切替環境を構築する
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>Windows環境では長らく <a target="_blank" rel="nofollow noopener" href="https://github.com/nullivex/nodist">Nodist</a> を使ってきましたが、流石にそろそろ見切りを付けて安定的に Node.js を使用できる環境を構築したいと考えました。</p>
<p>理由としては以下の2点。</p>
<ul>
<li>そもそも Nodist のバージョンが <code>0.9.1</code> (<code>< 1.0.0</code>) であること</li>
<li><code>0.9.1</code> のリリースが2019/3/30で、2年以上も更新がされていないこと</li>
</ul>
<p>正直、<a target="_blank" rel="nofollow noopener" href="https://zenn.dev/ymasaoka/articles/note-uninstall-nodish-windows">2020 年ではもう使えない Nodist はアンインストールする (Windows)</a>に全て書かれていることなので改めて書く必要はないかもしれません。</p>
<p>個人的には <code>npm</code> の切替時にエラーになってしまって切り替えられないなどの不具合が発生し始めたので、先述したようにそろそろ限界かな、と感じるようになりました。</p>
<p>そこで次の環境について考えたとき、やはり自PCの環境を汚さずに済むので Docker で構築することにしました。</p>
<h2 id="構成"><a href="#%E6%A7%8B%E6%88%90">構成</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/docker_sink_vertex">GitHub - arm-band/docker_sink_vertex: A collection of settings for running Node.js on Docker.</a></li>
</ul>
<h3 id="ディレクトリ構造"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E6%A7%8B%E9%80%A0">ディレクトリ構造</a></h3>
<pre><code>PROJECT_ROOT/
│
├ .env
├ .gitignore
├ docker-compose.yml
└ readme.md
</code></pre>
<p>今回は Docker公式イメージ の <a target="_blank" rel="nofollow noopener" href="https://hub.docker.com/_/node">Node.js</a> を使うので、構成はいたってシンプルです。</p>
<h3 id=".env"><a href="#.env">.env</a></h3>
<pre><code class="env">NODE_VERSION=16.3.0
PROJECT_ROOT_DIRECTORY=../workspace/
</code></pre>
<p>Docker Compose の前に <code>.env</code> のサンプルを。指定しているのは Node.js のイメージのバージョン指定とマウントするボリュームのパスです。</p>
<p>今回はそもそもバージョン切替可能な Node.js の環境を構築することが主眼なので、バージョン指定をパラメータで指定できるようにしておきます。</p>
<p>それから、 Node.js 環境で実行したいプロジェクトがあるはずなので、そのプロジェクトのディレクトリをコンテナ内にマウントさせるためにパス指定を記述しておきます。</p>
<h3 id="docker-compose.yml"><a href="#docker-compose.yml">docker-compose.yml</a></h3>
<pre><code class="yml">version: '3.8'
services:
vertex:
image: "node:$NODE_VERSION"
user: "node"
volumes:
# project root
- $PROJECT_ROOT_DIRECTORY:/home/node/app
tty: true
ports:
- "3000:3000"
- "3001:3001"
</code></pre>
<p>以上を踏まえて Docker Compose の yml 。</p>
<p><code>.env</code> で説明した通り、 Node.js のイメージ指定とボリュームマウントの指定があります。</p>
<p>地味にポイントなのは <code>ports</code> 。今回は Browsersync を使った Gulpタスク を走らせようとしているのですが、ブラウザはホスト側にしかないため、ホストからコンテナ内の Browsersync の API を参照できるようにポートを指定しておきます。</p>
<p>これで試験してみます。</p>
<h2 id="試験"><a href="#%E8%A9%A6%E9%A8%93">試験</a></h2>
<p>上述の <code>docker-compose.yml</code> を作る途中で <code>ports</code> 指定をせず、何もカスタマイズしていない Gulp を走らせました。すると、以下のようなエラーが発生しました。</p>
<pre><code class="bash">Couldn't open browser (if you are using BrowserSync in a headless environment, you might want to set the open option to false)
</code></pre>
<p>上述した通りブラウザはホスト側にしかなく、一方で Browsersync 含む Gulpタスク はコンテナ内で動いているので、当然と言えば当然ですよね。</p>
<p>これで <code>ports</code> 指定を加えました。</p>
<p>また、 Browsersync 側の設定も変更を加えます。</p>
<pre><code class="javascript">browserSync.init({
server: {
baseDir: './dist/'
},
// open: 'external',
open: false, // ブラウザオープンをしない
https: true
});
</code></pre>
<p><code>open</code>オプション を <code>false</code> にすることで、ブラウザを自動的に起動しないようにしました。これをしておかないと上述のエラーが発生してしまうので。</p>
<p>代わりに手動でブラウザを開く必要がありますが、已む無し。 <code>https://localhost:3000/</code> できちんと見られるので良しとします。</p>
<h2 id="試験2"><a href="#%E8%A9%A6%E9%A8%932">試験2</a></h2>
<p>追試験を実施している最中に、一部の環境で <code>gulp.watch</code> による自動ビルドが2回に1回しか走らない現象に遭遇しました。</p>
<p>Node.js のバージョンを切り替えてもダメで、しかも <code>ejs</code>ファイル はOKですが <code>scss</code>ファイル や <code>yml</code>ファイル はダメなど、条件がいまいちよく分かりません。</p>
<p>検索してみるとオプションで <code>{ usePolling: true }</code> を指定すると直ったというのを見かけたので Gulpタスク に書き足してみました。</p>
<p>すると、現象が収まりました……ということは、ファイルをウォッチするタイミングか何かが上手くいっていないということ?</p>
<p>とりあえず動いたので良しとします。</p>
<h2 id="試験3"><a href="#%E8%A9%A6%E9%A8%933">試験3</a></h2>
<p>試験2の途中で Node.js のバージョンを切り替えたらそもそも <code>yarn</code> がエラーでコケるなど副作用が発生したので<a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2021/07/05/node-sass-adjust-node16/">gulp-sass を Node.js v16 環境に合わせて調整する</a>に書いたように諸々対処しました。</p>
<p>これでようやく想定している Gulpタスク 一式が使えるようになりました。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li>きっかけ
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/ymasaoka/articles/note-uninstall-nodish-windows">2020 年ではもう使えない Nodist はアンインストールする (Windows)</a></li>
</ul></li>
<li><code>Couldn't open browser (if you are using BrowserSync in a headless environment, you might want to set the open option to false)</code> のエラー
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/42456424/browsersync-within-a-docker-container">javascript - Browsersync within a Docker container - Stack Overflow</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://kore1server.com/373/Laravel5.5%E3%80%81Mix%E3%81%AEBrowserSync">Laravel5.5、MixのBrowserSync</a></li>
</ul></li>
<li><code>gulp.watch</code> が動かない
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/AyumuNekozuki/niconico-darkmode/issues/54">【開発環境】gulpのwatchが動かない · Issue #54 · AyumuNekozuki/niconico-darkmode · GitHub</a></li>
</ul></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17047
2021-05-01T13:26:57+09:00
2021-05-01T13:28:14+09:00
https://crieit.net/posts/sqlite-docker-20210501
Docker で PHP + SQLite3 の開発環境を構築する
<p>SQLite を試験したくなったので、環境を Docker で作ることにしました。</p>
<p>ベースは <a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2021/02/12/docker_centos7_apache_php_xdebug/">CentOS7 + Apache + PHP7 (Composer, Xdebug) の開発環境を Docker で作る</a> で。</p>
<h2 id="構成"><a href="#%E6%A7%8B%E6%88%90">構成</a></h2>
<h3 id="ディレクトリ構造"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E6%A7%8B%E9%80%A0">ディレクトリ構造</a></h3>
<pre><code>PROJECT_ROOT/
│
# 略
│
├ sqlite/
│
# 略
</code></pre>
<p>SQLite 用のディレクトリを掘っただけで、後は同じです。</p>
<h3 id="docker-compose.yml"><a href="#docker-compose.yml">docker-compose.yml</a></h3>
<pre><code class="yaml">version: '3.8'
services:
web:
build:
context: ./apache/docker
dockerfile: Dockerfile
args:
# 略
SQLITE_TABLENAME: $SQLITE_TABLENAME
labels:
lamp.sqlite.php: "SQLite PHP"
volumes:
# 略
# sqlite
- ./sqlite:/var/sqlite/
# 略
entrypoint: bash -c "bash /workspace/entrypoint.sh $WEB_ROOT_DIRECTORY $WEB_DOMAIN $WEB_HOST_PORTNUM $WEB_CONTAINER_PORTNUM $WEB_HOST_PORTSSL $WEB_CONTAINER_PORTSSL $SQLITE_TABLENAME && /bin/bash"
</code></pre>
<p><code>docker-compose.yml</code> も大部分は同じです。変数(<code>SQLITE_TABLENAME</code>)とボリュームがそれぞれ1つ増えたのと、 entrypoint へ渡す引数が1つ増えたくらいです。</p>
<h3 id=".env"><a href="#.env">.env</a></h3>
<pre><code class="env">WEB_ROOT_DIRECTORY=sample_sqlite
WEB_DOMAIN=lvh.me
WEB_HOST_PORTNUM=8080
WEB_CONTAINER_PORTNUM=80
WEB_HOST_PORTSSL=4043
WEB_CONTAINER_PORTSSL=443
SQLITE_TABLENAME=maindb
</code></pre>
<p>上述の通り、 SQLite のファイル名を決める変数が増えました。</p>
<h3 id="apache/docker/Dockerfile"><a href="#apache%2Fdocker%2FDockerfile">apache/docker/Dockerfile</a></h3>
<pre><code class="dockerfile">FROM centos:centos7
# 略
# enable repository remi & remi-php74
RUN yum-config-manager --enable remi && yum-config-manager --enable remi-php74
# php
RUN yum -y install php php-devel php-pdo php-mysqlnd php-mbstring php-gd php-pear php-pecl-apc-devel zlib-devel php-xml php-mcrypt php-pecl-xdebug
# sqlite
RUN yum -y install sqlite sqlite-devel
# disable repository remi & remi-php74
RUN yum-config-manager --disable remi && yum-config-manager --disable remi-php74
# 略
# volume directory
RUN mkdir /template
RUN mkdir /var/www/${WEB_ROOT_DIRECTORY}
RUN mkdir /var/www/${WEB_ROOT_DIRECTORY}/web
RUN mkdir /workspace
RUN mkdir /var/sqlite
</code></pre>
<p>こちらも概ね同じ。 PHP のインストール直後に <code>sqlite</code>, <code>sqlite-devel</code> をインストールしています。また、最後にボリュームとしてマウントするディレクトリを作成しています。</p>
<h2 id="workspace/entrypoint.sh"><a href="#workspace%2Fentrypoint.sh">workspace/entrypoint.sh</a></h2>
<pre><code class="sh"># 略
# make sqlite file & create dummy table
if [[ ! -e /var/sqlite/${7}.sqlite3 ]]; then
echo ".exit" | echo "create table testtable(one varchar(10), two smallint);" | sqlite3 /var/sqlite/${7}.sqlite3
fi
# Apache start
/usr/sbin/httpd -DFOREGROUND &
</code></pre>
<p>entrypoint も同様ほぼ同じですが、 Apache 起動前に「もし SQLite のデータファイルが該当ディレクトリにない場合は作成」の処理を追加しました。テーブルがないとファイルが生成されなかったので、ダミーテーブルも CREATE しています。</p>
<h2 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h2>
<p>上述で構築された SQLite にダミーデータを流し込んでテストしてみます。</p>
<pre><code class="bash"># sqlite3 /var/sqlite/maindb.sqlite3
sqlite> insert into testtable values('hello', 10);
sqlite .exit
#
</code></pre>
<p>まずはダミーテーブルにダミーデータを INSERT します。</p>
<pre><code class="php"><?php
try {
$pdo = new PDO('sqlite:/var/sqlite/maindb.sqlite3');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT * FROM testtable WHERE two >= :two");
$stmt->execute([
'two' => 5
]);
$result = $stmt->fetchAll();
var_dump($result);
}
catch (Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
</code></pre>
<p>次に上述のような <code>index.php</code> を作成し、Webアクセスします。</p>
<pre><code>/var/www/sample_sqlite/web/index.php:25:
array (size=1)
0 =>
array (size=2)
'one' => string 'hello' (length=5)
'two' => string '10' (length=2)
</code></pre>
<p>結果。これで PHP から PDOオブジェクト 経由でダミーテーブルに接続できたので、ひとまず環境構築という点では完了です。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://it-afi.com/php/post-1253/">php 7.4をソースからインストール時にchecking for sqlite3 > 3.7.4… no configure: error: Package requirements (sqlite3 > 3.7.4) were not met:</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.agent-grow.com/self20percent/2018/08/06/linux-command-auto-yes/">コマンドの途中で聞いてくる yes を自動入力したい?それ yes で出来るよ – 自主的20%るぅる</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://linuxfan.info/post-1739">シェルスクリプトでファイルの存在を確認する方法 | LFI</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://laboradian.com/how-to-use-sqlite-from-php/">PHP から SQLite を使う手順 – ラボラジアン</a>
<ul>
<li>最終的には SQLite3オブジェクト からではなく PDOオブジェクト から接続してしまいましたが</li>
</ul></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/39_isao/items/a5b4940138bced936de0">PHP + SQLite3 超入門したメモ - Qiita</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/15974
2020-06-23T01:07:00+09:00
2020-06-23T01:07:43+09:00
https://crieit.net/posts/SMB-samba-Dockerfile-docker-compose
無認証 SMB を samba で秒で立ち上げる Dockerfile (& docker-compose)
<p>docker 上の Linux (alpine) で Samba を立ち上げ、 無認証の SMB 共有を開始する Dockerfile をメモっておく。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://gist.github.com/advanceboy/a315d83d900929103d858a461b673e52">https://gist.github.com/advanceboy/a315d83d900929103d858a461b673e52</a></p>
<pre><code class="Dockerfile">FROM alpine:3.10
RUN mkdir -p /samba/share && \
chmod -R 0777 /samba/share && \
chown -R nobody:nobody /samba/share
# install samba
RUN apk update && \
apk add samba
RUN { \
echo "[global]"; \
echo " security = user"; \
echo " map to guest = Bad User"; \
echo " guest account = nobody"; \
echo " min protocol = SMB2"; \
echo "[public]"; \
echo " path = /samba/share"; \
echo " writable = yes"; \
echo " guest ok = yes"; \
echo " guest only = yes"; \
echo " create mode = 0666"; \
echo " directory mode = 0777"; \
} > /etc/samba/smb.conf
EXPOSE 139 445
# start smbd as foreground
ENTRYPOINT ["/bin/ash"]
CMD ["-c", "nmbd restart -D && smbd restart -FS --no-process-group </dev/null"]
</code></pre>
<h3 id="使用例"><a href="#%E4%BD%BF%E7%94%A8%E4%BE%8B">使用例</a></h3>
<p>手っ取り早く実行したい場合、以下のような <code>docker-compose.yml</code> を <code>Dockerfile</code> と同じフォルダに保存し、</p>
<p>```yaml:docker-compose.yml<br />
version: '3'<br />
services:<br />
smb:<br />
build: .<br />
ports:<br />
- 445:445</p>
<pre><code><br />コマンドプロンプト等のターミナルで、以下のように実行する。
```bash
docker-compose build
docker-compose up
</code></pre>
<h3 id="何に使うのか"><a href="#%E4%BD%95%E3%81%AB%E4%BD%BF%E3%81%86%E3%81%AE%E3%81%8B">何に使うのか</a></h3>
<p>docker でデータを永続化する際、 <a target="_blank" rel="nofollow noopener" href="https://docs.docker.com/storage/bind-mounts/">Bind Mounts</a> を使えば、デスクトップ側にファイルが永続化されているため、そのまま永続化されたファイルを覗き見ることができる。</p>
<p>しかし、 Bind Mounts では一部の機能に制限があることから、 <a target="_blank" rel="nofollow noopener" href="https://docs.docker.com/storage/volumes/">Volumes (Named Volumes, Anonymous Volumes)</a> を使うこともあるだろう。<br />
(とりわけ Windows デスクトップから Linux コンテナを使う場合、 ファイルシステムの違いから Bind Mounts だと期待しない動きに遭遇しやすい。)</p>
<p>このとき、 Volumes の中身を SMB で共有させるコンテナを起動させておくと、 デスクトップ側から Volumes の中身が簡単に見られるようになるので、開発や検証に便利になる。<br />
(但し上記の手順だと、 認証などが一切なく、 ネットワーク内のだれからでもアクセスできるので、 実運用上では 別途認証やアクセス元の制限を加えるなど、注意は必要だ。)</p>
<h3 id="Docker Desktop for Windows での回避策"><a href="#Docker+Desktop+for+Windows+%E3%81%A7%E3%81%AE%E5%9B%9E%E9%81%BF%E7%AD%96">Docker Desktop for Windows での回避策</a></h3>
<p>ホスト側が Linux であったり、 Windows 上の Docker Toolbox であれば、上記の手順だけでも問題なく SMB 共有が実行されるだろう。</p>
<p>しかし、 ホスト側が Docker Desktop for Windows である場合は、 Windows とコンテナの間で 445 ポートが競合してしまい、 以下のようなエラーが出て起動に失敗するはずだ。</p>
<pre><code class="text">ERROR: for smb Cannot start service smb: Ports are not available: listen tcp 0.0.0.0:445: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
ERROR: Encountered errors while bringing up the project.
</code></pre>
<p>SMB は他のポートではアクセスができない。<br />
また、 Docker Desktop for Windows では、 Windows デスクトップにポートフォワーディングせずに、 Hyper-V 上の Linux のホストマシンにアクセスする方法が用意されていない。<br />
このため、コンテナの SMB 共有させたければ Docker Desktop を起動している Windows 側の SMB を止めるしかない。</p>
<p>[blogcard url="http://sangosthi.blogspot.com/2011/03/how-to-disable-cifssmb-port-445-on.html"]</p>
<p><a href="https://crieit.now.sh/upload_images/74b1ca7505c22dfdf8d56c3b135a152b5ef0d6afbcdd8.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/74b1ca7505c22dfdf8d56c3b135a152b5ef0d6afbcdd8.png?mw=700" alt="2002_docker_samba_smb-01.png" /></a></p>
<p>上記の記事にあるように、 Windows 側で <code>Server</code> サービスを止め、無効化した後に OS を再起動すると、 445 ポートが空く。<br />
この状態で、 <code>docker-compose up</code> すれば、エラーなく実行できるだろう。<br />
ただ、ファイル共有をはじめとする様々な機能が Windows 側で動かなくなるだろうが。。。<br />
(ということもあり、あまりオススメできる方法ではない。)</p>
advanceboy
tag:crieit.net,2005:PublicArticle/15658
2019-12-30T14:15:44+09:00
2019-12-30T14:15:44+09:00
https://crieit.net/posts/Firebase-Vue-js-Cloud-Functions-docker-compose
Firebase フロントエンド(Vue.js)/Cloud Functions を同一docker-composeで実行する際に感じたこと
<h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2>
<p>2019/12/30現在において、Firebaseを開発する際に生じる不都合の一つとして、node version管理があると思います.</p>
<p>Cloud Functionsの開発において、nodeのバージョンはversion8、あるいは10がサポートされています.</p>
<blockquote>
<p>Cloud Functions ランタイムに関数をデプロイするには Firebase CLI が必要です。Node.js バージョン 8 と 10 がサポートされています。Node.js と npm をインストールする場合は、Node Version Manager をおすすめします。<br />
<a target="_blank" rel="nofollow noopener" href="https://firebase.google.com/docs/functions/get-started?hl=ja">https://firebase.google.com/docs/functions/get-started?hl=ja</a></p>
</blockquote>
<p>つまり、こんなことが頻発します.</p>
<pre><code class="bash">[dorakueyon]% yarn build
yarn run v1.19.2
error functions@: The engine "node" is incompatible with this module. Expected version "8". Got "10.15.3"
error Commands cannot run with an incompatible environment.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
</code></pre>
<p>このように、異なるversionが依存する開発では、その依存性をDockerに閉じ込めることで幸せになれます.</p>
<p>参考として、githubにcodeを置かせていただきました.<br />
- <a target="_blank" rel="nofollow noopener" href="https://github.com/dorakueyon/vue-firebase-cloud-function-docker-starter">github.com/dorakueyon/vue-firebase-cloud-function-docker-starter</a></p>
<h2 id="Vue.js + Cloud Functionsのフォルダ構成"><a href="#Vue.js+%2B+Cloud+Functions%E3%81%AE%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E6%A7%8B%E6%88%90">Vue.js + Cloud Functionsのフォルダ構成</a></h2>
<p>Docker化する前に、プロジェクトを作成した上でフォルダ構成をみてみます.</p>
<ul>
<li>Vue.js + Firebaseプロジェクト作成</li>
</ul>
<pre><code class="bash">$ vue create project-name
$ firebase init
</code></pre>
<ul>
<li>フォルダ構成 (node_modules配下を除いています)</li>
</ul>
<pre><code class="bash">.
├── README.md
├── babel.config.js
├── firebase.json
├── functions
│ ├── node_modules
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ └── tsconfig.json
├── node_modules
├── package.json
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── App.vue
│ ├── assets
│ ├── components
│ ├── main.ts
│ ├── router
│ ├── shims-tsx.d.ts
│ ├── shims-vue.d.ts
│ └── views
├── tsconfig.json
└── yarn.lock
</code></pre>
<p>FrontとCloud Functionsを開発する場合、プロジェクト直下と./funcions直下とで開発環境が分かれます.</p>
<p>それぞれにDockerfileを配置した上で、プロジェクト直下にdocker-compose.ymlを配置します.</p>
<ul>
<li>Dockerファイルを追加したフォルダ構成 (node_modules配下を除いています)</li>
</ul>
<pre><code class="bash">.
├── Dockerfile <-
├── README.md
├── babel.config.js
├── docker-compose.yml <-
├── firebase.json
├── functions
│ ├── Dockerfile <-
│ ├── node_modules
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ │ ├── index.ts
│ │ └── services
│ │ └── project-name -> ../../../src/services/project-name <- シンボリックリンク
│ └── tsconfig.json
├── node_modules
├── package.json
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── App.vue
│ ├── assets
│ ├── components
│ ├── main.ts
│ ├── router
│ ├── services
│ │ └── project-name <- シンボリックリンク先
│ │ └── constants.ts
│ ├── shims-tsx.d.ts
│ ├── shims-vue.d.ts
│ └── views
├── tsconfig.json
└── yarn.lock
</code></pre>
<h2 id="Docker化"><a href="#Docker%E5%8C%96">Docker化</a></h2>
<p>Docker化にむけて、下記の要件があります.</p>
<ul>
<li>プロジェクト直下のfirebase関連ファイル(firebase.json, .firebaserc)を、./functions側でも参照したい</li>
<li>./functions側からプロジェクト直下の定数やtypeをシンボリックリンクで参照する場合がある</li>
</ul>
<p>上記を念頭に、<code>Dockerfile/docker-compose.yml</code>を作成します.</p>
<h3 id="プロジェクト直下のDockerfile"><a href="#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E7%9B%B4%E4%B8%8B%E3%81%AEDockerfile">プロジェクト直下のDockerfile</a></h3>
<ul>
<li>こちらは特に考えることはありません</li>
</ul>
<pre><code class="Docker">FROM node:12-alpine
ENV WORKDIR /work
WORKDIR $WORKDIR
COPY package.json $WORKDIR
RUN yarn
COPY tsconfig.json $WORKDIR
COPY *.config.js $WORKDIR/
COPY public $WORKDIR/
COPY src $WORKDIR/src
EXPOSE 8080
CMD yarn serve
</code></pre>
<h3 id="./functionsのDockerfile"><a href="#.%2Ffunctions%E3%81%AEDockerfile">./functionsのDockerfile</a></h3>
<p>./functions/Dockerfileと、./docker-comose.ymlを比較しながらご確認ください.</p>
<ul>
<li>WORKDIRを<code>/work/functions</code>とする</li>
<li>./functions直下のファイルCOPYは、コピー元をプロジェクト直下からの相対パスで指定する</li>
<li>プロジェクト直下のファイルCOPYは、コンテナの<code>/work</code>配下に設置する</li>
</ul>
<pre><code class="Docker">FROM node:8-alpine
ENV WORKDIR /work/functions
WORKDIR $WORKDIR
COPY ./functions/package.json $WORKDIR
RUN yarn
# firebase
RUN yarn global add firebase-tools
COPY ./functions/tsconfig.json $WORKDIR
COPY ./functions/lib $WORKDIR/lib
COPY ./functions/src $WORKDIR/src
# # for symbolic link (./functions/src/services/project-name)
# COPY ./src/services/project-name /work/src/services/project-name
# firebase
COPY firebase.json /work
COPY .firebaserc /work
# COPY ./functions/.runtimeconfig.json $WORKDIR # if needed
# COPY ./functions/credentials $WORKDIR/credentials # if needed
# settings for runtime emulator
ENV HOST 0.0.0.0
EXPOSE 5000
EXPOSE 9005
</code></pre>
<h3 id="プロジェクト直下のdocker-compose.yml"><a href="#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E7%9B%B4%E4%B8%8B%E3%81%AEdocker-compose.yml">プロジェクト直下のdocker-compose.yml</a></h3>
<ul>
<li>上記Cloud FunctionsのDockerfileにあわせるため<code>build:</code>のcontext, dockerfileを別に指定する</li>
<li>symbolic linkされている(プロジェクト直下にある)実体ファイルの変更もfunctions側のdockerに反映させるため、<code>./src:/work/src</code>を追加</li>
</ul>
<pre><code class="Docker">version: '3'
services:
main:
build: .
container_name: front
volumes:
- ./public:/work/public
- ./src:/work/src
ports:
- 8080:8080
tty: true
command: yarn serve
functions:
build:
context: ./
dockerfile: ./functions/Dockerfile
container_name: functions
volumes:
- ./functions/lib:/work/functions/lib
- ./functions/src:/work/functions/src
- ./src:/work/src # for symbolic link
# environment:
# - GOOGLE_APPLICATION_CREDENTIALS=./credentials/firebase-adminsdk.json
ports:
- 5000:5000
- 9005:9005
tty: true
</code></pre>
<h2 id="開発の場合"><a href="#%E9%96%8B%E7%99%BA%E3%81%AE%E5%A0%B4%E5%90%88">開発の場合</a></h2>
<p>開発環境立ち上げます</p>
<pre><code class="bash">$ docker-compose build && docker-compose up
</code></pre>
<p>その後の開発は下記のようにすすめます</p>
<h3 id="front"><a href="#front">front</a></h3>
<p><code>http://localhost:8080</code>にVue.jsプロジェクトがホットリロードされます</p>
<h3 id="Cloud Functions"><a href="#Cloud+Functions">Cloud Functions</a></h3>
<p>こちらは多少面倒ではあります</p>
<ol>
<li>dockerコンテナに入る</li>
<li>firebase loginしていなければfirebase loginを実施</li>
<li>firebase serveやfirebase functions:shellなどでdebugging</li>
</ol>
<p>以下 <code>docker exec functions -it sh</code> してコンテナ内で</p>
<pre><code>$ firebase login # if you are not logged in.
$ firebase serve
$ firebase functions:shell
</code></pre>
<p>Cloud Functionsのデバッグについてはまだペインが多いです..</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://firebase.google.com/docs/functions/local-shell?hl=ja">関数をインタラクティブにテストする(Firebase official)</a></li>
</ul>
<p>firebase loginの認証情報を永続化(都度<code>fireabase login</code>したくない)人は下記のサイトが参考になるかもしれません(試していません..)</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/pannpers/items/244a7e3c18d8c8422e4f">[Firebase] Cloud Functionsで消耗したくない人のために、開発環境のベストプラクティスをまとめていったらDockerに行き着いた話</a></li>
</ul>
<h2 id="deploy"><a href="#deploy">deploy</a></h2>
<ul>
<li>github actions/ circleCIなど利用したほうがよいでしょう.</li>
</ul>
<h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2>
<p>少し強引な形となってしまいましたが、Dockerの恩恵をうけることができる状態までできました.<br />
ただし、<code>./functions/Dockerfile</code>のフォルダのコンテキストが親階層直下にある点に気持ち悪さがあります.</p>
<p>ここの気持ちわるさの解消は今後の課題とします.</p>
dorakueyon
tag:crieit.net,2005:PublicArticle/15557
2019-11-21T23:48:51+09:00
2019-11-21T23:48:51+09:00
https://crieit.net/posts/MQTT
MQTTを使ってみよう
<h1 id="MQTT(MQ Telemetry Transport)とは?"><a href="#MQTT%28MQ+Telemetry+Transport%29%E3%81%A8%E3%81%AF%EF%BC%9F">MQTT(MQ Telemetry Transport)とは?</a></h1>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://ja.wikipedia.org/wiki/MQ_Telemetry_Transport">wikipedia</a></li>
</ul>
<p>通信プロトコルの一種でPub/Sub型のデータ配信モデル。<br />
軽量プロトコルのため、主にIoTの分野で使われていることが多いです。</p>
<h2 id="Pub/Sub型"><a href="#Pub%2FSub%E5%9E%8B">Pub/Sub型</a></h2>
<p>Pub/Sub型に関わるのは次の3者。</p>
<ul>
<li>Publisher メッセージを出す人</li>
<li>Subscriber メッセージを読む人</li>
<li>Broker 配送業者(中継サーバ)</li>
</ul>
<p>履歴の残らないLINE、という感じでしょうか。</p>
<h1 id="中継サーバを立ててみよう"><a href="#%E4%B8%AD%E7%B6%99%E3%82%B5%E3%83%BC%E3%83%90%E3%82%92%E7%AB%8B%E3%81%A6%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86">中継サーバを立ててみよう</a></h1>
<p><a target="_blank" rel="nofollow noopener" href="https://hub.docker.com/_/eclipse-mosquitto">eclipse-mosquitto</a>というMQTTサーバのdockerイメージが配布されています。</p>
<p>今回はホストの1883番ポートにmosquittoサーバを公開します。<br />
さらにリバースプロキシの後ろに配置するため、nginxと同じnetwork(ここでは<strong>default</strong>)に接続します。</p>
<p><strong>docker-compose.yml(抜粋)</strong></p>
<pre><code class="yml"> mosquitto:
image: eclipse-mosquitto
hostname: mosquitto
container_name: mosquitto
ports:
- "1883:1883"
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf
networks:
- default
</code></pre>
<p><strong>moquitto.conf(一部)</strong></p>
<pre><code class="conf"># ========================================================
# Default listener
# ========================================================
# Port to use for the default listener.
port 1883
# Choose the protocol to use when listening.
protocol websockets
# listener port-number [ip address/host name]
listener 9001
</code></pre>
<p><strong>nginx.conf(listen 443)</strong></p>
<pre><code> location /mqtt {
proxy_pass http://mosquitto:1883/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
</code></pre>
<h1 id="クライアント(react)側実装"><a href="#%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%28react%29%E5%81%B4%E5%AE%9F%E8%A3%85">クライアント(react)側実装</a></h1>
<pre><code class="javascript">import PahoMQTT from "paho-mqtt";
const uuidv4 = require('uuid/v4');
//wssを利用する
const client = new PahoMQTT.Client(
'******',443,uuidv4()
);
export const connect=()=>{
client.connect({
userName: "******",
password: "********",
useSSL: true,
onSuccess,
onFailure
});
client.onMessageArrived = onMessageArrived;
client.onConnectionLost = onConnectionLost;
}
const onSuccess=()=>{
client.subscribe(TOPIC);
}
const onFailure=()=>{
console.log('connect failed.')
}
export const onMessageArrived=(message)=>{
console.log(message.payloadString);
}
export const send=(message)=>{
client.send(TOPIC, message, 0, false);
}
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
connect();
}
}
</code></pre>
<h1 id="アドベントカレンダー"><a href="#%E3%82%A2%E3%83%89%E3%83%99%E3%83%B3%E3%83%88%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC">アドベントカレンダー</a></h1>
<ul>
<li><a href="https://crieit.net/advent-calendars/2019/crieit">crieitアドベントカレンダー「なんでも」</a></li>
</ul>
<p>2日目に登板予定です。<br />
MQTTを基礎技術に使ったアプリを作る予定です。</p>
ckoshien
tag:crieit.net,2005:PublicArticle/15402
2019-09-17T08:33:54+09:00
2019-09-17T08:43:38+09:00
https://crieit.net/posts/Docker-Laravel
DockerでLaravelのローカル開発環境構築を行う
<p>Laravelの環境構築を行う場合はDockerを利用するのが個人的には一番早くて軽くて良いと思っています。普段はDocker Hubにアップしてある自分で作ったオレオレDockerイメージを利用しているのですが、久しぶりに丁度よいLaravel用のDockerイメージが無いのかなと見直してみて、ちょうど良さそうなものがあったのでそちらを使って環境構築を試してみました。(最近作ったばかりなので十分な確認はできていません)</p>
<h2 id="今回使うDockerイメージ"><a href="#%E4%BB%8A%E5%9B%9E%E4%BD%BF%E3%81%86Docker%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8">今回使うDockerイメージ</a></h2>
<p>今回使うDockerイメージは下記です。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://hub.docker.com/r/lorisleiva/laravel-docker/">https://hub.docker.com/r/lorisleiva/laravel-docker/</a></p>
<p>READMEに詳しい使い方が載っていないのですが、pull数も多いし(CIで主に使っているのかもしれません)GitHubでの評価も他のイメージに比べて高いので、良さそうかなと思いました。XDebugもYarnも入っているようですので、このイメージ一つで一通りのことはできそうな気がします。</p>
<h2 id="構築する環境"><a href="#%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B%E7%92%B0%E5%A2%83">構築する環境</a></h2>
<p>下記の環境で構築します。</p>
<ul>
<li>PHP 7.3</li>
<li>Laravel 6.0</li>
<li>MySQL 5.7</li>
<li>phpMyAdmin</li>
<li>Yarn</li>
</ul>
<h2 id="docker-compose.ymlをつくる"><a href="#docker-compose.yml%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8B">docker-compose.ymlをつくる</a></h2>
<p>実際の開発時にはdocker-composeを利用するため、まずはdocker-compose.ymlを書きます。これはプロジェクト初期化ようですので、あとでまた調整します。</p>
<pre><code class="yml">version: '2'
volumes:
db_data:
driver: local
services:
mysql:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
MYSQL_DATABASE: laravel
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=mysql
- PMA_USER=root
- PMA_PASSWORD=
ports:
- 8001:80
app:
image: lorisleiva/laravel-docker:7.3
volumes:
- .:/var/www
ports:
- 8000:8000
tty: true
stdin_open: true
# command: php artisan serve --host=0.0.0.0
</code></pre>
<h3 id="MySQL"><a href="#MySQL">MySQL</a></h3>
<p>MySQLはパスワード無しをOKとします。ローカル環境ですのでパスワードなしのrootログインで問題ありません。データベースとしてlaravelを自動的に作成します。現在はLaravelのプロジェクトを作成すると、.envにはlaravelというデータベースを使用するように初期化されるようです。</p>
<h3 id="phpMyAdmin"><a href="#phpMyAdmin">phpMyAdmin</a></h3>
<p>ソフトを使ってMySQLに接続することも可能ですが、phpMyAdminのDockerイメージも存在するためそれを使います。これで<code>http://localhost:8001</code>でphpMyAdminを使うことが出来てとても楽です。</p>
<h2 id="アプリケーションを作成する"><a href="#%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B">アプリケーションを作成する</a></h2>
<p>とりあえず先程のdocker-compose.ymlを配置し、そこにシェルで移動します。そして各イメージを起動します。</p>
<pre><code class="sh">docker-compose up -d
</code></pre>
<p><code>docker ps</code>で正常に起動できているかを確認することも出来ます。</p>
<p>次にdocker-compose.ymlで定義しているappというLaravelが動作するコンテナに入ります。</p>
<pre><code class="sh">docker-compose exec app bash
</code></pre>
<p><code>php -v</code>とするとPHP7.3のバージョンが表示されると思います。ここにLaravelの公式マニュアルに従ってLaravelアプリケーションの初期化を行います。</p>
<pre><code class="sh">composer create-project --prefer-dist laravel/laravel blog
</code></pre>
<p>blogフォルダにアプリケーションが作成されますので、そのフォルダに移動してアプリケーションを起動してみます。</p>
<pre><code class="sh">cd blog
php artisan serve --host=0.0.0.0
</code></pre>
<p>下記のようなメッセージが表示されれば問題ありません。</p>
<pre><code>Laravel development server started: <http://0.0.0.0:8000>
PHP 7.3.8 Development Server started at Wed Sep 11 23:57:18 2019
</code></pre>
<p>問題なければ<code>http://localhost:8000</code>にアクセスすると下記のような画面が表示されます。</p>
<p><a href="https://crieit.now.sh/upload_images/6e2af66c610d88bc766649f72032893a5d798a64cedbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6e2af66c610d88bc766649f72032893a5d798a64cedbe.png?mw=700" alt="" /></a></p>
<h3 id="普段利用する用に調整"><a href="#%E6%99%AE%E6%AE%B5%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E7%94%A8%E3%81%AB%E8%AA%BF%E6%95%B4">普段利用する用に調整</a></h3>
<p>とりあえず環境構築は出来ましたが、普段の利用にはちょっと使いづらいので調整します。まずは一旦コンテナを終了させます。Ctrl+Dのショートカットかexitコマンドでコンテナのシェルを抜けます。そして下記を実行して終了させます。</p>
<pre><code class="sh">docker-compose down
</code></pre>
<p>そしてdocker-compose.ymlを先程作成されたblogフォルダに入れてしまいましょう。配置が気持ち悪ければその後blogフォルダの名前を変えたり位置を変えたりしてください。次にdocker-compose.ymlのappのセクションに下記の行を追加します。</p>
<pre><code class="yml"> command: php artisan serve --host=0.0.0.0
</code></pre>
<p>これでdocker-composeでupした際に自動的にサーバーも起動し、わざわざコマンドで起動しなくてもブラウザでLaravelアプリケーションにアクセスできるようになります。</p>
<p>これで普段は開発を始める時にup、終了する時にdownを行うだけでOKとなります。</p>
<h2 id="その他細かい部分も確認"><a href="#%E3%81%9D%E3%81%AE%E4%BB%96%E7%B4%B0%E3%81%8B%E3%81%84%E9%83%A8%E5%88%86%E3%82%82%E7%A2%BA%E8%AA%8D">その他細かい部分も確認</a></h2>
<p>とりあえず動いたので他の細かい部分も確認していきます。すべて<code>docker-compose exec app bash</code>でコンテナ内に入って実行します。</p>
<h3 id="MySQLとの連携"><a href="#MySQL%E3%81%A8%E3%81%AE%E9%80%A3%E6%90%BA">MySQLとの連携</a></h3>
<p>MySQLと正常に連携できているか確認してみます。今回の方法で作成したLaravelアプリケーションには元々ユーザー関連のテーブルを初期化するためのマイグレーションファイルが入っていますので、それを実行してみます。</p>
<p>まずは<code>.env</code>のホスト名だけ変更しておきます。</p>
<pre><code class="env">DB_HOST=mysql
</code></pre>
<p>そして実行します。</p>
<pre><code class="sh">php artisan migrate
</code></pre>
<p>問題なければ下記のように実行ログが表示されます。</p>
<pre><code>Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.07 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.05 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.03 seconds)
</code></pre>
<h3 id="ルーティングの確認"><a href="#%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%AE%E7%A2%BA%E8%AA%8D">ルーティングの確認</a></h3>
<p>正常にルーティングが行われているか確認します。まずは適当なコントローラを作成します。</p>
<pre><code class="sh">php artisan make:controller PostController
</code></pre>
<p>これで<code>app/Http/Controller/PostController.php</code>が生成されますので、下記のメソッドを追加しておきます。アクセスするとJSONのレスポンスを返すだけのアクションです。</p>
<pre><code class="php"> public function index()
{
return response()->json(['hello' => 'world']);
}
</code></pre>
<p>これにアクセスできるように、ルーティングを追加します。<code>routes/web.php</code>に下記を追記します。</p>
<pre><code class="php">Route::resource('posts', 'PostController');
</code></pre>
<p>これで<code>http://localhost:8000/posts</code>にアクセスすれば下記のようなページが表示されます。</p>
<pre><code>{"hello":"world"}
</code></pre>
<h3 id="Vue.jsの確認"><a href="#Vue.js%E3%81%AE%E7%A2%BA%E8%AA%8D">Vue.jsの確認</a></h3>
<p>Laravel6からデフォルトではVue.jsが入らなくなったようです。ただし<code>ui</code>コマンドですぐ初期化できるようです。詳しくは下記の記事に書いています。</p>
<p><a href="https://crieit.net/posts/Laravel-6-Vue-js-React">Laravel 6 でVue.jsやReactを使う</a></p>
<p>hotコマンドを使ってブラウザで確認する際に8080ポートでjsやcssファイルが読み込まれますが、このイメージだとそのままはアクセスできないため、hotコマンドに<code>--host=0.0.0.0</code>というホスト名の指定を追加しておきましょう。</p>
<pre><code class="json">"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --host=0.0.0.0 --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
</code></pre>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>自分で作ったオレオレイメージをbuildせずともなんとなくいい感じにできた気がします。今回使ったイメージがメンテナンスされると嬉しいですね。Dockerが使える方は是非試してみてください。</p>
だら@Crieit開発者
tag:crieit.net,2005:PublicArticle/15347
2019-08-24T18:40:20+09:00
2019-08-24T20:15:23+09:00
https://crieit.net/posts/google-home-voicetext-dockerfile
google-home-voicetextのdockerfileを改良する
<h1 id="google-home-voicetextって?"><a href="#google-home-voicetext%E3%81%A3%E3%81%A6%EF%BC%9F">google-home-voicetextって?</a></h1>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/sikkimtemi/google-home-voicetext">google-home-voicetext</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sikkim/items/f03df7e2db13ea7f5a2b">Google Homeを手軽に喋らせる仕組み(google-home-voicetext)を作った</a></li>
</ul>
<p>google homeを自発的に話すようにできる<code>google-home-notifier</code>の改良版。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/sikkimtemi/google-home-voicetext-docker">google-home-voicetext-docker</a></li>
</ul>
<p>作者の方がdockerfileも用意してくださっているのですが、<br />
docker-composeで立ち上げた後、コンテナにログインして環境構築をする必要があり、しょっちゅうコンテナを作り直す私にとっては使い辛かったので<strong>何とか作業を簡略/最適化できないかと思ったのが今回の趣旨</strong>です。</p>
<h1 id="自発的にしゃべらせる"><a href="#%E8%87%AA%E7%99%BA%E7%9A%84%E3%81%AB%E3%81%97%E3%82%83%E3%81%B9%E3%82%89%E3%81%9B%E3%82%8B">自発的にしゃべらせる</a></h1>
<h2 id="alexa vs google home"><a href="#alexa+vs+google+home">alexa vs google home</a></h2>
<p>alexaはリマインダーAPIにプログラムを組んで登録するのが楽なのですが、</p>
<ul>
<li>alexaに話しかける</li>
<li>画面からOAuth認証を行う</li>
</ul>
<p>などのユーザーアクションを起こさないと、APIアクセスに必要なトークンが払い出されないことがわかり、今回は実装を断念。</p>
<p>その点、google homeはchromecastに用いられているライブラリを使って音声のキャストなどを行うことができるため、比較的実装が容易ということがわかりました。</p>
<p>ただ、機能によってはalexaの方が優れている面もあり、一長一短というところです。</p>
<h1 id="dockerfileの修正"><a href="#dockerfile%E3%81%AE%E4%BF%AE%E6%AD%A3">dockerfileの修正</a></h1>
<pre><code class="dockerfile">FROM node:10.16
RUN npm update -y -g npm
RUN apt-get update
RUN apt-get install -y vim avahi-daemon libavahi-compat-libdnssd-dev locales
RUN locale-gen ja_JP.UTF-8
RUN echo "export LANG=ja_JP.UTF-8" >> ~/.bashrc
#RUN mkdir /myapps
#RUN cd myapps
#WORKDIR /myapps
RUN git clone https://github.com/sikkimtemi/google-home-voicetext.git
#RUN cd google-home-voicetext/
WORKDIR google-home-voicetext
RUN npm install
#RUN npm install forever -g
RUN patch -uR node_modules/mdns/lib/browser.js < mdns_patch/browser.js.patch
#RUN service dbus start
#RUN service avahi-daemon start
#VOLUME [ "/myapps" ]
#CMD node file-server.js & node api-server.js
</code></pre>
<p>あえてコメントアウトしたところも残していますが、<a target="_blank" rel="nofollow noopener" href="https://github.com/sikkimtemi/google-home-voicetext-docker/blob/master/README.md">README</a>と比べながら照合していただけるとよいと思います。</p>
<ul>
<li>コンテナの中でgit cloneします。</li>
<li>cloneしたフォルダに移動してnpmインストール</li>
<li>npm インストール後にcloneしたソースに含まれるパッチをあてます。</li>
<li>環境変数の設定はcompose側で行います。</li>
<li>mdns関連のサービスの起動もcompose側のコマンドで設定します。</li>
</ul>
<h1 id="docker-compose.ymlの記述"><a href="#docker-compose.yml%E3%81%AE%E8%A8%98%E8%BF%B0">docker-compose.ymlの記述</a></h1>
<pre><code class="yml">node-google-home:
build: './speaker'
#container_name: 'node'
command: >
sh -c "service dbus start &&
service avahi-daemon start &&
node file-server.js &
node api-server.js "
working_dir: '/google-home-voicetext'
volumes:
- ./myapps:/myapps
ports:
- '8080:8080'
- '8888:8888'
environment:
- TZ=Japan
- VOICETEXT_API_KEY=*****
- WIRELESS_IP=192.168.***.***
- GOOGLE_HOME_IP=192.168.***.***
- WIRELESS_MODULE_NAME=en0
- VOICETEXT_SPEAKER=HARUKA
tty: true
restart: always
</code></pre>
<p>compose側では、mdns関連のサービスの起動とサーバプロセスの起動を行っています。<br />
foreverをインストールして、プロセスの維持をしようと思ったのですが、何回かmdnsサービスが立ち上がらない時があり、その場合はプロセスの再起動というよりはコンテナを破棄して再度コンテナを立上げるのが良いと判断しました。</p>
<h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2>
<p>今回の改良ではdockerfileへの理解が十分でないというのもあり、<br />
(使っていないのですが)ボリュームのマウントがうまくいっていないという問題点も...。</p>
ckoshien