tag:crieit.net,2005:https://crieit.net/tags/Apache/feed 「Apache」の記事 - Crieit Crieitでタグ「Apache」に投稿された最近の記事 2022-04-25T23:31:20+09:00 https://crieit.net/tags/Apache/feed tag:crieit.net,2005:PublicArticle/18174 2022-04-25T23:31:20+09:00 2022-04-25T23:31:20+09:00 https://crieit.net/posts/apache-log-backslash-x-percent-encode-20220428 \xe3\x83\xbc ... のような \x 始まりのエンコードがされた文字列について <p>時折 Apache のログで見かける \xe3\x83\xbc ... のような \x 始まりのエンコードがされた文字列の正体がようやく分かったのでメモ。</p> <h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2> <p>事の発端は、 Apache のログを眺めていると時折</p> <blockquote> <p>\xe3\x83\x87\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\x99\xe3\x83\xbc\xe3\x82\xb9\xe3\x82\xa8\xe3\x83\xa9\xe3\x83\xbc</p> </blockquote> <p>のような何某かのエンコードがされた文字列を見かけることがあったのですが</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://do-gugan.com/~furuta/archives/2021/02/wpap.html">WordPressが原因不明に遅いのが解消(WPアソシエイトポストR2のキャッシュテーブル不具合?) | 道具眼日誌:古田-私的記録</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.mt-megami.com/article/460600017">読めないエラー:\xe3\x83\x87\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\x99\xe3\x83\xbc\xe3\x82\xb9\xe3\x82\xa8\xe3\x83\xa9\xe3\x83\xbc ? 女神山の麓より</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://isalu.org/mr-database-error/">【PHP エラーログ】\xe3\x83\x87\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\x99\xe3\x83\xbc\xe3\x82\xb9\xe3\x82\xa8\xe3\x83\xa9\xe3\x83\xbc | ISALU Blog</a></li> </ul> <p>長らくその正体が杳として知れない状態が続いていました。</p> <h2 id="調査"><a href="#%E8%AA%BF%E6%9F%BB">調査</a></h2> <p>ところが、別件で検索していたら、偶然正体が分かったのでメモ。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://ozuma.hatenablog.jp/entry/20130714/1373811634">Apache 2.2.25とRewriteLogのエスケープと日本語 (CVE-2013-1862) - ろば電子が詰まつてゐる</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://rikuga.me/2014/04/15/apache%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%AD%E3%82%B0%E3%81%AE%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E3%81%8C%E9%81%A9%E5%BD%93%E3%81%AA%E6%B0%97/">インフラ関係のメモ書き | Apacheのアクセスログの日本語エスケープが適当な気がする</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://alaki.co.jp/blog/?p=2394">日本語URLを含むリダイレクトの罠にかかっても無事でいられる2つの対策</a></li> </ul> <p>これは Apache 2.2.25 で修正されたログ出力の脆弱性対策とのこと。</p> <p>具体的には、</p> <ul> <li>Apache のログを CLI やシェルスクリプトで処理する際に、制御文字を含ませることで意図しない動作を引き起こすことを防ぐためにあえてエスケープするようになった <ul> <li>特にこうした作業をするのは管理者権限のケースが多いと想定されるため</li> </ul></li> <li>これにより、日本語などの文字列のパーセントエンコーディングの際に <code>%</code> を <code>\x</code> に変換している</li> </ul> <p>ということ。</p> <p>てっきり UTF-8 や UTF-16 の特殊形のようなものかと思ったのですが、実際はパーセントエンコーディングの変形に過ぎなかった、と。</p> <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%E3%82%B1%E3%83%BC%E3%82%B9">サンプルケース</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://do-gugan.com/~furuta/archives/2021/02/wpap.html">WordPressが原因不明に遅いのが解消(WPアソシエイトポストR2のキャッシュテーブル不具合?) | 道具眼日誌:古田-私的記録</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.mt-megami.com/article/460600017">読めないエラー:\xe3\x83\x87\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\x99\xe3\x83\xbc\xe3\x82\xb9\xe3\x82\xa8\xe3\x83\xa9\xe3\x83\xbc ? 女神山の麓より</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://isalu.org/mr-database-error/">【PHP エラーログ】\xe3\x83\x87\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\x99\xe3\x83\xbc\xe3\x82\xb9\xe3\x82\xa8\xe3\x83\xa9\xe3\x83\xbc | ISALU Blog</a></li> </ul> <h3 id="正体"><a href="#%E6%AD%A3%E4%BD%93">正体</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://ozuma.hatenablog.jp/entry/20130714/1373811634">Apache 2.2.25とRewriteLogのエスケープと日本語 (CVE-2013-1862) - ろば電子が詰まつてゐる</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://rikuga.me/2014/04/15/apache%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%AD%E3%82%B0%E3%81%AE%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E3%81%8C%E9%81%A9%E5%BD%93%E3%81%AA%E6%B0%97/">インフラ関係のメモ書き | Apacheのアクセスログの日本語エスケープが適当な気がする</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://alaki.co.jp/blog/?p=2394">日本語URLを含むリダイレクトの罠にかかっても無事でいられる2つの対策</a></li> </ul> <h3 id="変換フォーム"><a href="#%E5%A4%89%E6%8F%9B%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0">変換フォーム</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://maku77.github.io/js/web/encode-uri.html">URL エンコード/デコードを行う (encodeURI, encodeURIComponent) | まくまくJavaScriptノート</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/DecoratedKnight/items/103ab57431b6c448e535">特定の文字列を全て置換する[Javascript] - Qiita</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/18124 2022-02-24T23:29:56+09:00 2022-02-24T23:44:23+09:00 https://crieit.net/posts/Gitlab-push-buffalo 【障害切り分けのコツはまずは森を見ること!】Gitlabのpushエラー、原因は(恐らく?)buffalo製ルータだった話 <p>お久しぶりですにゃ。<br /> やらなきゃいけない事があるからと、”<strong>優先度の低いものをする時間をマストタスクに割り当てよう</strong>”と考えながら<br /> 、<strong>結局マスト作業も先延ばしになり帳尻合わせが大変になる</strong>時空を生きて21年目の私です😢</p> <p>実はこの間に、所属している会社のブログも1ページながら担当させていただきましたねこ!業務内容とおすすめ焼酎4選という内容なので、<br /> 良かったら探してみて欲しいぎょぴ!!<br /> (さすがにネコ語は自重しましたぎょぴぼー)<br /> 貴重な経験をさせてくださった弊社の担当者様、ありがとうございますにゃー!</p> <p>久しぶりの投稿ということで前置きが長くなってしまいましたが、<br /> <strong>今回は自宅で特定の通信がハングアップしてしまったときのこと</strong>を綴りますぴょん。<br /> ※解決法とういうよりは、ハチャメチャに慌ててる私をご覧いただく記事となります。</p> <hr /> <h4 id="v目次にゃv"><a href="#v%E7%9B%AE%E6%AC%A1%E3%81%AB%E3%82%83v">v目次にゃv</a></h4> <p>1.今回起こった問題<br /> 2.一旦バックグラウンド<br /> 3.対処1<br /> 4.対処2<br /> 5. 切り分け<br /> 6. 今回の件から私が得るべき教訓は…<br /> 7. エンドタイトル</p> <hr /> <h4 id="今回起こった問題"><a href="#%E4%BB%8A%E5%9B%9E%E8%B5%B7%E3%81%93%E3%81%A3%E3%81%9F%E5%95%8F%E9%A1%8C">今回起こった問題</a></h4> <p>自宅クライアントPCからドメインでGitlabへ200MB付近の容量ファイルをgit pushすると</p> <blockquote> <p>error: RPC failed; curl 56 Recv failure: Connection was reset<br /> fatal: The remote end hung up unexpectedly</p> </blockquote> <p>とのエラーが出てpushできない。※今回は19MBのサイズでエラー出ました<br /> どうやら<strong>サイズ制限にかかり、正常にpushできていない</strong>みたい。<br /> ※ファイルサイズが小さいものは問題なくpushできます。</p> <p>〇 5KB<br /> ✖ 19MB</p> <hr /> <h4 id="一旦バックグラウンド"><a href="#%E4%B8%80%E6%97%A6%E3%83%90%E3%83%83%E3%82%AF%E3%82%B0%E3%83%A9%E3%82%A6%E3%83%B3%E3%83%89">一旦バックグラウンド</a></h4> <p>唐突ですが、当時の自宅の簡単な構成を…<br /> <a href="https://crieit.now.sh/upload_images/c8e3813e38831a16492d64162853d8f062177aebea260.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c8e3813e38831a16492d64162853d8f062177aebea260.png?mw=700" alt="image.png" /></a></p> <p>Windowsサーバより外の構成は私関与していなかったので、聞き伝えでの図ですが…<br /> 今回、外部からWebサーバにアクセスできるように<strong>buffaloルータでポート開放</strong>されていますうさぎ~。</p> <p>また、CentOS内部では、80番ポートはプロジェクト管理ソフトWebGUIへ(Apache)<br /> GitLabはパッケージ内包のNginxで動いています。<br /> <strong>hoge/projects</strong>と<strong>hoge/gitlab</strong>で<strong>サブディレクトリ</strong>にして、<strong>Apaceでリバースプロキシ設定で運用</strong>していますきんぎょ~。<br /> 今回アクセスする経路はドメイン指定するので<strong>1度インターネット抜けしてからLAN内にあるサーバに戻ってくる</strong>形です。(混乱する要因の1つ)<br /> この辺の詳細は省きます。わけわかランボルギーニ~(^^♪<ふんっ!ふんっ!</p> <hr /> <h4 id="対処1"><a href="#%E5%AF%BE%E5%87%A6%EF%BC%91">対処1</a></h4> <p>原因を調べたところ、GItLab側(Nginx)で<strong>一定値を超えるものは制限</strong>をかけているらしい。(そもそも大容量通信を想定していない)<br /> 早速、ネットに記載されていた対処法を試すねこ!</p> <p>まずは<strong>クライアント側でバッファを増やす設定</strong>をするにゃ</p> <pre><code>git config --global http.postBuffer 524288000 </code></pre> <p>次に<strong>サーバ側のGitlabのサイズ制限を変更す</strong>るために、Nginxのconfigに追記するぎょぴぼー。</p> <pre><code>client_max_body_size 200M </code></pre> <p>その後、各ソフトとサーバーを<strong>再起動</strong>っぽ!<br /> 。<br /> 。<br /> 。<br /> 同じエラーが返ってくる…</p> <hr /> <h4 id="対処2"><a href="#%E5%AF%BE%E5%87%A6%EF%BC%92">対処2</a></h4> <p>根気強くネットで解決策をさがすと、”<strong>プロキシを挟まずに直でGitlabにつないだらいけた</strong>!!”との記事を発見!<br /> バックグラウンドを見ていただくと分かると思いますが、自宅構成では<br /> <strong>クライアントからGitlabに行く際に、リバースプロキシを介しています</strong>。<br /> しかし、リバースプロキシを使わないと、Gitlabかプロジェクト管理GUIのどちらか一方しかアクセス出来なくなりますぴょん…<br /> もちろん、URLでポート指定すればよいのですが、ユーザ側の負担が増えるため却下ですにゃ…<br /> というか、そもそも<strong>Apacheにデフォルトでサイズ制限はない</strong>らしい!!(もしかしたらという事もあるので一応設定をいろいろ試しました)</p> <hr /> <h4 id="切り分け"><a href="#%E5%88%87%E3%82%8A%E5%88%86%E3%81%91">切り分け</a></h4> <p>ここまで、サーバ側、もしくはクライアントの設定を疑い試行錯誤してきましたが、一向に解決しないため、<br /> サーバ内だけでなく全体を見て切り分けを行いましたきんぎょ。<br /> 通常なら切り分けを最初にするべきですが、ネット上に同じ問題に直面している方がおり、<br /> さらに解決策まで載っているという事で<strong>先入観を持ってしまったのが私の敗因</strong>ですねこ…</p> <p>まずはリバースプロキシが原因かどうかを確認するため、<br /> 新しくテスト仮想サーバをつくり、Gitlabだけ構築します。<br /> Gitlabは設定を変更せず、リポジトリだけ作成し、大容量push時にエラーを返す状態を再現します。<br /> ドメインを紐づけるのはめんどくさかったので、プライベートIPで開くようにしました。</p> <p>↓リポジトリパス↓</p> <blockquote> <p>http:\192.168.100.101/gitlab/piyopiyo.git</p> </blockquote> <pre><code>###push 結果↓ 〇 5KBのデータ  ←小さいファイルはOKですね 〇 19MBのデータ ←え!?pushできた!!!! </code></pre> <p>ということは、<strong>GitlabやNginxは問題なし</strong>。リバースプロキシが怪しい…<br /> 前段階でリバースプロキシは違うと踏んでただけに驚きました。</p> <p>より本番環境に近い(外部からのアクセス)挙動も確認したいので、一応ドメインとIPを紐づける(もちろん本番環境のIPは重複を避け変更しておく)<br /> クライアント側でリポジトリのパスをドメイン指定に変更<br /> ↓リポジトリパス↓</p> <blockquote> <p>http:\hogehoge.nk/gitlab.piyopiyo.git</p> </blockquote> <pre><code>###push 結果↓ 〇 5KBのデータ  ←小さいファイルはOK ✖ 19MBのデータ  ←あれ、いつものエラーで通らない…💦 </code></pre> <p>小さいファイルは通っているのでDNSの根本的な間違えはなさそう…<br /> 今回はリバースプロキシは設定していないので、リバースプロキシのせいでエラーが出るわけではなさそう<br /> もしや、<strong>wanを抜ける過程で失敗している</strong>??</p> <hr /> <p>テスト仮想サーバを閉じ、本番サーバのIPとドメインを紐づけ直して再度検証</p> <pre><code>###push 結果↓ 〇 5KBのデータ  ←小さいのは通った! ✖ 19MBのデータ  ←通らない </code></pre> <p>この場合、以下の2つ範囲で考えることが出来ますね。<br /> <strong>①プロバイダ側で何かしら制限がある(これだったらお手上げです😢)<br /> ②自分の管轄範囲のNWで問題がある</strong></p> <p><del><strong>想定できる原因</strong></del><br /> <del>・大容量通信は弾いている<br />  →Youtube等の大容量のデータはup,down共に正常に疎通可能。おそらく違う。</del></p> <p><del>・特定プロトコルの大容量データを弾いている<br />  →gitの仕様詳細まで分からず、未検証。(今回はサイズによらずHTTPを使っているはず)</del></p> <p><del>・十分な帯域が確保できず、通信量を絞っている<br />  →サーバ側のタイムアウト時間も延長したがダメ</del></p> <p>Lanでは繋がり、Wanでは繋がらない(小さいデータは繋がるが)という事で、私の手が届く1番Wan側のbuffaloルータを詳しく見てみます。<br /> 設定を覗いた感じ、QoSが設定してあるわけでもなく、問題はなさそう。<br /> <strong>機器固有の設定は不明</strong>なので、我が家にある<strong>FortiGateに置き換えることにした</strong>にゃ!<br /> <a href="https://crieit.now.sh/upload_images/c8e3813e38831a16492d64162853d8f0621774bb13a10.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c8e3813e38831a16492d64162853d8f0621774bb13a10.png?mw=700" alt="image.png" /></a><br /> ついでなので、セグメント別けしました。(NW図の構成が甘くてすみません)</p> <p>FortiGateの設定を行い、接続確認をしました。<br /> ↓リポジトリパス↓</p> <blockquote> <p>http:\hogehoge.nk/gitlab.piyopiyo.git</p> </blockquote> <pre><code>###push 結果↓ 〇 5KBのデータ  ←小さいファイルはOK 〇 19MBのデータ  ←無事に通った! </code></pre> <p><strong>通常利用が想定されるWanを介しての大小データのpushに成功したのにゃ!!</strong></p> <hr /> <h4 id="今回の件から私が得るべき教訓は…"><a href="#%E4%BB%8A%E5%9B%9E%E3%81%AE%E4%BB%B6%E3%81%8B%E3%82%89%E7%A7%81%E3%81%8C%E5%BE%97%E3%82%8B%E3%81%B9%E3%81%8D%E6%95%99%E8%A8%93%E3%81%AF%E2%80%A6">今回の件から私が得るべき教訓は…</a></h4> <p>まずは、今回、問題解決に至るまでのネックポイント<br /> ・ネット記事に、同一サーバにWebサーバを同時導入(リバースプロキシ使用)例が少ない<br /> ・GitHubの方がユーザが多くGitlabはどちらかといえば少数派なため、なぜかGithubの記事に案内される<br /> ・Hyper-vよりDockerを使用している例が多いため、解決法がマッチしない<br /> ・buffaloルータの仕様を理解できていない</p> <p>以上を踏まえ、<strong>今回の件から私が得るべき教訓は、全体を見て切り分けをしっかりしよう!ということだ。</strong></p> <p>↓今回の切り分け例↓<br /> <strong>サーバサイド</strong><br /> ・リバースプロキシがおかしい<br /> ・Gitlabがおかしい<br /> ・Nginxがおかしい<br /> ・ポートやファイアウォールの設定がうまく機能していない<br /> <strong>その他物理</strong><br /> ・クライアントの設定ミス<br /> ・物理機器の故障、謎仕様<br /> <strong>ネットワークサイド</strong><br /> ・Wan側がおかしい<br /> ・Lan側がおかしい<br /> ・NW境界部がうまく機能していない</p> <p>てっきりサーバ側だと思い込んでそちらばかり対応にあたったのがダメでした。<br /> 今回は<strong>ネットワークサイド、NW境界部(buffaloルータの仕様なのかな?)があたり</strong>でしたね…<br /> 結局、最たる原因は仕様が不明のため、buffaloさんには問い合わせて回答をいただく予定です。</p> <h4 id="エンドタイトル"><a href="#%E3%82%A8%E3%83%B3%E3%83%89%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB">エンドタイトル</a></h4> <p>今回は個人的にいろいろな事象が複雑に面倒くさく絡まっていたのが、解決への道を妨げるものでした。<br /> リソースの関係上仕方がないとはいえ、シンプルな設計の重要さを身をもって学びました。み〇ほ銀行のジャングルシステムがいい例ですね。いや、悪い例か…<br /> 複雑なものをどのようにまとめようか思考しながら筆をとった結果、語尾も中途半端になる始末…(しかも非常に読みづらくて申し訳ない)</p> <p>今回はここまで🐾<br /> 自宅にて、焼酎のお湯割りを飲みながら…。</p> <p>次回も頑張るきんぎょー…</p> <h5 id="編集後記"><a href="#%E7%B7%A8%E9%9B%86%E5%BE%8C%E8%A8%98">編集後記</a></h5> <p>私のCrieit記事では、私個人の思ったことや考えを色濃く記事に出しています。qiitaやStack Overflowのような解決を求める記事や、参考となる記事とは違い、実際に困難(?)に直面しているへっぽこ技術者の狭い視野やドキドキを臨場感のある雰囲気を含め楽しんで屍を越えて下されば幸いです。</p> <p>せっかくなので、次回あたりFortiGateの設定などもご紹介できればよいですにゃ~…</p> keito_woood 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 &quot;copy('https://getcomposer.org/installer', 'composer-setup.php');&quot; && php composer-setup.php && php -r &quot;unlink('composer-setup.php');&quot; && 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 &quot;/C=/ST=/L=/O=/OU=/CN=*.lvh.me&quot; ## 略 # 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 &quot;/C=/ST=/L=/O=/OU=/CN=www.example.com&quot; ## 略 # 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/17521 2021-07-18T17:02:26+09:00 2021-07-18T17:02:26+09:00 https://crieit.net/posts/change-output-php-log-by-htaccess-20210718 .htaccess で PHP のエラーログの出力先を変える <p><code>/var/log/</code> に潜らなくとも、あるいは <code>php.ini</code> を編集しなくとも PHP のログを手軽に簡単に確認できる場所に出力できないか試してみました。</p> <pre><code class="htaccess">php_flag log_errors On php_value error_log PATH/TO/LOG/error_log.log </code></pre> <p>結果、上述二文を <code>.htaccess</code> に記述することで PHP のログの出力先を変えることができました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.welcart.com/documents/archives/3706">PHP のエラーログを出力するにはどうしたら良いですか? - Welcart サポート</a></li> </ul> <h3 id="PHPでどうにかしようとした (失敗)"><a href="#PHP%E3%81%A7%E3%81%A9%E3%81%86%E3%81%AB%E3%81%8B%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F+%28%E5%A4%B1%E6%95%97%29">PHPでどうにかしようとした (失敗)</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/notona/items/b821ed0ad04ac3ef8f80">php のエラー発生時に処理をはさみたい - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://ysklog.net/php/4181.html">【PHP】「error_log」の出力先を指定してデータを記録 - ysklog</a></li> </ul> <h4 id="関数リファレンス"><a href="#%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9">関数リファレンス</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/function.set-exception-handler.php">PHP: set_exception_handler - Manual</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/function.set-error-handler.php">PHP: set_error_handler - Manual</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/function.register-shutdown-function.php">PHP: register_shutdown_function - Manual</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/exception.tostring.php">PHP: Exception::__toString - Manual</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/exception.getmessage.php">PHP: Exception::getMessage - Manual</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/class.errorexception.php">PHP: ErrorException - Manual</a></li> </ul> <h3 id="エラーの種類とフラグ"><a href="#%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AE%E7%A8%AE%E9%A1%9E%E3%81%A8%E3%83%95%E3%83%A9%E3%82%B0">エラーの種類とフラグ</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/kyo_mizu/items/a1d185c7a32019b0f98c">PHPのエラーの種類 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/errorfunc.constants.php">PHP: 定義済み定数 - Manual</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/17321 2021-05-31T12:53:01+09:00 2021-05-31T12:54:07+09:00 https://crieit.net/posts/5-Web-60b45d9dcbeca サーバ入門5 Webサーバのインストールと動作確認 <h2 id="Apache HTTP Server"><a href="#Apache+HTTP+Server">Apache HTTP Server</a></h2> <p>世界中で最も多く使われているOSSのWebサーバソフトウェア<br /> ・信頼性が高い、Webで情報を入手しやすいといった特徴がある。<br /> ※Apacheは仕組み上Clok(クライアント1万台問題)を抱えているので、万単位のリクエストを処理するようなWebサーバでは、nginxが使われる。</p> <h2 id="Apacheのインストール"><a href="#Apache%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">Apacheのインストール</a></h2> <p><code>$su - →    #yum -y install httpd(CentOSではhttpdというパッケージを指定)</code></p> <h2 id="Apacheの起動"><a href="#Apache%E3%81%AE%E8%B5%B7%E5%8B%95">Apacheの起動</a></h2> <p>Windowsと異なり、インストールしてもApache HTTP Serverは起動していない。<br /> <code>#systemctl start httpd(インストールしただけでは起動していない)</code><br /> <code>#systemctl status httpd(本当に起動したのか状態を確認する)</code><br /> ※ステータスが<strong>active</strong>になっていれば、httpdは起動している。</p> <h2 id="Apacheを自動起動させる"><a href="#Apache%E3%82%92%E8%87%AA%E5%8B%95%E8%B5%B7%E5%8B%95%E3%81%95%E3%81%9B%E3%82%8B">Apacheを自動起動させる</a></h2> <p>OSを起動(再起動)したときに自動でApache HTTP Serverを起動させたい場合。<br /> <code>#systemctl enable httpd</code><br /> <code>#systemctl is-enabled httpd(自動起動が有効か確認)</code><br /> ※is-enabledの結果が<strong>enabled</strong>になっていれば、httpdは自動起動する。disabledの場合は、自動起動しないことを意味する。</p> <h1 id="cystemctlコマンド"><a href="#cystemctl%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89">cystemctlコマンド</a></h1> <p>Linuxの起動処理や、システム管理をコントロールするためのコマンド。サービスの起動や停止の操作する際に欠かせない。<br /> <code>#systemctl [サブコマンド] [サービス名(ユニット名)]</code></p> <div class="table-responsive"><table> <thead> <tr> <th>サブコマンド</th> <th>効果</th> </tr> </thead> <tbody> <tr> <td><strong>start</strong></td> <td><strong>開始する</strong></td> </tr> <tr> <td>restart</td> <td>再起動する</td> </tr> <tr> <td>stop</td> <td>停止する</td> </tr> <tr> <td><strong>status</strong></td> <td><strong>状態を確認する</strong></td> </tr> <tr> <td><strong>enable</strong></td> <td><strong>自動起動を有効にする</strong></td> </tr> <tr> <td>disable</td> <td>自動起動を無効にする</td> </tr> <tr> <td><strong>is-enabled</strong></td> <td><strong>自動起動の状態を確認する</strong></td> </tr> <tr> <td>list-unit-files</td> <td>インストールされているユニットを表示する</td> </tr> </tbody> </table></div> <p>etc...</p> <h1 id="ファイアーウォールの設定"><a href="#%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%83%BC%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A">ファイアーウォールの設定</a></h1> <p>以下のコマンドを入力し、外部からサーバへHTTP通信を許可にする。<br /> <code>#firewall-cmd --permanent --add-service=http</code><br /> <code>#firewall-cmd --reload</code><br /> <code>#firewall-cmd --list-services</code><br /> 「--list-srvices」でHTTPがリストに追加されたことを確認する。</p> <h1 id="firewall-cmdコマンド"><a href="#firewall-cmd%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89">firewall-cmdコマンド</a></h1> <p>CentOS7では、ファイアーウォールにfirewalldが採用されている。fairewalldをコマンドで操作できるのが「<strong>firewall-cmd</strong>」<br /> <code>#firewall-cmd [オプション]</code><br /> ※オプション「<strong>--permanent</strong>」を加えない場合は設定が即時反映されるが、fairealldを起動すると<strong>設定が元に戻る</strong>。</p> <div class="table-responsive"><table> <thead> <tr> <th>オプション</th> <th>効果</th> </tr> </thead> <tbody> <tr> <td><strong>--add-service=サービス</strong></td> <td><strong>指定サービスの通信を許可にする</strong></td> </tr> <tr> <td>--remove-service=サービス</td> <td>指定サービスの通信を許可しない</td> </tr> <tr> <td><strong>--permanent</strong></td> <td><strong>永続化を指定※即時反映には--reloadが必須</strong></td> </tr> <tr> <td><strong>--reload</strong></td> <td><strong>設定をリロードする</strong></td> </tr> <tr> <td><strong>--list-services</strong></td> <td><strong>許可されたサービスを確認する</strong></td> </tr> <tr> <td>--list-all</td> <td>ゾーンの状態を確認する</td> </tr> <tr> <td>--get-services</td> <td>--add-srviceで指定できるサービス名を確認する</td> </tr> </tbody> </table></div> <p>etc...</p> <h3 id="firewalld"><a href="#firewalld">firewalld</a></h3> <p>・・・LinuxOS用のファイアーウォール管理ツール<br /> ・Webサーバには<strong>ドキュメントルート</strong>と呼ばれる、<strong>公開するコンテンツを配置するディレクトリ</strong>がある。httpdの場合「/var/www/html/」<br /> ・Webサーバに<strong>ファイル名を指定せずにアクセスした場合</strong>「<strong>index.html</strong>」という名前のファイルが表示される。</p> <h1 id="サーバソフトウェアのインストールフロー"><a href="#%E3%82%B5%E3%83%BC%E3%83%90%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%95%E3%83%AD%E3%83%BC">サーバソフトウェアのインストールフロー</a></h1> <p>パッケージのインストール(yum)<br /> ↓<br /> (設定ファイルの編集)(vim)※場合によっては設定しない<br /> ↓<br /> サービス起動と確認(systemctl)<br /> ↓<br /> サービス自動起動設定と確認(systemctl)<br /> ↓<br /> ファイアーウォールの設定(firewall-cmd)<br /> ↓<br /> 動作確認</p> ko00w1 tag:crieit.net,2005:PublicArticle/17154 2021-05-17T16:39:10+09:00 2021-05-17T16:39:10+09:00 https://crieit.net/posts/server-apache-install 【サーバ基礎】Apacheのインストールと自動設定 <h3><a target="_blank" rel="nofollow noopener" href="https://ja.wikipedia.org/wiki/Apache_HTTP_Server">Apache HTTP Server</a>をインストールします。</h3> <p>centOS7で、次の操作を行います。</p> <pre><code>$ su - # yum -y install httpd </code></pre> <p>インストールができたら、起動します。</p> <pre><code># systemctl start httpd # systemctl status httpd </code></pre> <h3 id="自動起動の設定"><a href="#%E8%87%AA%E5%8B%95%E8%B5%B7%E5%8B%95%E3%81%AE%E8%A8%AD%E5%AE%9A">自動起動の設定</a></h3> <p>OSの起動のときに、サーバの起動も行いたいときは以下の設定をします。</p> <pre><code># systemctl enable httpd # systemctl is-enabled httpd </code></pre> skyms tag:crieit.net,2005:PublicArticle/17122 2021-05-14T12:59:20+09:00 2021-05-14T13:02:02+09:00 https://crieit.net/posts/200 ある日突然ロードアベレージが200を超えた <p>※サーバの知識が乏しい為、誤った情報を載せるわけにもいかないので<br /> 具体的な解決方までは記載してません。ポエム感覚です。</p> <h2 id="何が起きた"><a href="#%E4%BD%95%E3%81%8C%E8%B5%B7%E3%81%8D%E3%81%9F">何が起きた</a></h2> <p>ある日、自分が開発した社内チャットツールが504エラーで開けなくなりました。<br /> クッソ時間をかけてターミナルを開き、<code>top</code>で確認したところ<code>load average:86</code> となっていて爆笑しました。(笑っている場合ではない)<br /> その後、色々対処している最終に230くらいになりました。写真撮っておけば良かったな(白目)。</p> <h2 id="どうしてそうなった"><a href="#%E3%81%A9%E3%81%86%E3%81%97%E3%81%A6%E3%81%9D%E3%81%86%E3%81%AA%E3%81%A3%E3%81%9F">どうしてそうなった</a></h2> <p>他のツールから、かなりの数のメッセージが送られてきたのが原因でした。<br /> と言っても1分に100件~200件程度なので、めちゃくちゃ多いのか?と言われれば微妙なところです。</p> <h2 id="とりあえず復活させるぞ"><a href="#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9A%E5%BE%A9%E6%B4%BB%E3%81%95%E3%81%9B%E3%82%8B%E3%81%9E">とりあえず復活させるぞ</a></h2> <p>実は以前にも同じことが起きたのですが、そのときはまだサーバの知識が今より乏しく、<br /> とりあえず早く復旧させなきゃという気持ちが先走って<code>reboot</code>してしまいました。<br /> もちろんこれで直ることもありますが、下手すると<code>reboot</code>してから1時間くらい立ち上がらないなんてこともあるので(経験者は語る)、<br /> むやみにやらないべきだと思います。</p> <h3 id="何が原因か突き止める"><a href="#%E4%BD%95%E3%81%8C%E5%8E%9F%E5%9B%A0%E3%81%8B%E7%AA%81%E3%81%8D%E6%AD%A2%E3%82%81%E3%82%8B">何が原因か突き止める</a></h3> <p>めちゃくちゃ重いときはターミナルを開くのも一苦労であることが多いですが、めげずに待ちましょう。<br /> で、私はとりあえず<code>top</code>でロードアベレージやメモリ、CPUを確認します。<br /> 入っているなら、<code>htop</code>の方が見やすいかも。</p> <p>その後はひらすらググります!!!<br /> 「ロードアベレージ 高い」「メモリ 解放されない」とか。<br /> もっと根本的に「504エラー 原因 突き止める」とか。</p> <p>あと、アプリ自体のlogも確認します。<br /> 今回の場合は、ログファイルが朝の時点で昨日より3倍のサイズだったり、<br /> メッセージ送信のAPIがめちゃくちゃ呼ばれていた形跡があったので、予測通りこれ原因だな…と確信しました。</p> <h3 id="原因の元をどうにかする"><a href="#%E5%8E%9F%E5%9B%A0%E3%81%AE%E5%85%83%E3%82%92%E3%81%A9%E3%81%86%E3%81%AB%E3%81%8B%E3%81%99%E3%82%8B">原因の元をどうにかする</a></h3> <p>とりあえずApacheの再起動を試みましたが、タイムアウトでエラーになり出来ませんでした。<br /> これはkillするしかないな…と思い、以下のように対処。</p> <pre><code class="bash"># Apacheのプロセスを確認 ps agx | grep httpd # とりあえず一番上に出てきたプロセスをkill sudo kill 34568 (※PID) # ロードアベレージが落ち着いてきたらApache再起動 sudo systemctl restart httpd </code></pre> <p>この処理が終わるまでも時間かかりますが、<br /> <code>kill</code>されてからは徐々にロードアベレージも減っていきました。<br /> Apacheを再起動し、なんとか復旧しました。</p> <h2 id="おわり"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A">おわり</a></h2> <p>根本的に、<br /> 「100件程度のメッセージで落ちないような設計にしろよ!」とか<br /> 「そもそも1分に100件送ってくんなよ!!」とか<br /> その辺りの問題はまだありますが、それはまた別の話として。</p> <p>以前よりはサーバダウンにも冷静に対処出来たんじゃないかなと思います。<br /> 今回は原因がわかっていたので良かったですが、また別の要因で再発したときにも慌てず対処したいなと思う所存でございます。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16833 2021-04-11T15:40:59+09:00 2021-04-11T22:21:47+09:00 https://crieit.net/posts/XAMPP-Apache-URL 【XAMPP】【Apache】URLとフォルダパスの関係を定義する <h1 id="httpd.confファイルの編集"><a href="#httpd.conf%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E7%B7%A8%E9%9B%86">httpd.confファイルの編集</a></h1> <ol> <li>「XAMPP Control Panel」を起動する。</li> <li>Apacheの「Config」ボタンを押す。</li> <li>Apache(httpd.conf)を選択する。</li> </ol> <hr /> <h1 id="URLとフォルダパスの関係を定義する"><a href="#URL%E3%81%A8%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%91%E3%82%B9%E3%81%AE%E9%96%A2%E4%BF%82%E3%82%92%E5%AE%9A%E7%BE%A9%E3%81%99%E3%82%8B">URLとフォルダパスの関係を定義する</a></h1> <ol> <li>ファイル内をキーワード「Alias: Maps web paths」で検索する。</li> <li>該当コメントの後に、下記を追記する。<br /> [URL]のリクエストを受け付けると、Webサーバ内の[フォルダパス]を参照する。</li> </ol> <pre><code>alias [URL] "[ディレクトリパス]" <Directory "[ディレクトリパス]"> Options Indexes followSymLinks MultiViews AllowOverride All Order allow,deny Allow from all Require all granted </Directory> </code></pre> <p>例)</p> <pre><code>alias /hoge "/xampp/htdocs/hogeproject/public/" <Directory "/xampp/htdocs/hogeproject/public/"> Options Indexes followSymLinks MultiViews AllowOverride All Order allow,deny Allow from all Require all granted </Directory> </code></pre> <p>Webブラウザで「http://localhost/hoge/fuga.html」を指定すると、「/xampp/htdocs/hogeproject/public/fuga.html」を表示する。</p> <hr /> <p>「PHPフレームワーク Laravel入門 第2版」P21で、<br /> ---引用---<br /> ファイルを開いたら、<strong>末尾</strong>に以下のように追記をしましょう。<br /> ---引用ここまで---<br /> と記載されていたのに、その通り設定しても「ページが見つかりません」となってしまったので、気になって調べてみた。</p> <hr /> <h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1> <p>Aliasディレクティブ:特定のパスへのリクエストに対してドキュメントルート以外のディレクトリを割り当てる(<a target="_blank" rel="nofollow noopener" href="https://www.javadrive.jp/apache/ini/index12.html">https://www.javadrive.jp/apache/ini/index12.html</a>)</p> <p>もっとhttpd.confの設定(<a target="_blank" rel="nofollow noopener" href="http://www.nina.jp/server/redhat/httpd/httpd_conf.html">http://www.nina.jp/server/redhat/httpd/httpd_conf.html</a>)</p> <p>PHPフレームワーク Laravel入門 第2版(<a target="_blank" rel="nofollow noopener" href="https://www.shuwasystem.co.jp/book/9784798060996.html">https://www.shuwasystem.co.jp/book/9784798060996.html</a>)</p> acmz tag:crieit.net,2005:PublicArticle/16713 2021-03-03T22:12:17+09:00 2021-03-03T22:12:17+09:00 https://crieit.net/posts/perl-enable-by-htaccess-20210303 .htaccess で Perl を有効にする <p><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/02/03/perl-operation/">Apache の設定を編集</a>した方が早そうですが、 <code>.htaccess</code> で Perl を有効にしたい場合のメモです。</p> <pre><code class="htaccess">Options +ExecCGI AddHandler cgi-script cgi AddType application/x-httpd-cgi .cgi .pl </code></pre> <p>Apache の conf と代わり映えしないですが、一応メモしておきます。</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/shotets/items/cf0783530a1f2809c4d5">.htaccess の書き方(設定変更編) - Qiita</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/16600 2021-01-14T23:46:32+09:00 2021-01-14T23:46:32+09:00 https://crieit.net/posts/apache-logging-input-of-post-and-output-20210114 Apache でフォームの入力内容などをロギングする <p>フォームの検証などで Apache に送信される <code>POST</code> の内容を確認したい、ということになり、その際の方法をメモ。ちなみに、テスト環境なのでHTTPSではなくHTTP通信です。</p> <h2 id="設定変更"><a href="#%E8%A8%AD%E5%AE%9A%E5%A4%89%E6%9B%B4">設定変更</a></h2> <p>Apache の設定を変更することで <code>POST</code> の内容をロギングすることができました。</p> <pre><code class="bash"># less /etc/httpd/conf.modules.d/00-base.conf ## 略 LoadModule dumpio_module modules/mod_dumpio.so ## 略 </code></pre> <p><code>dumpio_module</code> が読み込まれていることを確認。</p> <pre><code class="bash"># vi /ect/httpd/conf/httpd.conf ## 略 #LogLevel warn DumpIOInput On DumpIOOutput On LogLevel debug dumpio:trace7 ## 略 </code></pre> <p>デフォルトの <code>LogLevel</code> である <code>warn</code> をコメントアウトして、 <code>LogLevel debug dumpio:trace7</code> に変更。古いサーバならば <code>dumpio:trace7</code> の部分がなくても行ける(むしろ <code>dumpio:trace7</code> を付けるとエラーになる)ようです。</p> <p>また、今回は入出力両方を見るために <code>DumpIOInput</code>, <code>DumpIOOutput</code> の両方を <code>On</code> にしました。</p> <pre><code class="bash"># systemctl reload httpd </code></pre> <p>これで Apache の設定再読み込み。</p> <pre><code class="bash"># less /var/log/error_log ## 略 [DDD mmm dd hh:ii:ss.mmmmmm yyyy] [dumpio:trace7] [pid 0000:tid 000000000000000] mod_dumpio.c(000): [client 192.0.2.1:55555] mod_dumpio: dumpio_in (data-HEAP): data%5Bwp-check-locked-posts%5D%5B%5D=post-8964&data%5Bwp-check-locked-posts%5D%5B%5D=post-8959&data%5Bwp-check-locked-posts%5D%5B%5D=post-8941&data%5Bwp-check-locked-posts%5D%5B%5D=post-8911&data%5Bwp-check-locked-posts%5D%5B%5D=post-8896&data%5Bwp-check-locked-posts%5D%5B%5D=post-8858&data%5Bwp-check-locked-posts%5D%5B%5D=post-8852&data%5Bwp-check-locked-posts%5D%5B%5D=post-8836&data%5Bwp-check-locked-posts%5D%5B%5D=post-8814&data%5Bwp-check-locked-posts%5D%5B%5D=post-8800&data%5Bwp-check-locked-posts%5D%5B%5D=post-8789&data%5Bwp-check-locked-posts%5D%5B%5D=post-8783&data%5Bwp-check-locked-posts%5D%5B%5D=post-8777&data%5Bwp-check-locked-posts%5D%5B%5D=post-8768&data%5Bwp-check-locked-posts%5D%5B%5D=post-8765&data%5Bwp-check-locked-posts%5D%5B%5D=post-8762&data%5Bwp-check-locked-posts%5D%5B%5D=post-8740&data%5Bwp-check-locked-posts%5D%5B%5D=post-8713&data%5Bwp-check-locked-posts%5D%5B%5D=post-8697&data%5Bwp-check-locked-posts%5D%5B%5D=post-8673&interval=15&_nonce=340f139c5d&action=heartbeat&screen_id=edit-post&has_focus=true ## 略 </code></pre> <p>これで <code>error_log</code> に入出力が記録されていることを確認(上の例は WordPress の投稿編集画面で「更新」したものの一部)。大丈夫そうです。</p> <p>なお、 <code>error_log</code> が凄い勢いで増えてくので検証が終わったら設定をすぐに戻した方が良いですね。</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/whywaita/items/fa6f83f4f62fc431bf55">Apache 2.4でPOSTの内容をログに出力するときは"LogLevel debug"だけじゃ出てこない - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/shyamahira/items/417234d169e331138c2c">ApacheでPOSTデータをログに記録したい - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/edapo/items/61589f496e7c7169c9d0">HTTP POST でデータを送って中身を確認したい - Qiita</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/16569 2021-01-09T00:05:45+09:00 2021-01-09T00:05:45+09:00 https://crieit.net/posts/set-up-apache-to-gzip-20210109 Apache で gzip のファイル圧縮転送 を設定する <p>Apache で gzip のファイル圧縮転送 を設定するメモです。</p> <h2 id="設定前の動作確認"><a href="#%E8%A8%AD%E5%AE%9A%E5%89%8D%E3%81%AE%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">設定前の動作確認</a></h2> <p>試しに Apache 2.4系 のサーバに設定してみます。</p> <p>ちなみに設定前のとある WordPress のサイトのトップページを表示するとこのような感じ。</p> <p><a href="https://crieit.now.sh/upload_images/bc4147749145500703a1418c253625835ff8744931c15.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc4147749145500703a1418c253625835ff8744931c15.jpg?mw=700" alt="Chrome の Devtools で network を見る。 transferred が 1.4MB あることが分かる。" /></a></p> <p>Chrome の Devtools で network タブを開いてページをリロードすると、画像のような状態に。 <code>transferred</code> が <code>1.4MB</code> と表示されています。</p> <p><a href="https://crieit.now.sh/upload_images/108a8e79a118a713239369889835f60e5ff8746184131.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/108a8e79a118a713239369889835f60e5ff8746184131.jpg?mw=700" alt="トップページのHTMLリソースのレスポンスヘッダ" /></a></p> <p>トップページのHTMLリソースのレスポンスヘッダはこのような感じ。 <code>Connection</code> と <code>Content-Type</code> が隣接しています。</p> <h2 id="設定変更"><a href="#%E8%A8%AD%E5%AE%9A%E5%A4%89%E6%9B%B4">設定変更</a></h2> <p>設定する前にいくつか確認を。</p> <pre><code class="bash"># cd /etc/httpd/ # cd ./modules/ # ls libphp7-zts.so mod_deflate.so mod_proxy_express.so libphp7.so mod_dialup.so mod_proxy_fcgi.so ## 略 ## 略 ## 略 </code></pre> <p>まずは gzip圧縮に必要なモジュール <code>mod_deflate.so</code> があることを確認。</p> <pre><code class="bash"># cd ../ # less ./conf/httpd.conf ## 略 Include conf.modules.d/*.conf ## 略 IncludeOptional conf.d/*.conf </code></pre> <p>次に <code>httpd.conf</code> で <code>conf.modules.d/</code>ディレクトリ下 の <code>.conf</code>ファイル と <code>conf.d/</code>ディレクトリ下 の <code>.conf</code>ファイル を読み込む設定になっていることを確認。</p> <pre><code class="bash"># cd ../conf.modules.d/ # less 00-base.conf ## 略 LoadModule deflate_module modules/mod_deflate.so </code></pre> <p>続いて <code>conf.modules.d/00-base.conf</code> で <code>mod_deflate.so</code> がロードされるようになっていることを確認。</p> <pre><code class="bash"># cd ../conf.d/ # vi deflate.conf # This file is config of deflate_module. <IfModule mod_deflate.c> SetOutputFilter DEFLATE AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/javascript AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/atom_xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/json AddOutputFilterByType DEFLATE application/ld+json AddOutputFilterByType DEFLATE application/x-javascript AddOutputFilterByType DEFLATE application/x-httpd-php </IfModule> </code></pre> <p>ここまでを確認したら、 <code>conf.d/deflate.conf</code> ファイルを作成して設定を記述します。</p> <p>テキストファイルで、通信することがありえそうなものを入れてみました。</p> <pre><code class="bash"># ls -al ## 略 -rw-r--r-- 1 ADMIN_USER ADMIN_USER 857 mm dd hh:ii deflate.conf ## 略 -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1254 MM dd yyyy php.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 9465 MM dd yyyy ssl.conf ## 略 </code></pre> <p>念のため権限を確認。元々存在する <code>php.conf</code> 等と比較しておきます。</p> <pre><code class="bash"># systemctl reload httpd # </code></pre> <p>Apache をリロード。</p> <p>これで設定完了です。</p> <h2 id="設定後の動作確認"><a href="#%E8%A8%AD%E5%AE%9A%E5%BE%8C%E3%81%AE%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">設定後の動作確認</a></h2> <p>さて、先程のサイトをもう一度見てみます。</p> <p><a href="https://crieit.now.sh/upload_images/a2406453c3877362774d643555bd4b8c5ff8747d72444.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a2406453c3877362774d643555bd4b8c5ff8747d72444.jpg?mw=700" alt="設定後の Devtools。 transferred が 934kB に変化した。" /></a></p> <p>今度は <code>transferred</code> が <code>934kB</code> と表示されました。 約400kB くらい圧縮されました。</p> <p><a href="https://crieit.now.sh/upload_images/91fd8b02ed2488dedffa429e2b4bcc755ff87487bbf2c.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/91fd8b02ed2488dedffa429e2b4bcc755ff87487bbf2c.jpg?mw=700" alt="設定後のトップページのHTMLリソースのレスポンスヘッダ" /></a></p> <p>設定後のトップページのHTMLリソースのレスポンスヘッダ。 <code>Connection</code> と <code>Content-Type</code> の間に <code>Content-Encoding: gzip</code> が追加されたことが確認できました。</p> <hr /> <p>表示速度は気持ち速くなったかな、くらいですが、転送容量を見ると gzip圧縮 は効いていることが確認できました。</p> <p>ちなみに、 gzip圧縮 の設定をすると転送量は小さくなりますがその分サーバ側で処理をするため、容量の大きなファイルや元々圧縮されているファイルを圧縮すると余計な負荷がかかって逆効果なことも考えられます。</p> <p>そのため、MIMEタイプの設定で画像ファイル等は除外しています。</p> <h2 id="余談"><a href="#%E4%BD%99%E8%AB%87">余談</a></h2> <h3 id="余談1"><a href="#%E4%BD%99%E8%AB%871">余談1</a></h3> <p>今回の gzip圧縮 の設定ファイルの置き場所について <code>conf.d/</code> か <code>conf.modules.d/</code> か迷ったのですが、 <code>conf.modules.d/README</code> を読むと</p> <pre><code class="bash"># less conf.modules.d/README This directory holds configuration files for the Apache HTTP Server; any files in this directory which have the ".conf" extension will be processed as httpd configuration files. This directory contains configuration fragments necessary only to load modules. Administrators should use the directory "/etc/httpd/conf.d" to modify the configuration of httpd, or any modules. Files are processed in sorted order and should have a two digit numeric prefix. See httpd.conf(5) for more information. </code></pre> <p>ということで、 <code>conf.d/</code> にしました。</p> <h3 id="余談2"><a href="#%E4%BD%99%E8%AB%872">余談2</a></h3> <p>上記の <code>README</code> に記載がありますが、 <code>conf.modules.d/</code> の <code>.conf</code> ファイルは <code>00-base.conf</code> や <code>01-cgi.conf</code>, <code>15-php.conf</code> というように数字2桁のプレフィックスが付いています。</p> <blockquote> <p>Files are processed in sorted order and should have a two digit numeric prefix.</p> </blockquote> <p>このプレフィックスは数字で順番がソートされ、 <code>.conf</code>ファイル が読み込まれる順番が決まる。(そのソートのルールを保つため)プレフィックスは2桁にすべき、ということのようです。</p> <p>ソート順を保つためであって、 <code>01</code> や <code>15</code> の数字そのものに意味はなさそうな気がしました。</p> <p>何故ここを気にしたかと言うと、最初は <code>conf.modules.d/</code> に gzip圧縮 の設定ファイルを置こうとしていて、かつ deflate が元々は「空気を抜く、しぼませる」という意味なので気体にあやかって 22.4l で <code>224-deflate.conf</code> という名前にしようかと思ったためです( <code>README</code> を読んで止めましたが)。</p> <h3 id="余談3"><a href="#%E4%BD%99%E8%AB%873">余談3</a></h3> <p><code>.conf</code>ファイル を読み込むのに、 <code>httpd.conf</code> の中で <code>Include</code> と <code>IncludeOptional</code> の2つのディレクティブが既述されていたのでメモ。</p> <p>これらの違いは「<code>IncludeOptional</code> は指定されたファイルやディレクトリが存在しない場合でもエラーが発生しない」という点のようです。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="gzip圧縮"><a href="#gzip%E5%9C%A7%E7%B8%AE">gzip圧縮</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://itsakura.com/apache-gzip">Apache gzipでファイルを圧縮して転送する | ITSakura</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/tsukue/items/9ad0d8612879cabbd066">【初心者向け】Apacheでgzip - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.softel.co.jp/blogs/tech/archives/4240">【Apache】gzip圧縮してみる(帯域対策、Webサイト高速化) at softelメモ</a></li> <li><code>SetOutputFilter</code>: <a target="_blank" rel="nofollow noopener" href="https://httpd.apache.org/docs/2.4/ja/mod/core.html#setoutputfilter">core - Apache HTTP サーバ バージョン 2.4</a></li> </ul> <h3 id="MIMEタイプ"><a href="#MIME%E3%82%BF%E3%82%A4%E3%83%97">MIMEタイプ</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types">よくある MIME タイプ - HTTP | MDN</a></li> </ul> <h3 id="Include と IncludeOptional"><a href="#Include+%E3%81%A8+IncludeOptional">Include と IncludeOptional</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/100/items/ab31e57fcc66ac661d5c">Apache 2.4 設定ファイルの記述例 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/false-git@github/items/650895076217845ad829">FreeBSDのapacheの設定ファイルの変化 - Qiita</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/16416 2020-12-24T00:28:56+09:00 2020-12-24T00:29:36+09:00 https://crieit.net/posts/ansible-remove-user-and-settings-of-vsftpd-apache-20201224 vsftpd と Apache の設定を削除しLinuxユーザも削除する <p>以前取り上げた<a href="https://crieit.net/posts/ansible-settings-vsftpd-and-apache-20201202">Ansible を使って FTPユーザの作成と Apache の仮想サイトの設定をする</a>の逆方向バージョンです。</p> <p>つまり、</p> <ul> <li>Linuxユーザを削除</li> <li>上記ユーザを vsftpdユーザ からも削除</li> <li>Apache の仮想サイトの設定と該当ディレクトリのデータを全て削除</li> </ul> <p>を行うタスクを作ろう、と考えました。</p> <p>これは、上記のプレイブックを一時的なテスト環境として作った後、削除することも往々にしてあり、手動で削除するのが面倒になってきたからです。</p> <h2 id="前提"><a href="#%E5%89%8D%E6%8F%90">前提</a></h2> <p>テストに利用するサーバは前の記事と同じサーバで、該当プレイブックによって vsftpd や Apache が設定されている、という状況を想定しています。</p> <h2 id="設定"><a href="#%E8%A8%AD%E5%AE%9A">設定</a></h2> <h3 id="ディレクトリ階層"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E9%9A%8E%E5%B1%A4">ディレクトリ階層</a></h3> <pre><code class="bash">PROJECT_ROOT/ ├ workspace/ │ ├ entrypoint.sh │ └ ansible/ │ ├ (諸々元のプレイブックと同じ構造) │ ├ main.yml // Ansible の設定用 playbook │ └ resset.yml // 今回追加した削除用タスク │ ├ docker-compose.yml └ Dockerfile </code></pre> <p>ほぼ前の記事の通り、というか同じプロジェクトをそのまま流用しています。元々の意図が設定用プレイブックに対して設定を元に戻すためのものなので、同じ場所にあった方が都合は良いと考えました。</p> <p>ただ、リセットするためのタスクは設定用タスクほど複雑ではないのでタスクを分割せずに1つのファイルに既述することにしました。</p> <h3 id="ansible/vars/param_vars.yml"><a href="#ansible%2Fvars%2Fparam_vars.yml">ansible/vars/param_vars.yml</a></h3> <pre><code class="yml">username: USERNAME password: Password1234 rootdirectory: sample_site domain: www.sample.jp ipaddress: 192.0.2.1 portnum: 80 </code></pre> <p>上記ディレクトリ構造より、設定用のプレイブックに使用する変数ファイルがあるため、これをそのまま流用します。</p> <h3 id="ansible/resset.yml"><a href="#ansible%2Fresset.yml">ansible/resset.yml</a></h3> <pre><code class="yml">- name: Remove vsftpd and httpd settings become: yes become_user: ADMIN_USER become_method: su hosts: - add_vhost_servers vars_files: ./vars/param_vars.yml tasks: - name: Remove user user: name: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" state: absent remove: yes - name: Remove user in vsftpd user_list blockinfile: path: /etc/vsftpd/user_list create: yes insertafter: EOF marker: "# {mark} ANSIBLE basic setup: <span>{</span><span>{</span> username <span>}</span><span>}</span>" block: "" - name: Remove user_conf file file: path: "/etc/vsftpd/user_conf/<span>{</span><span>{</span> username <span>}</span><span>}</span>" state: absent - name: Restart vsftpd systemd: name: vsftpd.service state: restarted daemon_reload: yes - name: Remove Apache virtual site data file: path: "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" state: absent - name: Remove Apache conffile file: path: "/etc/httpd/conf.d/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>.conf" state: absent - name: Restart httpd systemd: name: httpd.service state: reloaded daemon_reload: yes </code></pre> <p>今回のメイン。削除用のタスクです。</p> <p>やっていることは冒頭で記した通り。</p> <h2 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h2> <h3 id="削除用プレイブックを走らせる前"><a href="#%E5%89%8A%E9%99%A4%E7%94%A8%E3%83%97%E3%83%AC%E3%82%A4%E3%83%96%E3%83%83%E3%82%AF%E3%82%92%E8%B5%B0%E3%82%89%E3%81%9B%E3%82%8B%E5%89%8D">削除用プレイブックを走らせる前</a></h3> <pre><code class="bash"># less /etc/passwd ## 略 USERNAME:x: </code></pre> <p>設定用プレイブックで追加されたユーザがいることを確認。</p> <pre><code class="bash"># less /etc/vsftpd/user_list ## 略 # BEGIN ANSIBLE basic setup: USERNAME USERNAME # END ANSIBLE basic setup: USERNAME </code></pre> <p>ここにも。</p> <pre><code class="bash"># ls -al /etc/vsftpd/user_conf/ 合計 4 drwxrwxr-x 2 ADMIN_USER ADMIN_USER 23 MM月 DD hh:ii . drwxr-xr-x 3 ADMIN_USER ADMIN_USER 150 MM月 DD hh:ii .. -rw-rw-r-- 1 ADMIN_USER ADMIN_USER 107 MM月 DD hh:ii USERNAME # less /etc/vsftpd/user_conf/USERNAME # BEGIN ANSIBLE basic setup: USERNAME local_root=/var/www/sample_site # END ANSIBLE basic setup: USERNAME </code></pre> <p>ここにも。</p> <pre><code class="bash"># ls -al /var/www/ 合計 4 drwxr-xr-x 5 ADMIN_USER ADMIN_USER 51 MM月 DD hh:ii . drwxr-xr-x. 22 ADMIN_USER ADMIN_USER 4096 MM月 DD hh:ii .. drwxr-xr-x 2 ADMIN_USER ADMIN_USER 6 MM月 DD hh:ii cgi-bin drwxr-xr-x 3 ADMIN_USER ADMIN_USER 35 MM月 DD hh:ii html drwxr-xr-x 3 ADMIN_USER ADMIN_USER 17 MM月 DD hh:ii sample_site # ls -al /etc/httpd/conf.d/ 合計 36 drwxr-xr-x 2 ADMIN_USER ADMIN_USER 137 MM月 DD hh:ii . drwxr-xr-x 5 ADMIN_USER ADMIN_USER 92 MM月 DD hh:ii .. -rw-r--r-- 1 ADMIN_USER ADMIN_USER 366 MM月 DD hh:ii README -rw-r--r-- 1 ADMIN_USER ADMIN_USER 2926 MM月 DD hh:ii autoindex.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii php.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 9443 MM月 DD hh:ii ssl.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii userdir.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 824 MM月 DD hh:ii welcome.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 439 MM月 DD hh:ii sample_site.conf # less /etc/httpd/conf.d/sample_site.conf <VirtualHost 192.0.2.1:80> DocumentRoot "/var/www/sample_site/web" ServerName www.sample_site.jp ServerAlias sample_site.jp ScriptAlias /cgi-bin/ /var/www/sample_site/web/cgi-bin/ RewriteEngine on RewriteCond %{HTTP_HOST} ^sample_site\.jp$ RewriteRule ^(.*)$ http://www.sample_site.jp$1 [R=301,L] <Directory "/var/www/sample_site/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>Apache 側にも仮想サイトの設定があり、仮想サイト用のディレクトリが切られていることを確認。</p> <p>FTPでログインしたり、 <code>hosts</code> で名前解決して仮想サイトにアクセスできることを確認。</p> <p>一通りプレイブックの設定通りです。</p> <h3 id="削除用プレイブックを走らせる"><a href="#%E5%89%8A%E9%99%A4%E7%94%A8%E3%83%97%E3%83%AC%E3%82%A4%E3%83%96%E3%83%83%E3%82%AF%E3%82%92%E8%B5%B0%E3%82%89%E3%81%9B%E3%82%8B">削除用プレイブックを走らせる</a></h3> <h4 id="Dry run"><a href="#Dry+run">Dry run</a></h4> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/reset.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K --check BECOME password: PLAY [Remove vsftpd and httpd settings] *************************************************************************** TASK [Gathering Facts] ********************************************************************************************ok: [192.0.2.1] TASK [Remove user] ************************************************************************************************changed: [192.0.2.1] TASK [Remove user in vsftpd user_list] ****************************************************************************changed: [192.0.2.1] TASK [Remove user_conf file] **************************************************************************************changed: [192.0.2.1] TASK [Restart vsftpd] *********************************************************************************************changed: [192.0.2.1] TASK [Remove Apache virtual site data] ****************************************************************************changed: [192.0.2.1] TASK [Remove Apache conffile] *************************************************************************************changed: [192.0.2.1] TASK [Restart httpd] **********************************************************************************************changed: [192.0.2.1] PLAY RECAP ********************************************************************************************************192.0.2.1 : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>まずは Dry run でエラーが出ないことを確認。大丈夫そうです。</p> <h4 id="本番"><a href="#%E6%9C%AC%E7%95%AA">本番</a></h4> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/reset.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K BECOME password: PLAY [Remove vsftpd and httpd settings] *************************************************************************** TASK [Gathering Facts] ********************************************************************************************ok: [192.0.2.1] TASK [Remove user] ************************************************************************************************changed: [192.0.2.1] TASK [Remove user in vsftpd user_list] ****************************************************************************changed: [192.0.2.1] TASK [Remove user_conf file] **************************************************************************************changed: [192.0.2.1] TASK [Restart vsftpd] *********************************************************************************************changed: [192.0.2.1] TASK [Remove Apache virtual site data] ****************************************************************************changed: [192.0.2.1] TASK [Remove Apache conffile] *************************************************************************************changed: [192.0.2.1] TASK [Restart httpd] **********************************************************************************************changed: [192.0.2.1] PLAY RECAP ********************************************************************************************************192.0.2.1 : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>続いて本番実行。完了しました。</p> <h3 id="削除用プレイブックを走らせた後"><a href="#%E5%89%8A%E9%99%A4%E7%94%A8%E3%83%97%E3%83%AC%E3%82%A4%E3%83%96%E3%83%83%E3%82%AF%E3%82%92%E8%B5%B0%E3%82%89%E3%81%9B%E3%81%9F%E5%BE%8C">削除用プレイブックを走らせた後</a></h3> <p>それでは、念のため確認していきたいと思います。</p> <pre><code class="bash"># less /etc/passwd </code></pre> <p>設定したユーザが消えていることを確認。</p> <pre><code class="bash"># ls -al /etc/vsftpd/user_conf/ 合計 0 drwxrwxr-x 2 ADMIN_USER ADMIN_USER 6 MM月 DD hh:ii . drwxr-xr-x 3 ADMIN_USER ADMIN_USER 150 MM月 DD hh:ii .. # less /etc/vsftpd/user_list ## 略 nobody </code></pre> <p>vsftpd の設定も消えています。OK。</p> <pre><code class="bash"># ls -al /var/www/ 合計 4 drwxr-xr-x 4 ADMIN_USER ADMIN_USER 33 MM月 DD hh:ii . drwxr-xr-x. 22 ADMIN_USER ADMIN_USER 4096 MM月 DD hh:ii .. drwxr-xr-x 2 ADMIN_USER ADMIN_USER 6 MM月 DD hh:ii cgi-bin drwxr-xr-x 3 ADMIN_USER ADMIN_USER 35 MM月 DD hh:ii html # ls -al /etc/httpd/conf.d/ 合計 32 drwxr-xr-x 2 ADMIN_USER ADMIN_USER 114 MM月 DD hh:ii . drwxr-xr-x 5 ADMIN_USER ADMIN_USER 92 MM月 DD hh:ii .. -rw-r--r-- 1 ADMIN_USER ADMIN_USER 366 MM月 DD hh:ii README -rw-r--r-- 1 ADMIN_USER ADMIN_USER 2926 MM月 DD hh:ii autoindex.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii php.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 9443 MM月 DD hh:ii ssl.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii userdir.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 824 MM月 DD hh:ii welcome.conf </code></pre> <p>仮想サイトのディレクトリは丸ごと消えて、設定ファイルも消えました。OKです。</p> <p>当然、FTPでログインできなくなっていますし、ブラウザでアクセスすると仮想サイトが消えたので代理の仮想サイトが応答してきました。OKです。</p> <hr /> <p>以上より、一通り意図通りの動作になったことを確認できました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="Ansible"><a href="#Ansible">Ansible</a></h3> <h4 id="ユーザ削除"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E5%89%8A%E9%99%A4">ユーザ削除</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/moiwa/items/bab0f4c8d0dbf361afa4">Ansible ~userモジュール~ - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/KeijiYONEDA/items/011b78b12022202d4ea1">【Ansible】開発者ユーザー追加・削除のベスト・プラクティスを考える - Qiita</a></li> </ul> <h4 id="ファイル削除"><a href="#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%89%8A%E9%99%A4">ファイル削除</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tekunabe.hatenablog.jp/entry/2019/03/03/ansible_file_intro#-%E4%BE%8B2-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%84%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B">[Ansible] file モジュールの基本的な使い方(ファイルやディレクトリの操作) - てくなべ (tekunabe)</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/waterada/items/4e64cc6f810a92001c95">ansible のモジュール(ファイル操作等)をまとめてみました - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.greptips.com/posts/1269/">Ansibleのfileモジュールでディレクトリをabsentするのは危険 - grep Tips *</a></li> </ul> <h4 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tech.smartcamp.co.jp/entry/2019/05/10/215035">Ansible Playbookでユーザ管理(登録・削除)をまるっとやる - SMARTCAMP Engineer Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/volanja/items/54a7dbc75b909e89d8fc">Ansibleの新モジュール replace(置換)を使ってみた。 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://uuutee.net/ansible/howto-replacing-text-with-ansible/">Ansibleでテキスト置換を行ういくつかの方法 | uuutee.log</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://akishin.hatenablog.jp/entry/20130817/1376709924">Ansible で複数行の文字列置換 - akishin999の日記</a></li> </ul> <h3 id="Linuxコマンド"><a href="#Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89">Linuxコマンド</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://eng-entrance.com/linux-command-userdel">userdelコマンドについて詳しくまとめました 【Linuxコマンド集】</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/16274 2020-12-07T15:32:40+09:00 2020-12-19T02:30:06+09:00 https://crieit.net/posts/Markdown-2-5fcdcc8866d16 CentOS7にWebサーバをインストールしよう <p>CentOS7に <strong>WEB サーバ (apache)</strong> をインストールし、テストWEBページを公開してみよう</p> <h2 id="インストール手順"><a href="#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%89%8B%E9%A0%86">インストール手順</a></h2> <ol> <li>Apache(web サーバソフト)をインストールする</li> </ol> <pre><code>$ sudo yum -y install httpd </code></pre> <ol start="2"> <li>Apache(web サーバソフト)を起動する</li> </ol> <pre><code>$ sudo systemctl start httpd </code></pre> <ol start="3"> <li>Apache(web サーバソフト)の起動状態を確認する</li> </ol> <pre><code class="vim">$ sudo systemctl status httpd </code></pre> <p><em>出力結果に<strong>Active: active (running)</strong> が表示されていれば、正常に起動しています</em></p> masaochann tag:crieit.net,2005:PublicArticle/16255 2020-12-04T00:13:51+09:00 2020-12-04T00:13:51+09:00 https://crieit.net/posts/ansible-settings-vsftpd-and-apache-20201202 Ansible を使って FTPユーザの作成と Apache の仮想サイトの設定をする <p>Ansible を使って設定を行う例として、 Linuxユーザを作成してFTPユーザとし、 Apache の仮想サイトを作成する部分をやってみたいと思います。</p> <h2 id="前提"><a href="#%E5%89%8D%E6%8F%90">前提</a></h2> <p>対象サーバの LAMP は<a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/07/09/centos7-wordpress-move/">CentOS7.5 + Apache + PHP + MySQL サーバを構築し、WordPressサイトを引っ越す(2018/11/20)</a>のうち</p> <ul> <li>1.初期設定 ~ 4.リポジトリ追加</li> <li>5.vsftpd のうち <ul> <li>5.1.インストール, 5.2.設定</li> </ul></li> <li>6.Apache ~ 11.Webmin</li> <li>12.Apache仮想サイトのうち <ul> <li>12.1.ダミーサイトの作成</li> </ul></li> <li>16.SSH</li> </ul> <p>が既に設定済みの状態のサーバとします(13.Let’s Encrypt ~ 15.WP-CLI は対象外)。</p> <p>また、今回 Ansible で設定するのは</p> <ul> <li>5.vsftpd のうち <ul> <li>5.3.ユーザ設定</li> <li>5.4.ユーザ作成・設定</li> </ul></li> <li>12.Apache仮想サイトのうち <ul> <li>12.2. 仮想サイト作成</li> </ul></li> </ul> <p>の部分を想定しています。</p> <h2 id="設定"><a href="#%E8%A8%AD%E5%AE%9A">設定</a></h2> <h3 id="ディレクトリ階層"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E9%9A%8E%E5%B1%A4">ディレクトリ階層</a></h3> <pre><code class="bash">PROJECT_ROOT/ ├ workspace/ // データ永続化領域 │ ├ entrypoint.sh // Dockerコンテナ起動時に実行するシェルスクリプト │ └ ansible/ // Ansible 用ディレクトリ │ ├ targets/ // リモートホストの情報を収めるディレクトリ │ │ └ hosts // リモートサーバの一覧 (今回は1つのみ) │ │ │ ├ tasks/ // Ansible のタスクを収めるディレクトリ │ │ ├ add_user.yml // Linuxユーザの作成 │ │ ├ vsftpd_user_settings.yml // vsftpd の設定 │ │ └ apache_settings.yml // Apache 仮想サイトの設定 │ │ │ ├ templates/ // Apache 仮想サイト設定のテンプレートを収めるディレクトリ │ │ └ vhost.conf.j2 // Apache 仮想サイト設定のテンプレート │ │ │ ├ vars/ // 各種パラメータ変数の設定を収めるディレクトリ │ │ └ param_vars.yml // 各種パラメータ変数 │ │ │ └ main.yml // Ansible の playbook │ ├ docker-compose.yml // Docker Compose 設定ファイル └ Dockerfile // Dockerfile </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/10/22/build_docker_container_as_ansible_controller/">Ansibleコントロールノード を Dockerコンテナ でビルドし、リモートサーバに公開鍵認証でSSH接続してインストール済みのパッケージの一覧を取得するまで</a>や<a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/11/06/ansible_execute_yum_update/">Ansible を使って yum update を実行する</a>の記事の構造をベースにカスタマイズ。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/philotic_moby_test/tree/yum_update">arm-band/philotic_moby_test at yum_update</a></li> </ul> <p>一揃いを Github に置きました。</p> <h3 id="Dockerfile, docker-compose.yml, entrypoint.sh. ansible/targets/hosts"><a href="#Dockerfile%2C+docker-compose.yml%2C+entrypoint.sh.+ansible%2Ftargets%2Fhosts">Dockerfile, docker-compose.yml, entrypoint.sh. ansible/targets/hosts</a></h3> <p>この辺りはそのまま。 <code>ansible/targets/hosts</code> はグループ名を変更していますが、対となる <code>ansible/main.yml</code> の <code>hosts</code> の指定を変えれば良いだけなので些事。</p> <h3 id="ansible/vars/param_vars.yml"><a href="#ansible%2Fvars%2Fparam_vars.yml">ansible/vars/param_vars.yml</a></h3> <pre><code class="yaml">username: USERNAME password: Password1234 rootdirectory: sample_site domain: www.sample.jp ipaddress: 192.0.2.1 portnum: 80 </code></pre> <p>まずは今回の新顔の変数から。当初は末尾の「備考1: コマンドライン引数を変数に代入する」のように引数でコマンドラインから直接渡すことを考えていましたが、上記の通り6つもあるとそれだけでコマンドが長くなってしまい可読性が下がるので最終的に止めました。</p> <p>代わりに変数を1つのファイルにまとめて、コマンド自体の長さは変わらないように調整しました。</p> <p>この場合、以下の <code>ansible/main.yml</code> で触れますが <code>vars_files: ./vars/param_vars.yml</code> という一行で変数ファイルの読み込みができ、かつそれ以降は <code>vars</code> キーで変数としてそのまま使用できるので導入はわりとすんなり行きました。</p> <h3 id="ansible/main.yml"><a href="#ansible%2Fmain.yml">ansible/main.yml</a></h3> <pre><code class="yaml">- name: Settings vsftpd and httpd become: yes become_user: ADMIN_USER become_method: su hosts: - add_vhost_servers vars_files: ./vars/param_vars.yml tasks: - name: Add Linux User include_tasks: ./tasks/add_user.yml vars: user: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" passwd: "<span>{</span><span>{</span> password <span>}</span><span>}</span>" - name: Settings vsftpd user_list and user_conf include_tasks: ./tasks/vsftpd_user_settings.yml vars: user: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" directory: "<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" - name: Setup Apache conffile include_tasks: ./tasks/apache_settings.yml vars: directory: "<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" url: "<span>{</span><span>{</span> domain <span>}</span><span>}</span>" ip: "<span>{</span><span>{</span> ipaddress <span>}</span><span>}</span>" portnumber: "<span>{</span><span>{</span> portnum <span>}</span><span>}</span>" </code></pre> <p>タスクのメイン部分。基本は前回と同様で、 <code>tasks</code> で指定する各種タスクが置き換わった形です。変数については上記の通り。</p> <h3 id="ansible/tasks/add_user.yml"><a href="#ansible%2Ftasks%2Fadd_user.yml">ansible/tasks/add_user.yml</a></h3> <pre><code class="yaml">- name: Add user, setting password and groups user: name: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" password: "<span>{</span><span>{</span> password | password_hash('sha512') <span>}</span><span>}</span>" groups: apache append: yes </code></pre> <p><code>ansible/main.yml</code> から渡ってきた各変数が使用される(ここでは <code>username</code>, <code>password</code>)、という形です。</p> <p>一点注意なのはパスワードはそのままだと平文で保存されてしまいますが、実際に認証する際はハッシュ値に変換されるので不一致となってしまいます。そこで、<strong>保存時にハッシュ値に変換</strong>するように <code>password_hash('sha512')</code> を噛ませています。</p> <h3 id="ansible/tasks/vsftpd_user_settings.yml"><a href="#ansible%2Ftasks%2Fvsftpd_user_settings.yml">ansible/tasks/vsftpd_user_settings.yml</a></h3> <pre><code class="yaml">- name: Settings vsftpd user_list blockinfile: path: /etc/vsftpd/user_list create: yes insertafter: EOF marker: "# {mark} ANSIBLE basic setup: <span>{</span><span>{</span> username <span>}</span><span>}</span>" block: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" - name: Settings vsftpd user_conf blockinfile: path: "/etc/vsftpd/user_conf/<span>{</span><span>{</span> username <span>}</span><span>}</span>" create: yes insertafter: EOF marker: "# {mark} ANSIBLE basic setup: <span>{</span><span>{</span> username <span>}</span><span>}</span>" block: "local_root=/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" - name: Restart vsftpd systemd: name: vsftpd.service state: restarted daemon_reload: yes </code></pre> <p>次は vsftpd の設定。 <code>user_list</code> にユーザとして登録し、 <code>user_conf</code> ディレクトリの下にユーザ名のファイルを作成、そこに <code>local_root</code> の指定を記述する、という内容です。</p> <p>ここでも一点注意。</p> <p>設定ファイルへの書き込みとして <code>blockinfile</code> を使用しているのですが、 <strong><code>marker</code> の値がユニークでない</strong>と、 <code>loop</code> で繰り返し処理をしたり、今回のケースだと異なる仮想サイトの設定を行ったり(Ansible を2回実行する)した場合に<strong>後勝ちで上書きされてしまう</strong>こと。</p> <p>今回のケースでは <code>user_list</code> に2回目の変数のユーザしか残らなくなってしまいます。そのため、 <strong><code>marker</code> の最後にユーザ名を混ぜることでコメント文が実行の度にユニークとなる</strong>ようにしました。</p> <h3 id="ansible/tasks/apache_settings.yml"><a href="#ansible%2Ftasks%2Fapache_settings.yml">ansible/tasks/apache_settings.yml</a></h3> <pre><code class="yaml">- name: mkdir root file: path: "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" state: directory owner: ADMIN_USER group: ADMIN_USER mode: 0755 recurse: no - name: mkdir web file: path: "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web" state: directory owner: apache group: apache mode: 0775 recurse: no - name: Setup Apache conffile template: src: ../templates/vhost.conf.j2 dest: "/etc/httpd/conf.d/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>.conf" mode: '0644' - name: Restart httpd systemd: name: httpd.service state: reloaded daemon_reload: yes </code></pre> <p>続いて Apache 仮想サイトの設定。ディレクトリを作ったり権限・所有者設定したり。</p> <p>最後の <code>Setup Apache conffile</code> の処理では jinja2 のテンプレートから仮想サイト用の conf ファイルを作成しています。</p> <h3 id="ansible/templates/vhost.conf.j2"><a href="#ansible%2Ftemplates%2Fvhost.conf.j2">ansible/templates/vhost.conf.j2</a></h3> <pre><code class="jinja2"><VirtualHost <span>{</span><span>{</span> ipaddress <span>}</span><span>}</span>:<span>{</span><span>{</span> portnum <span>}</span><span>}</span>> DocumentRoot "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web" ServerName <span>{</span><span>{</span> domain <span>}</span><span>}</span> {% if domain | regex_search("^www\.", ignorecase=True) %} ServerAlias <span>{</span><span>{</span> domain | regex_replace("^www\.(.*)$", '\\1') <span>}</span><span>}</span> {% endif %} ScriptAlias /cgi-bin/ /var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web/cgi-bin/ {% if domain | regex_search("^www\.", ignorecase=True) %} RewriteEngine on RewriteCond %{HTTP_HOST} <span>{</span><span>{</span> domain | regex_replace("^www\.(.*)$", '^\\1$') | regex_replace("\.", '\.') <span>}</span><span>}</span> RewriteRule ^(.*)$ http://<span>{</span><span>{</span> domain <span>}</span><span>}</span>$1 [R=301,L] {% endif %} <Directory "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>大体設定ファイルの内容ですが、各種変数を使用しています。</p> <p>また、ドメイン(変数 <code>domain</code> )が <code>www.</code> 始まりの場合はサーバ名を <code>www.example.jp</code> のように <code>www.</code> 付きとし、同時に <code>ServerAlias</code> で <code>example.jp</code> と <code>www.</code> なしもフォローするような条件分岐(<code>if</code>, <code>regex_search</code>)を挟みました。</p> <p>併せて、 <code>www.</code> なしのURLにアクセスした場合に <code>www.</code> ありにリダイレクトする設定も、変数 <code>domain</code> を正規表現置換(<code>regex_replace</code>)で一括で入れるようにしました。</p> <p>例えば、 <code>domain: www.example.jp</code> とした場合は以下のような設定ファイルが作成されます。</p> <pre><code><VirtualHost 192.0.2.1:80> DocumentRoot "/var/www/example/web" ServerName www.example.jp ServerAlias example.jp ScriptAlias /cgi-bin/ /var/www/example/web/cgi-bin/ RewriteEngine on RewriteCond %{HTTP_HOST} ^example\.jp$ RewriteRule ^(.*)$ http://www.example.jp$1 [R=301,L] <Directory "/var/www/example/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>一方、 <code>domain: form.example.jp</code> のようなケースだと以下。</p> <pre><code><VirtualHost 192.0.2.1:80> DocumentRoot "/var/www/form_example/web" ServerName form.example.jp ScriptAlias /cgi-bin/ /var/www/form_example/web/cgi-bin/ <Directory "/var/www/form_example/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>上記の通り、 <code>ServerAlias</code> と <code>Rewrite</code> 系がありません。</p> <h2 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h2> <p>以上のような構成で動作検証。</p> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/main.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K BECOME password: PLAY [Settings vsftpd and httpd] ********************************************************************************** TASK [Gathering Facts] ********************************************************************************************ok: [192.0.2.1] TASK [Add Linux User] *********************************************************************************************included: /workspace/ansible/tasks/add_user.yml for 192.0.2.1 TASK [Add user, setting password and groups] **********************************************************************changed: [192.0.2.1] TASK [Settings vsftpd user_list and user_conf] ********************************************************************included: /workspace/ansible/tasks/vsftpd_user_settings.yml for 192.0.2.1 TASK [Settings vsftpd user_list] **********************************************************************************changed: [192.0.2.1] TASK [Settings vsftpd user_conf] **********************************************************************************changed: [192.0.2.1] TASK [Restart vsftpd] *********************************************************************************************changed: [192.0.2.1] TASK [Setup Apache conffile] **************************************************************************************included: /workspace/ansible/tasks/apache_settings.yml for 192.0.2.1 TASK [mkdir root] *************************************************************************************************changed: [192.0.2.1] TASK [mkdir web] **************************************************************************************************changed: [192.0.2.1] TASK [Setup Apache conffile] **************************************************************************************changed: [192.0.2.1] TASK [Restart httpd] **********************************************************************************************changed: [192.0.2.1] PLAY RECAP ********************************************************************************************************192.0.2.1 : ok=12 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>OKです。</p> <p>仮想サイトにアクセスして Apache のデフォルトページが表示される、FTPでログインできる、ファイルアップロードなどの操作ができる、といった動作を一通りできることを確認できました。</p> <h3 id="備考1: コマンドライン引数を変数に代入する"><a href="#%E5%82%99%E8%80%831%3A+%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E5%BC%95%E6%95%B0%E3%82%92%E5%A4%89%E6%95%B0%E3%81%AB%E4%BB%A3%E5%85%A5%E3%81%99%E3%82%8B">備考1: コマンドライン引数を変数に代入する</a></h3> <p>例えば、以下のような <code>main.yml</code> を用意します。</p> <pre><code class="yaml">- name: Get packages from hosts and do yum update become: yes become_user: ADMIN_USER become_method: su hosts: - update_servers tasks: - name: Get packages from hosts before update include_tasks: ./tasks/get_packages.yml - name: Output packages from hosts before update include_tasks: ./tasks/output_packages.yml vars: flag: "<span>{</span><span>{</span> before <span>}</span><span>}</span>" - name: Do yum update include_tasks: ./tasks/yum_update.yml - name: Get packages from hosts after update include_tasks: ./tasks/get_packages.yml - name: Output packages from hosts after update include_tasks: ./tasks/output_packages.yml vars: flag: "<span>{</span><span>{</span> after <span>}</span><span>}</span>" </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/11/06/ansible_execute_yum_update/">Ansible を使って yum update を実行する</a> の <code>main.yml</code> のうち、 <code>vars</code> の部分を少し編集したものです。</p> <p>これで以下のように playbook を実行。</p> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/main.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K -e &quot;before=before2 after=after22&quot; </code></pre> <p>すると、 <code>workspace/192.0.2.1_packages_before2</code> と <code>workspace/192.0.2.1_packages_after22</code> が生成され、コマンドラインの引数が変数として使用されたことが分かりました。</p> <p>当初はこれの延長線を考えていましたが、冒頭の通り6つも引数があると長くなってしまうので最終的には不採用としました。</p> <p>ただし、これはこれで引数の使い方として参考になりそうなのでメモとして残しておきます。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="Ansible"><a href="#Ansible">Ansible</a></h3> <h4 id="引数、変数"><a href="#%E5%BC%95%E6%95%B0%E3%80%81%E5%A4%89%E6%95%B0">引数、変数</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/YumaInaura/items/6e05d87858bd647d11ab">ansible コマンドでモジュール引数 ( パラメータ ) を複数渡す方法 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/2.9_ja/user_guide/modules_intro.html">モジュールの概要 - Ansible Documentation</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_variables.html">変数の使用 - Ansible Documentation</a></li> </ul> <h4 id="変数"><a href="#%E5%A4%89%E6%95%B0">変数</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/c_u/items/e91ca023fbb124fec34a">Ansible: vars_files を使用した loop処理 - Qiita</a></li> </ul> <p><code>vars_files</code> を採用。</p> <h4 id="ユーザ作成"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E4%BD%9C%E6%88%90">ユーザ作成</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.netassist.ne.jp/blog/?p=156">Ansibleでユーザ追加 | Netassist Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/moiwa/items/bab0f4c8d0dbf361afa4">Ansible ~userモジュール~ - Qiita</a></li> </ul> <h4 id="パスワード"><a href="#%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89">パスワード</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.netassist.ne.jp/blog/?p=967">Ansibleでユーザパスワード設定 | Netassist Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sicksixrock66/items/474068167de9c8454319">適当にansibleでrootパスワードを変えようとしたらアクセスできなくなった件 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://teratail.com/questions/263760">Linux - Ansibleでパスワード変更の際に、パスワードポリシーを遵守させたい|teratail</a></li> </ul> <h4 id="Facts"><a href="#Facts">Facts</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://nwengblog.com/ansible-facts/">Ansible:Factsについて(Ansible 2.9.6) | matsublog</a></li> </ul> <h4 id="設定に追記"><a href="#%E8%A8%AD%E5%AE%9A%E3%81%AB%E8%BF%BD%E8%A8%98">設定に追記</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/YuukiMiyoshi/items/f1b773f65792ce0e9101">【Ansible】そのCopy、Blockinfileの方が良いかも? - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/nakacya/items/a624f6710c3ca0edc8a9">Ansible Blockinfile の tips - Qiita</a></li> </ul> <h4 id="blockfile"><a href="#blockfile">blockfile</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://dekitakotono.blogspot.com/2019/05/blockinfile.html">blockinfile モジュール-φ(.. ) のメモ</a></li> </ul> <blockquote> <p>複数のテキストブロックを追加する場合、マーカーラインをユニークにしないとテキストブロックが上書きされる</p> </blockquote> <p><code>marker</code> の文字列はユニークになるようにすること。</p> <h4 id="systemd"><a href="#systemd">systemd</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tnamao.hatenablog.com/entry/2016/12/03/014742">ansible で systemd 配下のサービスを扱う - 日記</a></li> <li><a target="_blank" rel="nofollow noopener" href="http://pj-doaa.hatenablog.com/entry/2017/09/05/120849">AnsibleのModule:systemd - ときどきAnsible日記</a></li> </ul> <h4 id="ディレクトリ作成"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E4%BD%9C%E6%88%90">ディレクトリ作成</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/hnakamur/items/b5a17d8cb289432014d5">[Ansible] ディレクトリが無かったら作成する - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://blog.adachin.me/archives/2781">[ansible]ディレクトリ作成はfileモジュールで! ? ADACHIN SERVER LABO</a></li> </ul> <h4 id="httpd"><a href="#httpd">httpd</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://dev.classmethod.jp/articles/tutorial-ansible-with-role/">Role を使ったAnsibleのチュートリアル | Developers.IO</a></li> </ul> <h4 id="jinja2, if"><a href="#jinja2%2C+if">jinja2, if</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yteraoka/items/7119d4e1e2f8faddfb64">Ansible の Template 機能の紹介 - Qiita</a></li> </ul> <h4 id="jinja2, regrex"><a href="#jinja2%2C+regrex">jinja2, regrex</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html">Using filters to manipulate data - Ansible Documentation</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/30413616/using-regex-in-jinja-2-for-ansible-playbooks">python - using regex in jinja 2 for ansible playbooks - Stack Overflow</a></li> </ul> <h3 id="usermod"><a href="#usermod">usermod</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.atmarkit.co.jp/ait/articles/1612/14/news022.html">【 usermod 】コマンド――ユーザーアカウントの情報を変更する:Linux基本コマンドTips(73) - @IT</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/16210 2020-11-10T18:19:54+09:00 2020-11-10T18:22:30+09:00 https://crieit.net/posts/Apache-Laravel-Vue-js-Vuetify-web 【Apache Laravel Vue.js Vuetify】webアプリをスマホに対応させるためにやったこと <p>Apache+Laravel+Vue.js+Vuetify で作った社内ツールをスマホ対応したときに行った作業内容メモ。<br /> <del>ほんとにiosが嫌いになりそうだった</del></p> <p>対応ブラウザは、</p> <ul> <li>chrome(PC, Android, ios)</li> <li>safari(ios)</li> </ul> <h2 id="まずはiPhone、Androidのデバッグが出来るように準備する"><a href="#%E3%81%BE%E3%81%9A%E3%81%AFiPhone%E3%80%81Android%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%81%8C%E5%87%BA%E6%9D%A5%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B">まずはiPhone、Androidのデバッグが出来るように準備する</a></h2> <p>それぞれの端末を持っていれば、PCに繋いでデバッグができる!なんて素晴らしい。<br /> iosはiPhone以外にもiPad、iPod touch でも問題なし。<br /> それぞれ以下を参考に。</p> <p>Android:<a target="_blank" rel="nofollow noopener" href="https://qiita.com/hojishi/items/12b726f8b02ef3d713e4">https://qiita.com/hojishi/items/12b726f8b02ef3d713e4</a><br /> ios:<a target="_blank" rel="nofollow noopener" href="https://webkatu.com/archives/ios-safari-debug-on-windows/">https://webkatu.com/archives/ios-safari-debug-on-windows/</a></p> <h2 id="Polyfillを入れる"><a href="#Polyfill%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B">Polyfillを入れる</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://v2.vuetifyjs.com/ja/getting-started/browser-support/">Vuetifyの公式ドキュメント</a>に則って入れればOK。</p> <pre><code class="bash">npm install babel-polyfill --save npm install @babel/preset-env --save </code></pre> <p>インストール後、<br /> <code>import Vue from 'vue'</code> とか<br /> <code>import vuetify from '@/plugins/vuetify</code><br /> を書いているファイルに、<br /> <code>import 'babel-polyfill'</code> を追加。<br /> (自分の場合は <code>/resources/assets/js/app.js</code>)</p> <p>ルートディレクトリの .babelrcに、</p> <pre><code> { "presets": ["@babel/preset-env"] } </code></pre> <h2 id="対応していないjsを地道に直す"><a href="#%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84js%E3%82%92%E5%9C%B0%E9%81%93%E3%81%AB%E7%9B%B4%E3%81%99">対応していないjsを地道に直す</a></h2> <p>特に問題なければ、↑を行えば画面は表示されるはず…と思っていたのだが、画面が真っ白だった。</p> <p>エラーを調べると、どうやら正規表現で後読みを使っているのが原因みたいだったので、該当箇所を修正。<br /> (safariは後読みに対応していない)</p> <p>※書いている最中に気づいたけど、それってつまりうまくPolyfillが使えていなかったのでは…??</p> <h2 id="「Error: Network Error POST 応答を解析できません」を直す"><a href="#%E3%80%8CError%3A+Network+Error%E3%80%80POST++%E5%BF%9C%E7%AD%94%E3%82%92%E8%A7%A3%E6%9E%90%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%80%8D%E3%82%92%E7%9B%B4%E3%81%99">「Error: Network Error POST 応答を解析できません」を直す</a></h2> <p>iosのみ起きる謎現象。これに2日かかった…<br /> 自分は、Apacheの設定を変更で直った。</p> <pre><code><Directory "/var/www/html/public"> AllowOverride All # Allow open access: Header unset Upgrade ←これを追加 </Directory> </code></pre> <p>とりあえずここまでで画面が開けるようになりました。<br /> 以降は細かい部分です。</p> <h2 id="スクロールを入れたくないのにスマホだと入ってしまう"><a href="#%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E3%82%92%E5%85%A5%E3%82%8C%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%AE%E3%81%AB%E3%82%B9%E3%83%9E%E3%83%9B%E3%81%A0%E3%81%A8%E5%85%A5%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86">スクロールを入れたくないのにスマホだと入ってしまう</a></h2> <p>webアプリ全体にスクロールを入れたくない場合、bodyに<code>height:100%</code>とか入れればPCでは大丈夫だったりしたんですが、<br /> スマホだとどうにも謎のスクロールが入ってしまうので、以下のように対応。</p> <pre><code class="html"><html id="content">  … </code></pre> <p>※jsでhtmlのところにstyleを指定する方法がわからなかったのでid属性を無理やり、、、</p> <pre><code class="js">const windowHeight = window.innerHeight; // windowの高さを取得 // <html>の高さを、windowsの高さいっぱいに設定 document.getElementById("content").style.height = windowHeight + "px"; // bodyはheight:100% document.body.style.height = "100%"; // スクロールバー非表示 // スマホのときはbodyに、PCのときはhtmlにかけないと反映されないっぽいので分ける const isSP = /iPhone|iPod|iPad|Android/i.test(navigator.userAgent); if (isSP) { document.body.style.overflowY = "hidden"; } else { document.getElementById("content").style.overflowY = "hidden"; } </code></pre> <p>…無理矢理感半端ないけど、ひとまずこれでPCでもスマホでも画面いっぱいでコンテンツが収まるようになった。</p> <h2 id="iosだけ、キーボードのenterでボタンクリック判定されてしまう"><a href="#ios%E3%81%A0%E3%81%91%E3%80%81%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%81%AEenter%E3%81%A7%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E5%88%A4%E5%AE%9A%E3%81%95%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86">iosだけ、キーボードのenterでボタンクリック判定されてしまう</a></h2> <p>PCやAndroidでは大丈夫なのに、iosだけ起きる謎現象。<br /> 改行する度にボタンが押されて送信されるという、、、、</p> <p>※単純にv-formのsubmitイベントが発火してしまっている場合は、<a target="_blank" rel="nofollow noopener" href="https://riotz.works/articles/lopburny/2019/07/31/page-reload-issue-by-implicit-submission/">こちら</a>を参考に。</p> <p>根本的な原因はわからなかったため、<br /> 入力文字が空欄・改行のみの場合は、ボタンクリックで呼ばれる処理が走らないようにした。</p> <pre><code class="html"><textarea v-model="inputText"></textarea> <v-btn @click="submit()">送信</v-btn> </code></pre> <pre><code class="js"><br />data: () => ({ inputText: "", }), computed: { /** * 空文字判定 */ isTextEmpty() { return !this.inputText || !this.inputText.match(/\S/g); }, }, methods: { submit() { if (this.isTextEmpty) return; // 以下送信処理 } } </code></pre> <h2 id="iosだけファイルアップロードができない"><a href="#ios%E3%81%A0%E3%81%91%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84">iosだけファイルアップロードができない</a></h2> <p>ファイル選択のダイアルボックスを開く→ファイルを選択→アップロード<br /> という流れのとき、iosだけダイアルボックスが開かないという謎現象。<br /> エラーも出ない…</p> <p>調べてみたら、どうやら<code>input.onchange</code>が動いていないようだった。</p> <pre><code class="javascript">function uplod() { return new Promise(resolve => { const input = document.createElement('input'); input.type = "file"; input.multiple = false; input.accept = "image/gif,image/jpeg,image/png"; input.onchange = event => { var file = event.target.files[0]; resolve(file); }; input.click(); }); } </code></pre> <p>ios以外は↑でも動いたが、どうやらiosではちゃんと<code><input></code>要素をDOMに追加してあげないといけないらしい。<br /> 参考:<a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only">https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only</a></p> <p>というわけで、以下のように修正</p> <pre><code class="javascript">function uplod() { return new Promise(resolve => { const input = document.createElement('input'); input.type = 'file'; input.multiple = false; input.accept = "image/gif,image/jpeg,image/png"; document.body.appendChild(input); // ←DOMに追加 input.onchange = event => { var file = event.target.files[0]; document.body.removeChild(input); // ←DOMから削除 resolve(file); }; input.click(); }); } </code></pre> <h2 id="iosだけ画像が縦に伸びる時"><a href="#ios%E3%81%A0%E3%81%91%E7%94%BB%E5%83%8F%E3%81%8C%E7%B8%A6%E3%81%AB%E4%BC%B8%E3%81%B3%E3%82%8B%E6%99%82">iosだけ画像が縦に伸びる時</a></h2> <p>これは別記事にもメモしてあるが、<br /> <code>display:flex;</code>を指定している箇所に、<code>align-items: flex-start;</code>を追記するだけ。<br /> 参考:<a target="_blank" rel="nofollow noopener" href="https://nichiyogogo.com/image-looks-stretched/">https://nichiyogogo.com/image-looks-stretched/</a></p> <h2 id="iosだけ、heightを指定した要素内の「overflow-y: visible scroll;」が効かない"><a href="#ios%E3%81%A0%E3%81%91%E3%80%81height%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E8%A6%81%E7%B4%A0%E5%86%85%E3%81%AE%E3%80%8Coverflow-y%3A+visible+scroll%3B%E3%80%8D%E3%81%8C%E5%8A%B9%E3%81%8B%E3%81%AA%E3%81%84">iosだけ、heightを指定した要素内の「overflow-y: visible scroll;」が効かない</a></h2> <p>これもiosの一部で起きる現象。<br /> safariのバージョンの問題かもしれない。</p> <p>ますは<a target="_blank" rel="nofollow noopener" href="https://shanabrian.com/web/html-css-js-technics/css-ios-safari-02.php">ここ</a>を参考に修正。<br /> 自分はこのときにも頑なに<code>overflow-y: visible scrol</code>と書き続けていたら直らず、<br /> 素直に <code>overflow-y:auto;</code> にするだけで解決…。</p> <h2 id="おわり"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A">おわり</a></h2> <p>ほとんどios対応ですね。<br /> Androidはグリッドをちゃんと設定して、表示崩れしないようにだけしてあげれば殆ど動きました。<br /> マジでiosとsafariが嫌いになりそうだった…。</p> みみみみみ tag:crieit.net,2005:PublicArticle/15275 2019-07-25T03:03:37+09:00 2019-07-25T03:18:33+09:00 https://crieit.net/posts/PHP-API PHPで爆速APIを作るとき工夫したこと <p>「サーモンランAPI」という配信専用のAPIです。<br /> <a target="_blank" rel="nofollow noopener" href="https://splamp.info/salmon/api/">https://splamp.info/salmon/api/</a></p> <p>任天堂ソフト「Splatoon2」のサーモンランの最新情報を取得できます。</p> <h1 id="爆速のために"><a href="#%E7%88%86%E9%80%9F%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AB">爆速のために</a></h1> <p>Apacheサーバー上で、JSONデータを静的ファイルとして配信しています。</p> <p>これまでスプランプ(※うちのサイト)では「<a target="_blank" rel="nofollow noopener" href="https://splamp.info/spstage2/">スプステージ2</a>」という名前でバトルステージの情報を返すAPIを運用してきたのですが、こちらはオプションの充実のために、PHPファイルにアクセスさせる動的な仕組みでした。</p> <p>今回静的ファイルにした理由です。</p> <ol> <li><p>オプションを付けないほうがシンプル<br /> … タイムゾーンなどの混乱の解消のため、時間データはUnixtimeだけにしました。言語も日英同時に配信することにしました。</p></li> <li><p>サーバー負荷が激減する<br /> … 毎回DBにアクセスしたりせずに済むのでレスポンス速度が向上します。</p></li> <li><p>クライアントでキャッシュが有効になる<br /> … ヘッダの<code>Last-Modified</code>や<code>E-tag</code>により、クライアントでキャッシュが有効になります。</p></li> </ol> <h1 id="仕組み"><a href="#%E4%BB%95%E7%B5%84%E3%81%BF">仕組み</a></h1> <p>APIのアクセス先は一見「/salmon/api/now」や「/salmon/api/all」のように見えますが、実は<code>.htaccess</code>で「/salmon/api/」の別の子フォルダにあるJSONファイルにリライトしています。<br /> 例:</p> <pre><code class="apache">RewriteEngine On RewriteRule ^all$ xxx.xxx [L] </code></pre> <p>また、JSONファイルは更新用プログラムによって、定期的に新しいファイルに上書きされます。</p> <p>更新用プログラムはcronで定期的に更新すべきかチェックしていて、更新があるとDBからデータを取得・整形して、出力します。</p> <p>JSONは何となく可読性を高めたくなったので、インデントを付けたり無意味なエスケープを消したりしてみました。</p> <pre><code class="php">$json = json_encode($output, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); </code></pre> <h1 id="ヘッダ問題"><a href="#%E3%83%98%E3%83%83%E3%83%80%E5%95%8F%E9%A1%8C">ヘッダ問題</a></h1> <p>今回一番欠かせなかったのはヘッダの付与でした。</p> <p>毎アクセス動的生成していた頃はPHPの<code>header()</code>なんかを使っていたのですが、今回は静的ファイルですから、Apacheの力を借りる他ありません。</p> <p>Apacheでは、<code>.htaccess</code>を使うと配下のファイルに対して指定したヘッダを付与することができます。</p> <pre><code class="apache">Header set (ヘッダ名) "(値)" </code></pre> <p>今回加えたヘッダは以下の二つです。</p> <pre><code class="apache">Header set Access-Control-Allow-Origin "*" Header set Content-Type "application/json; charset=utf-8" </code></pre> <p><code>Content-Type</code>では、文字化けしたりしないようにUTF-8を明示しています。</p> <p><code>Access-Control-Allow-Origin</code>というのは見たことない人もいるのではないでしょうか。これは、JavaScriptにおいてクロスオリジンでアクセスしてもよいかの指定になります。</p> <p>これをサーバーが明示的に許可しないとjsがアクセスすることはできません。jsでオープンなAPIが使えないなんてもったいない。<code>*</code>を指定することで誰でもアクセスできるようになります。(CORS / Cross-Origin Resource Sharingの許可、と呼ばれたりします。)</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <ul> <li>サーバー上でキャッシュ(静的ファイル)を生成した</li> <li><code>.htaccess</code>でヘッダを指定した</li> <li><code>Access-Control-Allow-Origin</code>の指定でjs勢にも利用してもらえる</li> </ul> <h1 id="感想"><a href="#%E6%84%9F%E6%83%B3">感想</a></h1> <p>JavaScriptからのアクセス許可については、実際にjs勢の方から問い合わせがあって初めて気づきました。意外と見落としている方は多いんじゃないでしょうか。</p> <p>個人的な信条として「サーバーサイドの魔法」というのがあります。サーバーサイドは制約が少なく、予想外のことができるということです。Apacheの設定ファイル<code>.htaccess</code>は特にその幅を広げてくれるので気に入っています。<br /> 他にも色々な機能があるので、調べてみると面白いと思います。<br /> <a target="_blank" rel="nofollow noopener" href="https://murashun.jp/blog/20141229-01.html">.htaccess の書き方 | murashun.jp</a></p> <h1 id="サーモンランAPIの他の記事"><a href="#%E3%82%B5%E3%83%BC%E3%83%A2%E3%83%B3%E3%83%A9%E3%83%B3API%E3%81%AE%E4%BB%96%E3%81%AE%E8%A8%98%E4%BA%8B">サーモンランAPIの他の記事</a></h1> <p>サーモンランAPIについて<br /> <a target="_blank" rel="nofollow noopener" href="https://splamp.info/salmon/api/">https://splamp.info/salmon/api/</a></p> <p>サーモンランAPIサンプル集(連載)<br /> <a href="https://crieit.net/magazines/barley_ural/サーモンランAPIサンプル集">https://crieit.net/magazines/barley_ural/サーモンランAPIサンプル集</a></p> ウラル tag:crieit.net,2005:PublicArticle/15272 2019-07-23T04:30:25+09:00 2019-07-23T04:34:47+09:00 https://crieit.net/posts/PHP-5d360ed14c851 PHPで新しいプロセスに処理を引き継ぐ方法 <h1 id="動機"><a href="#%E5%8B%95%E6%A9%9F">動機</a></h1> <p>PHPで無限ループ処理をしたかったのですが、サーバーの都合上5分でプロセスがタイムアウトしてしまうので、PHPからコマンドを呼び出して、新しくPHPプロセスを立てて処理を引き継ぐことにしました。</p> <h1 id="方法"><a href="#%E6%96%B9%E6%B3%95">方法</a></h1> <p>PHPで外部コマンドを実行するには、<code>exec()</code>を使います。</p> <p>ところで、PHPがインストールされているOSで<code>/home/example.php</code>を実行するなら、次のようなコマンドを打ちますよね。</p> <pre><code class="console">php /home/example.php </code></pre> <p>( ˘ω˘) 。o(つまりこうすれば…)</p> <pre><code class="php">exec('php /home/example.php'); </code></pre> <p>残念!!</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ねえプロセス殺せないんだけどなんで??????</p>— ウラル (@barley_ural) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/barley_ural/status/1152569096367591425?ref_src=twsrc%5Etfw">July 20, 2019</a></blockquote> <p>処理中のプロセスを見ると、大量のPHPが。そして、手元には大量のエラー通知メールが…。</p> <p>ここで、<code>exec()</code>のPHPリファレンスをもう一度よく見てみましょう。</p> <blockquote> <p>注意:</p> <p>プログラムがこの関数で始まる場合、 バックグラウンドで処理を続けさせるには、 プログラムの出力をファイルや別の出力ストリームにリダイレクトする必要があります。 そうしないと、プログラムが実行を終えるまで PHP はハングしてしまいます。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/function.exec.php">https://www.php.net/manual/ja/function.exec.php</a></p> </blockquote> <p>つまり<code>exec()</code>からコマンドを実行すると、子プロセスの出力があるまでこのPHPはkillされないということです。これは、<code>exec()</code>が返り値を待っているためでしょう。</p> <p>しかし厄介なのは、この待機中のプロセスは子プロセスが終了しない限り、あらゆるタイムアウト処理を無視する点です。いつまでもプロセスに残り続け、メモリを食い続けるのです。</p> <p>これを防ぐためには、以下のようにします。</p> <pre><code class="php">exec('php /home/example.php > /dev/null &'); </code></pre> <p><code>></code>を使うと、左側(ここでは<code>php /home/example.php</code>)の出力を右側(ここでは<code>/dev/null</code>)にリダイレクトします。</p> <p><code>/dev/null</code>は虚無を表すスペシャルファイルで、ここを出力先に指定すると、その出力は破棄されます。</p> <p><code>&</code>はコマンドの後ろに付けることで、バックグラウンド実行を示します。これにより、非同期でその処理を扱うことができます。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>PHPで新しいプロセスを立ててバックグラウンド実行するには次のコマンドを使います。</p> <pre><code class="php">exec('php /home/example.php > /dev/null &'); </code></pre> <p>重たい処理だけバックグラウンドに逃がしたいときにも使えそうです。</p> <h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/inosy22/items/341cfc589494b8211844">Linuxコマンド(Bash)でバックグラウンド実行する方法のまとめメモ</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://www.softel.co.jp/blogs/tech/archives/5697">【php】 exec()関数などでバックグラウンドでコマンドを実行するとき</a></p> ウラル tag:crieit.net,2005:PublicArticle/15228 2019-07-12T19:35:42+09:00 2019-07-12T19:35:42+09:00 https://crieit.net/posts/apache-configtest-Syntax-OK apacheのconfigtestは"Syntax OK"でもエラー扱い <h2 id="最初に。ごめんなさい"><a href="#%E6%9C%80%E5%88%9D%E3%81%AB%E3%80%82%E3%81%94%E3%82%81%E3%82%93%E3%81%AA%E3%81%95%E3%81%84">最初に。ごめんなさい</a></h2> <p>タイトル盛りました。<br /> 正確には、<br /> <strong>apacheのconfigtestは"Syntax OK" を標準エラー出力する。戻り値はちゃんと0が返る。</strong><br /> です。</p> <p>調べてもあまり情報出てこなかったし、誰も気にしていないんだろうけど。</p> <h2 id="確認したバージョン"><a href="#%E7%A2%BA%E8%AA%8D%E3%81%97%E3%81%9F%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3">確認したバージョン</a></h2> <pre><code>Server version: Apache/2.2.34 (Unix) </code></pre> <pre><code>Server version: Apache/2.4.33 (Unix) </code></pre> <h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2> <p>定期的に(結構な頻度で)apacheのエイリアスを増やさなきゃいけない不思議な環境がありまして。<br /> いい加減、手作業がダルいので、シェルで自動化しようと考えまして。</p> <pre><code class="sh"># 色々処理をごにょごにょ doSomething1 doSomething2 doSomething... service httpd configtest >> logfile RET=$? echo $RET >> logfile if [ ${RET} = 0 ]; then service httpd graceful fi </code></pre> <p>(今、そらで書いたのでだいぶ怪しい)</p> <p>で、動かして見たらconfigtestのところがログになかった。<br /> あれ???ってなって、構文ミスったかな? とか、いろいろ見直した。<br /> 最終的にやっと気が付いて、</p> <pre><code class="sh"># 色々処理をごにょごにょ doSomething doSomething2 doSomething... service httpd configtest >> logfile 2>&1 RET=$? echo $RET >> logfile if [ ${RET} = 0 ]; then service httpd graceful fi </code></pre> <p>これでちゃんとログに出た。</p> <h2 id="ちょっと待って"><a href="#%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E5%BE%85%E3%81%A3%E3%81%A6">ちょっと待って</a></h2> <p>Q. これってapacheの仕様うんぬんの前に……。<br /> A. はい。何らかのエラー出力があった場合もログに出ないので、最初のプログラムはただの僕が作ったバグです。</p> <h2 id="まあ"><a href="#%E3%81%BE%E3%81%82">まあ</a></h2> <p>戻り値はちゃんと出し分けてるのに(当たり前だ)<br /> 出力は出し分けずに標準エラー出力で統一ってのも、なんか不思議な気はする。<br /> まあ、だいたい2>&1するし、実害はないんだけど。</p> hammhiko