<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>記事一覧 on heppoko blog</title><link>https://blog-0847c6.gitlab.io/posts/</link><description>Recent content in 記事一覧 on heppoko blog</description><generator>Hugo -- gohugo.io</generator><language>ja-jp</language><lastBuildDate>Mon, 11 May 2026 00:00:00 +0900</lastBuildDate><atom:link href="https://blog-0847c6.gitlab.io/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>GitHub CLI (gh auth login) で Git の HTTPS 認証を安全にする</title><link>https://blog-0847c6.gitlab.io/posts/2026/05/11/github-cli-auth/</link><pubDate>Mon, 11 May 2026 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2026/05/11/github-cli-auth/</guid><description>&lt;p&gt;本記事は Ubuntu 24.04 を前提としています。&lt;/p&gt;
&lt;h2 id="きっかけ"&gt;&lt;a href="#%e3%81%8d%e3%81%a3%e3%81%8b%e3%81%91" class="header-anchor"&gt;&lt;/a&gt;きっかけ
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git remote -v&lt;/code&gt; を眺めていたら、Personal Access Token (PAT) が remote URL に丸ごと埋め込まれている状態になっていました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;origin https://ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxx@github.com/USER/REPO.git (fetch)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;origin https://ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxx@github.com/USER/REPO.git (push)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;.git/config&lt;/code&gt; はリポジトリに含まれないため「push しても外には出ない」ものの、ローカルで露出する経路は意外と多くあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;シェル履歴 (&lt;code&gt;~/.bash_history&lt;/code&gt; &lt;code&gt;~/.zsh_history&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;エディタや CI のログ、画面共有・スクリーンショット&lt;/li&gt;
&lt;li&gt;うっかり配布した dotfiles リポジトリ&lt;/li&gt;
&lt;li&gt;マルウェアやリモートアクセスで &lt;code&gt;.git/config&lt;/code&gt; が読まれる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;しかも classic PAT はスコープが粗く、&lt;code&gt;repo&lt;/code&gt; 権限があれば private リポジトリ全体の閲覧・書き換え、強制 push による履歴破壊、GitHub Actions secrets の窃取まで可能になります。攻撃者は奪った瞬間には何もせず静かに watch することもできるため、「使われた形跡がない」では安心できません。&lt;/p&gt;
&lt;p&gt;これを機に、PAT を URL に埋めず GitHub CLI (&lt;code&gt;gh&lt;/code&gt;) の credential helper に任せる構成に切り替えました。&lt;/p&gt;
&lt;h2 id="ゴール構成"&gt;&lt;a href="#%e3%82%b4%e3%83%bc%e3%83%ab%e6%a7%8b%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;ゴール構成
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;remote URL は素の &lt;code&gt;https://github.com/USER/REPO.git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;認証は &lt;code&gt;gh&lt;/code&gt; が credential helper として処理 (トークンは OS のセキュアストア管理)&lt;/li&gt;
&lt;li&gt;devcontainer を作り直しても再ログイン不要&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="手順"&gt;&lt;a href="#%e6%89%8b%e9%a0%86" class="header-anchor"&gt;&lt;/a&gt;手順
&lt;/h2&gt;&lt;h3 id="1-露出したトークンを-revoke-最優先"&gt;&lt;a href="#1-%e9%9c%b2%e5%87%ba%e3%81%97%e3%81%9f%e3%83%88%e3%83%bc%e3%82%af%e3%83%b3%e3%82%92-revoke-%e6%9c%80%e5%84%aa%e5%85%88" class="header-anchor"&gt;&lt;/a&gt;1. 露出したトークンを revoke (最優先)
&lt;/h3&gt;&lt;p&gt;remote URL を書き換える前に、まず GitHub 側でトークンを無効化します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;classic PAT: &lt;a class="link" href="https://github.com/settings/tokens" target="_blank" rel="noopener"
 &gt;https://github.com/settings/tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;fine-grained PAT: &lt;a class="link" href="https://github.com/settings/personal-access-tokens" target="_blank" rel="noopener"
 &gt;https://github.com/settings/personal-access-tokens&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;該当トークンを Delete した瞬間に無効になります。順序として &lt;strong&gt;これを先にやる&lt;/strong&gt; ことが大切です。後の手順を待っている間に古いトークンが他経路で使われるリスクを断ちます。&lt;/p&gt;
&lt;h3 id="2-gh-をインストール"&gt;&lt;a href="#2-gh-%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;2. &lt;code&gt;gh&lt;/code&gt; をインストール
&lt;/h3&gt;&lt;p&gt;devcontainer 環境なら &lt;code&gt;ghcr.io/devcontainers/features/github-cli&lt;/code&gt; feature で &lt;code&gt;gh&lt;/code&gt; がすでに入っています。&lt;/p&gt;
&lt;p&gt;ホスト (Ubuntu 24.04) に入れる場合は、以下の記事を参考にしてください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog-0847c6.gitlab.io/posts/2026/05/09/github-cli/" &gt;GitHub CLI (gh) のインストールと基本的な使い方&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-gh-auth-login-で認証"&gt;&lt;a href="#3-gh-auth-login-%e3%81%a7%e8%aa%8d%e8%a8%bc" class="header-anchor"&gt;&lt;/a&gt;3. &lt;code&gt;gh auth login&lt;/code&gt; で認証
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh auth login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;対話で以下のように選びます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;? Where do you use GitHub? GitHub.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;? What is your preferred protocol for Git operations? HTTPS
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;? Authenticate Git with your GitHub credentials? Yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;? How would you like to authenticate GitHub CLI? Login with a web browser
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Authenticate Git with your GitHub credentials? → Yes&lt;/code&gt; が肝で、これが &lt;code&gt;git config --global credential.helper&lt;/code&gt; を &lt;code&gt;gh&lt;/code&gt; 経由に書き換えてくれます。以後 &lt;code&gt;git push&lt;/code&gt; のたびに &lt;code&gt;gh&lt;/code&gt; が裏でトークンを取り出して認証してくれます。&lt;/p&gt;
&lt;p&gt;devcontainer のようなヘッドレス環境ではブラウザは自動で開きません。表示される 8 桁のワンタイムコードをコピーし、ホスト側のブラウザで &lt;a class="link" href="https://github.com/login/device" target="_blank" rel="noopener"
 &gt;https://github.com/login/device&lt;/a&gt; に貼って承認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;✓ Authentication complete.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;✓ Logged in as USER
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="4-remote-url-からトークンを除去"&gt;&lt;a href="#4-remote-url-%e3%81%8b%e3%82%89%e3%83%88%e3%83%bc%e3%82%af%e3%83%b3%e3%82%92%e9%99%a4%e5%8e%bb" class="header-anchor"&gt;&lt;/a&gt;4. remote URL からトークンを除去
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote set-url origin https://github.com/USER/REPO.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote -v
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;トークン部分が消えていれば OK です。&lt;code&gt;git fetch origin&lt;/code&gt; がパスワードを聞かれずに通れば認証は機能しています。&lt;/p&gt;
&lt;h3 id="5-シェル履歴の残骸を確認"&gt;&lt;a href="#5-%e3%82%b7%e3%82%a7%e3%83%ab%e5%b1%a5%e6%ad%b4%e3%81%ae%e6%ae%8b%e9%aa%b8%e3%82%92%e7%a2%ba%e8%aa%8d" class="header-anchor"&gt;&lt;/a&gt;5. シェル履歴の残骸を確認
&lt;/h3&gt;&lt;p&gt;revoke 済みでも、ローカル履歴に残ったトークン文字列は気持ちが悪いものです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -rn &lt;span class="s1"&gt;&amp;#39;ghp_&amp;#39;&lt;/span&gt; ~/.bash_history ~/.zsh_history 2&amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ヒットしたら該当行を削除します (&lt;code&gt;history -d &amp;lt;行番号&amp;gt;&lt;/code&gt; でメモリ上を消した後、ファイルも編集しておきます)。&lt;/p&gt;
&lt;h2 id="devcontainer-での認証共有"&gt;&lt;a href="#devcontainer-%e3%81%a7%e3%81%ae%e8%aa%8d%e8%a8%bc%e5%85%b1%e6%9c%89" class="header-anchor"&gt;&lt;/a&gt;devcontainer での認証共有
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;gh&lt;/code&gt; の認証情報は &lt;code&gt;~/.config/gh/hosts.yml&lt;/code&gt; (と OS のセキュアストア) に保存されます。devcontainer をリビルドすると &lt;code&gt;~/.config/gh&lt;/code&gt; が消えて再ログインが必要になるため、ホストの設定を bind mount で共有します。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.devcontainer/devcontainer.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsonc" data-lang="jsonc"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;mounts&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind,consistency=cached&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;source=${localEnv:HOME}/.claude.json,target=/home/vscode/.claude.json,type=bind,consistency=cached&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;source=${localEnv:HOME}/.config/gh,target=/home/vscode/.config/gh,type=bind,consistency=cached&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;前提として &lt;strong&gt;ホスト側に &lt;code&gt;~/.config/gh&lt;/code&gt; ディレクトリが存在している必要があります&lt;/strong&gt; (なければ bind mount に失敗します)。ホストにも &lt;code&gt;gh&lt;/code&gt; を入れて &lt;code&gt;gh auth login&lt;/code&gt; 済みにしておくのが一番シンプルです。事情があってホスト側で &lt;code&gt;gh&lt;/code&gt; を使わない場合でも、空ディレクトリだけ作っておけばマウント自体は通ります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p ~/.config/gh &lt;span class="c1"&gt;# ホスト側で実行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;設定変更後は VSCode の &lt;strong&gt;Dev Containers: Rebuild Container&lt;/strong&gt; でリビルドすると反映されます。&lt;/p&gt;
&lt;h2 id="補足-ssh-鍵にしないのか"&gt;&lt;a href="#%e8%a3%9c%e8%b6%b3-ssh-%e9%8d%b5%e3%81%ab%e3%81%97%e3%81%aa%e3%81%84%e3%81%ae%e3%81%8b" class="header-anchor"&gt;&lt;/a&gt;補足: SSH 鍵にしないのか
&lt;/h2&gt;&lt;p&gt;SSH 鍵認証もアリですが、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;鍵ファイル自体の管理 (&lt;code&gt;~/.ssh&lt;/code&gt; のパーミッション、複数マシン間の同期) が発生します&lt;/li&gt;
&lt;li&gt;GitHub Actions など他用途で &lt;code&gt;gh&lt;/code&gt; をどのみち使うことが多いです&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そのため、個人開発の HTTPS なら &lt;code&gt;gh auth login&lt;/code&gt; ひとつに寄せた方がメンテが楽だと感じています。複数アカウントの切替も &lt;code&gt;gh auth switch&lt;/code&gt; で済むのが良いところです。&lt;/p&gt;
&lt;h2 id="まとめ"&gt;&lt;a href="#%e3%81%be%e3%81%a8%e3%82%81" class="header-anchor"&gt;&lt;/a&gt;まとめ
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;PAT を URL に埋めるのは「公開リポジトリに含まれない」だけでローカル経路の露出リスクは大きいです。露出に気付いた時点で revoke が最優先となります。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gh auth login&lt;/code&gt; で credential helper を任せれば URL からトークンを排除でき、トークンは OS のセキュアストアに隔離されます。&lt;/li&gt;
&lt;li&gt;devcontainer ではホストの &lt;code&gt;~/.config/gh&lt;/code&gt; を bind mount しておくと、リビルドのたびに再ログインしなくて済みます。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>ターミナルから GitLab を操る：公式 CLI「glab」導入・活用ガイド</title><link>https://blog-0847c6.gitlab.io/posts/2026/05/10/glab/</link><pubDate>Sun, 10 May 2026 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2026/05/10/glab/</guid><description>&lt;p&gt;GitHub に &lt;code&gt;gh&lt;/code&gt; があるように、GitLab には &lt;strong&gt;&lt;code&gt;glab&lt;/code&gt;&lt;/strong&gt; があります。ブラウザを開かずに Issue を確認したり、MR（マージリクエスト）を作成したり、CI/CD パイプラインの状況を監視したりできるため、エンジニアの生産性を大きく向上させてくれます。&lt;/p&gt;
&lt;h2 id="1-インストール方法"&gt;&lt;a href="#1-%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e6%96%b9%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;1. インストール方法
&lt;/h2&gt;&lt;p&gt;devcontainer を使っていない場合は、ホスト側に &lt;code&gt;glab&lt;/code&gt; をインストールして使います。devcontainer を使う場合は、コンテナイメージに &lt;code&gt;glab&lt;/code&gt; をインストールしておくか、devcontainer の &lt;code&gt;Dockerfile&lt;/code&gt; / &lt;code&gt;devcontainer.json&lt;/code&gt; で導入しておきます。&lt;/p&gt;
&lt;p&gt;一般的な手順としては、&lt;code&gt;Dockerfile&lt;/code&gt; に &lt;code&gt;curl&lt;/code&gt; で &lt;code&gt;glab&lt;/code&gt; の公式パッケージを取得して &lt;code&gt;apt install&lt;/code&gt; するか、&lt;code&gt;apt&lt;/code&gt; リポジトリからインストールする形です。コンテナ内で &lt;code&gt;glab --version&lt;/code&gt; を実行して、インストールが正しくできていることを確認してください。&lt;/p&gt;
&lt;p&gt;OS ごとの主要なインストールコマンドは以下の通りです。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;OS&lt;/th&gt;
 &lt;th&gt;インストールコマンド&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;macOS&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;brew install glab&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Windows (winget)&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;winget install glab&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Windows (scoop)&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;scoop install glab&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Linux (Ubuntu/Debian)&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;sudo apt install glab&lt;/code&gt;（※公式リポジトリ推奨）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;インストール後、&lt;code&gt;glab --version&lt;/code&gt; で正常にインストールされたか確認しましょう。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-初期設定認証"&gt;&lt;a href="#2-%e5%88%9d%e6%9c%9f%e8%a8%ad%e5%ae%9a%e8%aa%8d%e8%a8%bc" class="header-anchor"&gt;&lt;/a&gt;2. 初期設定（認証）
&lt;/h2&gt;&lt;p&gt;インストールが完了したら、GitLab アカウントと連携させます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;glab auth login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;実行すると対話形式で以下の項目を聞かれます：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;GitLab インスタンスの種類&lt;/strong&gt;: GitLab.com か 自前運用のサーバー（Self-Managed）かを選択。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;認証方法&lt;/strong&gt;: &lt;code&gt;Web&lt;/code&gt; を選択するとブラウザが開いて簡単に認証できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プロトコル&lt;/strong&gt;: &lt;code&gt;SSH&lt;/code&gt; または &lt;code&gt;HTTPS&lt;/code&gt; を選択。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;設定が完了すると、&lt;code&gt;~/.config/glab-cli/config.yml&lt;/code&gt; に設定が保存されます。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-devcontainer-での認証情報共有"&gt;&lt;a href="#3-devcontainer-%e3%81%a7%e3%81%ae%e8%aa%8d%e8%a8%bc%e6%83%85%e5%a0%b1%e5%85%b1%e6%9c%89" class="header-anchor"&gt;&lt;/a&gt;3. devcontainer での認証情報共有
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;glab&lt;/code&gt; の認証情報は &lt;code&gt;~/.config/glab-cli/config.yml&lt;/code&gt; に保存されます。devcontainer をリビルドするとコンテナ内の &lt;code&gt;~/.config/glab-cli&lt;/code&gt; が消えて再ログインが必要になるため、ホスト側の設定を bind mount で共有しておくと便利です。&lt;/p&gt;
&lt;p&gt;一般的には、&lt;code&gt;.devcontainer/devcontainer.json&lt;/code&gt; の &lt;code&gt;mounts&lt;/code&gt; にホストの &lt;code&gt;~/.config/glab-cli&lt;/code&gt; を追加します。例:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsonc" data-lang="jsonc"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;mounts&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;source=${localEnv:HOME}/.config/glab-cli,target=/home/vscode/.config/glab-cli,type=bind,consistency=cached&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;もし &lt;code&gt;gh&lt;/code&gt; など別の CLI も devcontainer 内で使うなら、同じように &lt;code&gt;~/.config/gh&lt;/code&gt; を共有することもできます。&lt;/p&gt;
&lt;p&gt;ホスト側に &lt;code&gt;~/.config/glab-cli&lt;/code&gt; が存在していれば、ホストで一度 &lt;code&gt;glab auth login&lt;/code&gt; しておけばコンテナ側でも同じ認証を使えます。ホストにディレクトリがない場合は、&lt;code&gt;mkdir -p ~/.config/glab-cli&lt;/code&gt; で空ディレクトリを作成しておけばマウントが通ります。&lt;/p&gt;
&lt;p&gt;このようにしておけば、&lt;code&gt;glab&lt;/code&gt; の認証設定をホストと devcontainer で共通化し、コンテナ再構築後も再ログイン不要で作業を続けやすくなります。&lt;/p&gt;
&lt;h2 id="4-よく使う基本コマンド集"&gt;&lt;a href="#4-%e3%82%88%e3%81%8f%e4%bd%bf%e3%81%86%e5%9f%ba%e6%9c%ac%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e9%9b%86" class="header-anchor"&gt;&lt;/a&gt;4. よく使う基本コマンド集
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;glab&lt;/code&gt; のコマンド体系は &lt;code&gt;glab &amp;lt;リソース名&amp;gt; &amp;lt;アクション&amp;gt;&lt;/code&gt; という形式で、&lt;code&gt;gh&lt;/code&gt; と非常に似ています。&lt;/p&gt;
&lt;h3 id="-merge-request-mr-を操作する"&gt;&lt;a href="#-merge-request-mr-%e3%82%92%e6%93%8d%e4%bd%9c%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;■ Merge Request (MR) を操作する
&lt;/h3&gt;&lt;p&gt;開発のメイン作業となる MR 操作です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MR の一覧表示&lt;/strong&gt;: &lt;code&gt;glab mr list&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MR の作成&lt;/strong&gt;: &lt;code&gt;glab mr create --fill&lt;/code&gt;（現在のブランチから自動入力で作成）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MR の詳細表示&lt;/strong&gt;: &lt;code&gt;glab mr view &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MR を承認&lt;/strong&gt;: &lt;code&gt;glab mr approve &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MR をマージ&lt;/strong&gt;: &lt;code&gt;glab mr merge &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-issue-課題-を管理する"&gt;&lt;a href="#-issue-%e8%aa%b2%e9%a1%8c-%e3%82%92%e7%ae%a1%e7%90%86%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;■ Issue (課題) を管理する
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Issue 一覧&lt;/strong&gt;: &lt;code&gt;glab issue list&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Issue 作成&lt;/strong&gt;: &lt;code&gt;glab issue create -t &amp;quot;タイトル&amp;quot; -description &amp;quot;内容&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-cicd-パイプラインを確認する"&gt;&lt;a href="#-cicd-%e3%83%91%e3%82%a4%e3%83%97%e3%83%a9%e3%82%a4%e3%83%b3%e3%82%92%e7%a2%ba%e8%aa%8d%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;■ CI/CD パイプラインを確認する
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;glab&lt;/code&gt; 独自の強力な機能の一つが、CI パイプラインのリアルタイム監視です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;パイプラインの状態表示&lt;/strong&gt;: &lt;code&gt;glab pipeline status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実行中のログをリアルタイム表示&lt;/strong&gt;: &lt;code&gt;glab pipeline ci view&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;失敗したジョブの再実行&lt;/strong&gt;: &lt;code&gt;glab ci retry&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-gh-と-glab-の主な対応表"&gt;&lt;a href="#4-gh-%e3%81%a8-glab-%e3%81%ae%e4%b8%bb%e3%81%aa%e5%af%be%e5%bf%9c%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;4. &lt;code&gt;gh&lt;/code&gt; と &lt;code&gt;glab&lt;/code&gt; の主な対応表
&lt;/h2&gt;&lt;p&gt;GitHub CLI に慣れている方向けのクイック比較です。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;機能&lt;/th&gt;
 &lt;th&gt;GitHub (&lt;code&gt;gh&lt;/code&gt;)&lt;/th&gt;
 &lt;th&gt;GitLab (&lt;code&gt;glab&lt;/code&gt;)&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;認証&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;gh auth login&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;glab auth login&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;PR / MR 作成&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;gh pr create&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;glab mr create&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;PR / MR チェックアウト&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;gh pr checkout &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;glab mr checkout &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;リポジトリ作成&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;gh repo create&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;glab project create&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;CI 監視&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;gh run watch&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;glab pipeline ci view&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="5-自社運用の-gitlab-self-managed-で使うコツ"&gt;&lt;a href="#5-%e8%87%aa%e7%a4%be%e9%81%8b%e7%94%a8%e3%81%ae-gitlab-self-managed-%e3%81%a7%e4%bd%bf%e3%81%86%e3%82%b3%e3%83%84" class="header-anchor"&gt;&lt;/a&gt;5. 自社運用の GitLab (Self-Managed) で使うコツ
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;glab&lt;/code&gt; は GitLab.com だけでなく、会社などで独自に立てている GitLab サーバーでも使えます。その場合、環境変数でホストを指定しておくと便利です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;GITLAB_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gitlab.example.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="まとめ"&gt;&lt;a href="#%e3%81%be%e3%81%a8%e3%82%81" class="header-anchor"&gt;&lt;/a&gt;まとめ
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;glab&lt;/code&gt; を導入することで、「コードを書く → プッシュする → ブラウザで MR を作る → CI の完了を待つ」という一連の流れをターミナルから一歩も出ずに行えるようになります。&lt;/p&gt;
&lt;p&gt;まずは &lt;code&gt;glab mr list&lt;/code&gt; から始めて、快適な GitLab ライフを送りましょう！&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;参考リンク:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.gitlab.com/ee/editor_extensions/gitlab_cli/" target="_blank" rel="noopener"
 &gt;GitLab CLI 公式ドキュメント&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://gitlab.com/gitlab-org/cli" target="_blank" rel="noopener"
 &gt;GitHub リポジトリ (gitlab-org/cli)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>GitHub CLI (gh) のインストールと基本的な使い方</title><link>https://blog-0847c6.gitlab.io/posts/2026/05/09/github-cli/</link><pubDate>Sat, 09 May 2026 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2026/05/09/github-cli/</guid><description>&lt;p&gt;GitHub CLI (&lt;code&gt;gh&lt;/code&gt;) は、GitHub が公式に提供しているコマンドラインツールです。&lt;/p&gt;
&lt;p&gt;ブラウザを開かなくても、リポジトリの clone、Issue の確認、Pull Request の作成、GitHub Actions の実行状況確認などをターミナルから操作できます。Git と組み合わせて使うと、日常の GitHub 作業をかなり短い導線にできます。&lt;/p&gt;
&lt;p&gt;この記事では、Windows と Ubuntu で &lt;code&gt;gh&lt;/code&gt; をインストールし、最初に覚えておくと便利な基本コマンドをまとめます。&lt;/p&gt;
&lt;h2 id="gh-でできること"&gt;&lt;a href="#gh-%e3%81%a7%e3%81%a7%e3%81%8d%e3%82%8b%e3%81%93%e3%81%a8" class="header-anchor"&gt;&lt;/a&gt;gh でできること
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;gh&lt;/code&gt; を使うと、たとえば以下のような作業をターミナルから実行できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub へのログイン&lt;/li&gt;
&lt;li&gt;リポジトリの clone / 作成 / 表示&lt;/li&gt;
&lt;li&gt;Issue の一覧表示 / 作成 / 表示&lt;/li&gt;
&lt;li&gt;Pull Request の一覧表示 / 作成 / checkout / merge&lt;/li&gt;
&lt;li&gt;GitHub Actions の workflow / run の確認&lt;/li&gt;
&lt;li&gt;ブラウザで現在のリポジトリや PR を開く&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GitHub の画面を見に行く回数を減らせるので、コードを書いている流れを止めにくいのが大きなメリットです。&lt;/p&gt;
&lt;h2 id="インストール"&gt;&lt;a href="#%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;インストール
&lt;/h2&gt;&lt;h3 id="windows-にインストールする"&gt;&lt;a href="#windows-%e3%81%ab%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;Windows にインストールする
&lt;/h3&gt;&lt;p&gt;Windows では、公式手順として WinGet を使う方法が一番簡単です。&lt;/p&gt;
&lt;p&gt;PowerShell または Windows Terminal を開いて、以下を実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;winget&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-id&lt;/span&gt; &lt;span class="n"&gt;GitHub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;cli
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;インストール後、ターミナルを開き直して確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;gh&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;バージョン情報が表示されればインストール完了です。&lt;/p&gt;
&lt;p&gt;アップデートする場合は以下です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;winget&lt;/span&gt; &lt;span class="n"&gt;upgrade&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-id&lt;/span&gt; &lt;span class="n"&gt;GitHub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;cli
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;もし WinGet を使わない場合は、GitHub CLI の Releases ページから MSI インストーラーをダウンロードして導入することもできます。&lt;/p&gt;
&lt;h3 id="ubuntu-にインストールする"&gt;&lt;a href="#ubuntu-%e3%81%ab%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;Ubuntu にインストールする
&lt;/h3&gt;&lt;p&gt;Ubuntu では、標準の apt リポジトリからそのままインストールできます。&lt;/p&gt;
&lt;p&gt;まずパッケージ情報を更新してから、&lt;code&gt;gh&lt;/code&gt; をインストールします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install gh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh --version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;アップデートする場合は、通常の apt パッケージと同じです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install gh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;もし apt で見つからない場合や、GitHub CLI の最新版を追いたい場合は、GitHub CLI 公式リポジトリを追加する方法もあります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;type&lt;/span&gt; -p wget &amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;sudo apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt install wget -y&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir -p -m &lt;span class="m"&gt;755&lt;/span&gt; /etc/apt/keyrings
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget -nv -O /tmp/githubcli-archive-keyring.gpg https://cli.github.com/packages/githubcli-archive-keyring.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo cp /tmp/githubcli-archive-keyring.gpg /etc/apt/keyrings/githubcli-archive-keyring.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir -p -m &lt;span class="m"&gt;755&lt;/span&gt; /etc/apt/sources.list.d
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb [arch=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;dpkg --print-architecture&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/github-cli.list &amp;gt; /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install gh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通常利用なら、まずは &lt;code&gt;sudo apt install gh&lt;/code&gt; で十分です。&lt;/p&gt;
&lt;h2 id="初期設定-github-にログインする"&gt;&lt;a href="#%e5%88%9d%e6%9c%9f%e8%a8%ad%e5%ae%9a-github-%e3%81%ab%e3%83%ad%e3%82%b0%e3%82%a4%e3%83%b3%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;初期設定: GitHub にログインする
&lt;/h2&gt;&lt;p&gt;インストールできたら、GitHub アカウントでログインします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh auth login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;対話形式でいくつか質問されます。個人利用で GitHub.com を使うなら、だいたい以下の選択で問題ありません。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;? Where do you use GitHub? GitHub.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;? What is your preferred protocol for Git operations? HTTPS
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;? Authenticate Git with your GitHub credentials? Yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;? How would you like to authenticate GitHub CLI? Login with a web browser
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ポイントは、&lt;code&gt;Authenticate Git with your GitHub credentials?&lt;/code&gt; で &lt;code&gt;Yes&lt;/code&gt; を選ぶことです。これにより、&lt;code&gt;gh&lt;/code&gt; だけでなく通常の &lt;code&gt;git push&lt;/code&gt; や &lt;code&gt;git fetch&lt;/code&gt; の HTTPS 認証も &lt;code&gt;gh&lt;/code&gt; に任せられます。&lt;/p&gt;
&lt;p&gt;ブラウザが開いたら GitHub にログインして認証します。WSL やサーバー上などブラウザを開きにくい環境では、表示されたワンタイムコードを手元のブラウザで入力して認証します。&lt;/p&gt;
&lt;p&gt;ログイン状態は以下で確認できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh auth status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="普通の-git-コマンドでも-gh-の認証情報は使われる"&gt;&lt;a href="#%e6%99%ae%e9%80%9a%e3%81%ae-git-%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e3%81%a7%e3%82%82-gh-%e3%81%ae%e8%aa%8d%e8%a8%bc%e6%83%85%e5%a0%b1%e3%81%af%e4%bd%bf%e3%82%8f%e3%82%8c%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;普通の git コマンドでも gh の認証情報は使われる？
&lt;/h2&gt;&lt;p&gt;使われます。ただし、&lt;code&gt;gh auth login&lt;/code&gt; の途中で以下を選んでいることが前提です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;? Authenticate Git with your GitHub credentials? Yes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この設定を有効にすると、&lt;code&gt;gh&lt;/code&gt; が Git の credential helper として設定されます。そのため、以下のような普通の Git コマンドでも、&lt;code&gt;gh&lt;/code&gt; でログインした認証情報が利用されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git fetch origin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git pull
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push origin main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;確認するには、Git の credential helper 設定を見ます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --global --get credential.helper
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;環境によって表示は少し違いますが、&lt;code&gt;gh auth git-credential&lt;/code&gt; を使う設定になっていれば OK です。&lt;/p&gt;
&lt;p&gt;注意点として、この仕組みが使われるのは基本的に HTTPS の remote URL です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote -v
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;remote URL が以下のようになっていれば、HTTPS 経由です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;origin https://github.com/OWNER/REPO.git (fetch)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;origin https://github.com/OWNER/REPO.git (push)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一方で、&lt;code&gt;git@github.com:OWNER/REPO.git&lt;/code&gt; のような SSH の remote URL を使っている場合は、Git の認証は SSH key 側で行われます。この場合でも &lt;code&gt;gh&lt;/code&gt; コマンド自体の GitHub API 操作には、&lt;code&gt;gh auth login&lt;/code&gt; の認証情報が使われます。&lt;/p&gt;
&lt;h2 id="よく使う基本コマンド"&gt;&lt;a href="#%e3%82%88%e3%81%8f%e4%bd%bf%e3%81%86%e5%9f%ba%e6%9c%ac%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;よく使う基本コマンド
&lt;/h2&gt;&lt;p&gt;ここからは、最初に覚えておくと便利なコマンドです。&lt;/p&gt;
&lt;h3 id="リポジトリ操作"&gt;&lt;a href="#%e3%83%aa%e3%83%9d%e3%82%b8%e3%83%88%e3%83%aa%e6%93%8d%e4%bd%9c" class="header-anchor"&gt;&lt;/a&gt;リポジトリ操作
&lt;/h3&gt;&lt;p&gt;リポジトリを clone します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh repo clone OWNER/REPO
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;たとえば GitHub CLI 本体のリポジトリなら以下です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh repo clone cli/cli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;現在のリポジトリをブラウザで開きます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh repo view --web
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;新しいリポジトリを作成します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh repo create
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;対話形式で公開範囲やローカルディレクトリの扱いを選べます。スクリプト化したい場合は、&lt;code&gt;--public&lt;/code&gt; や &lt;code&gt;--private&lt;/code&gt; などのオプションを付けて実行できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh repo create my-app --private --source&lt;span class="o"&gt;=&lt;/span&gt;. --remote&lt;span class="o"&gt;=&lt;/span&gt;origin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="issue-操作"&gt;&lt;a href="#issue-%e6%93%8d%e4%bd%9c" class="header-anchor"&gt;&lt;/a&gt;Issue 操作
&lt;/h3&gt;&lt;p&gt;Issue の一覧を表示します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh issue list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Issue の詳細を表示します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh issue view &lt;span class="m"&gt;123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Issue を作成します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh issue create --title &lt;span class="s2"&gt;&amp;#34;ログイン画面の文言を修正する&amp;#34;&lt;/span&gt; --body &lt;span class="s2"&gt;&amp;#34;ボタンの表記を変更する&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ブラウザで Issue を開きたい場合は &lt;code&gt;--web&lt;/code&gt; を付けます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh issue view &lt;span class="m"&gt;123&lt;/span&gt; --web
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pull-request-操作"&gt;&lt;a href="#pull-request-%e6%93%8d%e4%bd%9c" class="header-anchor"&gt;&lt;/a&gt;Pull Request 操作
&lt;/h3&gt;&lt;p&gt;Pull Request の一覧を表示します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh pr list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;現在のブランチから Pull Request を作成します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh pr create
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;コミットメッセージやブランチ情報からタイトル・本文を自動入力したい場合は &lt;code&gt;--fill&lt;/code&gt; が便利です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh pr create --fill
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pull Request の詳細を表示します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh pr view &lt;span class="m"&gt;123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pull Request のブランチをローカルに checkout します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh pr checkout &lt;span class="m"&gt;123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;レビューや CI の状態を確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh pr checks &lt;span class="m"&gt;123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;マージします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh pr merge &lt;span class="m"&gt;123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="github-actions-操作"&gt;&lt;a href="#github-actions-%e6%93%8d%e4%bd%9c" class="header-anchor"&gt;&lt;/a&gt;GitHub Actions 操作
&lt;/h3&gt;&lt;p&gt;workflow の一覧を表示します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh workflow list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;実行履歴を表示します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh run list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最新の workflow run を確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh run view
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;実行中の workflow を待ちます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh run watch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;失敗したジョブのログを確認する場合は、まず &lt;code&gt;gh run list&lt;/code&gt; で run ID を確認してから以下を実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh run view RUN_ID --log-failed
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="便利な使い方"&gt;&lt;a href="#%e4%be%bf%e5%88%a9%e3%81%aa%e4%bd%bf%e3%81%84%e6%96%b9" class="header-anchor"&gt;&lt;/a&gt;便利な使い方
&lt;/h2&gt;&lt;h3 id="現在のページをブラウザで開く"&gt;&lt;a href="#%e7%8f%be%e5%9c%a8%e3%81%ae%e3%83%9a%e3%83%bc%e3%82%b8%e3%82%92%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e3%81%a7%e9%96%8b%e3%81%8f" class="header-anchor"&gt;&lt;/a&gt;現在のページをブラウザで開く
&lt;/h3&gt;&lt;p&gt;現在のリポジトリを GitHub 上で開きます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh browse
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Issue や PR の URL を組み立てる必要がないので、地味に便利です。&lt;/p&gt;
&lt;h3 id="自分に関係する状況をまとめて見る"&gt;&lt;a href="#%e8%87%aa%e5%88%86%e3%81%ab%e9%96%a2%e4%bf%82%e3%81%99%e3%82%8b%e7%8a%b6%e6%b3%81%e3%82%92%e3%81%be%e3%81%a8%e3%82%81%e3%81%a6%e8%a6%8b%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;自分に関係する状況をまとめて見る
&lt;/h3&gt;&lt;p&gt;自分に関連する Issue、PR、レビュー依頼などを確認できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;朝の作業開始時に一度実行すると、見るべきものをざっと把握できます。&lt;/p&gt;
&lt;h3 id="エイリアスを作る"&gt;&lt;a href="#%e3%82%a8%e3%82%a4%e3%83%aa%e3%82%a2%e3%82%b9%e3%82%92%e4%bd%9c%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;エイリアスを作る
&lt;/h3&gt;&lt;p&gt;よく使うコマンドは短い別名を付けられます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh &lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; prs &lt;span class="s1"&gt;&amp;#39;pr list --author @me&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh prs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この例では、自分が作成した Pull Request 一覧を &lt;code&gt;gh prs&lt;/code&gt; で表示できます。&lt;/p&gt;
&lt;h2 id="windows-と-ubuntu-で共通して気をつけること"&gt;&lt;a href="#windows-%e3%81%a8-ubuntu-%e3%81%a7%e5%85%b1%e9%80%9a%e3%81%97%e3%81%a6%e6%b0%97%e3%82%92%e3%81%a4%e3%81%91%e3%82%8b%e3%81%93%e3%81%a8" class="header-anchor"&gt;&lt;/a&gt;Windows と Ubuntu で共通して気をつけること
&lt;/h2&gt;&lt;h3 id="ターミナルを開き直す"&gt;&lt;a href="#%e3%82%bf%e3%83%bc%e3%83%9f%e3%83%8a%e3%83%ab%e3%82%92%e9%96%8b%e3%81%8d%e7%9b%b4%e3%81%99" class="header-anchor"&gt;&lt;/a&gt;ターミナルを開き直す
&lt;/h3&gt;&lt;p&gt;Windows ではインストーラーが PATH を更新します。&lt;code&gt;gh&lt;/code&gt; が見つからない場合は、Windows Terminal や PowerShell を開き直してください。&lt;/p&gt;
&lt;p&gt;Ubuntu でも、インストール後にシェルがコマンドの場所をキャッシュしている場合があります。うまく認識されないときは、ターミナルを開き直すか &lt;code&gt;hash -r&lt;/code&gt; を実行します。&lt;/p&gt;
&lt;h3 id="git-の認証方式をそろえる"&gt;&lt;a href="#git-%e3%81%ae%e8%aa%8d%e8%a8%bc%e6%96%b9%e5%bc%8f%e3%82%92%e3%81%9d%e3%82%8d%e3%81%88%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;Git の認証方式をそろえる
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;gh auth login&lt;/code&gt; で HTTPS を選び、Git の認証にも &lt;code&gt;gh&lt;/code&gt; を使う設定にした場合、リモート URL も HTTPS にしておくと扱いやすいです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote -v
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote set-url origin https://github.com/OWNER/REPO.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;SSH を使いたい場合は、&lt;code&gt;gh auth login&lt;/code&gt; の対話で SSH を選び、SSH key の登録も &lt;code&gt;gh&lt;/code&gt; に任せることができます。HTTPS と SSH のどちらでも使えますが、チームや自分の環境で片方に寄せておくとトラブルシュートが楽です。&lt;/p&gt;
&lt;h3 id="github-enterprise-server-を使う場合"&gt;&lt;a href="#github-enterprise-server-%e3%82%92%e4%bd%bf%e3%81%86%e5%a0%b4%e5%90%88" class="header-anchor"&gt;&lt;/a&gt;GitHub Enterprise Server を使う場合
&lt;/h3&gt;&lt;p&gt;会社などで GitHub Enterprise Server を使っている場合は、ホスト名を指定してログインします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh auth login --hostname github.example.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通常の GitHub.com とは認証先が別になるため、&lt;code&gt;gh auth status&lt;/code&gt; でどのホストにログインしているか確認しておくと安心です。&lt;/p&gt;
&lt;h2 id="まとめ"&gt;&lt;a href="#%e3%81%be%e3%81%a8%e3%82%81" class="header-anchor"&gt;&lt;/a&gt;まとめ
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;gh&lt;/code&gt; を入れておくと、GitHub 上の操作をターミナルから自然に扱えるようになります。&lt;/p&gt;
&lt;p&gt;まずは以下の流れだけ覚えておけば十分です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh auth login
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh repo clone OWNER/REPO
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh issue list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh pr list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh pr create --fill
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gh run list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;慣れてきたら &lt;code&gt;gh pr checkout&lt;/code&gt;、&lt;code&gt;gh pr checks&lt;/code&gt;、&lt;code&gt;gh run watch&lt;/code&gt; あたりを使うと、Pull Request と CI の確認がかなり楽になります。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://cli.github.com/" target="_blank" rel="noopener"
 &gt;GitHub CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://cli.github.com/manual/" target="_blank" rel="noopener"
 &gt;GitHub CLI Manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/cli/cli/blob/trunk/docs/install_windows.md" target="_blank" rel="noopener"
 &gt;Installing gh on Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/cli/cli/blob/trunk/docs/install_linux.md" target="_blank" rel="noopener"
 &gt;Installing gh on Linux and BSD&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Jekyll で Minimal Mistakes のテーマを適用する</title><link>https://blog-0847c6.gitlab.io/posts/2024/12/19/jekyll/</link><pubDate>Thu, 19 Dec 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/12/19/jekyll/</guid><description>&lt;p&gt;いろいろテーマを探してみましたが、多機能かつドキュメントが充実していたのでこれにしてみました。&lt;/p&gt;
&lt;p&gt;以下の記事で作成した環境に対して適用します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2024/09/jekyll-docker.html" target="_blank" rel="noopener"
 &gt;https://kuttsun.blogspot.com/2024/09/jekyll-docker.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尚、デモページ、およびドキュメントは以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/mmistakes/minimal-mistakes" target="_blank" rel="noopener"
 &gt;https://github.com/mmistakes/minimal-mistakes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="テーマの適用"&gt;&lt;a href="#%e3%83%86%e3%83%bc%e3%83%9e%e3%81%ae%e9%81%a9%e7%94%a8" class="header-anchor"&gt;&lt;/a&gt;テーマの適用
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Gemfile&lt;/code&gt; に以下を追加します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;minimal-mistakes-jekyll&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;_cofig.yml&lt;/code&gt; でテーマを指定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minimal-mistakes-jekyll&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;必要に応じて各記事のレイアウトを変更します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;single&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;選択できるレイアウトについては以下を参照してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/layouts/" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/layouts/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;テーマを適用するだけならこれだけで OK でした。&lt;/p&gt;
&lt;h2 id="その他の設定"&gt;&lt;a href="#%e3%81%9d%e3%81%ae%e4%bb%96%e3%81%ae%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;その他の設定
&lt;/h2&gt;&lt;p&gt;公式のドキュメントに詳しく書かれているので、ここでは個人的に必要なものだけ抜粋して記載します。&lt;/p&gt;
&lt;h3 id="スキンを変更する"&gt;&lt;a href="#%e3%82%b9%e3%82%ad%e3%83%b3%e3%82%92%e5%a4%89%e6%9b%b4%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;スキンを変更する
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/configuration/#skin" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/configuration/#skin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_config.yml&lt;/code&gt; に以下のように記述します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;minimal_mistakes_skin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="記事内の目次を作成する"&gt;&lt;a href="#%e8%a8%98%e4%ba%8b%e5%86%85%e3%81%ae%e7%9b%ae%e6%ac%a1%e3%82%92%e4%bd%9c%e6%88%90%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;記事内の目次を作成する
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/layouts/#table-of-contents" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/layouts/#table-of-contents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;フロントマターで以下のように設定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;toc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;toc_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;My Table of Contents&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;toc_icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cog&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="記事を広げる"&gt;&lt;a href="#%e8%a8%98%e4%ba%8b%e3%82%92%e5%ba%83%e3%81%92%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;記事を広げる
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/layouts/#wide-page" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/layouts/#wide-page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;記事を目次のスペースまで広げるには、フロントマターで以下を設定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;wide&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ページの作成"&gt;&lt;a href="#%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ae%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;ページの作成
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;_pages&lt;/code&gt; というフォルダを作成し、そこに記事を追加します。&lt;br&gt;
&lt;code&gt;_config.yml&lt;/code&gt; に以下を追加し、&lt;code&gt;_pages&lt;/code&gt; フォルダのドキュメントを変換対象に指定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="カテゴリごとの記事一覧ページを作成"&gt;&lt;a href="#%e3%82%ab%e3%83%86%e3%82%b4%e3%83%aa%e3%81%94%e3%81%a8%e3%81%ae%e8%a8%98%e4%ba%8b%e4%b8%80%e8%a6%a7%e3%83%9a%e3%83%bc%e3%82%b8%e3%82%92%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;カテゴリごとの記事一覧ページを作成
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/layouts/#archive-layout" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/layouts/#archive-layout&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_pages&lt;/code&gt; に &lt;code&gt;category-archive.md&lt;/code&gt; というファイルを作成し、以下のような内容を記述します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Posts by Category&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;categories&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;permalink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/categories/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;author_profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="タグごとの記事一覧ページを作成"&gt;&lt;a href="#%e3%82%bf%e3%82%b0%e3%81%94%e3%81%a8%e3%81%ae%e8%a8%98%e4%ba%8b%e4%b8%80%e8%a6%a7%e3%83%9a%e3%83%bc%e3%82%b8%e3%82%92%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;タグごとの記事一覧ページを作成
&lt;/h3&gt;&lt;p&gt;カテゴリとほぼ同じです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/layouts/#archive-layout" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/layouts/#archive-layout&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_pages&lt;/code&gt; に &lt;code&gt;tag-archive.md&lt;/code&gt; というファイルを作成し、以下のような内容を記述します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Posts by Tag&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;permalink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/tags/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tags&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;author_profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="年ごとの記事一覧ページを作成"&gt;&lt;a href="#%e5%b9%b4%e3%81%94%e3%81%a8%e3%81%ae%e8%a8%98%e4%ba%8b%e4%b8%80%e8%a6%a7%e3%83%9a%e3%83%bc%e3%82%b8%e3%82%92%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;年ごとの記事一覧ページを作成
&lt;/h3&gt;&lt;p&gt;カテゴリとほぼ同じです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/layouts/#archive-layout" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/layouts/#archive-layout&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_pages&lt;/code&gt; に &lt;code&gt;year-achive.md&lt;/code&gt; というファイルを作成し、以下のような内容を記述します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Posts by Year&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;permalink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/year-archive/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;posts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;author_profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="サイドバーを作成する"&gt;&lt;a href="#%e3%82%b5%e3%82%a4%e3%83%89%e3%83%90%e3%83%bc%e3%82%92%e4%bd%9c%e6%88%90%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;サイドバーを作成する
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/layouts/#custom-sidebar-navigation-menu" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/layouts/#custom-sidebar-navigation-menu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/layout-sidebar-nav-list/" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/layout-sidebar-nav-list/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/layout-sidebar-custom/" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/layout-sidebar-custom/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_data/navigation.yml&lt;/code&gt; を作成し、以下のような内容を記述します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Getting Started&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Quick-Start Guide&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/quick-start-guide/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Structure&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/structure/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Installation&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/installation/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Upgrading&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/upgrading/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Customization&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Configuration&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/configuration/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Navigation&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/navigation/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;UI Text&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/ui-text/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Authors&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/authors/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Layouts&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/layouts/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Content&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Working with Posts&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/posts/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Working with Pages&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/pages/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Working with Collections&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/collections/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Helpers&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/helpers/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Utility Classes&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/utility-classes/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Extras&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Stylesheets&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/stylesheets/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;JavaScript&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/javascript/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;サイドバーを表示させたい記事のフロントマターに以下を追加します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docs&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;全ての記事に表示したい場合は、&lt;code&gt;_config.yml&lt;/code&gt; で以下のようにデフォルト値を設定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docs&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;show_date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="画面上部にナビゲーションを作成する"&gt;&lt;a href="#%e7%94%bb%e9%9d%a2%e4%b8%8a%e9%83%a8%e3%81%ab%e3%83%8a%e3%83%93%e3%82%b2%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%92%e4%bd%9c%e6%88%90%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;画面上部にナビゲーションを作成する
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/navigation/" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/navigation/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_data/navigation.yml&lt;/code&gt; を作成し、以下のような内容を記述します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Quick-Start Guide&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docs/quick-start-guide/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Posts&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/year-archive/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Categories&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/categories/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Tags&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/tags/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Pages&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/page-archive/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Collections&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/collection-archive/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;External Link&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://google.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;_blank&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="記事に投稿日を表示"&gt;&lt;a href="#%e8%a8%98%e4%ba%8b%e3%81%ab%e6%8a%95%e7%a8%bf%e6%97%a5%e3%82%92%e8%a1%a8%e7%a4%ba" class="header-anchor"&gt;&lt;/a&gt;記事に投稿日を表示
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/configuration/#post-dates" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/configuration/#post-dates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_config.yml&lt;/code&gt; に以下を設定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;posts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;show_date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="投稿日のフォーマットを指定"&gt;&lt;a href="#%e6%8a%95%e7%a8%bf%e6%97%a5%e3%81%ae%e3%83%95%e3%82%a9%e3%83%bc%e3%83%9e%e3%83%83%e3%83%88%e3%82%92%e6%8c%87%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;投稿日のフォーマットを指定
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/configuration/#post-dates" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/configuration/#post-dates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_config.yml&lt;/code&gt; で以下のように設定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;date_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;%Y-%m-%d&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="コードブロックにコピーボタンを付ける"&gt;&lt;a href="#%e3%82%b3%e3%83%bc%e3%83%89%e3%83%96%e3%83%ad%e3%83%83%e3%82%af%e3%81%ab%e3%82%b3%e3%83%94%e3%83%bc%e3%83%9c%e3%82%bf%e3%83%b3%e3%82%92%e4%bb%98%e3%81%91%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;コードブロックにコピーボタンを付ける
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/configuration/#code-block-copy-button" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/configuration/#code-block-copy-button&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_config.yml&lt;/code&gt; に以下を設定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;enable_copy_code_button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="サイト内検索を有効にする"&gt;&lt;a href="#%e3%82%b5%e3%82%a4%e3%83%88%e5%86%85%e6%a4%9c%e7%b4%a2%e3%82%92%e6%9c%89%e5%8a%b9%e3%81%ab%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;サイト内検索を有効にする
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/configuration/#site-search" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/configuration/#site-search&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_config.yml&lt;/code&gt; に以下を追加します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;search&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;検索エンジンは変更できるようです（上記リンク参照）。&lt;/p&gt;
&lt;h3 id="パンくずリストの作成"&gt;&lt;a href="#%e3%83%91%e3%83%b3%e3%81%8f%e3%81%9a%e3%83%aa%e3%82%b9%e3%83%88%e3%81%ae%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;パンくずリストの作成
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/configuration/#breadcrumb-navigation-beta" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/configuration/#breadcrumb-navigation-beta&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://mmistakes.github.io/minimal-mistakes/docs/configuration/#archive-settings" target="_blank" rel="noopener"
 &gt;https://mmistakes.github.io/minimal-mistakes/docs/configuration/#archive-settings&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://gwenneg.com/2024/08/17/blogging-with-minimal-effort.html" target="_blank" rel="noopener"
 &gt;https://gwenneg.com/2024/08/17/blogging-with-minimal-effort.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>docker コンテナ起動時に /tmp ディレクトリの中身を削除する</title><link>https://blog-0847c6.gitlab.io/posts/2024/12/11/docker/</link><pubDate>Wed, 11 Dec 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/12/11/docker/</guid><description>&lt;p&gt;Linux ではシステム起動時に &lt;code&gt;/tmp&lt;/code&gt; ディレクトリの中身がクリアされます。&lt;br&gt;
しかし、docker コンテナの場合は、通常はコンテナを再起動しても &lt;code&gt;/tmp&lt;/code&gt; ディレクトリの中身はクリアされません。&lt;/p&gt;
&lt;p&gt;docker コンテナで起動時に &lt;code&gt;/tmp&lt;/code&gt; ディレクトリの中身をクリアするには、以下のように &lt;code&gt;tmpfs&lt;/code&gt; ボリュームを使用する方法があります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker run --tmpfs /tmp my_image
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;docker compose の場合は以下のように指定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;my_service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my_image&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tmpfs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/tmp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# その他の設定&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;尚、docker compose で手動でボリュームを再作成したい場合は、以下のように &lt;code&gt;docker compose down -v&lt;/code&gt; コマンドを使用して既存のボリュームを削除し、その後 &lt;code&gt;docker compose up -d&lt;/code&gt; コマンドで新しいボリュームを作成してコンテナを起動します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker compose down -v
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;</description></item><item><title>Stable Diffusion web UI を動かしてみた</title><link>https://blog-0847c6.gitlab.io/posts/2024/12/10/stable-diffution/</link><pubDate>Tue, 10 Dec 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/12/10/stable-diffution/</guid><description>&lt;p&gt;ローカル環境で画像生成AIを使いたかったので、docker を使って Stable Diffusion web UI を動かしてみました。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Ubuntu 20.04&lt;/li&gt;
&lt;li&gt;docker 24.0.7&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="手順"&gt;&lt;a href="#%e6%89%8b%e9%a0%86" class="header-anchor"&gt;&lt;/a&gt;手順
&lt;/h2&gt;&lt;p&gt;Stable Diffusion web UI のリポジトリは以下になります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/AUTOMATIC1111/stable-diffusion-webui" target="_blank" rel="noopener"
 &gt;https://github.com/AUTOMATIC1111/stable-diffusion-webui&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Docker 版のリポジトリは以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/AbdBarho/stable-diffusion-webui-docker" target="_blank" rel="noopener"
 &gt;https://github.com/AbdBarho/stable-diffusion-webui-docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;まずはクローンしてきます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ git clone https://github.com/AbdBarho/stable-diffusion-webui-docker.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;あとは基本的に &lt;a class="link" href="https://github.com/AbdBarho/stable-diffusion-webui-docker/wiki/Setup" target="_blank" rel="noopener"
 &gt;Setup&lt;/a&gt; に記載されている通りにすすめるだけです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;stable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;diffusion&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webui&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="n"&gt;compose&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="n"&gt;download&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="n"&gt;compose&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;しかし、私の場合、&lt;code&gt;docker compose --profile auto up --build&lt;/code&gt; を実行したときにいくつかエラーが発生しました。&lt;/p&gt;
&lt;p&gt;最初に発生したエラーは以下です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="n"&gt;Step&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RUN&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;mount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;fonts&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dejavu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="n"&gt;rsync&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;jq&lt;/span&gt; &lt;span class="n"&gt;moreutils&lt;/span&gt; &lt;span class="n"&gt;aria2&lt;/span&gt; &lt;span class="n"&gt;ffmpeg&lt;/span&gt; &lt;span class="n"&gt;libglfw3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libgles2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mesa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;libcairo2&lt;/span&gt; &lt;span class="n"&gt;libcairo2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;essential&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;mount&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="n"&gt;requires&lt;/span&gt; &lt;span class="n"&gt;BuildKit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Refer&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;buildkit&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;learn&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;BuildKit&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;auto&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Build&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;生成AIに聞いてみた結果、どうやら buildx を手動でインストールする必要があるみたいでした。&lt;/p&gt;
&lt;p&gt;まずバイナリをダウンロードします:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -SL https://github.com/docker/buildx/releases/download/v0.10.4/buildx-v0.10.4.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ダウンロードしたファイルに実行権限を付与します:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod a+x ~/.docker/cli-plugins/docker-buildx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Docker Buildx が正しくインストールされたことを確認します:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker buildx version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで &lt;code&gt;docker buildx&lt;/code&gt; コマンドが利用できるようになります。&lt;br&gt;
再度 &lt;code&gt;docker-compose --profile auto up --build&lt;/code&gt; を実行したところ、今度は以下のエラーが発生しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | Installing extension dependencies (if any)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | Traceback (most recent call last):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/stable-diffusion-webui/webui.py&amp;#34;, line 13, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | initialize.imports()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/stable-diffusion-webui/modules/initialize.py&amp;#34;, line 23, in imports
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | import gradio # noqa: F401
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/gradio/__init__.py&amp;#34;, line 3, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | import gradio.components as components
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/gradio/components/__init__.py&amp;#34;, line 3, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | from gradio.components.bar_plot import BarPlot
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/gradio/components/bar_plot.py&amp;#34;, line 7, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | import altair as alt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/altair/__init__.py&amp;#34;, line 649, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | from altair.vegalite import *
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/altair/vegalite/__init__.py&amp;#34;, line 2, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | from .v5 import *
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/altair/vegalite/v5/__init__.py&amp;#34;, line 2, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | from altair.expr.core import datum
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/altair/expr/__init__.py&amp;#34;, line 11, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | from altair.expr.core import ConstExpression, FunctionExpression
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/altair/expr/core.py&amp;#34;, line 6, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | from altair.utils import SchemaBase
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/altair/utils/__init__.py&amp;#34;, line 14, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | from .plugin_registry import PluginRegistry
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | File &amp;#34;/opt/conda/lib/python3.10/site-packages/altair/utils/plugin_registry.py&amp;#34;, line 13, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | from typing_extensions import TypeIs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auto-cpu_1 | ImportError: cannot import name &amp;#39;TypeIs&amp;#39; from &amp;#39;typing_extensions&amp;#39; (/opt/conda/lib/python3.10/site-packages/typing_extensions.py)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これについては現時点でのバグっぽいですが、以下に回避策がありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/AbdBarho/stable-diffusion-webui-docker/issues/729" target="_blank" rel="noopener"
 &gt;https://github.com/AbdBarho/stable-diffusion-webui-docker/issues/729&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これで上手くいき、http://localhost:7860/ にアクセスすれば使用できました。&lt;/p&gt;
&lt;h2 id="sdxlモデルの設定"&gt;&lt;a href="#sdxl%e3%83%a2%e3%83%87%e3%83%ab%e3%81%ae%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;SDXLモデルの設定
&lt;/h2&gt;&lt;p&gt;SDXL モデルの設定については以下が参考になりました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://soroban.highreso.jp/article/article-042#651d4816a6d63105f25c3c7e-1aca58d91345337803792bb7" target="_blank" rel="noopener"
 &gt;https://soroban.highreso.jp/article/article-042#651d4816a6d63105f25c3c7e-1aca58d91345337803792bb7&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ただ、モデルと VAE の配置場所は現在のバージョンだと少し異なるようです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;モデル: &lt;code&gt;data/models/Stable-diffusion&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;VAE: &lt;code&gt;data/models/VAE&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;p&gt;^ &lt;a class="link" href="https://soroban.highreso.jp/article/article-042#651d4816a6d63105f25c3c7e-1aca58d91345337803792bb7" target="_blank" rel="noopener"
 &gt;https://soroban.highreso.jp/article/article-042#651d4816a6d63105f25c3c7e-1aca58d91345337803792bb7&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://highreso.jp/edgehub/stablediffusion/vae.html#index_id8" target="_blank" rel="noopener"
 &gt;https://highreso.jp/edgehub/stablediffusion/vae.html#index_id8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://e-penguiner.com/stable-diffusion-webui-docker/" target="_blank" rel="noopener"
 &gt;https://e-penguiner.com/stable-diffusion-webui-docker/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://note.com/npaka/n/nc8b0e9a91d97" target="_blank" rel="noopener"
 &gt;https://note.com/npaka/n/nc8b0e9a91d97&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://zenn.dev/karaage0703/articles/bf86fe4946417b" target="_blank" rel="noopener"
 &gt;https://zenn.dev/karaage0703/articles/bf86fe4946417b&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://pc.watch.impress.co.jp/docs/column/nishikawa/1485422.html" target="_blank" rel="noopener"
 &gt;https://pc.watch.impress.co.jp/docs/column/nishikawa/1485422.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>asciidoctor-pdf で見出し前の改ページを無効にする</title><link>https://blog-0847c6.gitlab.io/posts/2024/09/30/asciidoctor-pdf/</link><pubDate>Mon, 30 Sep 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/09/30/asciidoctor-pdf/</guid><description>&lt;p&gt;asciidoctor-pdf で PDF を作成したときに、見出しレベル２の前に改ページが自動挿入されて無駄に余白があるページがあったので、これを無効化する方法です。&lt;/p&gt;
&lt;p&gt;PDF 作成時に指定するテーマファイルで設定します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.asciidoctor.org/pdf-converter/latest/theme/heading/#chapter" target="_blank" rel="noopener"
 &gt;https://docs.asciidoctor.org/pdf-converter/latest/theme/heading/#chapter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これを踏まえ、&lt;code&gt;heading-chapter&lt;/code&gt; で &lt;code&gt;break-before&lt;/code&gt; を &lt;code&gt;auto&lt;/code&gt; に指定すれば改ページが無効になりました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;heading:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; chapter:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; break-before: auto
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ただ、&lt;code&gt;auto&lt;/code&gt; なので、場合によっては改ページされる場合もあるかもしれません。&lt;/p&gt;
&lt;p&gt;尚、上記の設定は &lt;code&gt;doctype&lt;/code&gt; が &lt;code&gt;book&lt;/code&gt; の場合のみ有効なようです。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.asciidoctor.org/pdf-converter/latest/theme/heading/#chapter" target="_blank" rel="noopener"
 &gt;https://docs.asciidoctor.org/pdf-converter/latest/theme/heading/#chapter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Asciidoc で include ディレクティブを使用している場合の画像へのパス</title><link>https://blog-0847c6.gitlab.io/posts/2024/09/26/asciidoc/</link><pubDate>Thu, 26 Sep 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/09/26/asciidoc/</guid><description>&lt;p&gt;画像を読み込んでいるファイルを、別の階層にあるファイルから &lt;code&gt;include&lt;/code&gt; ディレクティブで読み込むと、相対パスの位置が変わってしまいます。&lt;/p&gt;
&lt;p&gt;画像を読み込んでいるファイルを単体で表示したときにはそのファイルからの相対パスになりますが、&lt;code&gt;include&lt;/code&gt; しているファイルを表示したときには、&lt;code&gt;include&lt;/code&gt; しているファイルからの相対パスになってしまいます。&lt;/p&gt;
&lt;p&gt;同様のことで悩んでいる方はそれなりにいるようで、実際私もかなり困っています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/hyt126/items/7a070bc2b1e185b9146f" target="_blank" rel="noopener"
 &gt;https://qiita.com/hyt126/items/7a070bc2b1e185b9146f&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/ihgs/items/3c7a4fa9a2a81b23da82" target="_blank" rel="noopener"
 &gt;https://qiita.com/ihgs/items/3c7a4fa9a2a81b23da82&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://discuss.asciidoctor.org/Strange-issues-with-asciidoc-imagesdir-stops-working-td8194.html" target="_blank" rel="noopener"
 &gt;https://discuss.asciidoctor.org/Strange-issues-with-asciidoc-imagesdir-stops-working-td8194.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;とりあえずの解決方法としては、私にとっては以下の方法が一番役に立ちました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://stackoverflow.com/questions/75919047/images-in-various-locations-in-included-asciidoc-files" target="_blank" rel="noopener"
 &gt;https://stackoverflow.com/questions/75919047/images-in-various-locations-in-included-asciidoc-files&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ちょっと手間ですが、&lt;code&gt;include&lt;/code&gt; 直前で &lt;code&gt;imagedir&lt;/code&gt; を都度セットします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;:imagesdir: hoge
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;include::hoge/included_file.adoc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ただし、多重で include している場合は上記では上手くいきません。&lt;br&gt;
この場合は、試行錯誤の結果、以下のようにすることで上手くいきました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifdef::imagesdir[:imagesdir: {imagesdir}/hoge]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifndef::imagesdir[:imagesdir: hoge]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;include::hoge/included_file.adoc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;imagesdir&lt;/code&gt; が既に定義されている（＝別のファイルから include されている）場合は、現在の &lt;code&gt;imagesdir&lt;/code&gt; に付加する形で &lt;code&gt;imagesdir&lt;/code&gt; を再定義します。&lt;br&gt;
&lt;code&gt;imagesdir&lt;/code&gt; が定義されていない（＝別のファイルから include されていない）場合は、前述と同じように &lt;code&gt;imagesdir&lt;/code&gt; を定義します。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://stackoverflow.com/questions/75919047/images-in-various-locations-in-included-asciidoc-files" target="_blank" rel="noopener"
 &gt;https://stackoverflow.com/questions/75919047/images-in-various-locations-in-included-asciidoc-files&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Jekyll で Asciidoc を使用する</title><link>https://blog-0847c6.gitlab.io/posts/2024/09/12/jekyll-asciidoc/</link><pubDate>Thu, 12 Sep 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/09/12/jekyll-asciidoc/</guid><description>&lt;p&gt;markdown だけでなく asciidoc も使えたら便利なので。&lt;/p&gt;
&lt;p&gt;以下の記事で作成した環境に対して asciidoc を使えるようにします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2024/09/jekyll-docker.html" target="_blank" rel="noopener"
 &gt;https://kuttsun.blogspot.com/2024/09/jekyll-docker.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;調べたところ以下のプラグインを使えば出来そうだったので、これを使ってみます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/asciidoctor/jekyll-asciidoc" target="_blank" rel="noopener"
 &gt;https://github.com/asciidoctor/jekyll-asciidoc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gemfile-の変更"&gt;&lt;a href="#gemfile-%e3%81%ae%e5%a4%89%e6%9b%b4" class="header-anchor"&gt;&lt;/a&gt;Gemfile の変更
&lt;/h2&gt;&lt;p&gt;ドキュメントの通りに、&lt;code&gt;Gemfile&lt;/code&gt; に以下を追加します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;group :jekyll_plugins do
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; gem &amp;#39;jekyll-asciidoc&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;_config.yml&lt;/code&gt; に以下を追加します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;plugins:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - jekyll-asciidoc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;尚、&lt;code&gt;jekyll-asciidoc&lt;/code&gt; は他のプラグインより先に記述する必要があるそうです。&lt;br&gt;
詳細は以下を参照してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/asciidoctor/jekyll-asciidoc?tab=readme-ov-file#plugin-ordering" target="_blank" rel="noopener"
 &gt;https://github.com/asciidoctor/jekyll-asciidoc?tab=readme-ov-file#plugin-ordering&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これで、&lt;code&gt;_post&lt;/code&gt; フォルダ内に asciidoc で書いたドキュメントを追加すれば OK です。&lt;br&gt;
ファイル名は Jekyll の決まりとして、&lt;code&gt;YYYY-MM-DD-title.adoc&lt;/code&gt; のように日付が入っている必要があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://jekyllrb-ja.github.io/docs/posts/" target="_blank" rel="noopener"
 &gt;https://jekyllrb-ja.github.io/docs/posts/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下、サンプル通りに記事を作成してみました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;= Sample Page
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;:page-layout: post
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;:page-permalink: /sample/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;:url-asciidoctor: https://asciidoctor.org
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;This is a sample page composed in AsciiDoc.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Jekyll converts it to HTML using {url-asciidoctor}[Asciidoctor].
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[source,ruby]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;puts &amp;#34;Hello, World!&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ただし、&lt;code&gt;layuout&lt;/code&gt; は &lt;code&gt;post&lt;/code&gt; に変更しています。&lt;br&gt;
レイアウトについては以下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/a999/items/6c29ce072c19448ea579" target="_blank" rel="noopener"
 &gt;https://qiita.com/a999/items/6c29ce072c19448ea579&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これできちんと表示されることを確認しました。&lt;/p&gt;
&lt;h2 id="include-ディレクティブを使用するときの相対パス"&gt;&lt;a href="#include-%e3%83%87%e3%82%a3%e3%83%ac%e3%82%af%e3%83%86%e3%82%a3%e3%83%96%e3%82%92%e4%bd%bf%e7%94%a8%e3%81%99%e3%82%8b%e3%81%a8%e3%81%8d%e3%81%ae%e7%9b%b8%e5%af%be%e3%83%91%e3%82%b9" class="header-anchor"&gt;&lt;/a&gt;include ディレクティブを使用するときの相対パス
&lt;/h2&gt;&lt;p&gt;asciidoc では &lt;code&gt;include&lt;/code&gt; ディレクティブを使用して他の asciidoc ファイルを読み込むことができますが、このままやっても上手く描画されませんでした。&lt;br&gt;
同様の内容が issue に挙がっていました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/asciidoctor/jekyll-asciidoc/issues/182" target="_blank" rel="noopener"
 &gt;https://github.com/asciidoctor/jekyll-asciidoc/issues/182&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ベースディレクトリの設定がデフォルトではプロジェクトルートになっているので、ソースディレクトリとなるように設定すれば良さそうです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/asciidoctor/jekyll-asciidoc?tab=readme-ov-file#specifying-the-base-directory" target="_blank" rel="noopener"
 &gt;https://github.com/asciidoctor/jekyll-asciidoc?tab=readme-ov-file#specifying-the-base-directory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_config.yml&lt;/code&gt; に以下を追記すれば上手くいきました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;asciidoctor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;base_dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="l"&gt;docdir&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;safe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/asciidoctor/jekyll-asciidoc" target="_blank" rel="noopener"
 &gt;https://github.com/asciidoctor/jekyll-asciidoc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/a999/items/6c29ce072c19448ea579" target="_blank" rel="noopener"
 &gt;https://qiita.com/a999/items/6c29ce072c19448ea579&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/asciidoctor/jekyll-asciidoc/issues/182" target="_blank" rel="noopener"
 &gt;https://github.com/asciidoctor/jekyll-asciidoc/issues/182&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Jekyll + Docker で静的サイトを作成する</title><link>https://blog-0847c6.gitlab.io/posts/2024/09/11/jekyll-docker/</link><pubDate>Wed, 11 Sep 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/09/11/jekyll-docker/</guid><description>&lt;p&gt;一番基本的なところを試してみたかっただけなのですが、嵌ったのでメモしておきます。&lt;/p&gt;
&lt;p&gt;公式の Docker イメージは以下のようなのでこれを使いますが、長い間メンテナンスされていないようです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://hub.docker.com/r/jekyll/jekyll/" target="_blank" rel="noopener"
 &gt;https://hub.docker.com/r/jekyll/jekyll/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Ubuntu 20.04&lt;/li&gt;
&lt;li&gt;docker 24.0.7&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="新規作成"&gt;&lt;a href="#%e6%96%b0%e8%a6%8f%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;新規作成
&lt;/h2&gt;&lt;p&gt;まずはドキュメントに従って、以下のコマンドでブログを新規作成してみます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;site_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-blog&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --rm &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --volume&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;:/srv/jekyll&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -it jekyll/jekyll &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sh -c &lt;span class="s2"&gt;&amp;#34;chown -R jekyll /usr/gem/ &amp;amp;&amp;amp; jekyll new &lt;/span&gt;&lt;span class="nv"&gt;$site_name&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$site_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以下のエラーが出て失敗します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/usr/local/lib/ruby/3.1.0/fileutils.rb:243:in `mkdir&amp;#39;: Permission denied @ dir_s_mkdir - /srv/jekyll/my-blog (Errno::EACCES)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これでかなり嵌ったのですが、以下の記事を見つけました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://stackoverflow.com/questions/57503011/unable-to-build-cloned-jekyll-site-jekyll-3-8-5-error-permission-denied-d" target="_blank" rel="noopener"
 &gt;https://stackoverflow.com/questions/57503011/unable-to-build-cloned-jekyll-site-jekyll-3-8-5-error-permission-denied-d&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;どうやら環境変数を指定すればいいそうです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;site_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-blog&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;rm&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;JEKYLL_UID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1001&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;JEKYLL_GID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1001&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;$PWD:/srv/jekyll&amp;#34;&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;jekyll&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jekyll&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;chown -R jekyll /usr/gem/ &amp;amp;&amp;amp; jekyll new $site_name&amp;#34;&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;site_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで、&lt;code&gt;my-blog&lt;/code&gt; というフォルダが作成され、中に Jekyll のブログの雛形が作成されています。&lt;/p&gt;
&lt;h2 id="ビルド"&gt;&lt;a href="#%e3%83%93%e3%83%ab%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;ビルド
&lt;/h2&gt;&lt;p&gt;上記で作成した内容をビルドして静的サイトを生成します。&lt;br&gt;
引き続き、環境変数を指定したうえでドキュメント通りに以下を実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;site_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-blog&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;rm&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;JEKYLL_UID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1001&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;JEKYLL_GID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1001&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;$PWD/$site_name:/srv/jekyll&amp;#34;&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;jekyll&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jekyll&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;jekyll&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;my-blog&lt;/code&gt; の中に &lt;code&gt;_site&lt;/code&gt; というフォルダが出力されました。&lt;/p&gt;
&lt;h2 id="サーバー起動"&gt;&lt;a href="#%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e8%b5%b7%e5%8b%95" class="header-anchor"&gt;&lt;/a&gt;サーバー起動
&lt;/h2&gt;&lt;p&gt;次はサーバーを起動してブラウザからアクセスしてみます。&lt;br&gt;
こちらも引き続き、環境変数を指定したうえでドキュメント通りに以下を実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;site_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-blog&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;rm&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;JEKYLL_UID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1001&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;JEKYLL_GID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1001&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;$PWD/$site_name:/srv/jekyll&amp;#34;&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;jekyll&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jekyll&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;jekyll&lt;/span&gt; &lt;span class="n"&gt;serve&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;force_polling&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;livereload&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以下のエラーが出ました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;site_ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rubygems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;core_ext&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;kernel_require&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;: cannot load such file -- webrick (LoadError)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;webrick がないそうなので、&lt;code&gt;my-blog&lt;/code&gt; 内の &lt;code&gt;Gemfile&lt;/code&gt; に以下を追加します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gem &amp;#34;webrick&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで上記のコマンドを実行すれば無事サーバーが起動し、&lt;code&gt;http://localhost:4000&lt;/code&gt; にアクセスすることで閲覧できました。&lt;/p&gt;
&lt;h2 id="所感"&gt;&lt;a href="#%e6%89%80%e6%84%9f" class="header-anchor"&gt;&lt;/a&gt;所感
&lt;/h2&gt;&lt;p&gt;公式の Docker イメージ使って基本的なことを確認したかっただけなのに全然動かねぇじゃんって思いました。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://stackoverflow.com/questions/57503011/unable-to-build-cloned-jekyll-site-jekyll-3-8-5-error-permission-denied-d" target="_blank" rel="noopener"
 &gt;https://stackoverflow.com/questions/57503011/unable-to-build-cloned-jekyll-site-jekyll-3-8-5-error-permission-denied-d&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>asciidoctor-pdf で admonition のアイコンを別の画像に差し替える</title><link>https://blog-0847c6.gitlab.io/posts/2024/09/09/asciidoctor-pdf/</link><pubDate>Mon, 09 Sep 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/09/09/asciidoctor-pdf/</guid><description>&lt;p&gt;アイコン画像を別で用意して、それに差し替える方法です。&lt;/p&gt;
&lt;p&gt;ドキュメント内で以下のように記述して、アイコンを画像ベースの設定に変更します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;:icons: image
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そのうえで、PDF 作成用のテーマファイルで以下のように画像を指定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;admonition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# NOTEのアイコン画像のパスを指定&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;caution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# CAUTIONのアイコン画像のパスを指定&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.asciidoctor.org/asciidoc/latest/macros/icons-image/" target="_blank" rel="noopener"
 &gt;https://docs.asciidoctor.org/asciidoc/latest/macros/icons-image/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.asciidoctor.org/pdf-converter/latest/theme/admonition/" target="_blank" rel="noopener"
 &gt;https://docs.asciidoctor.org/pdf-converter/latest/theme/admonition/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[PySide] Windows で実行するとオーバーフローエラーが発生</title><link>https://blog-0847c6.gitlab.io/posts/2024/08/30/pyside/</link><pubDate>Fri, 30 Aug 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/08/30/pyside/</guid><description>&lt;p&gt;PySide6 で作成したアプリを Pyinstaller で exe 化して実行すると、オーバーフローのエラーが発生しました。&lt;/p&gt;
&lt;p&gt;エラーの内容は以下です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;OverflowError: Python int too large to convert to C long
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;該当箇所のコードは、以下のように &lt;code&gt;QLineChart&lt;/code&gt; を使ってグラフを作成している箇所でした。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;series&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QLineSeries&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 省略...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qdt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QDateTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qdt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setSecsSinceEpoch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;series&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qdt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toMSecsSinceEpoch&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;toMSecsSinceEpoch()&lt;/code&gt; はエポックタイムをミリ秒で返す関数です。&lt;br&gt;
これを &lt;code&gt;append&lt;/code&gt; 関数に渡すと、32bit の範囲を超えているとしてエラーが発生していました。&lt;/p&gt;
&lt;p&gt;ビルド環境も実行環境も 64bit なのに、何故 32bit の &lt;code&gt;long int&lt;/code&gt; として扱われているのか？&lt;br&gt;
調べてみたところ、以下の記事に辿り着きました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://stackoverflow.com/questions/72568201/why-overflowerror-occured-only-on-pyside6" target="_blank" rel="noopener"
 &gt;https://stackoverflow.com/questions/72568201/why-overflowerror-occured-only-on-pyside6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;どうやら &lt;code&gt;float&lt;/code&gt; でキャストすれば良さそうということで、以下のように修正したところ、正常に動作するようになりました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;series&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qdt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toMSecsSinceEpoch&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://stackoverflow.com/questions/72568201/why-overflowerror-occured-only-on-pyside6" target="_blank" rel="noopener"
 &gt;https://stackoverflow.com/questions/72568201/why-overflowerror-occured-only-on-pyside6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[python] pipenv で無関係のパッケージが勝手にアップデートされる</title><link>https://blog-0847c6.gitlab.io/posts/2024/07/17/python/</link><pubDate>Wed, 17 Jul 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/07/17/python/</guid><description>&lt;p&gt;pipenv でパッケージをインストールしたときに、全く関係ないパッケージが勝手にアップデートされて困ったことがありました。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--keep-outdated&lt;/code&gt; を付与すればいいという情報もありますが、現在の pipenv ではこのオプションは削除されています。&lt;/p&gt;
&lt;p&gt;とりあえず以下のようにして回避しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. &lt;code&gt;Pipfile&lt;/code&gt; 内の全てのパッケージのバージョンを指定&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Pipfile&lt;/code&gt; をエディタで開き、でバージョンを指定していなかったパッケージに全てバージョンを記入しました。&lt;br&gt;
バージョンは、&lt;code&gt;Pipfile.lock&lt;/code&gt; を参照して、現在インストールされているバージョンを記入しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. すべてのパッケージをアンインストール&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pipenv uninstall --all
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3. &lt;code&gt;Pipfile.lock&lt;/code&gt; を削除&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ rm Pipfile.lock
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;4. 新しい依存関係をインストール&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pipenv install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;</description></item><item><title>Shotcut でフリーズフレームを入れる</title><link>https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/</link><pubDate>Sat, 06 Jul 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/</guid><description>&lt;p&gt;動画編集ソフトの Shotcut にはフレーズフレーム機能はありませんが、以下のようにすることで簡単にフリーズフレームを入れることができます。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Shotcut 24.06.26&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;図中の動画は以下のサイトから適当にダウンロードしてきました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://pixabay.com/ja/" target="_blank" rel="noopener"
 &gt;https://pixabay.com/ja/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="やり方"&gt;&lt;a href="#%e3%82%84%e3%82%8a%e6%96%b9" class="header-anchor"&gt;&lt;/a&gt;やり方
&lt;/h2&gt;&lt;p&gt;フリーズフレームを入れたい場所に再生ヘッドを移動し、「再生ヘッドで分割する」を選択します。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="394px" data-flex-grow="164" height="1192" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/01.webp" srcset="https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/01_hu_13c47485009a3bb9.webp 800w, https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/01_hu_13b5569e1b3d2054.webp 1600w, https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/01.webp 1959w" width="1959"&gt;&lt;/p&gt;
&lt;p&gt;「ファイル &amp;gt; 書き出し &amp;gt; フレーム」で、フレームを静止画としてエクスポートします。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="394px" data-flex-grow="164" height="1192" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/02.webp" srcset="https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/02_hu_5bb43a42897a0304.webp 800w, https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/02_hu_260ae78f37f07176.webp 1600w, https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/02.webp 1959w" width="1959"&gt;&lt;/p&gt;
&lt;p&gt;エクスポートした静止画を取り込み、それを分割した動画の間に挿入します。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="394px" data-flex-grow="164" height="1192" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/03.webp" srcset="https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/03_hu_583c6a7187ad788f.webp 800w, https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/03_hu_acd59012dd79302.webp 1600w, https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/03.webp 1959w" width="1959"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="394px" data-flex-grow="164" height="1192" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/04.webp" srcset="https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/04_hu_5e94c474bed7aabe.webp 800w, https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/04_hu_5432112a7badea80.webp 1600w, https://blog-0847c6.gitlab.io/posts/2024/07/06/shotcut/04.webp 1959w" width="1959"&gt;&lt;/p&gt;
&lt;p&gt;あとは、挿入した静止画を選択し、右クリックして「プロパティ」を開き、長さを変更します。&lt;/p&gt;</description></item><item><title>redis コンテナでの redis-server の起動方法による違い</title><link>https://blog-0847c6.gitlab.io/posts/2024/06/27/redis/</link><pubDate>Thu, 27 Jun 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/06/27/redis/</guid><description>&lt;p&gt;redis の公式のイメージを docker compose で動かしていたのですが、&lt;code&gt;command&lt;/code&gt; を指定しない場合のデフォルトの実行コマンドは &lt;code&gt;redis-server&lt;/code&gt; で、この場合、コンテナを再起動してもデータが残っていました。&lt;/p&gt;
&lt;p&gt;しかし、コマンドを &lt;code&gt;command: sh -c &amp;quot;redis-server&amp;quot;&lt;/code&gt; としたところ、コンテナ再起動でデータがクリアされたので、両者の違いについて ChatGPT に聞いてみました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;command: &amp;quot;redis-server&amp;quot;:&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;この設定では、単純に redis-server コマンドが実行されます。Docker はこのコマンドを直接実行し、Redis サーバーが起動します。この場合、Redis サーバーが直接起動されるため、Redis のデフォルトの動作が適用され、データが残ります。再起動してもデータがクリアされないのは、Redis サーバーが正しく起動し、データをインメモリに保持しているためです。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;code&gt;command: sh -c &amp;quot;redis-server&amp;quot;:&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一方、この設定では、sh -c コマンドを使用してシェルでコマンドを実行します。sh -c コマンドは、指定されたコマンドをシェル経由で実行します。この場合、redis-server コマンドがシェル経由で実行されるため、Docker はシェルプロセスを起動し、そのシェルプロセスが redis-server コマンドを実行します。この場合、シェルプロセスがメインプロセスとなり、redis-server がそのサブプロセスとして実行されます。そのため、正しくプロセスが管理されない可能性があり、コンテナの再起動時にデータがクリアされる可能性があります。&lt;/p&gt;</description></item><item><title>[PySide] qasync を使って非同期処理をバックグランドで行う</title><link>https://blog-0847c6.gitlab.io/posts/2024/04/22/pyside/</link><pubDate>Mon, 22 Apr 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/04/22/pyside/</guid><description>&lt;p&gt;PySide6 で GUI アプリを作成している中で、I/O バウンドな処理の完了を待っていると GUI が固まりました。&lt;/p&gt;
&lt;p&gt;通常、バックグラウンドで何か処理を行う際に GUI の処理を止めないようにするために、QThread などを使って別スレッドで処理を行いつつ GUI スレッドを回したりします。&lt;br&gt;
今回もそうやって作っていたのですが、完了までに時間のかかる I/O バウンドな処理を行わせたい場合、上手くいかない場合がありました。
I/O バウンドな処理なので、ayncio を使って非同期処理にしてやればいいと思ったのですが、Qt のイベントループと asyncio を適切に統合する必要があるようで、どのように記述すればいいのかいまいち分かりませんでした。&lt;/p&gt;
&lt;p&gt;そんな中、&lt;code&gt;qasync&lt;/code&gt; というライブラリを使えば、とても簡単に処理を組み込むことができました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/CabbageDevelopment/qasync" target="_blank" rel="noopener"
 &gt;https://github.com/CabbageDevelopment/qasync&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;コードの記述も、QThread を使う場合に比べシンプルでスッキリします。&lt;/p&gt;
&lt;p&gt;ちなみに、&lt;code&gt;asyncqt&lt;/code&gt; というライブラリもありますが、こちらは既にメンテナンスされていないようです。
&lt;code&gt;qasync&lt;/code&gt; は &lt;code&gt;asyncqt&lt;/code&gt; のフォークで、現在でもメンテナンスされているようなので、使うなら &lt;code&gt;qasync&lt;/code&gt; のほうが良いと思います。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;python 3.11&lt;/li&gt;
&lt;li&gt;pyside6 6.6.3.1&lt;/li&gt;
&lt;li&gt;qasync 0.27.1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="サンプルコード"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;サンプルコード
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;PySide6.QtWidgets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;QApplication&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QMainWindow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QPushButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QVBoxLayout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QWidget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QLabel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;qasync&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;QEventLoop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;asyncSlot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QMainWindow&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setWindowTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;qasync sample&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Press the button.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QPushButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Start&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clicked&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on_button_clicked&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QVBoxLayout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QWidget&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setCentralWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@asyncSlot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_button_clicked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;waiting...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# I/O バウンドな処理を想定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Press the button.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QEventLoop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_event_loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MainWindow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/CabbageDevelopment/qasync" target="_blank" rel="noopener"
 &gt;https://github.com/CabbageDevelopment/qasync&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ubuntu のユーザー名を変更する</title><link>https://blog-0847c6.gitlab.io/posts/2024/04/02/ubuntu/</link><pubDate>Tue, 02 Apr 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/04/02/ubuntu/</guid><description>&lt;p&gt;Ubuntu 20.04 で確認しました。&lt;/p&gt;
&lt;h2 id="新しいユーザーを作成する"&gt;&lt;a href="#%e6%96%b0%e3%81%97%e3%81%84%e3%83%a6%e3%83%bc%e3%82%b6%e3%83%bc%e3%82%92%e4%bd%9c%e6%88%90%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;新しいユーザーを作成する
&lt;/h2&gt;&lt;p&gt;ログインユーザー自身のユーザー名は変更できないので、一時的に管理者権限を持ったユーザーを作成します。&lt;/p&gt;
&lt;p&gt;Ubuntu の場合は以下のように GUI で簡単に追加できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;設定 &amp;gt; ユーザー &amp;gt; ユーザーを追加&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ユーザー名とグループ名の変更"&gt;&lt;a href="#%e3%83%a6%e3%83%bc%e3%82%b6%e3%83%bc%e5%90%8d%e3%81%a8%e3%82%b0%e3%83%ab%e3%83%bc%e3%83%97%e5%90%8d%e3%81%ae%e5%a4%89%e6%9b%b4" class="header-anchor"&gt;&lt;/a&gt;ユーザー名とグループ名の変更
&lt;/h2&gt;&lt;p&gt;作成した新しいユーザーでログインして行います。&lt;/p&gt;
&lt;h3 id="ユーザー名の変更"&gt;&lt;a href="#%e3%83%a6%e3%83%bc%e3%82%b6%e3%83%bc%e5%90%8d%e3%81%ae%e5%a4%89%e6%9b%b4" class="header-anchor"&gt;&lt;/a&gt;ユーザー名の変更
&lt;/h3&gt;&lt;p&gt;以下のコマンドを実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo usermod -l new_username -d /home/new_username -m old_username
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;尚、&lt;code&gt;usermod&lt;/code&gt; コマンドの &lt;code&gt;-g&lt;/code&gt; オプションでグループ名も一緒に変更できるような記述も見つけましたが、私の場合、&lt;code&gt;usermod: グループ 'new_username' は存在しません&lt;/code&gt; のエラーが表示されてできなかったため、ユーザー名とグループ名の変更を分けて行いました。&lt;/p&gt;
&lt;h3 id="グループ名の変更"&gt;&lt;a href="#%e3%82%b0%e3%83%ab%e3%83%bc%e3%83%97%e5%90%8d%e3%81%ae%e5%a4%89%e6%9b%b4" class="header-anchor"&gt;&lt;/a&gt;グループ名の変更
&lt;/h3&gt;&lt;p&gt;以下のコマンドを実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo groupmod -n new_username old_username
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以上で、変更後のユーザーでログインして問題なく使えることを確認しました。&lt;br&gt;
ただ、唯一、ユーザーのアイコン画像だけがクリアされていました。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://zenn.dev/creationup2u/articles/1d863f40fec16a" target="_blank" rel="noopener"
 &gt;https://zenn.dev/creationup2u/articles/1d863f40fec16a&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://minory.org/linux-usermod.html" target="_blank" rel="noopener"
 &gt;https://minory.org/linux-usermod.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Docker] Python の Windows コンテナを動かしてみた</title><link>https://blog-0847c6.gitlab.io/posts/2024/03/18/docker-python/</link><pubDate>Mon, 18 Mar 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/03/18/docker-python/</guid><description>&lt;p&gt;ホストもコンテナも Windows になるので、Dockerfile の記述方法や、コンテナ起動時のオプションの指定方法なども Linux とは異なります。&lt;/p&gt;
&lt;p&gt;Windows 上で Docker を (Docker Desktop を使わずに) 動かす方法については以下を参照してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2023/11/docker-windows.html" target="_blank" rel="noopener"
 &gt;https://kuttsun.blogspot.com/2023/11/docker-windows.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そのうえで、今回 Python の Windows コンテナを動かしてみました。&lt;/p&gt;
&lt;p&gt;Docker Hub にある Python の Windows コンテナとしては、&lt;code&gt;windowsservercore-ltsc2022&lt;/code&gt; と &lt;code&gt;windowsservercore-1809&lt;/code&gt; があるようです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://hub.docker.com/_/python" target="_blank" rel="noopener"
 &gt;https://hub.docker.com/_/python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回は &lt;code&gt;python:3.11-windowsservercore-1809&lt;/code&gt; のイメージを使いました。&lt;/p&gt;
&lt;h2 id="dockerfile-のサンプル"&gt;&lt;a href="#dockerfile-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;Dockerfile のサンプル
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;FROM python:3.11-windowsservercore-1809
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CMD &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cmd.exe&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Linux コンテナでは &lt;code&gt;CMD [ &amp;quot;/bin/bash&amp;quot; ]&lt;/code&gt; のように記述していましたが、Windows コンテナでは &lt;code&gt;CMD [&amp;quot;cmd.exe&amp;quot;]&lt;/code&gt; または &lt;code&gt;CMD [&amp;quot;powershell.exe&amp;quot;]&lt;/code&gt; のように記述します。&lt;/p&gt;
&lt;h2 id="コンテナ起動例"&gt;&lt;a href="#%e3%82%b3%e3%83%b3%e3%83%86%e3%83%8a%e8%b5%b7%e5%8b%95%e4%be%8b" class="header-anchor"&gt;&lt;/a&gt;コンテナ起動例
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; docker run -it --rm ^
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name コンテナ名 ^
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v %CD%&lt;span class="se"&gt;\w&lt;/span&gt;orkspace:C:&lt;span class="se"&gt;\w&lt;/span&gt;orkspace ^
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --workdir&lt;span class="o"&gt;=&lt;/span&gt;C:&lt;span class="se"&gt;\w&lt;/span&gt;orkspace ^
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; イメージ名
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Linux ではカレントディレクトリを指定するために &lt;code&gt;$(pwd)&lt;/code&gt; と記述したりしていましたが、Windows なので &lt;code&gt;%CD%&lt;/code&gt; と記述します。&lt;br&gt;
パスの区切りは &lt;code&gt;\(バックスラッシュ)&lt;/code&gt; になります。&lt;br&gt;
コマンド途中での改行も、Linux ではバックスラッシュでしたが、Windows なので &lt;code&gt;^&lt;/code&gt; になります。&lt;br&gt;
また、Windows コンテナなので、マウント先のパスも C ドライブからのパスで記述します。&lt;/p&gt;
&lt;p&gt;とりあえずここまで。&lt;br&gt;
追々いろいろ追記するかもしれません。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/ishibashi-futoshi/items/db807d64624f43be1be9" target="_blank" rel="noopener"
 &gt;https://qiita.com/ishibashi-futoshi/items/db807d64624f43be1be9&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>YOLOv8 を動かそうとしたら ImportError: libGL.so.1: cannot open shared object file: No such file or directory のエラーが出た</title><link>https://blog-0847c6.gitlab.io/posts/2024/02/28/yolov8/</link><pubDate>Wed, 28 Feb 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/02/28/yolov8/</guid><description>&lt;p&gt;python で YOLOv8 を動かそうとしたら以下のエラーが出ました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from ultralytics import YOLO
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Traceback (most recent call last):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/workspace/yolov8/test1.py&amp;#34;, line 1, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; from ultralytics import YOLO
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/usr/local/lib/python3.11/site-packages/ultralytics/__init__.py&amp;#34;, line 5, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; from ultralytics.data.explorer.explorer import Explorer
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/usr/local/lib/python3.11/site-packages/ultralytics/data/__init__.py&amp;#34;, line 3, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; from .base import BaseDataset
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/usr/local/lib/python3.11/site-packages/ultralytics/data/base.py&amp;#34;, line 12, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; import cv2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/usr/local/lib/python3.11/site-packages/cv2/__init__.py&amp;#34;, line 181, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; bootstrap()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/usr/local/lib/python3.11/site-packages/cv2/__init__.py&amp;#34;, line 153, in bootstrap
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; native_module = importlib.import_module(&amp;#34;cv2&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/usr/local/lib/python3.11/importlib/__init__.py&amp;#34;, line 126, in import_module
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return _bootstrap._gcd_import(name[level:], package, level)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ImportError: libGL.so.1: cannot open shared object file: No such file or directory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このエラーは、OpenCV が GPU の OpenGL ライブラリを見つけられないことが原因で起きているエラーのようです。&lt;/p&gt;
&lt;p&gt;YOLOv8 (ultralytics) をインストールすると依存関係にある OpenCV もインストールされるようですが、以下のページによれば、検出結果の可視化などを行ったりする場合のみ OpenCV が必要で、他のコア機能は OpenCV に依存しないとあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ultralytics/ultralytics/issues/2179" target="_blank" rel="noopener"
 &gt;https://github.com/ultralytics/ultralytics/issues/2179&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ultralytics/ultralytics/pull/3480" target="_blank" rel="noopener"
 &gt;https://github.com/ultralytics/ultralytics/pull/3480&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;しかし、私の場合、検出結果の可視化とか何もしていない、というかそもそも最初の import 文のところでエラーになってしまっています。&lt;/p&gt;
&lt;p&gt;尚、&lt;code&gt;opencv-python&lt;/code&gt; ではなく、&lt;code&gt;opencv-python-headless&lt;/code&gt; をインストールすれば解決できる場合もあるそうですが、私の場合、それでも上記のエラーが発生しました。&lt;/p&gt;
&lt;p&gt;仕方がないので、OpenGL のライブラリをインストールして解決しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo apt install -y libgl1-mesa-glx libglib2.0-0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://zenn.dev/techmadot/articles/opengl4-on-wsl" target="_blank" rel="noopener"
 &gt;https://zenn.dev/techmadot/articles/opengl4-on-wsl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ultralytics/ultralytics/tree/main" target="_blank" rel="noopener"
 &gt;https://github.com/ultralytics/ultralytics/tree/main&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.ultralytics.com/ja/quickstart/" target="_blank" rel="noopener"
 &gt;https://docs.ultralytics.com/ja/quickstart/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] Iris データセットを Pandas で読み込む</title><link>https://blog-0847c6.gitlab.io/posts/2024/02/21/python/</link><pubDate>Wed, 21 Feb 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/02/21/python/</guid><description>&lt;p&gt;機械学習のサンプルデータとしてよく使われるものの一つに Iris（アヤメ）のデータセットがあります。その読み込み方法です。&lt;/p&gt;
&lt;p&gt;Iris のデータセットを取得する方法自体はいくつかあるようです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://py-memo.com/python/load-iris/" target="_blank" rel="noopener"
 &gt;https://py-memo.com/python/load-iris/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回は Iris のデータは機械学習用の定番のライブラリである &lt;code&gt;scikit-learn&lt;/code&gt; を使いました。&lt;/p&gt;
&lt;h2 id="サンプルコード"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;サンプルコード
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sklearn.datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_iris&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;iris&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_iris&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df_iris&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iris&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;iris&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feature_names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 目的変数である花の種類（target）のカラムを作成（花の種類を数値から文字列に変換して追加）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df_iris&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iris&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;iris&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df_iris&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sepal length &lt;span class="o"&gt;(&lt;/span&gt;cm&lt;span class="o"&gt;)&lt;/span&gt; sepal width &lt;span class="o"&gt;(&lt;/span&gt;cm&lt;span class="o"&gt;)&lt;/span&gt; petal length &lt;span class="o"&gt;(&lt;/span&gt;cm&lt;span class="o"&gt;)&lt;/span&gt; petal width &lt;span class="o"&gt;(&lt;/span&gt;cm&lt;span class="o"&gt;)&lt;/span&gt; target
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;0&lt;/span&gt; 5.1 3.5 1.4 0.2 setosa
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;1&lt;/span&gt; 4.9 3.0 1.4 0.2 setosa
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;2&lt;/span&gt; 4.7 3.2 1.3 0.2 setosa
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;3&lt;/span&gt; 4.6 3.1 1.5 0.2 setosa
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;4&lt;/span&gt; 5.0 3.6 1.4 0.2 setosa
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;.. ... ... ... ... ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;145&lt;/span&gt; 6.7 3.0 5.2 2.3 virginica
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;146&lt;/span&gt; 6.3 2.5 5.0 1.9 virginica
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;147&lt;/span&gt; 6.5 3.0 5.2 2.0 virginica
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;148&lt;/span&gt; 6.2 3.4 5.4 2.3 virginica
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;149&lt;/span&gt; 5.9 3.0 5.1 1.8 virginica
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;150&lt;/span&gt; rows x &lt;span class="m"&gt;5&lt;/span&gt; columns&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;load_iris&lt;/code&gt; 関数で呼び出されたデータセットは numpy 形式です。&lt;br&gt;
これを扱いやすいように Pandas でデータフレームに変換しています。&lt;br&gt;
また、&lt;code&gt;load_iris&lt;/code&gt; 関数では、説明変数は &lt;code&gt;iris.data&lt;/code&gt;、目的変数は &lt;code&gt;iris.target&lt;/code&gt; に実装されています。&lt;br&gt;
カラム名は &lt;code&gt;iris.feature_names&lt;/code&gt; に入っています。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;iris.target&lt;/code&gt; は花の種類を数値として保持しており、その数値に対応した花の名前は &lt;code&gt;iris.target_names&lt;/code&gt; に定義されています。&lt;br&gt;
花の種類をカラムに追加する際には文字列に変換して追加しています。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://py-memo.com/python/load-iris/" target="_blank" rel="noopener"
 &gt;https://py-memo.com/python/load-iris/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/ao_log/items/fe9bd42fd249c2a7ee7a" target="_blank" rel="noopener"
 &gt;https://qiita.com/ao_log/items/fe9bd42fd249c2a7ee7a&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://py-memo.com/python/load-iris/" target="_blank" rel="noopener"
 &gt;https://py-memo.com/python/load-iris/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://aiacademy.jp/texts/show/?id=90" target="_blank" rel="noopener"
 &gt;https://aiacademy.jp/texts/show/?id=90&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>WSL で使用しているディスクスペースを解放する</title><link>https://blog-0847c6.gitlab.io/posts/2024/02/20/wsl/</link><pubDate>Tue, 20 Feb 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/02/20/wsl/</guid><description>&lt;p&gt;WSL 上の Ubuntu で docker を使っていたのですが、ストレージの空き容量が少なくなってきたので docker イメージを削除しても空き容量が変化しませんでした。&lt;/p&gt;
&lt;p&gt;調べてみたところ、どうやら仮想ディスクの最適化まで行わないとディスクスペースは解放されないようです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://01futabato10.hateblo.jp/entry/2022/12/02/095031" target="_blank" rel="noopener"
 &gt;https://01futabato10.hateblo.jp/entry/2022/12/02/095031&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/siruku6/items/c91a40d460095013540d" target="_blank" rel="noopener"
 &gt;https://qiita.com/siruku6/items/c91a40d460095013540d&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ただ、私の PC はストレージ容量が少なく、頻繁に Docker イメージを消して容量を確保しているため、都度コマンドを打つのは面倒ということで、スクリプト化しました。&lt;/p&gt;
&lt;p&gt;コマンドとしては、diskpart を使う方法と、Optimize-VHD を使う方法があるみたいですが、Optimize-VHD は Hyper-V を有効化する必要があり、Windows Home では使えないということで、今回は diskpart を使うことにしました。&lt;/p&gt;
&lt;p&gt;diskpart でスクリプトを実行する方法は以下に記載されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/diskpart-scripts-and-examples" target="_blank" rel="noopener"
 &gt;https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/diskpart-scripts-and-examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="サンプル"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;サンプル
&lt;/h2&gt;&lt;p&gt;まずは diskpart で実行するスクリプトを作成します（ここでは &lt;code&gt;sample.txt&lt;/code&gt; としました）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;select vdisk file=&amp;#34;%USERPROFILE%\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;attach vdisk readonly
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;compact vdisk
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;detach vdisk
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;file&lt;/code&gt; のパスは環境によって異なると思うので、以下を参考に調べてください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://01futabato10.hateblo.jp/entry/2022/12/02/095031" target="_blank" rel="noopener"
 &gt;https://01futabato10.hateblo.jp/entry/2022/12/02/095031&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そのうえで、以下のバッチファイルを作成します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wsl --shutdown
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;diskpart /s sample.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;あとはこのバッチファイルを実行するだけで OK です。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://01futabato10.hateblo.jp/entry/2022/12/02/095031" target="_blank" rel="noopener"
 &gt;https://01futabato10.hateblo.jp/entry/2022/12/02/095031&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/siruku6/items/c91a40d460095013540d" target="_blank" rel="noopener"
 &gt;https://qiita.com/siruku6/items/c91a40d460095013540d&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://dev.classmethod.jp/articles/windows-virtual-disk-compression/" target="_blank" rel="noopener"
 &gt;https://dev.classmethod.jp/articles/windows-virtual-disk-compression/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[python] ONVIF 対応カメラの RTSP 接続文字列を取得する</title><link>https://blog-0847c6.gitlab.io/posts/2024/02/15/rtsp/</link><pubDate>Thu, 15 Feb 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/02/15/rtsp/</guid><description>&lt;p&gt;ネットワークカメラの映像を取得するためにまず RTSP の接続文字列を取得する必要があったので、ONVIF の Profile S から取得してみました。&lt;/p&gt;
&lt;p&gt;ONVIF Profile S の仕様は以下にあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.onvif.org/profiles/specifications/" target="_blank" rel="noopener"
 &gt;https://www.onvif.org/profiles/specifications/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尚、単純に RTSP の接続文字列を取得したいだけなら ONVIF Device Manager というツールがあるので、それを使ったほうが楽です。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;python 3.11&lt;/li&gt;
&lt;li&gt;onvif-zeep 0.2.12&lt;/li&gt;
&lt;li&gt;onvif2-zeep 0.3.4&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ONVIF クライアントの python 実装である &lt;code&gt;onvif-zeep&lt;/code&gt; &lt;code&gt;onvif2-zeep&lt;/code&gt; を使ってみました。&lt;br&gt;
この２つの違いですが、以下のページによれば、&lt;code&gt;onvif2-zeep&lt;/code&gt; のほうは WSDL と H.265 に対応しているようです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://pypi.org/project/onvif2-zeep/" target="_blank" rel="noopener"
 &gt;https://pypi.org/project/onvif2-zeep/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下、&lt;code&gt;onvif-zeep&lt;/code&gt; &lt;code&gt;onvif2-zeep&lt;/code&gt; それぞれのサンプルコードです。&lt;/p&gt;
&lt;h2 id="onvif-zeep-でのサンプル"&gt;&lt;a href="#onvif-zeep-%e3%81%a7%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;onvif-zeep でのサンプル
&lt;/h2&gt;&lt;h3 id="準備"&gt;&lt;a href="#%e6%ba%96%e5%82%99" class="header-anchor"&gt;&lt;/a&gt;準備
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install onvif-zeep
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="サンプルコード"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;サンプルコード
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;onvif&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ONVIFCamera&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_all_rtsp_urls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;camera_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# ONVIFデバイスに接続&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ONVIFCamera&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;camera_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# プロファイルを取得&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;media&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;camera&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_media_service&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;profiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetProfiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;#print(profiles)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# すべてのプロファイルに対して RTSP URL を取得&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;token&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stream_uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetStreamUri&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;StreamSetup&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Stream&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;RTP-Unicast&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Transport&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Protocol&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;RTSP&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;ProfileToken&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream_uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;camera_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;192.168.0.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;get_all_rtsp_urls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;camera_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="onvif2-zeep-のサンプル"&gt;&lt;a href="#onvif2-zeep-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;onvif2-zeep のサンプル
&lt;/h2&gt;&lt;h3 id="準備-1"&gt;&lt;a href="#%e6%ba%96%e5%82%99-1" class="header-anchor"&gt;&lt;/a&gt;準備
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install onvif2-zeep
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="wsdl-のダウンロード"&gt;&lt;a href="#wsdl-%e3%81%ae%e3%83%80%e3%82%a6%e3%83%b3%e3%83%ad%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;WSDL のダウンロード
&lt;/h4&gt;&lt;p&gt;&lt;code&gt;onvif2-zeep&lt;/code&gt; を使用する場合、WSDL のファイル一式が必要なようです。&lt;br&gt;
以下のリポジトリからダウンロードできます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/onvif/specs" target="_blank" rel="noopener"
 &gt;https://github.com/onvif/specs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="サンプルコード-1"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89-1" class="header-anchor"&gt;&lt;/a&gt;サンプルコード
&lt;/h3&gt;&lt;p&gt;上記のコードから以下の２箇所を変更するだけです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from onvif2 import ONVIFCamera
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;camera = ONVIFCamera(camera_ip, 80, username, password, &amp;#39;./wsdl&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;ONVIFCamera&lt;/code&gt; の引数の最後で、WSDL ファイルのあるパスを指定します。&lt;/p&gt;
&lt;h2 id="実行結果"&gt;&lt;a href="#%e5%ae%9f%e8%a1%8c%e7%b5%90%e6%9e%9c" class="header-anchor"&gt;&lt;/a&gt;実行結果
&lt;/h2&gt;&lt;p&gt;Panasonic のカメラで試した結果が以下となります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;H264_1280x960: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile8
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;H264_800x600: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile7
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;H264_640x480: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile6
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;H264_320x240: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;JPEG_1280x960: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;JPEG_800x600: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;JPEG_640x480: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;JPEG_320x240: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ただ、H.265 のストリームがあるカメラ場合、&lt;code&gt;onvif-zeep&lt;/code&gt; &lt;code&gt;onvif2-zeep&lt;/code&gt; のどちらで試しても以下のように &lt;code&gt;Unknown error: Configuration not complete&lt;/code&gt; のエラーが出て取得することができませんでした。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;H26x_1: Unknown error: Configuration not complete
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;H26x_2: Unknown error: Configuration not complete
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;JPEG_1: rtsp://192.168.0.1/ONVIF/MediaInput?profile=def_profile5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;JPEG_2: rtsp://192.168.0.1/ONVIF/MediaInput?profile=def_profile6
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;カメラ側のプロファイル設定の問題のような気がしますが、よくわかりませんでした。&lt;/p&gt;
&lt;p&gt;ちなみに、他に TOA のカメラも試しましたが、こちらは H.265 の場合でも問題なく取得することができました。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.onvif.org/profiles/specifications/" target="_blank" rel="noopener"
 &gt;https://www.onvif.org/profiles/specifications/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Gymnasium の環境を動かしてみる</title><link>https://blog-0847c6.gitlab.io/posts/2024/02/12/gymnasium/</link><pubDate>Mon, 12 Feb 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/02/12/gymnasium/</guid><description>&lt;p&gt;強化学習について勉強しようと思い、まずはサンプルとしてよく取り上げられる OpenAI の gym の CartPole などを動かそうとしてみたところ、上手く動きませんでした。&lt;br&gt;
調べてみたところ、gym は現在ではもう更新されておらず、代わりに gym を fork した gymnasium というのがあるようなので、こちらを使って動かしてみました。&lt;/p&gt;
&lt;p&gt;実行環境は docker を使って構築します。&lt;br&gt;
とりあえず学習・推論はせず、単純に動かすだけです。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;WSL2(Ubuntu 22.04)&lt;/li&gt;
&lt;li&gt;docker 24.0.7&lt;/li&gt;
&lt;li&gt;python 3.11&lt;/li&gt;
&lt;li&gt;swig 4.2.0&lt;/li&gt;
&lt;li&gt;gymnasium 0.29.1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="dockerfile"&gt;&lt;a href="#dockerfile" class="header-anchor"&gt;&lt;/a&gt;Dockerfile
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;FROM python:3.11
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 先に swig をインストールしておかないと gymnasium のインストールに失敗しました
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;RUN pip install swig
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;RUN pip install gymnasium[box2d]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CMD [ &amp;#34;/bin/bash&amp;#34; ]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="コンテナの起動"&gt;&lt;a href="#%e3%82%b3%e3%83%b3%e3%83%86%e3%83%8a%e3%81%ae%e8%b5%b7%e5%8b%95" class="header-anchor"&gt;&lt;/a&gt;コンテナの起動
&lt;/h3&gt;&lt;p&gt;GUI を動かすので、コンテナは以下のように起動します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -it --rm &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v &lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;/workspace:/workspace &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /etc/group:/etc/group:ro &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /etc/passwd:/etc/passwd:ro &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -u &lt;span class="k"&gt;$(&lt;/span&gt;id -u &lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id -g &lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e DISPLAY &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /tmp/.X11-unix:/tmp/.X11-unix:rw &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --workdir /workspace &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; imagename
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これについては以下が参考になりました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/Spritaro/items/f907a9b52cb78e4fbec0" target="_blank" rel="noopener"
 &gt;https://qiita.com/Spritaro/items/f907a9b52cb78e4fbec0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cartpole-のサンプル"&gt;&lt;a href="#cartpole-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;CartPole のサンプル
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;gymnasium&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;gym&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 環境を作成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# render_mode は描画モードの指定。human は人間が見てわかるように動画として表示するという意味&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gym&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;CartPole-v1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;render_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;episode&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 環境をリセット&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 行動をランダムに選択&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_space&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# これがエージェントの行動になるので、本来はAIが行動を決定するべきところ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 選択した行動を実行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reward&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;terminated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;truncated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;#print(env.render()) # 状態の可視化(human の場合は不要)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 終了した場合、次のエピソードへ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;terminated&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;truncated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Episode&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;episode&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; finished after &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; timesteps&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="337px" data-flex-grow="140" height="434" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2024/02/12/gymnasium/cartpole.webp" width="610"&gt;&lt;/p&gt;
&lt;h2 id="lunarlander-のサンプル"&gt;&lt;a href="#lunarlander-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;LunarLander のサンプル
&lt;/h2&gt;&lt;p&gt;同様に以下のようにして LunarLander も動きました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;gymnasium&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;gym&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 環境を作成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# render_mode は描画モードの指定。human は人間が見てわかるように動画として表示するという意味&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gym&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LunarLander-v2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;render_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;episode&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 環境をリセット&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 行動をランダムに選択&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_space&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# これがエージェントの行動になるので、本来はAIが行動を決定するべきところ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 選択した行動を実行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reward&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;terminated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;truncated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;#print(env.render()) # 状態の可視化(human の場合は不要)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 終了した場合、次のエピソードへ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;terminated&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;truncated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Episode&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;episode&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; finished after &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; timesteps&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="339px" data-flex-grow="141" height="431" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2024/02/12/gymnasium/lunaerlander.webp" width="609"&gt;&lt;/p&gt;
&lt;h2 id="frozenlake-のサンプル"&gt;&lt;a href="#frozenlake-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;FrozenLake のサンプル
&lt;/h2&gt;&lt;p&gt;同様に以下のようにして FrozenLake も動きました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;gymnasium&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;gym&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 環境を作成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# render_mode は描画モードの指定。human は人間が見てわかるように動画として表示するという意味&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gym&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;FrozenLake-v1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;render_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;episode&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 環境をリセット、現在の観測値（observation）と情報（info）を取得&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 行動をランダムに選択&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_space&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# これがエージェントの行動になるので、本来はAIが行動を決定するべきところ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 選択した行動を実行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reward&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;terminated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;truncated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;#print(env.render()) # 状態の可視化(human の場合は不要)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 終了した場合、次のエピソードへ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;terminated&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;truncated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Episode&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;episode&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; finished after &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; timesteps&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="221px" data-flex-grow="92" height="287" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2024/02/12/gymnasium/fronzelake.png" width="265"&gt;&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/openai/gym/issues/3240" target="_blank" rel="noopener"
 &gt;https://github.com/openai/gym/issues/3240&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://note.com/kikaben/n/n57584c49d5c2" target="_blank" rel="noopener"
 &gt;https://note.com/kikaben/n/n57584c49d5c2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/Spritaro/items/f907a9b52cb78e4fbec0" target="_blank" rel="noopener"
 &gt;https://qiita.com/Spritaro/items/f907a9b52cb78e4fbec0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://amateur-engineer-blog.com/reinforce-learning-getting-started/#toc5" target="_blank" rel="noopener"
 &gt;https://amateur-engineer-blog.com/reinforce-learning-getting-started/#toc5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Windows と Ubuntu でマウスとキーボードを共有する</title><link>https://blog-0847c6.gitlab.io/posts/2024/01/26/barrier/</link><pubDate>Fri, 26 Jan 2024 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2024/01/26/barrier/</guid><description>&lt;p&gt;Barrier というソフトを使って、マウスとキーボードを共有します。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Windows 10
&lt;ul&gt;
&lt;li&gt;barrier 2.4.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ubuntu 20.04
&lt;ul&gt;
&lt;li&gt;barrier 2.3.2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Barrier を使う場合、どちらかをサーバーとして設定する必要がありますが、今回は Windows をサーバーとしました。&lt;/p&gt;
&lt;h2 id="windows-側"&gt;&lt;a href="#windows-%e5%81%b4" class="header-anchor"&gt;&lt;/a&gt;Windows 側
&lt;/h2&gt;&lt;h3 id="インストール"&gt;&lt;a href="#%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;インストール
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://github.com/debauchee/barrier/releases" target="_blank" rel="noopener"
 &gt;GitHub の Releases&lt;/a&gt; から最新の exe をダウンロードしてインストールします。&lt;br&gt;
Bonjourというソフトをインストールするかどうか聞かれますが、インストールしませんでした。&lt;/p&gt;
&lt;h3 id="設定"&gt;&lt;a href="#%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;設定
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;「サーバー」にチェックを入れる&lt;/li&gt;
&lt;li&gt;「サーバーの構成設定」を選択し、「モニタの結びつき」で任意のマスをクリックして、クライアント側のモニターを追加する
&lt;ul&gt;
&lt;li&gt;モニター名を後述のクライアント側の名前に合わせて入力する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;メニューバーから、「Barrier &amp;gt; 設定の変更」を選択し、「SSL を使用」のチェックを外す。&lt;/li&gt;
&lt;li&gt;開始を押す&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ubuntu-側"&gt;&lt;a href="#ubuntu-%e5%81%b4" class="header-anchor"&gt;&lt;/a&gt;Ubuntu 側
&lt;/h2&gt;&lt;h3 id="インストール-1"&gt;&lt;a href="#%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab-1" class="header-anchor"&gt;&lt;/a&gt;インストール
&lt;/h3&gt;&lt;p&gt;以下のコマンドを実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo apt install barrier
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="設定-1"&gt;&lt;a href="#%e8%a8%ad%e5%ae%9a-1" class="header-anchor"&gt;&lt;/a&gt;設定
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;「クライアント」にチェックを入れる&lt;/li&gt;
&lt;li&gt;「サーバーIP」にIPアドレスを入力する&lt;/li&gt;
&lt;li&gt;メニューバーから、「Barrier &amp;gt; Change Settings」を選択し、「Enable SSL」のチェックを外す。&lt;/li&gt;
&lt;li&gt;開始を押す&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="追加の設定"&gt;&lt;a href="#%e8%bf%bd%e5%8a%a0%e3%81%ae%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;追加の設定
&lt;/h2&gt;&lt;p&gt;ログイン画面（ロック画面）になるとマウスとキーボードが効かなくなるので、以下の設定も行いました。&lt;/p&gt;
&lt;h3 id="windows-サーバー-側"&gt;&lt;a href="#windows-%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc-%e5%81%b4" class="header-anchor"&gt;&lt;/a&gt;Windows (サーバー) 側
&lt;/h3&gt;&lt;p&gt;Barrier の設定で、権限昇格を「常に」に変更しました。&lt;br&gt;
恐らくセキュリティ的によろしくないので、やるなら自己責任でお願いします。&lt;/p&gt;
&lt;h3 id="ubuntu-クライアント-側"&gt;&lt;a href="#ubuntu-%e3%82%af%e3%83%a9%e3%82%a4%e3%82%a2%e3%83%b3%e3%83%88-%e5%81%b4" class="header-anchor"&gt;&lt;/a&gt;Ubuntu (クライアント) 側
&lt;/h3&gt;&lt;p&gt;Ubuntu 20.04 を使用している場合、GNOME デスクトップ環境がデフォルトで採用されているため、GDM (GNOME Display Manager) の設定を変更しました。&lt;/p&gt;
&lt;p&gt;まず、GDMの設定ファイルを開きます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/gdm3/custom.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;[daemon] セクションに以下を追加します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;daemon&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Greeter-setup-script&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/numlockx on
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;変更を有効にするためにGDMを再起動します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo service gdm restart
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ただし、セキュリティ的にはよろしくないので、やるなら自己責任でお願いします。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://nanjib.com/archives/1587" target="_blank" rel="noopener"
 &gt;https://nanjib.com/archives/1587&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://ossyaritoori.hatenablog.com/entry/2019/09/26/Barrier%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6%E8%A4%87%E6%95%B0%E3%81%AEPC%E9%96%93%E3%81%A7%E3%83%9E%E3%82%A6%E3%82%B9%E3%83%BB%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E5%85%B1%E6%9C%89" target="_blank" rel="noopener"
 &gt;https://ossyaritoori.hatenablog.com/entry/2019/09/26/Barrier%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6%E8%A4%87%E6%95%B0%E3%81%AEPC%E9%96%93%E3%81%A7%E3%83%9E%E3%82%A6%E3%82%B9%E3%83%BB%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E5%85%B1%E6%9C%89&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>GitLab Pages でディレクトリ一覧を表示したい</title><link>https://blog-0847c6.gitlab.io/posts/2023/12/25/gitlab-pages/</link><pubDate>Mon, 25 Dec 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/12/25/gitlab-pages/</guid><description>&lt;p&gt;GitLab Pages で公開しているサイトにアクセスしたときに、配下ディレクトリの一覧を表示させる方法です。&lt;/p&gt;
&lt;p&gt;GitLab 12.8 までは nginx の autoindex を有効にして index of で表示させることができたようですが、セキュリティの観点からその機能は削除されたそうです。&lt;/p&gt;
&lt;p&gt;なので、どうにかしてインデックスページを作成し、GitLab Pages に公開するしかありません。
例えば、Hugo や Jekyll で Sitemap やインデックスページの自動生成機能を使う方法があるようです。&lt;/p&gt;
&lt;p&gt;ただ、今回私はシェルスクリプトファイルで作成することにしました。&lt;/p&gt;
&lt;p&gt;以下、サンプルです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 公開ディレクトリ内のディレクトリ一覧を取得&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;dirs&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;public/*/&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# HTMLで一覧を表示するための変数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;lt;ul&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ディレクトリのHTMLリストを生成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; d in &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# フォルダ一覧のみに制限するため、publicディレクトリ内のサブディレクトリのみを対象としています。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$d&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed -e &lt;span class="s1"&gt;&amp;#39;s/public\///&amp;#39;&lt;/span&gt; -e &lt;span class="s1"&gt;&amp;#39;s/\///&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$list&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$list&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/ul&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# index.htmlファイルを作成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;タイトル&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; public/index.html &lt;span class="s"&gt;&amp;lt;&amp;lt; EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;&amp;lt;html&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;head&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;title&amp;gt;$title&amp;lt;/title&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;/head&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;body&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;h1&amp;gt;$title&amp;lt;/h1&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; $list
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;/body&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;&amp;lt;/html&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これを、&lt;code&gt;.gitlab-ci.yml&lt;/code&gt; の script の最後に実行すれば OK です。&lt;/p&gt;
&lt;p&gt;上記はディレクトリに限定していますが、応用でファイル一覧を出力できると思います。&lt;/p&gt;</description></item><item><title>GitLab Pages でブランチ毎にディレクトリを分けて公開したい</title><link>https://blog-0847c6.gitlab.io/posts/2023/12/20/gitlab-pages/</link><pubDate>Wed, 20 Dec 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/12/20/gitlab-pages/</guid><description>&lt;p&gt;mkdocs で作成したサイトを GitLab Pages で公開していたのですが、これをブランチ毎にディレクトリを分けて公開するようにしました。&lt;/p&gt;
&lt;p&gt;基本的には、キャッシュを有効にするだけで可能です。&lt;br&gt;
各ブランチでの成果物も一緒に Pages で公開したいため、キャッシュのキーは固定値にします。&lt;br&gt;
以下、 &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; の抜粋です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mkdocs build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;rm -rf public/${CI_COMMIT_REF_NAME}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mv site public/${CI_COMMIT_REF_NAME}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;artifacts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;public&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ブランチ毎に別のキャッシュを利用したい場合はブランチ名をキーにするが、&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 今回は全ブランチのビルド結果も一緒に公開したいため、キーは全ブランチで共通の固定値にする&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;common-key&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#key: &amp;#34;$CI_COMMIT_REF_NAME&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;public&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;site&lt;/code&gt; ディレクトリが mkdocs の成果物が入っているディレクトリですが、これを &lt;code&gt;public/ブランチ名&lt;/code&gt; に配置しています。&lt;/p&gt;
&lt;h2 id="注意点"&gt;&lt;a href="#%e6%b3%a8%e6%84%8f%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;注意点
&lt;/h2&gt;&lt;p&gt;デフォルトでは、保護されたブランチと保護されていないブランチではキャッシュが共有されないため、この場合はプロジェクトの設定変更が必要です。&lt;br&gt;
これを知らずに何度試してもキャッシュが共有されずはまっていました・・・。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://gitlab-docs.creationline.com/ee/ci/caching/#use-the-same-cache-for-all-branches" target="_blank" rel="noopener"
 &gt;https://gitlab-docs.creationline.com/ee/ci/caching/#use-the-same-cache-for-all-branches&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;変更する設定は以下です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;サイドメニューより、&lt;code&gt;Settings&lt;/code&gt; &amp;gt; &lt;code&gt;CI/CD&lt;/code&gt; を選択&lt;/li&gt;
&lt;li&gt;&lt;code&gt;General pipelines&lt;/code&gt; を開く&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Use separate caches for protected branches&lt;/code&gt; のチェックボックスをオフにする&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Save changes&lt;/code&gt; をクリックして保存&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://dev.to/zenika/gitlab-pages-preview-the-no-compromise-hack-to-serve-per-branch-pages-5599" target="_blank" rel="noopener"
 &gt;https://dev.to/zenika/gitlab-pages-preview-the-no-compromise-hack-to-serve-per-branch-pages-5599&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://gist.github.com/donaldpipowitch/2590b20520b2cf6ae01aab4f7b55f8fa" target="_blank" rel="noopener"
 &gt;https://gist.github.com/donaldpipowitch/2590b20520b2cf6ae01aab4f7b55f8fa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://gitlab-docs.creationline.com/ee/ci/caching/#use-the-same-cache-for-all-branches" target="_blank" rel="noopener"
 &gt;https://gitlab-docs.creationline.com/ee/ci/caching/#use-the-same-cache-for-all-branches&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] ModuleNotFoundError: No module named 'websockets.legacy' のエラーが出た</title><link>https://blog-0847c6.gitlab.io/posts/2023/12/01/python/</link><pubDate>Fri, 01 Dec 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/12/01/python/</guid><description>&lt;p&gt;Python のアプリを Nuitka で実行ファイルにして動かすと、Websockets に関するエラーが出ました。&lt;/p&gt;
&lt;p&gt;尚、python で実行したときには正常に動作しています。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Python 3.11&lt;/li&gt;
&lt;li&gt;Nuitka 1.9.2&lt;/li&gt;
&lt;li&gt;Websockets 11.0.3&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="エラーの内容"&gt;&lt;a href="#%e3%82%a8%e3%83%a9%e3%83%bc%e3%81%ae%e5%86%85%e5%ae%b9" class="header-anchor"&gt;&lt;/a&gt;エラーの内容
&lt;/h2&gt;&lt;p&gt;具体的には以下のようなエラーが出ました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Traceback (most recent call last):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/foo/main.py&amp;#34;, line 36, in subprocess
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/foo/asyncio/runners.py&amp;#34;, line 190, in run
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/foo/asyncio/runners.py&amp;#34;, line 118, in run
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/foo/asyncio/base_events.py&amp;#34;, line 653, in run_until_complete
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/foo/websocket_manager.py&amp;#34;, line 47, in run
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/foo/websocket_client.py&amp;#34;, line 38, in run
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/foo/websockets/imports.py&amp;#34;, line 77, in __getattr__
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; File &amp;#34;/foo/websockets/imports.py&amp;#34;, line 27, in import_name
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ModuleNotFoundError: No module named &amp;#39;websockets.legacy&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="とりあえずの対処法"&gt;&lt;a href="#%e3%81%a8%e3%82%8a%e3%81%82%e3%81%88%e3%81%9a%e3%81%ae%e5%af%be%e5%87%a6%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;とりあえずの対処法
&lt;/h2&gt;&lt;p&gt;以下に同じエラーの報告がありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/python-websockets/websockets/issues/974" target="_blank" rel="noopener"
 &gt;https://github.com/python-websockets/websockets/issues/974&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上記を参考に以下のように変更すればとりあえず解決しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;変更前&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import websockets
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;async for websocket in websockets.connect(uri):
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;変更後&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import websockets.client
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;async for websocket in websockets.client.connect(uri):
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="本来の解決方法"&gt;&lt;a href="#%e6%9c%ac%e6%9d%a5%e3%81%ae%e8%a7%a3%e6%b1%ba%e6%96%b9%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;本来の解決方法
&lt;/h2&gt;&lt;p&gt;上記のコードですが、どうやらこれは古い記述方法みたいです。&lt;br&gt;
最近の websockets (11.x 以降) では、接続の作成と処理は以下のように行うことを推奨しているようです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import websockets
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;while True:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; try:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; async with websockets.connect(uri) as websocket:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; # メッセージ処理 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; except Exception:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; # ここに再接続ロジックなど 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; await asyncio.sleep(retry_delay)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ただし、これで今回のエラーが解決するかどうかは試していません。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/python-websockets/websockets/issues/974" target="_blank" rel="noopener"
 &gt;https://github.com/python-websockets/websockets/issues/974&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Docker] Windows コンテナを動かす</title><link>https://blog-0847c6.gitlab.io/posts/2023/11/21/docker-windows/</link><pubDate>Tue, 21 Nov 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/11/21/docker-windows/</guid><description>&lt;p&gt;Docker Desktop を使わずに、Windows 10 に Docker のバイナリを直接インストールして、Windows コンテナを動かすまでをやってみました。&lt;/p&gt;
&lt;p&gt;やり方は以下のドキュメントに記載されていました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/engine/install/binaries/#install-server-and-client-binaries-on-windows" target="_blank" rel="noopener"
 &gt;https://docs.docker.com/engine/install/binaries/#install-server-and-client-binaries-on-windows&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;記載の通り、これで動かせるようになるのは Windows コンテナのみで、Linux コンテナは動かせません。&lt;br&gt;
Windows 上で Linux コンテナを動かしたい場合は、WSL を使う方法などがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2022/01/wsl2-ubuntu-docker.html" target="_blank" rel="noopener"
 &gt;https://kuttsun.blogspot.com/2022/01/wsl2-ubuntu-docker.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Windows 10 Pro&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="windows-の機能の有効化"&gt;&lt;a href="#windows-%e3%81%ae%e6%a9%9f%e8%83%bd%e3%81%ae%e6%9c%89%e5%8a%b9%e5%8c%96" class="header-anchor"&gt;&lt;/a&gt;Windows の機能の有効化
&lt;/h2&gt;&lt;p&gt;コントロールパネルの [Windows の機能の有効化または無効化] より、&lt;code&gt;コンテナ&lt;/code&gt; にチェックを入れます。&lt;br&gt;
これにチェックが入っていないと Docker コンテナが動きませんでした。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="270px" data-flex-grow="112" height="368" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2023/11/21/docker-windows/container.png" width="415"&gt;&lt;/p&gt;
&lt;p&gt;また、Hyper-V の有効化が必要という記事も見かけましたが、私の環境では Hyper-V を有効化しなくても動きました。&lt;br&gt;
Hyper-V については以下を参照してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/reference/hyper-v-requirements" target="_blank" rel="noopener"
 &gt;https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/reference/hyper-v-requirements&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="インストール方法"&gt;&lt;a href="#%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e6%96%b9%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;インストール方法
&lt;/h2&gt;&lt;h3 id="バイナリのダウンロード"&gt;&lt;a href="#%e3%83%90%e3%82%a4%e3%83%8a%e3%83%aa%e3%81%ae%e3%83%80%e3%82%a6%e3%83%b3%e3%83%ad%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;バイナリのダウンロード
&lt;/h3&gt;&lt;p&gt;以下からインストールしたい Docker のバージョンのバイナリファイルをダウンロードします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://download.docker.com/win/static/stable/x86_64/" target="_blank" rel="noopener"
 &gt;https://download.docker.com/win/static/stable/x86_64/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;現時点で最新の 24.0.7 をダウンロードしました。&lt;/p&gt;
&lt;h3 id="programfiles-への展開"&gt;&lt;a href="#programfiles-%e3%81%b8%e3%81%ae%e5%b1%95%e9%96%8b" class="header-anchor"&gt;&lt;/a&gt;ProgramFiles への展開
&lt;/h3&gt;&lt;p&gt;ダウンロードした zip を ProgramFiles に展開するため、PowerShell を管理者で起動して以下を実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Expand-Archive &amp;lt;ダウンロードした zip へのパス&amp;gt; -DestinationPath &lt;span class="nv"&gt;$Env&lt;/span&gt;:ProgramFiles
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;$Env:ProgramFiles&lt;/code&gt; は環境変数 &lt;code&gt;ProgramFiles&lt;/code&gt; を表示しており、通常は &lt;code&gt;C:\Program Files&lt;/code&gt; というパスになります。&lt;br&gt;
以降のコマンドは全て PowerShell で実行します。&lt;/p&gt;
&lt;h3 id="サービスへの登録"&gt;&lt;a href="#%e3%82%b5%e3%83%bc%e3%83%93%e3%82%b9%e3%81%b8%e3%81%ae%e7%99%bb%e9%8c%b2" class="header-anchor"&gt;&lt;/a&gt;サービスへの登録
&lt;/h3&gt;&lt;p&gt;Docker をサービスへ登録します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$Env&lt;/span&gt;:ProgramFiles&lt;span class="se"&gt;\D&lt;/span&gt;ocker&lt;span class="se"&gt;\d&lt;/span&gt;ockerd --register-service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; は、PowerShell においてコマンドやスクリプトを呼び出す演算子です。&lt;br&gt;
従って、環境変数展開後の &lt;code&gt;C:\ProgramFiles\Docker\dockerd&lt;/code&gt; という文字列をコマンドとして実行しています。&lt;/p&gt;
&lt;h3 id="サービスの開始"&gt;&lt;a href="#%e3%82%b5%e3%83%bc%e3%83%93%e3%82%b9%e3%81%ae%e9%96%8b%e5%a7%8b" class="header-anchor"&gt;&lt;/a&gt;サービスの開始
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Start-Service docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="動作確認"&gt;&lt;a href="#%e5%8b%95%e4%bd%9c%e7%a2%ba%e8%aa%8d" class="header-anchor"&gt;&lt;/a&gt;動作確認
&lt;/h3&gt;&lt;p&gt;Hello World イメージを動かしてみます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$Env&lt;/span&gt;:ProgramFiles&lt;span class="se"&gt;\D&lt;/span&gt;ocker&lt;span class="se"&gt;\d&lt;/span&gt;ocker run hello-world:nanoserver
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;基本的にはこれで上手くいくはずですが、プロキシ環境下の場合は、後述するプロキシ設定が必要になります。&lt;/p&gt;
&lt;h2 id="環境変数へパスを通す"&gt;&lt;a href="#%e7%92%b0%e5%a2%83%e5%a4%89%e6%95%b0%e3%81%b8%e3%83%91%e3%82%b9%e3%82%92%e9%80%9a%e3%81%99" class="header-anchor"&gt;&lt;/a&gt;環境変数へパスを通す
&lt;/h2&gt;&lt;p&gt;毎回 &lt;code&gt;&amp;amp;$Env:ProgramFiles\Docker\docker&lt;/code&gt; と打つのは面倒なため、&lt;code&gt;$env:ProgramFiles\docker\&lt;/code&gt; をPATHに追加します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;Environment&lt;span class="o"&gt;]&lt;/span&gt;::SetEnvironmentVariable&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Path&amp;#34;&lt;/span&gt;, &lt;span class="nv"&gt;$env&lt;/span&gt;:Path + &lt;span class="s2"&gt;&amp;#34;;&lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;:ProgramFiles\docker\&amp;#34;, [EnvironmentVariableTarget]::Machine)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;PowerShell を一度閉じて、再度開きます。&lt;br&gt;
これで以下のように &lt;code&gt;docker&lt;/code&gt; と打つだけで実行できるようになります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; docker run hello-world:nanoserver
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="プロキシ設定"&gt;&lt;a href="#%e3%83%97%e3%83%ad%e3%82%ad%e3%82%b7%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;プロキシ設定
&lt;/h2&gt;&lt;p&gt;プロキシ環境下では、プロキシサーバーの設定を行っていないと Docker イメージを pull できません。&lt;br&gt;
設定方法については以下に記載がありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/ja-jp/virtualization/windowscontainers/manage-docker/configure-docker-daemon" target="_blank" rel="noopener"
 &gt;https://learn.microsoft.com/ja-jp/virtualization/windowscontainers/manage-docker/configure-docker-daemon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;環境変数 &lt;code&gt;HTTP_PROXY&lt;/code&gt; &lt;code&gt;HTTPS_PROXY&lt;/code&gt; を設定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;Environment&lt;span class="o"&gt;]&lt;/span&gt;::SetEnvironmentVariable&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;HTTP_PROXY&amp;#34;&lt;/span&gt;, &lt;span class="s2"&gt;&amp;#34;http://&amp;lt;IP address&amp;gt;:&amp;lt;port&amp;gt;&amp;#34;&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;EnvironmentVariableTarget&lt;span class="o"&gt;]&lt;/span&gt;::Machine&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;設定後、Docker サービスを再起動します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Restart-Service docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="docker-クライアントのプロキシ設定"&gt;&lt;a href="#docker-%e3%82%af%e3%83%a9%e3%82%a4%e3%82%a2%e3%83%b3%e3%83%88%e3%81%ae%e3%83%97%e3%83%ad%e3%82%ad%e3%82%b7%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;docker クライアントのプロキシ設定
&lt;/h3&gt;&lt;p&gt;Linux では &lt;code&gt;~/.docker/config.json&lt;/code&gt; に設定しますが、Windows では &lt;code&gt;%USERPROFILE%\.docker\config.json&lt;/code&gt; に設定します。&lt;/p&gt;
&lt;p&gt;以下のように設定しておくことで、Dockerfile のビルドを行う際に &lt;code&gt;--build-args&lt;/code&gt; などで都度プロキシの設定を行う必要がなくなります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;proxies&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;default&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;httpProxy&amp;#34;: &amp;#34;http://&amp;lt;IPアドレス&amp;gt;:&amp;lt;port&amp;gt;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;httpsProxy&amp;#34;: &amp;#34;http://&amp;lt;IPアドレス&amp;gt;:&amp;lt;port&amp;gt;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;noProxy&amp;#34;: &amp;#34;localhost,127.0.0.1,host.docker.internal&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;もしかしたら、一度 Docker サービスを再起動する必要があるかもしれません。&lt;/p&gt;
&lt;h2 id="エラーが発生した場合"&gt;&lt;a href="#%e3%82%a8%e3%83%a9%e3%83%bc%e3%81%8c%e7%99%ba%e7%94%9f%e3%81%97%e3%81%9f%e5%a0%b4%e5%90%88" class="header-anchor"&gt;&lt;/a&gt;エラーが発生した場合
&lt;/h2&gt;&lt;p&gt;次のようなエラーが発生した場合、Docker サービスが起動していないか、プロキシにより通信が通っていないかのどちらか可能性が高いです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Unable to find image &lt;span class="s1"&gt;&amp;#39;hello-world:nanoserver&amp;#39;&lt;/span&gt; locally
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker: Error response from daemon: Get &lt;span class="s2"&gt;&amp;#34;https://registry-1.docker.io/v2/&amp;#34;&lt;/span&gt;: net/http: request canceled &lt;span class="k"&gt;while&lt;/span&gt; waiting &lt;span class="k"&gt;for&lt;/span&gt; connection &lt;span class="o"&gt;(&lt;/span&gt;Client.Timeout exceeded &lt;span class="k"&gt;while&lt;/span&gt; awaiting headers&lt;span class="o"&gt;)&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;See &lt;span class="s1"&gt;&amp;#39;docker run --help&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;また、次のようなエラーが発生した場合、[Windows の機能の有効化または無効化] で &lt;code&gt;コンテナ&lt;/code&gt; にチェックが入っていない可能性があります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker: Error response from daemon: hcs::CreateComputeSystem d5ccfe373c27d9053c87689f60075aed9acdca360d6cd42e1abdc5591bb60cbc: The request is not supported.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="アンインストール"&gt;&lt;a href="#%e3%82%a2%e3%83%b3%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;アンインストール
&lt;/h2&gt;&lt;p&gt;サービスから Docker を削除します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$Env&lt;/span&gt;:ProgramFiles&lt;span class="se"&gt;\D&lt;/span&gt;ocker&lt;span class="se"&gt;\d&lt;/span&gt;ockerd --unregister-service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これだけではまだ完全にサービスは削除されていないので、一度 OS を再起動します。&lt;br&gt;
その後、docker のフォルダを削除します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Remove-item -Recurse &lt;span class="nv"&gt;$Env&lt;/span&gt;:ProgramFiles&lt;span class="se"&gt;\D&lt;/span&gt;ocker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="アップデート"&gt;&lt;a href="#%e3%82%a2%e3%83%83%e3%83%97%e3%83%87%e3%83%bc%e3%83%88" class="header-anchor"&gt;&lt;/a&gt;アップデート
&lt;/h2&gt;&lt;p&gt;現在のバージョンをアンインストールし、新しいバージョンをインストールします。&lt;/p&gt;
&lt;h2 id="余談他の-windows-コンテナを動かしてみた"&gt;&lt;a href="#%e4%bd%99%e8%ab%87%e4%bb%96%e3%81%ae-windows-%e3%82%b3%e3%83%b3%e3%83%86%e3%83%8a%e3%82%92%e5%8b%95%e3%81%8b%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f" class="header-anchor"&gt;&lt;/a&gt;余談：他の Windows コンテナを動かしてみた
&lt;/h2&gt;&lt;p&gt;python3.11 の Windows コンテナを動かしてみました。&lt;/p&gt;
&lt;p&gt;python イメージのタグ一覧が以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://hub.docker.com/_/python" target="_blank" rel="noopener"
 &gt;https://hub.docker.com/_/python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Windows コンテナをベースとしている python3.11 のイメージとして以下の２つがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3.11-windowsservercore-ltsc2022&lt;/li&gt;
&lt;li&gt;3.11-windowsservercore-1809&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;私の PC では、&lt;code&gt;3.11-windowsservercore-ltsc2022&lt;/code&gt; は動かず、&lt;code&gt;3.11-windowsservercore-1809&lt;/code&gt; は動きました。&lt;br&gt;
ベースとしている Windows コンテナの詳細は以下で確認できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://hub.docker.com/_/microsoft-windows-servercore" target="_blank" rel="noopener"
 &gt;https://hub.docker.com/_/microsoft-windows-servercore&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.ulvaniac.co.jp/2023/09/06/docker-desktop%E3%82%92%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84windows%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E5%8B%95%E4%BD%9C%E6%96%B9%E6%B3%95/" target="_blank" rel="noopener"
 &gt;https://www.ulvaniac.co.jp/2023/09/06/docker-desktop%E3%82%92%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84windows%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E5%8B%95%E4%BD%9C%E6%96%B9%E6%B3%95/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://and-engineer.com/articles/YcGZxhYAACUAbPjg" target="_blank" rel="noopener"
 &gt;https://and-engineer.com/articles/YcGZxhYAACUAbPjg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/SGTY/items/1126e0b95c35843fd8c5" target="_blank" rel="noopener"
 &gt;https://qiita.com/SGTY/items/1126e0b95c35843fd8c5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.shibata.tech/entry/2016/08/05/233212" target="_blank" rel="noopener"
 &gt;https://blog.shibata.tech/entry/2016/08/05/233212&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/ja-jp/virtualization/windowscontainers/manage-docker/configure-docker-daemon" target="_blank" rel="noopener"
 &gt;https://learn.microsoft.com/ja-jp/virtualization/windowscontainers/manage-docker/configure-docker-daemon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] Pyinstaller, Nuitka で作成した実行ファイルで GLIBC のエラーが発生する</title><link>https://blog-0847c6.gitlab.io/posts/2023/11/17/pyinstaller-nuitka/</link><pubDate>Fri, 17 Nov 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/11/17/pyinstaller-nuitka/</guid><description>&lt;p&gt;pyinstaller, nuitka で作成した実行ファイルを別のマシンで実行するとエラーが出て動きませんでした。&lt;/p&gt;
&lt;p&gt;具体的には以下のような GLIBC に関するエラーが表示されました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pyinstaller の場合&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10562&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="n"&gt;loading&lt;/span&gt; &lt;span class="n"&gt;Python&lt;/span&gt; &lt;span class="n"&gt;lib&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/home/username/dist/main/libpython3.11.so.1.0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dlopen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gnu&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;libm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;so&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;GLIBC_2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; not found (required by /home/username/dist/main/libpython3.11.so.1.0)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Nuitka の場合&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./sample.bin: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33&amp;#39; not found (required by ./sample.bin)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./sample.bin: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34&amp;#39; not found (required by ./sample.bin)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./sample.bin: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.35&amp;#39; not found (required by /home/username/main.dist/libpython3.11.so.1.0)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./sample.bin: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33&amp;#39; not found (required by /home/username/main.dist/libpython3.11.so.1.0)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./sample.bin: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32&amp;#39; not found (required by /home/username/main.dist/libpython3.11.so.1.0)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./sample.bin: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34&amp;#39; not found (required by /home/username/main.dist/libpython3.11.so.1.0)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これの回避策は、サポートしたいシステムより古いシステムでビルドを行うことだそうです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://dev.to/k4ml/python-compile-standalone-executable-with-nuitka-1ml1" target="_blank" rel="noopener"
 &gt;https://dev.to/k4ml/python-compile-standalone-executable-with-nuitka-1ml1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/Nuitka/Nuitka/issues/1610" target="_blank" rel="noopener"
 &gt;https://github.com/Nuitka/Nuitka/issues/1610&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;私の場合、&lt;code&gt;python:3.11&lt;/code&gt; の Docker イメージを使ってビルドを行っていましたが、このイメージのディストリビューションは Debian 12 でした。
そこでビルドした成果物を Ubuntu 20.04 のマシンで動かすと上記のエラーが発生しました。&lt;/p&gt;
&lt;p&gt;なので、ビルドに使用する Docker イメージを &lt;code&gt;python:3.11-buster&lt;/code&gt; に変更したところ、エラーなく動作するようになりました。&lt;/p&gt;
&lt;p&gt;尚、&lt;code&gt;buster&lt;/code&gt; というのは Debian のコードネームのことで、Debian 10 のことだそうです。&lt;br&gt;
詳細は以下を参照してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.debian.org/releases/index.ja.html" target="_blank" rel="noopener"
 &gt;https://www.debian.org/releases/index.ja.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://dev.to/k4ml/python-compile-standalone-executable-with-nuitka-1ml1" target="_blank" rel="noopener"
 &gt;https://dev.to/k4ml/python-compile-standalone-executable-with-nuitka-1ml1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/Nuitka/Nuitka/issues/1610" target="_blank" rel="noopener"
 &gt;https://github.com/Nuitka/Nuitka/issues/1610&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.debian.org/releases/index.ja.html" target="_blank" rel="noopener"
 &gt;https://www.debian.org/releases/index.ja.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Docker] docker-compose の --scale でコンテナを複製した際に、コンテナ側で何番目のコンテナなのかを判別したい</title><link>https://blog-0847c6.gitlab.io/posts/2023/11/14/docker/</link><pubDate>Tue, 14 Nov 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/11/14/docker/</guid><description>&lt;p&gt;本来、スケールは大きな負荷を処理できるようにするために使用し、スケールしたコンテナ毎に異なる構成を使用すべきではないと思いますが、それでも、スケールしたコンテナ毎にぞれぞれ別の構成が適用できると便利な場合もあります。
その場合、複製したコンテナ内で、自身が何番目のコンテナなのかを把握できるのが最も都合が良いと考えます。&lt;/p&gt;
&lt;p&gt;しかし、調べてみてもやり方が分からず、同様の質問はいくつか見つかりますが、現状、docker compose にはそのような機能は提供されていないようです。
その代わりに、docker swarm でタスクスロットを使うことで、コンテナの番号をコンテナ内に設定することができました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/service_create/" target="_blank" rel="noopener"
 &gt;https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/service_create/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="サンプル"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;サンプル
&lt;/h2&gt;&lt;p&gt;以下のような docker-compose.yml を用意します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;version: &amp;#39;3&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;services:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; deploy:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; replicas: 3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hostname: &amp;#34;server-{{.Task.Slot}}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以下のコマンドでサービスを起動します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker swarm init # Swarmを初期化する（すでに初期化済みであれば不要）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker stack deploy -c docker-compose.yml my_stack
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;docker ps&lt;/code&gt; で確認すると、コンテナが3つ起動しているのが確認できます。&lt;br&gt;
ここで、3つのうちの1つのコンテナに入ってみます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker exec -it &amp;lt;コンテナ名&amp;gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;コンテナ内で hostname を確認すると、番号が振られていることが確認できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# echo $(hostname)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;尚、サービスを停止するには、以下のコマンドを使用します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker stack rm my_stack
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/service_create/" target="_blank" rel="noopener"
 &gt;https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/service_create/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://forums.docker.com/t/how-to-identify-the-number-of-scaled-container/15041/11" target="_blank" rel="noopener"
 &gt;https://forums.docker.com/t/how-to-identify-the-number-of-scaled-container/15041/11&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/docker/compose/issues/9153" target="_blank" rel="noopener"
 &gt;https://github.com/docker/compose/issues/9153&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] pytest で motor のテストを行う</title><link>https://blog-0847c6.gitlab.io/posts/2023/11/13/python/</link><pubDate>Mon, 13 Nov 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/11/13/python/</guid><description>&lt;p&gt;MongoDB 用の非同期ライブラリに motor を使用しており、pytest でテストコードを記述する際にモックをどうすればいいか悩みました。&lt;/p&gt;
&lt;p&gt;当初は pymongo を使って同期的に使用していたため、MongoDB のモックには mongomock を使用していましたが、motor を使用する場合には mongomock-motor が使うとテストできました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://pypi.org/project/mongomock-motor/" target="_blank" rel="noopener"
 &gt;https://pypi.org/project/mongomock-motor/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="インストール"&gt;&lt;a href="#%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;インストール
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install mongomock-motor
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="サンプルコード"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;サンプルコード
&lt;/h2&gt;&lt;p&gt;上記のページにあるサンプルコードを pytest で実行する例です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pytest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;mongomock_motor&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AsyncMongoMockClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@pytest.mark.asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_mock_client&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AsyncMongoMockClient&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tests&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test-1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;insert_one&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inserted_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://pypi.org/project/mongomock-motor/" target="_blank" rel="noopener"
 &gt;https://pypi.org/project/mongomock-motor/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>シェルスクリプトで sudo 権限で実行されているどうかをチェックする</title><link>https://blog-0847c6.gitlab.io/posts/2023/11/12/linux/</link><pubDate>Sun, 12 Nov 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/11/12/linux/</guid><description>&lt;p&gt;&lt;code&gt;id -u&lt;/code&gt; コマンドを使用して実行ユーザーの UID（ユーザーID）を確認することでチェックできます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# スクリプトをsudoで実行しているか確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;id -u&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -ne &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;このスクリプトはsudoで実行する必要があります。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通常、root ユーザーの UID は 0 となります。&lt;/p&gt;</description></item><item><title>Rocket.Chat 移行後にアップロードファイルの URL が古いままになっている</title><link>https://blog-0847c6.gitlab.io/posts/2023/10/19/rocketchat/</link><pubDate>Thu, 19 Oct 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/10/19/rocketchat/</guid><description>&lt;p&gt;Rocket.Chat を移行したのですが、アップロード済みファイルの URL と、サイト URL のリセット値が、移行前の古い URL のままになっていました。&lt;/p&gt;
&lt;h2 id="概要"&gt;&lt;a href="#%e6%a6%82%e8%a6%81" class="header-anchor"&gt;&lt;/a&gt;概要
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Rocket.Chat を移行し、ドメイン (サイトURL) が変わった&lt;/li&gt;
&lt;li&gt;その際、Rocket.Chatを 3.10.14 から 6.2.12 にアップグレードしている
&lt;ul&gt;
&lt;li&gt;MongoDB も 4.0 から 5.0 にアップグレード&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Rocket.Chat 起動時に指定する環境変数 &lt;code&gt;ROOT_URL&lt;/code&gt; は移行後の URL を設定済み&lt;/li&gt;
&lt;li&gt;Rocket.Chat の管理者メニューで設定できる &lt;code&gt;サイト URL&lt;/code&gt; も移行後の URL を設定済み&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この状況で、以下の２つの不具合を確認しました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;アップロード済みのファイルの URL (ダウンロードリンク) が移行前の古い URL になっている&lt;/li&gt;
&lt;li&gt;Rocket.Chat の管理者メニューで設定できる &lt;code&gt;サイト URL&lt;/code&gt; について、リセットボタンを押すと移行前の古い URL がセットされる&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="先に結論"&gt;&lt;a href="#%e5%85%88%e3%81%ab%e7%b5%90%e8%ab%96" class="header-anchor"&gt;&lt;/a&gt;先に結論
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;1.&lt;/code&gt; については MongoDB のデータを直接修正すれば直りました。&lt;br&gt;
&lt;code&gt;2.&lt;/code&gt; については未解決です。&lt;/p&gt;
&lt;h3 id="mongodb-のデータを確認することにしたきっかけ"&gt;&lt;a href="#mongodb-%e3%81%ae%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e7%a2%ba%e8%aa%8d%e3%81%99%e3%82%8b%e3%81%93%e3%81%a8%e3%81%ab%e3%81%97%e3%81%9f%e3%81%8d%e3%81%a3%e3%81%8b%e3%81%91" class="header-anchor"&gt;&lt;/a&gt;MongoDB のデータを確認することにしたきっかけ
&lt;/h3&gt;&lt;p&gt;いろいろググっていく中で以下のページに辿り着きました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.ryadel.com/en/rocket-chat-change-root_url-site-url-rocketchat/" target="_blank" rel="noopener"
 &gt;https://www.ryadel.com/en/rocket-chat-change-root_url-site-url-rocketchat/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;こちらの方法を試しても今回発生している不具合は直りませんでしたが、これをきっかけに MongoDB の中身を調査していくことで修正できました。&lt;/p&gt;
&lt;p&gt;MongoDB の中身の確認方法については以下が参考になりました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.mtioutput.com/entry/2019/02/21/180000" target="_blank" rel="noopener"
 &gt;https://www.mtioutput.com/entry/2019/02/21/180000&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://gihyo.jp/dev/serial/01/mongodb/0003" target="_blank" rel="noopener"
 &gt;https://gihyo.jp/dev/serial/01/mongodb/0003&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="調査の過程と修正方法"&gt;&lt;a href="#%e8%aa%bf%e6%9f%bb%e3%81%ae%e9%81%8e%e7%a8%8b%e3%81%a8%e4%bf%ae%e6%ad%a3%e6%96%b9%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;調査の過程と修正方法
&lt;/h2&gt;&lt;p&gt;Rocket.Chat と MongoDB は docker で動かしています。&lt;br&gt;
なので、まず MongoDB の docker コンテナに入ります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it rocketchat-mongo bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;コンテナに入ったら MongoDB シェルを開き、&lt;code&gt;rocketchat&lt;/code&gt; のデータベースを選択します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# mongo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; use rocketchat
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;コレクションを表示してみます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; show collections
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;たくさん表示されますが、ここから不具合内容に該当する箇所を推測して調査していきます。&lt;/p&gt;
&lt;h2 id="1-アップロードファイルのダウンロードリンクについて"&gt;&lt;a href="#1-%e3%82%a2%e3%83%83%e3%83%97%e3%83%ad%e3%83%bc%e3%83%89%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ae%e3%83%80%e3%82%a6%e3%83%b3%e3%83%ad%e3%83%bc%e3%83%89%e3%83%aa%e3%83%b3%e3%82%af%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6" class="header-anchor"&gt;&lt;/a&gt;1. アップロードファイルのダウンロードリンクについて
&lt;/h2&gt;&lt;p&gt;前述の &lt;code&gt;1.&lt;/code&gt; についてですが、こちらはアップロードファイルに関することなので、&lt;code&gt;rocketchat_uploads&lt;/code&gt; の中身を表示してみました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; db.rocketchat_uploads.find&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;20件のみ表示されますが、適当なデータ一件について中身をみると以下のような感じになっていました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;27JzjqpXHxAHBzaxp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;hoge.jpg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;51268&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;image/jpeg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;rid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MgKrXXN4XmQwtMMjgjXnWzpNvR6YrRpH4F&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;userId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;jXnWzpNvR6YrRpH4F&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;store&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;GridFS:Uploads&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_updatedAt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;ISODate(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2023-07-26T03:58:50.233Z&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;instanceId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;R252ARSHBKR3RrXHY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;identify&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;format&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;jpeg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;width&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;495&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;height&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;700&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;complete&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;etag&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HoMjiYj2fbb799RFK&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/ufs/GridFS:Uploads/27JzjqpXHxAHBzaxp/%E5%90%8D%E7%A7%B0%E6%9C%AA%E8%A8%AD%E5%AE%9A%201.jpg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;progress&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;token&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;68c8A8CAb8&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;uploadedAt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;ISODate(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2023-07-26T03:58:50.852Z&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;uploading&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;http://old_domain:port/ufs/GridFS:Uploads/27JzjqpXHxAHBzaxp/%E5%90%8D%E7%A7%B0%E6%9C%AA%E8%A8%AD%E5%AE%9A%201.jpg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;typeGroup&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;image&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;見てわかる通り、&lt;code&gt;url&lt;/code&gt; のフィールドにファイルへの絶対パスが記録されているため、これを修正しないと直らないんじゃないかと思いました。&lt;/p&gt;
&lt;p&gt;というわけで、以下のコマンドでドメインの部分のみを置換します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;db.rocketchat_uploads.find&lt;span class="o"&gt;()&lt;/span&gt;.forEach&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;row&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; row.url &lt;span class="o"&gt;=&lt;/span&gt; row.url.replace&lt;span class="o"&gt;(&lt;/span&gt;new RegExp&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;old_domain&amp;#34;&lt;/span&gt;, &lt;span class="s1"&gt;&amp;#39;g&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="s2"&gt;&amp;#34;new_domain&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; db.rocketchat_uploads.save&lt;span class="o"&gt;(&lt;/span&gt;row&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで Rocket.Chat のほうを確認すると、URL が直っていました。&lt;/p&gt;
&lt;h2 id="2-サイト-url-のリセット値について"&gt;&lt;a href="#2-%e3%82%b5%e3%82%a4%e3%83%88-url-%e3%81%ae%e3%83%aa%e3%82%bb%e3%83%83%e3%83%88%e5%80%a4%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6" class="header-anchor"&gt;&lt;/a&gt;2. サイト URL` のリセット値について
&lt;/h2&gt;&lt;p&gt;次に前述の &lt;code&gt;2.&lt;/code&gt; についてですが、設定に関することなので &lt;code&gt;rocketchat_settings&lt;/code&gt; を確認してみました。
こちらはついては中身を全てを見たかったので、以下のようにして json ファイルに出力して確認しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ mongoexport -d rocketchat -c rocketchat_settings -o rocketchat_settings.json --type&lt;span class="o"&gt;=&lt;/span&gt;json mongodb://localhost:27017
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;で、中身を確認してみましたが、それらしい設定は見当たりませんでした。&lt;br&gt;
他のコレクションもいろいろ確認してみましたが、それらしい設定は見つかっていません。&lt;/p&gt;
&lt;p&gt;というわけで未解決ですが、特に実害はないので放っておいてます。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.ryadel.com/en/rocket-chat-change-root_url-site-url-rocketchat/" target="_blank" rel="noopener"
 &gt;https://www.ryadel.com/en/rocket-chat-change-root_url-site-url-rocketchat/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.mtioutput.com/entry/2019/02/21/180000" target="_blank" rel="noopener"
 &gt;https://www.mtioutput.com/entry/2019/02/21/180000&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://gihyo.jp/dev/serial/01/mongodb/0003" target="_blank" rel="noopener"
 &gt;https://gihyo.jp/dev/serial/01/mongodb/0003&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Rocket.Chat のアップグレード手順</title><link>https://blog-0847c6.gitlab.io/posts/2023/10/11/rocketchat/</link><pubDate>Wed, 11 Oct 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/10/11/rocketchat/</guid><description>&lt;p&gt;アップグレード手順については以下に記載されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.rocket.chat/deploy/deploy-rocket.chat/updating-rocket.chat" target="_blank" rel="noopener"
 &gt;https://docs.rocket.chat/deploy/deploy-rocket.chat/updating-rocket.chat&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;アップグレードのフローが以下になります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://whimsical.com/upgrade-version-path-rocket-chat-51eoS7aUunTan5wLt2CBHU" target="_blank" rel="noopener"
 &gt;https://whimsical.com/upgrade-version-path-rocket-chat-51eoS7aUunTan5wLt2CBHU&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これに従ってアップデートしますが、いくつかはまったポイントがありました。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;p&gt;アップグレード前のバージョンは以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rocket.Chat Version: 3.10.4&lt;/li&gt;
&lt;li&gt;NodeJS Version: 12.18.4 - x64&lt;/li&gt;
&lt;li&gt;MongoDB Version: 4.0.28&lt;/li&gt;
&lt;li&gt;MongoDB Engine: wiredTiger&lt;/li&gt;
&lt;li&gt;Platform: linux&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rocket.Chat も MongoDB も docker で動かしています。&lt;/p&gt;
&lt;h2 id="rocketchat-3187-へのアップグレード"&gt;&lt;a href="#rocketchat-3187-%e3%81%b8%e3%81%ae%e3%82%a2%e3%83%83%e3%83%97%e3%82%b0%e3%83%ac%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;Rocket.Chat 3.18.7 へのアップグレード
&lt;/h2&gt;&lt;p&gt;現在のバージョンが 3.10.4 なので、3系の最新の 3.18.7 にアップグレードしました。&lt;br&gt;
すると、データベースバージョンのエラーが表示されたました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+----------------------------------------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; ERROR! SERVER STOPPED &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; Your database migration failed: &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; Start date cannot be later than expire date &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; Please make sure you are running the latest version and try again. &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; If the problem persists, please contact support. &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; This Rocket.Chat version: 3.18.7 &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; Database locked at version: &lt;span class="m"&gt;213&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; Database target version: &lt;span class="m"&gt;232&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; Commit: 660c9f5e896982932e1d02d35ddd6013c6b03e11 &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; Date: Mon May &lt;span class="m"&gt;30&lt;/span&gt; 19:06:57 &lt;span class="m"&gt;2022&lt;/span&gt; -0300 &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; Branch: HEAD &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; Tag: 3.18.7 &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+----------------------------------------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;対策は以下に書いてありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://martinschoeler.github.io/docs/administrator-guides/database-migration/" target="_blank" rel="noopener"
 &gt;https://martinschoeler.github.io/docs/administrator-guides/database-migration/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MongoDB のコンテナに入り、以下のコマンドを実行してバージョンを強制的に一つ上げます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# mongo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; use rocketchat
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; db.migrations.update({_id: &amp;#39;control&amp;#39;},{$set:{locked:false,version:231}})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで Rocket.Chat を再起動すれば OK でした。&lt;/p&gt;
&lt;h2 id="rocketchat-3187-から-487-へのアップグレード"&gt;&lt;a href="#rocketchat-3187-%e3%81%8b%e3%82%89-487-%e3%81%b8%e3%81%ae%e3%82%a2%e3%83%83%e3%83%97%e3%82%b0%e3%83%ac%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;Rocket.Chat 3.18.7 から 4.8.7 へのアップグレード
&lt;/h2&gt;&lt;p&gt;次に4系の最新の 4.8.7 にアップグレードしました。&lt;br&gt;
これはすんなりいきました。&lt;/p&gt;
&lt;h2 id="mongodb-のアップグレード"&gt;&lt;a href="#mongodb-%e3%81%ae%e3%82%a2%e3%83%83%e3%83%97%e3%82%b0%e3%83%ac%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;MongoDB のアップグレード
&lt;/h2&gt;&lt;p&gt;上記のフローによれば、Rocket.Chat を5系にアップグレードする前に、MongoDB を 5.0 以上までアップグレードする必要があります。&lt;br&gt;
方法については以下に記載されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.growi.org/ja/admin-guide/admin-cookbook/upgrade-mongodb.html" target="_blank" rel="noopener"
 &gt;https://docs.growi.org/ja/admin-guide/admin-cookbook/upgrade-mongodb.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mongodb-40-から-42-へのアップグレード"&gt;&lt;a href="#mongodb-40-%e3%81%8b%e3%82%89-42-%e3%81%b8%e3%81%ae%e3%82%a2%e3%83%83%e3%83%97%e3%82%b0%e3%83%ac%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;MongoDB 4.0 から 4.2 へのアップグレード
&lt;/h3&gt;&lt;p&gt;現在のバージョンが 4.0 なので、まずは 4.2 にアップグレードしました。
これはすんなりいきました。&lt;/p&gt;
&lt;h3 id="mongodb-42-から-44-へのアップグレード"&gt;&lt;a href="#mongodb-42-%e3%81%8b%e3%82%89-44-%e3%81%b8%e3%81%ae%e3%82%a2%e3%83%83%e3%83%97%e3%82%b0%e3%83%ac%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;MongoDB 4.2 から 4.4 へのアップグレード
&lt;/h3&gt;&lt;p&gt;次に 4.4 にアップグレードしたところ、以下のようなエラーとなりました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{&amp;#34;t&amp;#34;:{&amp;#34;$date&amp;#34;:&amp;#34;2023-10-13T00:38:13.842+00:00&amp;#34;},&amp;#34;s&amp;#34;:&amp;#34;W&amp;#34;, &amp;#34;c&amp;#34;:&amp;#34;STORAGE&amp;#34;, &amp;#34;id&amp;#34;:22347, &amp;#34;ctx&amp;#34;:&amp;#34;initandlisten&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;Failed to start up WiredTiger under any compatibility version. This may be due to an unsupported upgrade or downgrade.&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{&amp;#34;t&amp;#34;:{&amp;#34;$date&amp;#34;:&amp;#34;2023-10-13T00:38:13.842+00:00&amp;#34;},&amp;#34;s&amp;#34;:&amp;#34;F&amp;#34;, &amp;#34;c&amp;#34;:&amp;#34;STORAGE&amp;#34;, &amp;#34;id&amp;#34;:28595, &amp;#34;ctx&amp;#34;:&amp;#34;initandlisten&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;Terminating.&amp;#34;,&amp;#34;attr&amp;#34;:{&amp;#34;reason&amp;#34;:&amp;#34;95: Operation not supported&amp;#34;}}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{&amp;#34;t&amp;#34;:{&amp;#34;$date&amp;#34;:&amp;#34;2023-10-13T00:38:13.842+00:00&amp;#34;},&amp;#34;s&amp;#34;:&amp;#34;F&amp;#34;, &amp;#34;c&amp;#34;:&amp;#34;-&amp;#34;, &amp;#34;id&amp;#34;:23091, &amp;#34;ctx&amp;#34;:&amp;#34;initandlisten&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;Fatal assertion&amp;#34;,&amp;#34;attr&amp;#34;:{&amp;#34;msgid&amp;#34;:28595,&amp;#34;file&amp;#34;:&amp;#34;src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp&amp;#34;,&amp;#34;line&amp;#34;:958}}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{&amp;#34;t&amp;#34;:{&amp;#34;$date&amp;#34;:&amp;#34;2023-10-13T00:38:13.843+00:00&amp;#34;},&amp;#34;s&amp;#34;:&amp;#34;F&amp;#34;, &amp;#34;c&amp;#34;:&amp;#34;-&amp;#34;, &amp;#34;id&amp;#34;:23092, &amp;#34;ctx&amp;#34;:&amp;#34;initandlisten&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;\n\n***aborting after fassert() failure\n\n&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;MongoDB を 4.2 に戻してコンテナに入り、以下のコマンドを実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# mongo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; db.adminCommand( { setFeatureCompatibilityVersion: &amp;#34;4.2&amp;#34; } )
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで Rocket.Chat を再起動すれば OK でした。&lt;/p&gt;
&lt;h3 id="mongodb-44-から-50-へのアップグレード"&gt;&lt;a href="#mongodb-44-%e3%81%8b%e3%82%89-50-%e3%81%b8%e3%81%ae%e3%82%a2%e3%83%83%e3%83%97%e3%82%b0%e3%83%ac%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;MongoDB 4.4 から 5.0 へのアップグレード
&lt;/h3&gt;&lt;p&gt;次に 5.0 にアップグレードしたところ、同様のエラーとなりました。&lt;br&gt;
MongoDB を 4.4 に戻してコンテナに入り、以下のコマンドを実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# mongo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; db.adminCommand( { setFeatureCompatibilityVersion: &amp;#34;4.4&amp;#34; } )
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで Rocket.Chat を再起動すれば OK でした。&lt;/p&gt;
&lt;h2 id="rocketchat-487-から-5410-へのアップグレード"&gt;&lt;a href="#rocketchat-487-%e3%81%8b%e3%82%89-5410-%e3%81%b8%e3%81%ae%e3%82%a2%e3%83%83%e3%83%97%e3%82%b0%e3%83%ac%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;Rocket.Chat 4.8.7 から 5.4.10 へのアップグレード
&lt;/h2&gt;&lt;p&gt;MongoDB を 5.0 までアップグレードしたので、次は Rocket.Chat を5系の最新の 5.4.10 にアップグレードしました。&lt;br&gt;
すると以下のエラーが表示されました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/app/bundle/programs/server/node_modules/fibers/future.js:313
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; throw(ex);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ^
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;MongoServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at Timeout._onTimeout (/app/bundle/programs/server/npm/node_modules/meteor/npm-mongo/node_modules/mongodb/lib/sdam/topology.js:312:38)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at listOnTimeout (internal/timers.js:557:17)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at processTimers (internal/timers.js:500:7) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; reason: TopologyDescription {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; type: &amp;#39;ReplicaSetNoPrimary&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; servers: Map(1) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#39;localhost:27017&amp;#39; =&amp;gt; ServerDescription {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; _hostAddress: HostAddress { isIPv6: false, host: &amp;#39;localhost&amp;#39;, port: 27017 },
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; address: &amp;#39;localhost:27017&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; type: &amp;#39;Unknown&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hosts: [],
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; passives: [],
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; arbiters: [],
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; tags: {},
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; minWireVersion: 0,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; maxWireVersion: 0,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; roundTripTime: -1,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; lastUpdateTime: 17764280,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; lastWriteDate: 0,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; error: MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at connectionFailureError (/app/bundle/programs/server/npm/node_modules/meteor/npm-mongo/node_modules/mongodb/lib/cmap/connect.js:381:20)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at Socket.&amp;lt;anonymous&amp;gt; (/app/bundle/programs/server/npm/node_modules/meteor/npm-mongo/node_modules/mongodb/lib/cmap/connect.js:301:22)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at Object.onceWrapper (events.js:520:26)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at Socket.emit (events.js:400:28)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at emitErrorNT (internal/streams/destroy.js:106:8)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at emitErrorCloseNT (internal/streams/destroy.js:74:3)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; at processTicksAndRejections (internal/process/task_queues.js:82:21)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; stale: false,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; compatible: true,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; heartbeatFrequencyMS: 10000,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; localThresholdMS: 15,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; setName: &amp;#39;rs0&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; maxSetVersion: 2,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; maxElectionId: ObjectId {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [Symbol(id)]: Buffer(12) [Uint8Array] [
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 127, 255, 255, 255, 0,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 0, 0, 0, 0, 0,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 0, 10
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; commonWireVersion: 13,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; logicalSessionTimeoutMinutes: undefined
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;解決策は以下にありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/RocketChat/Rocket.Chat/releases/tag/5.0.0" target="_blank" rel="noopener"
 &gt;https://github.com/RocketChat/Rocket.Chat/releases/tag/5.0.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;環境変数 &lt;code&gt;MONGO_URL&lt;/code&gt; &lt;code&gt;MONGO_OPLOG_URL&lt;/code&gt; に &lt;code&gt;directConnection=true&lt;/code&gt; を追加します。&lt;br&gt;
例えば、&lt;code&gt;MONGO_URL=mongodb://mongo/rocketchat?replicaSet=rs0&amp;amp;directConnection=true&lt;/code&gt; のような感じです。&lt;/p&gt;
&lt;p&gt;これで Rocket.Chat を再起動すれば OK でした。&lt;/p&gt;
&lt;h2 id="rocketchat-を最新にアップデート"&gt;&lt;a href="#rocketchat-%e3%82%92%e6%9c%80%e6%96%b0%e3%81%ab%e3%82%a2%e3%83%83%e3%83%97%e3%83%87%e3%83%bc%e3%83%88" class="header-anchor"&gt;&lt;/a&gt;Rocket.Chat を最新にアップデート
&lt;/h2&gt;&lt;p&gt;最後に、Rocket.Chat を現在の最新バージョンである 6.3.9 にアップグレードしました。
以上で完了です。&lt;/p&gt;</description></item><item><title>[Python] OS の時刻（システムクロック）に影響を受けないように時間の計測を行う</title><link>https://blog-0847c6.gitlab.io/posts/2023/09/08/python/</link><pubDate>Fri, 08 Sep 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/09/08/python/</guid><description>&lt;p&gt;&lt;code&gt;time.monotonic()&lt;/code&gt; を使えば OK です。&lt;/p&gt;
&lt;p&gt;元々、以下の様に &lt;code&gt;time.time()&lt;/code&gt; を使って処理時間の計測を行っていたのですが、この場合、計測途中でシステムクロックが変更されてしまうと、計測時間も影響を受けてしまいます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# この間にシステムクロックが変更されると計測時間にも影響を与える&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;elapsed_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 過去に戻ると負の値に、未来に行くと大きな値になってしまう&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elapsed_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;time.monotonic()&lt;/code&gt; を使えばシステムクロックの影響を受けないので、純粋に処理にかかった実時間を計測できます。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.python.org/ja/3.10/library/time.html#time.monotonic" target="_blank" rel="noopener"
 &gt;https://docs.python.org/ja/3.10/library/time.html#time.monotonic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>YAML のアンカー/エイリアスと docker compose の profiles を使って docker-compose.yml を作成する</title><link>https://blog-0847c6.gitlab.io/posts/2023/08/25/yaml/</link><pubDate>Fri, 25 Aug 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/08/25/yaml/</guid><description>&lt;p&gt;github などで公開されている docker-compose.yml を見ていると、見慣れない表記を見かけることがあり、調べてみると YAML のアンカー/エイリアス機能であることがわかりました。&lt;/p&gt;
&lt;p&gt;これと、docker compose の &lt;code&gt;--profiles&lt;/code&gt; を組み合わせて、&lt;code&gt;docker-compose.yml&lt;/code&gt; 一つで様々な環境で動かすことができるようにしているのを見るととても便利だなと思ったので、メモしておきます。&lt;/p&gt;
&lt;h2 id="yaml-のアンカーとエイリアス"&gt;&lt;a href="#yaml-%e3%81%ae%e3%82%a2%e3%83%b3%e3%82%ab%e3%83%bc%e3%81%a8%e3%82%a8%e3%82%a4%e3%83%aa%e3%82%a2%e3%82%b9" class="header-anchor"&gt;&lt;/a&gt;yaml のアンカーとエイリアス
&lt;/h2&gt;&lt;p&gt;yaml 自体の標準機能です。&lt;br&gt;
これを使うことで、記述内容を共通化して DRY にできます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アンカー: &lt;code&gt;&amp;amp;&lt;/code&gt; を付けることで、他の場所でも参照できるようにします。&lt;/li&gt;
&lt;li&gt;エイリアス: &lt;code&gt;*&lt;/code&gt; を付けて、アンカーで定義した内容を参照します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;サンプル1&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;&amp;amp;hoge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;*hoge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上記の場合、以下の様に展開されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;サンプル2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;アンカー内にアンカーがあっても問題ありません。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;&amp;amp;hoge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;&amp;amp;piyo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;*hoge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;eee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;*piyo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上記の場合、以下の様に展開されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;eee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="マージ"&gt;&lt;a href="#%e3%83%9e%e3%83%bc%e3%82%b8" class="header-anchor"&gt;&lt;/a&gt;マージ
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;&amp;lt;&amp;lt;:&lt;/code&gt; と記述することで、アンカーで定義した内容をそのまま入れ込むことができます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;&amp;amp;hoge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;*hoge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3333&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上記の場合、以下の様に展開されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3333&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="アンカーの上書き"&gt;&lt;a href="#%e3%82%a2%e3%83%b3%e3%82%ab%e3%83%bc%e3%81%ae%e4%b8%8a%e6%9b%b8%e3%81%8d" class="header-anchor"&gt;&lt;/a&gt;アンカーの上書き
&lt;/h3&gt;&lt;p&gt;アンカー名と同じキーが後にあった場合、上書きされます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;&amp;amp;hoge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3333&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;eee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;*hoge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4444&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;fff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;*hoge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5555&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上記は以下のように展開されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3333&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;eee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4444&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3333&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;fff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ccc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2222&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5555&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これを使って、内容の大部分を共通化しつつ一部分だけは変えたいということができます。&lt;/p&gt;
&lt;h3 id="docker-composeyml-で使用する場合"&gt;&lt;a href="#docker-composeyml-%e3%81%a7%e4%bd%bf%e7%94%a8%e3%81%99%e3%82%8b%e5%a0%b4%e5%90%88" class="header-anchor"&gt;&lt;/a&gt;docker-compose.yml で使用する場合
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt; 内で共通の設定を括りだそうと以下の様に書くとエラーになります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;common: &amp;amp;common
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: hoge
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;service:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; app:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;&amp;lt;: *common
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;docker compose によって &lt;code&gt;common&lt;/code&gt; 自体が解釈されるためです。&lt;br&gt;
この場合、プレフィックスとして &lt;code&gt;x-&lt;/code&gt; を付けると、docker compose からは無視されるようになります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;x-common: &amp;amp;common
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: hoge
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;service:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; app:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;&amp;lt;: *x-common
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="docker-compose-の-profile"&gt;&lt;a href="#docker-compose-%e3%81%ae-profile" class="header-anchor"&gt;&lt;/a&gt;docker compose の profile
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt; で定義されたサービスに profiles を定義することで、サービスのグループ分けやタグ付けのようなことができます。&lt;br&gt;
以下が公式ドキュメントによる説明です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.jp/compose/profiles.html" target="_blank" rel="noopener"
 &gt;https://docs.docker.jp/compose/profiles.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;profiles で指定したサービスのみを起動させることができるようになります。&lt;/p&gt;
&lt;h2 id="上記を踏まえた実用的なサンプル"&gt;&lt;a href="#%e4%b8%8a%e8%a8%98%e3%82%92%e8%b8%8f%e3%81%be%e3%81%88%e3%81%9f%e5%ae%9f%e7%94%a8%e7%9a%84%e3%81%aa%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;上記を踏まえた実用的なサンプル
&lt;/h2&gt;&lt;p&gt;上記を踏まえると、yaml のアンカー/エイリアスにより記述内容を共通化しつつ、profile によって起動するコンテナを切り替えることができます。&lt;/p&gt;
&lt;p&gt;尚、今回の記事を書くことになった動機が、以下の Stable Diffusion 用の docker-compose.yml を見たときで、どういう意味なんだろうと思ったのがきっかけです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/AbdBarho/stable-diffusion-webui-docker" target="_blank" rel="noopener"
 &gt;https://github.com/AbdBarho/stable-diffusion-webui-docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GPU を使う場合と、CPU を使う場合とで上手く共通化されており、また記述量も少なくサンプルとして丁度いいので、こちらをサンプルとして挙げさせていただきます。&lt;/p&gt;
&lt;h2 id="docker-composeyml-の確認"&gt;&lt;a href="#docker-composeyml-%e3%81%ae%e7%a2%ba%e8%aa%8d" class="header-anchor"&gt;&lt;/a&gt;docker-compose.yml の確認
&lt;/h2&gt;&lt;p&gt;ちなみに、docker compose によってどのように yaml ファイルが読み込まれるか確認するには、config オプションを使用します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker compose config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://genzouw.com/entry/2021/06/19/082626/2661/#" target="_blank" rel="noopener"
 &gt;https://genzouw.com/entry/2021/06/19/082626/2661/#&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.jp/compose/profiles.html" target="_blank" rel="noopener"
 &gt;https://docs.docker.jp/compose/profiles.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://techracho.bpsinc.jp/hachi8833/2020_02_07/87447" target="_blank" rel="noopener"
 &gt;https://techracho.bpsinc.jp/hachi8833/2020_02_07/87447&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>`ImportError: cannot import name '_compare_version' from 'torchmetrics.utilities.imports'` のエラーが出る</title><link>https://blog-0847c6.gitlab.io/posts/2023/08/21/stable-diffusion/</link><pubDate>Mon, 21 Aug 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/08/21/stable-diffusion/</guid><description>&lt;p&gt;Stable Diffusion を動かそうとして以下のエラーが出ました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ImportError: cannot import name &amp;#39;_compare_version&amp;#39; from &amp;#39;torchmetrics.utilities.imports&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(/usr/local/lib/python3.8/site-packages/torchmetrics/utilities/imports.py)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以下に対策が載っており、&lt;code&gt;torchmetrics&lt;/code&gt; を &lt;code&gt;0.11.4&lt;/code&gt; にダウングレードすれば解決しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/11648" target="_blank" rel="noopener"
 &gt;https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/11648&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pip install torchmetrics==0.11.4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/11648" target="_blank" rel="noopener"
 &gt;https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/11648&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[VSCode] Markdown Preview Enhanced で HTML 出力する際にサイドバーの目次を入れる</title><link>https://blog-0847c6.gitlab.io/posts/2023/07/20/markdown-preview-enhanced/</link><pubDate>Thu, 20 Jul 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/07/20/markdown-preview-enhanced/</guid><description>&lt;p&gt;ずっとやり方が分からなかったのですが、英語版のマニュアルにやり方が書いてありました。&lt;/p&gt;
&lt;p&gt;サイドバーのTOCを生成するには、VSCode の Markdown Preview Enhanced の設定でスクリプトの実行を有効にする必要があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://shd101wyy.github.io/markdown-preview-enhanced/#/html?id=configuration" target="_blank" rel="noopener"
 &gt;https://shd101wyy.github.io/markdown-preview-enhanced/#/html?id=configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尚、上記の情報は現時点の日本語版のマニュアルには書いてありませんでした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://shd101wyy.github.io/markdown-preview-enhanced/#/ja-jp/html?id=%e8%a8%ad%e5%ae%9a" target="_blank" rel="noopener"
 &gt;https://shd101wyy.github.io/markdown-preview-enhanced/#/ja-jp/html?id=%e8%a8%ad%e5%ae%9a&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;VSCode 1.80.1&lt;/li&gt;
&lt;li&gt;Markdown Preview Enhanced v0.6.8&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="スクリプトの実行を有効にする"&gt;&lt;a href="#%e3%82%b9%e3%82%af%e3%83%aa%e3%83%97%e3%83%88%e3%81%ae%e5%ae%9f%e8%a1%8c%e3%82%92%e6%9c%89%e5%8a%b9%e3%81%ab%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;スクリプトの実行を有効にする
&lt;/h2&gt;&lt;p&gt;拡張機能の設定で &lt;code&gt;enableScriptExecution&lt;/code&gt; で検索すると設定項目が表示されるのでチェックを入れます。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="681px" data-flex-grow="284" height="245" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2023/07/20/markdown-preview-enhanced/01.png" width="696"&gt;&lt;/p&gt;
&lt;p&gt;尚、有効にするとセキュリティリスクがありますので、その点ご注意ください。&lt;/p&gt;
&lt;h2 id="html-の出力"&gt;&lt;a href="#html-%e3%81%ae%e5%87%ba%e5%8a%9b" class="header-anchor"&gt;&lt;/a&gt;html の出力
&lt;/h2&gt;&lt;p&gt;あとはマークダウンのプレビュー画面で右クリックし、HTML に出力するだけでサイドバーに目次が出力されます。&lt;br&gt;
尚、デフォルトではサイドバーは閉じた状態となっていました。&lt;br&gt;
マークダウン内に &lt;code&gt;toc: true&lt;/code&gt; を記述すると、サイドバーが開いた状態となりました。&lt;/p&gt;
&lt;p&gt;以下サンプルです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;html:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; toc: true
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 見出し1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;## 見出し2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;### 見出し3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;### 見出し3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 見出し1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;## 見出し2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="307px" data-flex-grow="128" height="552" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2023/07/20/markdown-preview-enhanced/02.png" width="707"&gt;&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://shd101wyy.github.io/markdown-preview-enhanced/#/html?id=configuration" target="_blank" rel="noopener"
 &gt;https://shd101wyy.github.io/markdown-preview-enhanced/#/html?id=configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/kumapo0313/items/a59df3d74a7eaaaf3137" target="_blank" rel="noopener"
 &gt;https://qiita.com/kumapo0313/items/a59df3d74a7eaaaf3137&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>WSL でディストリビューションを削除して再インストール後に起動エラーになる</title><link>https://blog-0847c6.gitlab.io/posts/2023/07/14/wsl/</link><pubDate>Fri, 14 Jul 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/07/14/wsl/</guid><description>&lt;p&gt;スタートメニューから Ubuntu 20.04 をアンインストールして、再度 MS ストアからインストールして起動しようとしたら以下のエラーが表示されました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ps" data-lang="ps"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;Error&lt;/span&gt; &lt;span class="nf"&gt;code:&lt;/span&gt; &lt;span class="nf"&gt;Wsl&lt;/span&gt;&lt;span class="nv"&gt;/Service/CreateInstance/MountVhd/ERROR_FILE_NOT_FOUND&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;まず、インストールされているディストリビューションを確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ps" data-lang="ps"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;wsl&lt;/span&gt; &lt;span class="nf"&gt;-l&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;Linux&lt;/span&gt; &lt;span class="nf"&gt;用&lt;/span&gt; &lt;span class="nf"&gt;Windows&lt;/span&gt; &lt;span class="nf"&gt;サブシステム&lt;/span&gt; &lt;span class="nf"&gt;ディストリビューション:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;Ubuntu-20.04&lt;/span&gt; &lt;span class="s"&gt;(既定)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;アンインストールしたはずのディストリビューションが残っていると思うので、以下のコマンドで登録を解除します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ps" data-lang="ps"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;wsl&lt;/span&gt; &lt;span class="nf"&gt;--unregister&lt;/span&gt; &lt;span class="nf"&gt;Ubuntu-20.04&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで、再度ディストリビューションを起動すれば OK です。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.techgaku.com/fix-ubuntu-boot-error-on-wsl-after-reinstall/" target="_blank" rel="noopener"
 &gt;https://www.techgaku.com/fix-ubuntu-boot-error-on-wsl-after-reinstall/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Microsoft ストア版の WSL をインストールする</title><link>https://blog-0847c6.gitlab.io/posts/2023/07/06/wsl/</link><pubDate>Thu, 06 Jul 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/07/06/wsl/</guid><description>&lt;p&gt;WSL について、Windows のコンポーネント（組み込み）として提供されているものと、Microsoft Store で提供されているものがあるのを知りました。&lt;/p&gt;
&lt;p&gt;きっかけは、WSL2 上の Ubuntu で systemd を使おうとしたら使えなかったことで、調べていくと WSL 自体のバージョンが 0.67.6 以降だと systemd が使えることがわかりました。&lt;/p&gt;
&lt;p&gt;WSL 自体のバージョンは以下のコマンドで確認できるらしいのですが、&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ps" data-lang="ps"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;wsl&lt;/span&gt; &lt;span class="nf"&gt;--version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;私の環境ではバージョンが表示されず、コマンドの説明が表示されてしまいました。&lt;/p&gt;
&lt;p&gt;これは、どうやら WSL のバージョンが古いのが原因らしく、最新版は Microsoft Store からインストールできるらしいと。&lt;br&gt;
ここで、2022年11月に正式版としてリリースされたストア版の WSL を知り、自分が使っていたのは「Windows の機能の有効化または無効化」からインストールしたコンポーネント版で、古いプレビュー版の WSL だということを知りました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/omu_kato/items/f9a6b5a02e25f5f2a487" target="_blank" rel="noopener"
 &gt;https://qiita.com/omu_kato/items/f9a6b5a02e25f5f2a487&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ストア版の WSL は普通に Microsoft Store で検索すれば見つかるので、そこでインストールするだけです。&lt;/p&gt;
&lt;p&gt;尚、既にコンポーネント版を使っていてもストア版をインストールして使えるようですが、私の環境では Ubuntu 22.04 を起動しようとすると &lt;code&gt;Error code: Wsl/Service/CreateInstance/MountVhd/ERROR_FILE_NOT_FOUND&lt;/code&gt; のエラーが出てしまいました。&lt;/p&gt;
&lt;p&gt;これについては、以下を参考に WSL から Ubuntu 22.04 の登録を解除すれば直りました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.techgaku.com/fix-ubuntu-boot-error-on-wsl-after-reinstall/" target="_blank" rel="noopener"
 &gt;https://www.techgaku.com/fix-ubuntu-boot-error-on-wsl-after-reinstall/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/omu_kato/items/f9a6b5a02e25f5f2a487" target="_blank" rel="noopener"
 &gt;https://qiita.com/omu_kato/items/f9a6b5a02e25f5f2a487&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/hiromasa-masuda/items/355fe0c882a1a0abe1e1" target="_blank" rel="noopener"
 &gt;https://qiita.com/hiromasa-masuda/items/355fe0c882a1a0abe1e1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.techgaku.com/fix-ubuntu-boot-error-on-wsl-after-reinstall/" target="_blank" rel="noopener"
 &gt;https://www.techgaku.com/fix-ubuntu-boot-error-on-wsl-after-reinstall/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>EasyTAG 2.4.3 で画像がある場合に mp3 ファイルのタグ書き込みに失敗する</title><link>https://blog-0847c6.gitlab.io/posts/2023/07/02/easytag/</link><pubDate>Sun, 02 Jul 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/07/02/easytag/</guid><description>&lt;p&gt;Windows で EasyTAG 2.4.3 の場合に発生します。&lt;/p&gt;
&lt;p&gt;いろいろ試しても上手くいかず悩んでいたのですが、以下に報告が上がっていました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://gitlab.gnome.org/GNOME/easytag/-/issues/5" target="_blank" rel="noopener"
 &gt;https://gitlab.gnome.org/GNOME/easytag/-/issues/5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2.4.2 にダウングレードすると問題なく書き込めました。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://gitlab.gnome.org/GNOME/easytag/-/issues/5" target="_blank" rel="noopener"
 &gt;https://gitlab.gnome.org/GNOME/easytag/-/issues/5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>systemd で環境変数を展開する</title><link>https://blog-0847c6.gitlab.io/posts/2023/06/14/systemd/</link><pubDate>Wed, 14 Jun 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/06/14/systemd/</guid><description>&lt;p&gt;環境変数を参照する Python アプリを systemd でサービス化したときにかなりはまってしまいました。&lt;/p&gt;
&lt;p&gt;systemd はユーザーの環境変数を参照しないようなので、ユニット定義ファイルで環境変数を設定する必要があるそうで、&lt;code&gt;Environment&lt;/code&gt; で記述したり、外部ファイルに定義して &lt;code&gt;EnvironmentFile&lt;/code&gt; で読み込む方法があるようです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://note.com/meiburg/n/n5cd098a8c744" target="_blank" rel="noopener"
 &gt;https://note.com/meiburg/n/n5cd098a8c744&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/yasushi-jp/items/97057509e96919c35f64" target="_blank" rel="noopener"
 &gt;https://qiita.com/yasushi-jp/items/97057509e96919c35f64&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;また、上記だと変数を展開することができないので、そのような場合には以下のように &lt;code&gt;ExecStartPre&lt;/code&gt; で &lt;code&gt;systemctl&lt;/code&gt; の &lt;code&gt;set-environment&lt;/code&gt; を使う方法などがあるようです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/kobanyan/items/f8e8a3bd5406e1d290fb" target="_blank" rel="noopener"
 &gt;https://qiita.com/kobanyan/items/f8e8a3bd5406e1d290fb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ただ、今回の私の場合は、シェル変数 &lt;code&gt;HOSTNAME&lt;/code&gt; を環境変数に export して参照したかったのですが、systemd にはホスト名を表す特殊な変数として &lt;code&gt;%H&lt;/code&gt; があるようなので、これを使って以下のようにすれば解決できました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Unit]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Description=My Python App
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Service]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ExecStart=/path/to/your/python/app.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Environment=&amp;#34;HOSTNAME=%H&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Install]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;WantedBy=multi-user.target
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://ja.stackoverflow.com/questions/62360/systemd-%E3%81%8B%E3%82%89%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%ABhome%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%9F%E3%81%84" target="_blank" rel="noopener"
 &gt;https://ja.stackoverflow.com/questions/62360/systemd-%E3%81%8B%E3%82%89%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%ABhome%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%9F%E3%81%84&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/kobanyan/items/f8e8a3bd5406e1d290fb" target="_blank" rel="noopener"
 &gt;https://qiita.com/kobanyan/items/f8e8a3bd5406e1d290fb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://stackoverflow.com/questions/37864999/referencing-other-environment-variables-in-systemd" target="_blank" rel="noopener"
 &gt;https://stackoverflow.com/questions/37864999/referencing-other-environment-variables-in-systemd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>VSCode で現在アクティブなタブの背景色を変更する</title><link>https://blog-0847c6.gitlab.io/posts/2023/06/12/vscode/</link><pubDate>Mon, 12 Jun 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/06/12/vscode/</guid><description>&lt;p&gt;Visual Studio Code のエディタで現在アクティブなタブの背景色が、デフォルトだと他のタブとあまり変わらなくて分かりづらいので、設定で変更しました。&lt;/p&gt;
&lt;p&gt;メニューより、ファイル &amp;gt; ユーザー設定 &amp;gt; 設定 を選択します。&lt;/p&gt;
&lt;p&gt;設定の検索より &lt;code&gt;workbench.colorCustomizations&lt;/code&gt; と入力し、「settings.json で編集」をクリックします。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="485px" data-flex-grow="202" height="282" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2023/06/12/vscode/vscode.png" width="570"&gt;&lt;/p&gt;
&lt;p&gt;そして、以下のように &lt;code&gt;tab.activeBackground&lt;/code&gt; を追記します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;#34;workbench.colorCustomizations&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;tab.activeBackground&amp;#34;: &amp;#34;#1b77cf&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://tekunabe.hatenablog.jp/entry/2021/05/23/134458" target="_blank" rel="noopener"
 &gt;https://tekunabe.hatenablog.jp/entry/2021/05/23/134458&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Telegraf で Jetson の GPU 情報を取得する</title><link>https://blog-0847c6.gitlab.io/posts/2023/05/27/telegraf/</link><pubDate>Sat, 27 May 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/05/27/telegraf/</guid><description>&lt;p&gt;Telegraf で GPU 情報を取得しよううとしたのですが、Jetson には &lt;code&gt;nvidia-smi&lt;/code&gt; のコマンドがありません。&lt;/p&gt;
&lt;p&gt;どうしようかなと思っていたら、以下の記事に Jetson で GPU 情報を取得する方法が書いてありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.influxdata.com/blog/nvidia-jetson-series-part-1-jetson-stats/" target="_blank" rel="noopener"
 &gt;https://www.influxdata.com/blog/nvidia-jetson-series-part-1-jetson-stats/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これを参考に、InfluxDB にデータを保存し、Grafana で可視化まで行いました。&lt;br&gt;
尚、TIG Stack (Telegraf, InfluxDB, Grafana) については以下を参考にしてください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2021/12/telegraf-influxdb-garafana.html" target="_blank" rel="noopener"
 &gt;https://kuttsun.blogspot.com/2021/12/telegraf-influxdb-garafana.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Jetson Xavier NX&lt;/li&gt;
&lt;li&gt;Ubuntu 18.04&lt;/li&gt;
&lt;li&gt;Telegraf 1.23.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Telegraf, InfluxDB, Grafana は Docker で動作させています。&lt;/p&gt;
&lt;h2 id="jetson-stats-のインストール"&gt;&lt;a href="#jetson-stats-%e3%81%ae%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab" class="header-anchor"&gt;&lt;/a&gt;Jetson Stats のインストール
&lt;/h2&gt;&lt;p&gt;まずはホストに Jetson Stats をインストールします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo apt-get install python3-pip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo -H python3 -m pip install -U jetson-stats
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;インストール後、一度ログアウト or 再起動します。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;jtop&lt;/code&gt; を実行して動作確認します。&lt;/p&gt;
&lt;h2 id="telegraf-の設定"&gt;&lt;a href="#telegraf-%e3%81%ae%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;Telegraf の設定
&lt;/h2&gt;&lt;p&gt;Jetson Stats を使って GPU の情報を取得する python スクリプトを作成し、それを Telegraf から定期的に実行するようにします。&lt;br&gt;
ただし、今回 Telegraf は Docker コンテナで動かしているので、上記の記事そのままでは上手く行きません。&lt;/p&gt;
&lt;h3 id="python-スクリプトの作成"&gt;&lt;a href="#python-%e3%82%b9%e3%82%af%e3%83%aa%e3%83%97%e3%83%88%e3%81%ae%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;Python スクリプトの作成
&lt;/h3&gt;&lt;p&gt;上記の記事にある以下のスクリプトを &lt;code&gt;jetson_stats.py&lt;/code&gt; という名前で保存しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Import jtop python library. We will use this to access the Jetson_Stats service.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;jtop&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jtop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;jtop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;jetson&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# jetson.stats provides our system measurements as type dict.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jetson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# time and uptime are proved as time objects. These needed to be converted before passing as a JSON string,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%m/&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s1"&gt;/%Y&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;uptime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;uptime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# We then convert our dict -&amp;amp;gt; Json string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;influx_json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;jetson&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;influx_json&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このスクリプトを Telegraf から定期的に実行することになります。&lt;/p&gt;
&lt;h3 id="dockerfile-の作成"&gt;&lt;a href="#dockerfile-%e3%81%ae%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;Dockerfile の作成
&lt;/h3&gt;&lt;p&gt;今までは Telegraf の Docker イメージをそのまま使っていましたが、このコンテナには Python の実行環境が入っていないため、上記の Python スクリプトを動かすことができません。&lt;br&gt;
そこで、以下のような Dockerfile を作成しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;telegraf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;1.23&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ARG&lt;/span&gt; &lt;span class="n"&gt;DEBIAN_FRONTEND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;noninteractive&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;COPY&lt;/span&gt; &lt;span class="n"&gt;jetson_stats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;RUN&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;apt&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;install&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;recommends&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;python3&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;python3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pip&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;python3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;setuptools&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;python3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;wheel&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;apt&lt;/span&gt; &lt;span class="n"&gt;autoremove&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt; &lt;span class="n"&gt;clean&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;rm&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rf&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lists&lt;/span&gt;&lt;span class="o"&gt;/*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;RUN&lt;/span&gt; &lt;span class="n"&gt;pip3&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;jetson&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;jetson_stats.py&lt;/code&gt; をイメージ内にコピーし、あとは Python の実行環境と Jetson Stats をインストールしています。&lt;/p&gt;
&lt;h3 id="docker-composeyml-の変更"&gt;&lt;a href="#docker-composeyml-%e3%81%ae%e5%a4%89%e6%9b%b4" class="header-anchor"&gt;&lt;/a&gt;docker-compose.yml の変更
&lt;/h3&gt;&lt;p&gt;コンテナ内で Jetson Stats を使うためには、&lt;code&gt;/run/jtop.sock&lt;/code&gt; をマウントする必要があるようです。&lt;br&gt;
ただ、それだけではアクセス権限の関係で以下のようなエラーが表示されました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jtop.core.exceptions.JtopException: I can&amp;#39;t access jetson_stats.service.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Docker コンテナの実行ユーザーを &lt;code&gt;/run/jtop.sock&lt;/code&gt; の所有グループに加えたら解決できたので、&lt;code&gt;group_add&lt;/code&gt; のプロパティを追加します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/rbonghi/jetson_stats" target="_blank" rel="noopener"
 &gt;https://github.com/rbonghi/jetson_stats&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上を踏まえ、docker-compose.yml を以下のように変更しました（今回に関連する部分のみ抜粋）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;telegraf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;telegraf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;telegraf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;HOSTNAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;NVIDIA_VISIBLE_DEVICES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;NVIDIA_DRIVER_CAPABILITIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;reservations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;devices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;gpu&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;unless&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stopped&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;6514&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;6514&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;telegraf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;telegraf&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;telegraf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ro&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ro&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nvidia&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;smi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nvidia&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;smi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ro&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 以下は Jetson Xavier NX 用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jtop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jtop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ro&lt;/span&gt; &lt;span class="c1"&gt;# https://github.com/rbonghi/jetson_stats&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;TELEGRAF_UID_GID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;group_add&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;${JTOP_GID:?}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="環境変数の追加"&gt;&lt;a href="#%e7%92%b0%e5%a2%83%e5%a4%89%e6%95%b0%e3%81%ae%e8%bf%bd%e5%8a%a0" class="header-anchor"&gt;&lt;/a&gt;環境変数の追加
&lt;/h3&gt;&lt;p&gt;上記の docker-compose.yml 内にある &lt;code&gt;JTOP_GID&lt;/code&gt; という環境変数を定義します。&lt;br&gt;
&lt;code&gt;~/.bashrc&lt;/code&gt; に以下を追記します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;JTOP_GID&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stat&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%g&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jtop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;再読み込みします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~$ &lt;span class="nb"&gt;source&lt;/span&gt; .bashrc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで、&lt;code&gt;/run/jtop.sock&lt;/code&gt; の所有グループを &lt;code&gt;JTOP_GID&lt;/code&gt; で参照できます。&lt;/p&gt;
&lt;h3 id="telegrafconf-の設定"&gt;&lt;a href="#telegrafconf-%e3%81%ae%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;telegraf.conf の設定
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;telegraf.conf&lt;/code&gt; に以下を追記します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[[inputs.exec]]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ## Commands array
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; commands = [
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;python3 /usr/local/bin/jetson_stats.py&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ## Timeout for each command to complete.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; timeout = &amp;#34;5s&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ## measurement name suffix (for separating different commands)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; name_suffix = &amp;#34;_jetson_stats&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ## Data format to consume.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ## Each data format has its own unique set of configuration options, read
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ## more about them here:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; data_format = &amp;#34;json&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ## Array of glob pattern strings or booleans keys that should be added as string fields.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; json_string_fields = [&amp;#34;jetson_uptime&amp;#34;, &amp;#34;jetson_nvp model&amp;#34;, &amp;#34;jetson_NVENC&amp;#34;, &amp;#34;jetson_NVDEC&amp;#34;, &amp;#34;jetson_NVJPG&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;内容は前述の参考記事の中身そのままです。&lt;/p&gt;
&lt;h3 id="テスト"&gt;&lt;a href="#%e3%83%86%e3%82%b9%e3%83%88" class="header-anchor"&gt;&lt;/a&gt;テスト
&lt;/h3&gt;&lt;p&gt;Docker コンテナに入って、以下のコマンドを実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python3 jetson_stats.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;json が取得できていれば OK です。&lt;/p&gt;
&lt;h2 id="grafana-のダッシュボードを作成"&gt;&lt;a href="#grafana-%e3%81%ae%e3%83%80%e3%83%83%e3%82%b7%e3%83%a5%e3%83%9c%e3%83%bc%e3%83%89%e3%82%92%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;Grafana のダッシュボードを作成
&lt;/h2&gt;&lt;p&gt;Jetson Stats 用のテンプレートがないかなと探してみましたが、見つかりませんでした。&lt;br&gt;
どうやら自分で作成するしかなさそうです。&lt;/p&gt;
&lt;p&gt;参考として、&lt;code&gt;jetson_stats.py&lt;/code&gt; を実行したら以下のような出力が得られます（わかりやすいように整形しています）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;jetson&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;09/14/2022&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;uptime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;0:40:39.970000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;jetson_clocks&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OFF&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;nvp model&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MODE_10W_DESKTOP&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;CPU1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;CPU2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;CPU3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;CPU4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;CPU5&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OFF&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;CPU6&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OFF&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;GPU&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;MTS FG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;MTS BG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RAM&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1413804&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;EMC&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1413804&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;SWAP&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;APE&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;NVENC&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OFF&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;NVDEC&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OFF&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;NVJPG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OFF&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;fan&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Temp AO&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;42.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Temp AUX&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;42.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Temp CPU&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;42.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Temp GPU&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;41.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Temp thermal&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;42.15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;power cur&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4166&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;power avg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4166&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これらの値が InfluxDB に格納されているはずなので、その値を使ってダッシュボードを作成していきます。&lt;br&gt;
尚、各プロパティの説明は以下にありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://rnext.it/jetson_stats/jtop.html#jtop.jtop.jtop.stats" target="_blank" rel="noopener"
 &gt;https://rnext.it/jetson_stats/jtop.html#jtop.jtop.jtop.stats&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;単位くらい書いておいてほしいなぁ〜。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.influxdata.com/blog/nvidia-jetson-series-part-1-jetson-stats/" target="_blank" rel="noopener"
 &gt;https://www.influxdata.com/blog/nvidia-jetson-series-part-1-jetson-stats/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/rbonghi/jetson_stats" target="_blank" rel="noopener"
 &gt;https://github.com/rbonghi/jetson_stats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/rbonghi/jetson_stats/issues/63" target="_blank" rel="noopener"
 &gt;https://github.com/rbonghi/jetson_stats/issues/63&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/manabuishiirb/items/a2620ec8020811540d81" target="_blank" rel="noopener"
 &gt;https://qiita.com/manabuishiirb/items/a2620ec8020811540d81&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://grafana.com/grafana/dashboards/14493-nvidia-jetson/" target="_blank" rel="noopener"
 &gt;https://grafana.com/grafana/dashboards/14493-nvidia-jetson/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>MongoDB と 2106 年問題</title><link>https://blog-0847c6.gitlab.io/posts/2023/05/23/mongodb/</link><pubDate>Tue, 23 May 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/05/23/mongodb/</guid><description>&lt;p&gt;ボタン電池がなくなり、RTC が遥か未来になったときに MongoDB が動作しなくなりました。（正確には、Python アプリにおいて、MongoDB の初期化を行う際にエラーとなりました。）&lt;/p&gt;
&lt;p&gt;MongoDB のバージョンは 6.0.5 です。&lt;/p&gt;
&lt;p&gt;調べてみると、MongoDB の ObjectID は先頭の4バイトがタイムスタンプ(UNIX タイム)となっているそうです。&lt;br&gt;
MongoDB はこれを符号なし整数として扱っていて、その場合の上限は &lt;code&gt;4,294,967,295&lt;/code&gt; であり、これは UTC で2106年2月7日6時28分16秒となります。&lt;br&gt;
というわけで、MongoDB はいわゆる 2106 年問題を孕んでいることになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.wdic.org/w/TECH/2106%E5%B9%B4%E5%95%8F%E9%A1%8C" target="_blank" rel="noopener"
 &gt;https://www.wdic.org/w/TECH/2106%E5%B9%B4%E5%95%8F%E9%A1%8C&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ちなみに、4バイトがタイムスタンプを符号付き整数として扱っている場合は 2038 年問題となります。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://stackoverflow.com/questions/42097779/how-can-mongodb-handle-objectid-timestamp-beyond-tue-19-jan-2038" target="_blank" rel="noopener"
 &gt;https://stackoverflow.com/questions/42097779/how-can-mongodb-handle-objectid-timestamp-beyond-tue-19-jan-2038&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://jira.mongodb.org/browse/GODRIVER-1092" target="_blank" rel="noopener"
 &gt;https://jira.mongodb.org/browse/GODRIVER-1092&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.wdic.org/w/TECH/2106%E5%B9%B4%E5%95%8F%E9%A1%8C" target="_blank" rel="noopener"
 &gt;https://www.wdic.org/w/TECH/2106%E5%B9%B4%E5%95%8F%E9%A1%8C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.mongodb.com/blog/post/generating-globally-unique-identifiers-for-use-with-mongodb" target="_blank" rel="noopener"
 &gt;https://www.mongodb.com/blog/post/generating-globally-unique-identifiers-for-use-with-mongodb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Docker] docker-compose の env_file 内でシェルスクリプトを実行する</title><link>https://blog-0847c6.gitlab.io/posts/2023/05/12/docker/</link><pubDate>Fri, 12 May 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/05/12/docker/</guid><description>&lt;p&gt;Docker Compose の env_file ディレクティブを使用する場合、原則として env_file に指定されたファイル内でシェルのシンタックスを使用することはできません。&lt;/p&gt;
&lt;p&gt;しかし、env_file にはシェルスクリプトを指定することもできますので、以下のようにシェルスクリプトファイル（例えば、env.shとします）を作成することで対応できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;MY_VARIABLE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my_value
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;docker-compose.yml の env_file ディレクティブでシェルスクリプトファイルを指定します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;myservice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./env.sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意点として、シェルスクリプトのパーミッションを正しく設定する必要があります。&lt;br&gt;
また、シェルスクリプト内で環境変数を定義する場合には &lt;code&gt;export&lt;/code&gt; する必要があります。&lt;/p&gt;
&lt;p&gt;ちなみに、env_file で定義された環境変数は、コンテナ内では使えますが、docker-compose.yml 内では使えません。&lt;br&gt;
（これでちょっとはまりました。）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://zenn.dev/rhene/scraps/781fdbecd340d3" target="_blank" rel="noopener"
 &gt;https://zenn.dev/rhene/scraps/781fdbecd340d3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://maku77.github.io/p/8r3cmu5/" target="_blank" rel="noopener"
 &gt;https://maku77.github.io/p/8r3cmu5/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://zenn.dev/rhene/scraps/781fdbecd340d3" target="_blank" rel="noopener"
 &gt;https://zenn.dev/rhene/scraps/781fdbecd340d3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] SyslogHandler でログを送信したときに `Bad file descriptor` のエラーになる</title><link>https://blog-0847c6.gitlab.io/posts/2023/04/05/python/</link><pubDate>Wed, 05 Apr 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/04/05/python/</guid><description>&lt;p&gt;SyslogHandler を使ってログを記録していたのですが、&lt;code&gt;Bad file descriptor&lt;/code&gt; のエラーが表示されてはまってしまいました。&lt;/p&gt;
&lt;p&gt;表示されたエラーは以下です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/usr/lib/python3.8/logging/handlers.py&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;940&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;emit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="ne"&gt;OSError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Errno&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Bad&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;descriptor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;アプリをマルチプロセスで動かしており、FastAPI ( +uvicorn) を使うとこのエラーが出るようになりました。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Python 3.8.10&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="対処方法"&gt;&lt;a href="#%e5%af%be%e5%87%a6%e6%96%b9%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;対処方法
&lt;/h2&gt;&lt;p&gt;調べても原因がさっぱりわからなかったのですが、最終的に以下のページにたどり着きました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/python/cpython/issues/87362" target="_blank" rel="noopener"
 &gt;https://github.com/python/cpython/issues/87362&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;どうやら Python の logging モジュールの不具合のようで、Python のバージョンを 3.11 まで上げると直りました。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/python/cpython/issues/87362" target="_blank" rel="noopener"
 &gt;https://github.com/python/cpython/issues/87362&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] マルチプロセスにおけるロギング (QueueHandler, QueueListener)</title><link>https://blog-0847c6.gitlab.io/posts/2023/04/04/python/</link><pubDate>Tue, 04 Apr 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/04/04/python/</guid><description>&lt;p&gt;SyslogHandler で UDP でログを記録していたのですが、マルチプロセスでは Socket 通信のところでエラーが発生しました。&lt;br&gt;
マルチプロセスでのロギングでは、&lt;code&gt;QueueHandler&lt;/code&gt; と &lt;code&gt;QueueListner&lt;/code&gt; を使ってログを一箇所に集約して書き込むようにする必要があります。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Python 3.8.10&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="基本的な書き方"&gt;&lt;a href="#%e5%9f%ba%e6%9c%ac%e7%9a%84%e3%81%aa%e6%9b%b8%e3%81%8d%e6%96%b9" class="header-anchor"&gt;&lt;/a&gt;基本的な書き方
&lt;/h2&gt;&lt;p&gt;とりあえずマルチプロセスは置いておいて、&lt;code&gt;QueueHandler&lt;/code&gt; と &lt;code&gt;QueueListener&lt;/code&gt; の基本的な使い方です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;multiprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DEBUG&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 標準出力の設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%(asctime)s&lt;/span&gt;&lt;span class="s1"&gt; [&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s1"&gt;] [&lt;/span&gt;&lt;span class="si"&gt;%(name)s&lt;/span&gt;&lt;span class="s1"&gt;] &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Syslog 出力の設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;syslog_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SysLogHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;514&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;syslog_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;HOSTNAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt; ris-main: %(message)s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ファイル出力の設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;file_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TimedRotatingFileHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;log/sample.log&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%(asctime)s&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="si"&gt;%(msecs)03d&lt;/span&gt;&lt;span class="s1"&gt; [&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s1"&gt;] [&lt;/span&gt;&lt;span class="si"&gt;%(name)s&lt;/span&gt;&lt;span class="s1"&gt;] &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;datefmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%Y-%m-&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s1"&gt; %H:%M:%S&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# キューハンドラの設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;que&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueueHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;que&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;queue_handler&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# リスナーの作成と開始&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueueListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;que&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;syslog_handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_listener&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;this is info&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;this is debug&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;critical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;this is critical&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_listener&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;logger&lt;/code&gt; を使って書いたログは &lt;code&gt;QueueHandler&lt;/code&gt; によりキューに入れられます。&lt;br&gt;
&lt;code&gt;QueueListner&lt;/code&gt; はキューに溜まったログを取り出して、&lt;code&gt;StreamHandler&lt;/code&gt; &lt;code&gt;SyslogHandler&lt;/code&gt; &lt;code&gt;TimedRotatingFileHandler&lt;/code&gt; で記録されます。&lt;/p&gt;
&lt;p&gt;尚、上記は &lt;code&gt;basicConfig&lt;/code&gt; を使って設定していますので、ライブラリなどのロギングにも影響します（対処方法は後述）。&lt;/p&gt;
&lt;h3 id="マルチプロセスで試してみた"&gt;&lt;a href="#%e3%83%9e%e3%83%ab%e3%83%81%e3%83%97%e3%83%ad%e3%82%bb%e3%82%b9%e3%81%a7%e8%a9%a6%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f" class="header-anchor"&gt;&lt;/a&gt;マルチプロセスで試してみた
&lt;/h3&gt;&lt;p&gt;上記を踏まえ、プロセスを３つ立ち上げ、各プロセス100回ログを記録させてみたサンプルが以下です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;multiprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DEBUG&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hoge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;) this is info&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;) this is debug&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;critical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;) this is critical&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 標準出力の設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%(asctime)s&lt;/span&gt;&lt;span class="s1"&gt; [&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s1"&gt;] [&lt;/span&gt;&lt;span class="si"&gt;%(name)s&lt;/span&gt;&lt;span class="s1"&gt;] &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Syslog 出力の設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;syslog_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SysLogHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;514&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;syslog_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;HOSTNAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt; ris-main: %(message)s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ファイル出力の設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;file_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TimedRotatingFileHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;log/sample.log&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%(asctime)s&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="si"&gt;%(msecs)03d&lt;/span&gt;&lt;span class="s1"&gt; [&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s1"&gt;] [&lt;/span&gt;&lt;span class="si"&gt;%(name)s&lt;/span&gt;&lt;span class="s1"&gt;] &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;datefmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%Y-%m-&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s1"&gt; %H:%M:%S&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# キューハンドラの設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;que&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueueHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;que&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;queue_handler&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# リスナーの作成と開始&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueueListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;que&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;syslog_handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_listener&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# プロセスの立ち上げ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;processes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hoge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# プロセスの終了を待つ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;KeyboardInterrupt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_listener&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;問題なくログが記録できていることが確認できました。&lt;/p&gt;
&lt;h2 id="basicconfig-を使わずに設定する"&gt;&lt;a href="#basicconfig-%e3%82%92%e4%bd%bf%e3%82%8f%e3%81%9a%e3%81%ab%e8%a8%ad%e5%ae%9a%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;basicConfig を使わずに設定する
&lt;/h2&gt;&lt;p&gt;上述したように、&lt;code&gt;basicConfig&lt;/code&gt; を使うとライブラリなどの全てのモジュールに影響するので、&lt;code&gt;logger&lt;/code&gt; に対して設定を行うようにします。&lt;br&gt;
ただ、そうなると都度設定を行う必要が出てくるので、以下のページを参考に共通の関数を作成しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://joemphilips.com/post/python_logging/" target="_blank" rel="noopener"
 &gt;http://joemphilips.com/post/python_logging/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ただし、QueueHandler を使う場合、キューを渡してやる必要があるので、それはグローバル変数として用意することにしました。&lt;br&gt;
ここらへん、もっと良い実装方法はないかなぁとは思いますが・・・。&lt;/p&gt;
&lt;p&gt;以下、サンプルです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# mylogger.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;multiprocessing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging.handlers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;multiprocessing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34; 共通のロガーを作成するための関数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; logging.getLogger と簡単に差し替えられるように同じ関数名としておく
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# キューハンドラの設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;queue_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueueHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_queue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queue_handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# main.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;mylogger&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;log_queue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 標準出力の設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%(asctime)s&lt;/span&gt;&lt;span class="s1"&gt; [&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s1"&gt;] [&lt;/span&gt;&lt;span class="si"&gt;%(name)s&lt;/span&gt;&lt;span class="s1"&gt;] &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Syslog 出力の設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;syslog_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SysLogHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;514&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;syslog_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;HOSTNAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt; ris-main: %(message)s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;syslog_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ファイル出力の設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;file_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TimedRotatingFileHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;log/sample.log&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%(asctime)s&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="si"&gt;%(msecs)03d&lt;/span&gt;&lt;span class="s1"&gt; [&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s1"&gt;] [&lt;/span&gt;&lt;span class="si"&gt;%(name)s&lt;/span&gt;&lt;span class="s1"&gt;] &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;datefmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%Y-%m-&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s1"&gt; %H:%M:%S&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# リスナーの作成と開始&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueueListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;log_queue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;stream_handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;syslog_handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;respect_handler_level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_listener&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;this is info&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;this is debug&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;critical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;this is critical&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;queue_listener&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;また、ここでは標準出力とそれ以外で、出力するログレベルを変えています。&lt;br&gt;
この場合、&lt;code&gt;QueueHandler&lt;/code&gt; の &lt;code&gt;respect_handler_level&lt;/code&gt; を &lt;code&gt;True&lt;/code&gt; にして、各ハンドラー側のレベルを優先するように設定してやる必要があります。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.python.org/ja/3.8/library/logging.handlers.html" target="_blank" rel="noopener"
 &gt;https://docs.python.org/ja/3.8/library/logging.handlers.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://ikatakos.com/pot/programming/python/packages/multiprocessing/queuehandler" target="_blank" rel="noopener"
 &gt;https://ikatakos.com/pot/programming/python/packages/multiprocessing/queuehandler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://rob-blackbourn.medium.com/how-to-use-python-logging-queuehandler-with-dictconfig-1e8b1284e27a" target="_blank" rel="noopener"
 &gt;https://rob-blackbourn.medium.com/how-to-use-python-logging-queuehandler-with-dictconfig-1e8b1284e27a&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://joemphilips.com/post/python_logging/" target="_blank" rel="noopener"
 &gt;http://joemphilips.com/post/python_logging/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[PySide] QTimer の使い方</title><link>https://blog-0847c6.gitlab.io/posts/2023/03/28/qtimer/</link><pubDate>Tue, 28 Mar 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/03/28/qtimer/</guid><description>&lt;p&gt;スレッドを使わずに定期的に GUI を更新するために、&lt;code&gt;QTimer&lt;/code&gt; の使い方と挙動について簡単に調べてみました。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Python 3.8.10&lt;/li&gt;
&lt;li&gt;PySide 6.2.2.1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="サンプルコード"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;サンプルコード
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;PySide6.QtCore&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;PySide6.QtWidgets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QApplication&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QWidget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QVBoxLayout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QLabel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QWidget&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;メインウィンドウ
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;countup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QVBoxLayout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__current_count&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;singleShot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__single_shot1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;singleShot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__single_shot2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__label&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__current_count&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;#time.sleep(3)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__current_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;現在のカウント: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__single_shot1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;, 10秒経過&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__single_shot2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;, 15秒経過&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;main_window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MainWindow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;main_window&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;　&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:40.166652, 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:41.115886, 2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:42.066937, 3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:43.026873, 4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:44.026648, 5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:45.026877, 6
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:46.026574, 7
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:47.026898, 8
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:48.026477, 9
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:49.027008, 10秒経過
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:49.027169, 10
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:50.027045, 11
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:51.026868, 12
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:52.027034, 13
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:53.026916, 14
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:54.026824, 15秒経過
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:04:54.027010, 15
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="処理に時間がかかった場合はどうなる"&gt;&lt;a href="#%e5%87%a6%e7%90%86%e3%81%ab%e6%99%82%e9%96%93%e3%81%8c%e3%81%8b%e3%81%8b%e3%81%a3%e3%81%9f%e5%a0%b4%e5%90%88%e3%81%af%e3%81%a9%e3%81%86%e3%81%aa%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;処理に時間がかかった場合はどうなる？
&lt;/h3&gt;&lt;p&gt;上記のコードでは、1秒ごとに &lt;code&gt;__timeout&lt;/code&gt; 関数が実行されますが、もしその中で処理に時間がかかったとしたらどうなるか？&lt;br&gt;
試しに3秒のスリープを入れてみました（上記のコメントアウトを解除）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:10.458991, 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:13.462465, 2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:16.464238, 3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:19.467192, 4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:22.470589, 10秒経過
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:22.471410, 5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:25.475184, 6
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:28.478740, 15秒経過
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:28.480526, 7
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2023-03-27 14:07:31.484492, 8
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;3秒経過後、すぐに &lt;code&gt;__timeout&lt;/code&gt; がコールされています。&lt;br&gt;
前の処理が完了しないと次の処理は行われないようです。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://fereria.github.io/reincarnation_tech/11_PySide/01_PySide_Basic/00_Tutorial/13_timer/" target="_blank" rel="noopener"
 &gt;https://fereria.github.io/reincarnation_tech/11_PySide/01_PySide_Basic/00_Tutorial/13_timer/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://fereria.github.io/reincarnation_tech/11_PySide/00_Tutorial/13_timer/" target="_blank" rel="noopener"
 &gt;https://fereria.github.io/reincarnation_tech/11_PySide/00_Tutorial/13_timer/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Nginx の proxy_pass で名前解決されない</title><link>https://blog-0847c6.gitlab.io/posts/2023/03/14/nginx/</link><pubDate>Tue, 14 Mar 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/03/14/nginx/</guid><description>&lt;p&gt;nginx を Docker コンテナとして動かしており、ホスト側へリバースプロキシを行おうとした際にはまってしまいました。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;docker 20.10.21&lt;/li&gt;
&lt;li&gt;nginx 1.23.3&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="問題と対策"&gt;&lt;a href="#%e5%95%8f%e9%a1%8c%e3%81%a8%e5%af%be%e7%ad%96" class="header-anchor"&gt;&lt;/a&gt;問題と対策
&lt;/h2&gt;&lt;p&gt;Docker コンテナ内からホストにアクセスする際には &lt;code&gt;host.docker.internal&lt;/code&gt; を指定します。&lt;br&gt;
これについては以下の記事を参照してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2022/06/docker.html" target="_blank" rel="noopener"
 &gt;https://kuttsun.blogspot.com/2022/06/docker.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;その上で、nginx の設定で以下のようにリバースプロキシの設定を行いました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="n"&gt;default_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;hoge&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;resolver&lt;/span&gt; &lt;span class="mf"&gt;127.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.11&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dummy_var&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rewrite&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;hoge&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="o"&gt;/$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dummy_var&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_http_version&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;Upgrade&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;alive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_cache_bypass&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Forwarded&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Forwarded&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Proto&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;すると、以下のように名前解決できないというエラーが表示されました。&lt;/p&gt;
&lt;p&gt;尚、コンテナ内に入って &lt;code&gt;curl&lt;/code&gt; などを使ってテストすると、きちんと &lt;code&gt;host.docker.internal&lt;/code&gt; の名前解決がされていました。&lt;br&gt;
いろいろ調べてみると、どうやら &lt;code&gt;proxy_pass&lt;/code&gt; では &lt;code&gt;/etc/hosts&lt;/code&gt; が参照されないそうです。&lt;/p&gt;
&lt;p&gt;どのように対応しようか悩んでいたところ、&lt;code&gt;upstream&lt;/code&gt; の設定ではきちんと &lt;code&gt;/etc/hosts&lt;/code&gt; が参照されるようでしたので、以下のように設定して回避することにしました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;upstream&lt;/span&gt; &lt;span class="n"&gt;backends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="n"&gt;default_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;hoge&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;resolver&lt;/span&gt; &lt;span class="mf"&gt;127.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.11&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dummy_var&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;backends&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rewrite&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;hoge&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="o"&gt;/$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dummy_var&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_http_version&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;Upgrade&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;alive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_cache_bypass&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Forwarded&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Forwarded&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Proto&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/yKanazawa/items/2136c4880e8d48370981" target="_blank" rel="noopener"
 &gt;https://qiita.com/yKanazawa/items/2136c4880e8d48370981&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://rougeref.hatenablog.com/entry/2022/06/13/185501" target="_blank" rel="noopener"
 &gt;https://rougeref.hatenablog.com/entry/2022/06/13/185501&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/tksugimoto/items/804e0051bf1b1ddab168" target="_blank" rel="noopener"
 &gt;https://qiita.com/tksugimoto/items/804e0051bf1b1ddab168&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Nginx で upstream の 名前解決を無効化（回避）する方法</title><link>https://blog-0847c6.gitlab.io/posts/2023/02/16/nginx/</link><pubDate>Thu, 16 Feb 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/02/16/nginx/</guid><description>&lt;p&gt;Docker で動かしている Nginx でリバースプロキシの設定を行い、別の Docker コンテナに転送するように設定したときにちょっとはまったのでメモです。&lt;/p&gt;
&lt;p&gt;コンテナ同士はコンテナ名を使ってアクセスできるので、Nginx の設定では以下のようにリバースプロキシの設定を行っています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;location /some_path {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_pass http://container-name.docker-network:port;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このとき、Nginx は 起動時に upstream の名前解決を行っているので、上記の URL の名前解決ができない場合（つまり転送先のコンテナが起動していない）と &lt;code&gt;host not found in upstream&lt;/code&gt; というエラーが表示されて起動に失敗します。&lt;/p&gt;
&lt;p&gt;私の場合、仕様によって起動するコンテナの数が異なったり、開発中は一部のコンテナだけ起動して確認したりするので、その都度 Nginx の設定を変えるのは面倒です。&lt;br&gt;
なので、名前解決できなくても Nginx が起動できるように回避策がないかと調べた所、以下の記事に書いてありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://serverfault.com/questions/700894/make-nginx-ignore-site-config-when-its-upstream-cannot-be-reached" target="_blank" rel="noopener"
 &gt;https://serverfault.com/questions/700894/make-nginx-ignore-site-config-when-its-upstream-cannot-be-reached&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;resolver&lt;/code&gt; のディレクティブを使って名前解決してやることで回避できるそうです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;some_path&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;resolver&lt;/span&gt; &lt;span class="mf"&gt;127.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# resolver 8.8.8.8 valid=30s; # or some other DNS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# resolver 127.0.0.11 valid=30s; # or Docker&amp;#39;s DNS server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dummy_var&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dummy_var&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;私の場合、Nginx を Docker で動かしているので、&lt;code&gt;127.0.0.11&lt;/code&gt; をリゾルバに指定することで、転送先のコンテナが起動していなくても Nginx が起動できるようになりました。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://architecting.hateblo.jp/entry/2021/01/12/124135" target="_blank" rel="noopener"
 &gt;https://architecting.hateblo.jp/entry/2021/01/12/124135&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://serverfault.com/questions/700894/make-nginx-ignore-site-config-when-its-upstream-cannot-be-reached" target="_blank" rel="noopener"
 &gt;https://serverfault.com/questions/700894/make-nginx-ignore-site-config-when-its-upstream-cannot-be-reached&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Linux で端末にリアルタイムに日時を表示する</title><link>https://blog-0847c6.gitlab.io/posts/2023/02/02/linux/</link><pubDate>Thu, 02 Feb 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/02/02/linux/</guid><description>&lt;p&gt;&lt;code&gt;watch&lt;/code&gt; コマンドと &lt;code&gt;date&lt;/code&gt; コマンドを組み合わせると簡単にできます。&lt;/p&gt;
&lt;p&gt;例えば以下のような感じです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ watch -t -n 0.01 date +%T.%N
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;watch&lt;/code&gt; は引数で指定したコマンドを一定間隔ごとに繰り返し実行するコマンドです。&lt;br&gt;
&lt;code&gt;-t&lt;/code&gt; はヘッダを非表示にします。&lt;br&gt;
&lt;code&gt;-n&lt;/code&gt; はコマンドを実行する間隔（秒）です。&lt;br&gt;
ここでは &lt;code&gt;date&lt;/code&gt; コマンドを 0.01 秒ごとに実行しています。&lt;br&gt;
&lt;code&gt;+%T.%N&lt;/code&gt; は日時の書式です。&lt;br&gt;
例えば、以下のようにすれば日付も表示されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ watch -t -n 0.01 &amp;#34;date &amp;#39;+%Y/%m/%d %T.%N&amp;#39;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;書式にスペースを含む場合、シングルコーテーションやダブルコーテーションで括る必要があります。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/ikesato/items/4e1d2ff5251f6805b2a0" target="_blank" rel="noopener"
 &gt;https://qiita.com/ikesato/items/4e1d2ff5251f6805b2a0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://hydrocul.github.io/wiki/commands/date.html" target="_blank" rel="noopener"
 &gt;https://hydrocul.github.io/wiki/commands/date.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] asyncio.Queue の動きを確認してみた</title><link>https://blog-0847c6.gitlab.io/posts/2023/02/01/python-asyncio/</link><pubDate>Wed, 01 Feb 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/02/01/python-asyncio/</guid><description>&lt;p&gt;&lt;code&gt;put&lt;/code&gt; や &lt;code&gt;get&lt;/code&gt; がコルーチンになっていたので、どういう動きになるのか確認してみました。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Python 3.8.1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="サンプルコード"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;サンプルコード
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;) before put&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;) after put&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 5回送ったらスリープ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;) get&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;出力は以下のようになりました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(0) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(0) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(1) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(1) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(2) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(2) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(3) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(3) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(4) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(4) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(0) get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(1) get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(2) get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(3) get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(4) get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(5) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(5) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(6) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(6) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(7) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(7) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(8) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(8) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(9) before put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(9) after put
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(5) get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(6) get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(7) get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(8) get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(9) get
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;put&lt;/code&gt; したあと、&lt;code&gt;sleep&lt;/code&gt; したところで制御が他に移っています。&lt;br&gt;
&lt;code&gt;get&lt;/code&gt; のほうは、キューの中身を全部取り終わって次のデータ待ちになったところで制御が他に移っています。&lt;/p&gt;</description></item><item><title>[Python] 同期処理を非同期化して扱う</title><link>https://blog-0847c6.gitlab.io/posts/2023/01/26/python/</link><pubDate>Thu, 26 Jan 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/01/26/python/</guid><description>&lt;p&gt;async のついていない関数を非同期化して、async のついた非同期関数と同じように扱いたいというときの方法です。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;python 3.8.1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="概要"&gt;&lt;a href="#%e6%a6%82%e8%a6%81" class="header-anchor"&gt;&lt;/a&gt;概要
&lt;/h2&gt;&lt;p&gt;同期関数を非同期化するには &lt;code&gt;run_in_executor&lt;/code&gt; を使用します。&lt;/p&gt;
&lt;p&gt;ただし、CPU バウンドな処理を非同期化しても並列では実行されないので、マルチプロセス化などを行う必要があります。
これについては以下の記事が参考になりました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://pod.hatenablog.com/entry/2019/03/21/162511" target="_blank" rel="noopener"
 &gt;https://pod.hatenablog.com/entry/2019/03/21/162511&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;また、&lt;code&gt;run_in_executor&lt;/code&gt; で実行する関数に名前付き引数を渡す場合、&lt;code&gt;functools.partial&lt;/code&gt; を使う必要があります。&lt;/p&gt;
&lt;p&gt;引数で渡せる値は、Python の仕様上 Picklable な値のみだそうです。&lt;br&gt;
ラムダ式やモジュールトップレベル以外で定義された関数やクラスは渡せません&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.python.org/ja/3/library/pickle.html#what-can-be-pickled-and-unpickled" target="_blank" rel="noopener"
 &gt;https://docs.python.org/ja/3/library/pickle.html#what-can-be-pickled-and-unpickled&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="サンプルコード"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;サンプルコード
&lt;/h2&gt;&lt;p&gt;上記を踏まえたサンプルコードです。&lt;br&gt;
同期処理として CPU バウンドを想定した処理を２つ、非同期処理として I/O バウンドを想定した処理を２つ、計４つの処理を並列で動かしています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;functools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ProcessPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cpu_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# CPU バウンドな処理を想定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cpu_bound[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;] count=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;io_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# I/O バウンドな処理を想定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;io_bound[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;] count=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_running_loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProcessPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_workers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run_in_executor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpu_bound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run_in_executor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpu_bound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;io_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;io_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;ProcessPoolExecutor&lt;/code&gt; により、CPU バウンドな処理はそれぞれ個別のプロセスとして動作させています。&lt;br&gt;
I/O バウンドな処理はどちらもメインプロセスで動作します。&lt;br&gt;
従って、I/O バウンドな処理のほうが少し終わるのが遅くなります。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://cpoint-lab.co.jp/article/202208/23186/" target="_blank" rel="noopener"
 &gt;https://cpoint-lab.co.jp/article/202208/23186/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://pod.hatenablog.com/entry/2019/03/21/162511" target="_blank" rel="noopener"
 &gt;https://pod.hatenablog.com/entry/2019/03/21/162511&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://hachibeedi.github.io/entry/unify-sync-and-async-function-in-python/" target="_blank" rel="noopener"
 &gt;https://hachibeedi.github.io/entry/unify-sync-and-async-function-in-python/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/smatsumt/items/d8f290e40077a14210f2" target="_blank" rel="noopener"
 &gt;https://qiita.com/smatsumt/items/d8f290e40077a14210f2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.python.org/ja/3/library/pickle.html#what-can-be-pickled-and-unpickled" target="_blank" rel="noopener"
 &gt;https://docs.python.org/ja/3/library/pickle.html#what-can-be-pickled-and-unpickled&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Grafana Cloud で InfluxDB v2 のデータを可視化する</title><link>https://blog-0847c6.gitlab.io/posts/2023/01/06/influxdb-cloud/</link><pubDate>Fri, 06 Jan 2023 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2023/01/06/influxdb-cloud/</guid><description>&lt;p&gt;InfluxDB v2 ではそれ自体でダッシュボードの作成もできますが、まだまだ使いにくかったり細かい設定ができなかったりしたので、使い慣れている Grafana を使うことにしました。&lt;br&gt;
また、この機会に Grafana もオンプレミス版からクラウドサービスの Grafana Cloud に変更しました。&lt;/p&gt;
&lt;p&gt;Grafana Cloud へのサインアップ方法などは割愛します。&lt;/p&gt;
&lt;h2 id="データソースの設定"&gt;&lt;a href="#%e3%83%87%e3%83%bc%e3%82%bf%e3%82%bd%e3%83%bc%e3%82%b9%e3%81%ae%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;データソースの設定
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;サイドメニューから &lt;code&gt;Data Sources&lt;/code&gt; を選択します。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Add data source&lt;/code&gt; をクリックし、&lt;code&gt;InfluxDB&lt;/code&gt; をクリックします。&lt;/li&gt;
&lt;li&gt;InfluxDB の情報を入力します。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;InfluxDB Cloud の場合、&lt;code&gt;Query Language&lt;/code&gt; は &lt;code&gt;Flux&lt;/code&gt; を選択します。&lt;br&gt;
また、URL, トークン、バケット名が必要になるので、以下を参考に取得しておきます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2022/12/influxdb-cloud.html" target="_blank" rel="noopener"
 &gt;https://kuttsun.blogspot.com/2022/12/influxdb-cloud.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ダッシュボードパネルの作成"&gt;&lt;a href="#%e3%83%80%e3%83%83%e3%82%b7%e3%83%a5%e3%83%9c%e3%83%bc%e3%83%89%e3%83%91%e3%83%8d%e3%83%ab%e3%81%ae%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;ダッシュボード（パネル）の作成
&lt;/h2&gt;&lt;p&gt;InfluxDB v1 では GUI でポチポチと設定していくだけでグラフが表示できましたが、InfluxDB v2 では Flux で処理を書いていく必要があります。&lt;br&gt;
最初は難しかったですが、慣れればこちらのほうが簡単に思えてきました。&lt;br&gt;
いくつか例を挙げます。&lt;/p&gt;
&lt;h3 id="基本"&gt;&lt;a href="#%e5%9f%ba%e6%9c%ac" class="header-anchor"&gt;&lt;/a&gt;基本
&lt;/h3&gt;&lt;p&gt;以下にサンプルがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://grafana.com/docs/grafana/latest/datasources/influxdb/query-editor/#use-macros" target="_blank" rel="noopener"
 &gt;https://grafana.com/docs/grafana/latest/datasources/influxdb/query-editor/#use-macros&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from(bucket:&amp;#34;バケット名&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; range(start: v.timeRangeStart, stop: v.timeRangeStop)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; filter(fn:(r) =&amp;gt; r._measurement == &amp;#34;メジャーメント名&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; filter(fn:(r) =&amp;gt; r[&amp;#34;_field&amp;#34;] == &amp;#34;表示したいフィールドの名前&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; aggregateWindow(every: v.windowPeriod, fn: mean)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;基本的にはこれでグラフが作成できます。&lt;/p&gt;
&lt;h3 id="一日ごとのデータを表示"&gt;&lt;a href="#%e4%b8%80%e6%97%a5%e3%81%94%e3%81%a8%e3%81%ae%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e8%a1%a8%e7%a4%ba" class="header-anchor"&gt;&lt;/a&gt;一日ごとのデータを表示
&lt;/h3&gt;&lt;p&gt;例えば株価の終値を表示したい場合などは以下のようにすることでできました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import &amp;#34;timezone&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;option location = timezone.location(name: &amp;#34;Asia/Tokyo&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from(bucket:&amp;#34;バケット名&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; range(start: -30d, stop: now())
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; filter(fn:(r) =&amp;gt; r._measurement == &amp;#34;メジャーメント名&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; filter(fn:(r) =&amp;gt; r[&amp;#34;_field&amp;#34;] == &amp;#34;表示したいフィールドの名前&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; aggregateWindow(every: 1d, fn: last)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ポイントは &lt;code&gt;aggregateWindow(every: 1d, fn: last)&lt;/code&gt; で、一日ごとの最後の値を取得しています。&lt;/p&gt;
&lt;p&gt;また、タイムゾーンを指定しないと UTC での終値（つまり、日本時間の9時の時点の値）が取得されてしまったので、JST を指定しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.influxdata.com/blog/time-zones-in-flux/" target="_blank" rel="noopener"
 &gt;https://www.influxdata.com/blog/time-zones-in-flux/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尚、私の場合はグラフではなくテーブル表示にしたかったため、グラフの表示期間に関わらず &lt;code&gt;range(start: -30d, stop: now())&lt;/code&gt; で直近30日固定表示にしています。&lt;/p&gt;
&lt;h3 id="累積グラフの作成"&gt;&lt;a href="#%e7%b4%af%e7%a9%8d%e3%82%b0%e3%83%a9%e3%83%95%e3%81%ae%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;累積グラフの作成
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;cumulativeSum&lt;/code&gt; を使います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.influxdata.com/influxdb/cloud/query-data/flux/cumulativesum/" target="_blank" rel="noopener"
 &gt;https://docs.influxdata.com/influxdb/cloud/query-data/flux/cumulativesum/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例えば、日次損益の集計を行う場合などは以下のようにするとできました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import &amp;#34;timezone&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;option location = timezone.location(name: &amp;#34;Asia/Tokyo&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from(bucket:&amp;#34;バケット名&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; range(start: -30d, stop: now())
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; filter(fn:(r) =&amp;gt; r._measurement == &amp;#34;メジャーメント名&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; filter(fn:(r) =&amp;gt; r[&amp;#34;_field&amp;#34;] == &amp;#34;表示したいフィールドの名前&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; aggregateWindow(every: 1d, fn: last)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; cumulativeSum()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一日ごとの値は取り出す方法は前述の例と同じです。&lt;br&gt;
あとはそれを &lt;code&gt;cumulativeSum()&lt;/code&gt; で加算していくだけです。&lt;br&gt;
これにより、一日ごとの値を加算してグラフに表示できます。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/aikige/items/22dc9ebc64e32a5bdfae" target="_blank" rel="noopener"
 &gt;https://qiita.com/aikige/items/22dc9ebc64e32a5bdfae&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/ekzemplaro/items/f462dfc0d81329b39c09" target="_blank" rel="noopener"
 &gt;https://qiita.com/ekzemplaro/items/f462dfc0d81329b39c09&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://rabbit-note.com/2022/09/12/influxdb-2-flux/" target="_blank" rel="noopener"
 &gt;https://rabbit-note.com/2022/09/12/influxdb-2-flux/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Influxdb Cloud を使ってみた</title><link>https://blog-0847c6.gitlab.io/posts/2022/12/26/influxdb-cloud/</link><pubDate>Mon, 26 Dec 2022 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2022/12/26/influxdb-cloud/</guid><description>&lt;p&gt;今までは AWS や GCP 上に InfluxDB の環境を用意して使っていたのですが、InfluxDB Cloud というクラウドサービスがあることを知ったので、使ってみました。&lt;br&gt;
バージョンも今までは v1 を使っていましたが、クラウドなので v2 に変わります。&lt;/p&gt;
&lt;h2 id="準備"&gt;&lt;a href="#%e6%ba%96%e5%82%99" class="header-anchor"&gt;&lt;/a&gt;準備
&lt;/h2&gt;&lt;h3 id="バケットの作成"&gt;&lt;a href="#%e3%83%90%e3%82%b1%e3%83%83%e3%83%88%e3%81%ae%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;バケットの作成
&lt;/h3&gt;&lt;p&gt;InfluxDB v1 系でいう、データベースとリテンションポリシーを合わせたようなものかなと思います。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;サイドメニューより &lt;code&gt;Load Data&lt;/code&gt; &amp;gt; &lt;code&gt;Buckets&lt;/code&gt; を選択します。&lt;/li&gt;
&lt;li&gt;画面右側の &lt;code&gt;GENERATE BUCKET&lt;/code&gt; &amp;gt; クリックします。&lt;/li&gt;
&lt;li&gt;バケット名を入力し、必要に応じてデータの保存期間を指定します（デフォルトでは 30 日経ったら古いデータが削除されます）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="343px" data-flex-grow="143" height="454" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog-0847c6.gitlab.io/posts/2022/12/26/influxdb-cloud/01.png" width="650"&gt;&lt;/p&gt;
&lt;h3 id="トークンの取得"&gt;&lt;a href="#%e3%83%88%e3%83%bc%e3%82%af%e3%83%b3%e3%81%ae%e5%8f%96%e5%be%97" class="header-anchor"&gt;&lt;/a&gt;トークンの取得
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;サイドメニューより &lt;code&gt;Load Data&lt;/code&gt; &amp;gt; &lt;code&gt;API Tokens&lt;/code&gt; を選択します。&lt;/li&gt;
&lt;li&gt;画面右側の &lt;code&gt;GENERATE API TOKEN&lt;/code&gt; &amp;gt; &lt;code&gt;All Access API Token&lt;/code&gt; を選択します。&lt;/li&gt;
&lt;li&gt;トークンが表示されるのでコピーします。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;コピーしたトークンは環境変数などに設定して使います。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;INFLUX_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;コピーしたトークン&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="url-の取得"&gt;&lt;a href="#url-%e3%81%ae%e5%8f%96%e5%be%97" class="header-anchor"&gt;&lt;/a&gt;URL の取得
&lt;/h3&gt;&lt;p&gt;API エンドポイントとなる URL は以下で取得できます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;画面上部のメールアドレスを選択 &amp;gt; &lt;code&gt;Settings&lt;/code&gt; をクリック&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="python-からデータを書き込む"&gt;&lt;a href="#python-%e3%81%8b%e3%82%89%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e6%9b%b8%e3%81%8d%e8%be%bc%e3%82%80" class="header-anchor"&gt;&lt;/a&gt;Python からデータを書き込む
&lt;/h2&gt;&lt;p&gt;以下の記事を参考にしてください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2022/12/python-influxdb-18-influxdbclient.html" target="_blank" rel="noopener"
 &gt;https://kuttsun.blogspot.com/2022/12/python-influxdb-18-influxdbclient.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;必要な情報はバケット名、トークン、URL です。&lt;/p&gt;
&lt;h2 id="ダッシュボードの作成"&gt;&lt;a href="#%e3%83%80%e3%83%83%e3%82%b7%e3%83%a5%e3%83%9c%e3%83%bc%e3%83%89%e3%81%ae%e4%bd%9c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;ダッシュボードの作成
&lt;/h2&gt;&lt;p&gt;別途記事にします。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://dev.classmethod.jp/articles/send-and-visualize-data-with-influxdb-cloud/" target="_blank" rel="noopener"
 &gt;https://dev.classmethod.jp/articles/send-and-visualize-data-with-influxdb-cloud/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] InfluxDB 1.8 で influxdb_client を使う</title><link>https://blog-0847c6.gitlab.io/posts/2022/12/21/influxdb-client/</link><pubDate>Wed, 21 Dec 2022 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2022/12/21/influxdb-client/</guid><description>&lt;p&gt;python で InfluxDB v1 に対してデータの読み書きを行う際に、ayncio を使って非同期化したいなと思ったのですが、今使っているライブラリの InfluxDBClient は asyncio に対応していないようでした。&lt;/p&gt;
&lt;p&gt;代わりに influxdata 社の influx-client を使うと asyncio を使えそうだったのですが、こちらは基本的に InfluxDB v2 以降にのみ対応しているようで、Flux という言語にしか対応していません。&lt;br&gt;
InfluxDB v1 以前は InfluxQL という SQL に近い言語が使われていました。&lt;/p&gt;
&lt;p&gt;こちら、以下のページが参考になりました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://rabbit-note.com/2022/09/12/influxdb-2-flux/" target="_blank" rel="noopener"
 &gt;https://rabbit-note.com/2022/09/12/influxdb-2-flux/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ただ、InfluxDB 1.7以降でも設定を変更することで Flux が使えるようになるそうです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/influxdata/influxdb-client-python#influxdb-1-8-api-compatibility" target="_blank" rel="noopener"
 &gt;https://github.com/influxdata/influxdb-client-python#influxdb-1-8-api-compatibility&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;従って、InfluxDB v1 でも Flux を有効にしたうえで、Flux でクエリを記述してデータを取得するようにすれば、asyncio を使って非同期化することができそうです。&lt;br&gt;
ちなみに、データの書き込みに関しては Flux は関係ありませんでした。&lt;/p&gt;
&lt;p&gt;以下、InfluxDB v1 の前提で書いていますが、v2 でも基本的には同じです。&lt;br&gt;
&lt;code&gt;bucket&lt;/code&gt; &lt;code&gt;token&lt;/code&gt; の指定方法が異なるだけです。&lt;/p&gt;
&lt;h2 id="環境"&gt;&lt;a href="#%e7%92%b0%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;環境
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;InfluxDB 1.8.10&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="flux-言語を有効化する"&gt;&lt;a href="#flux-%e8%a8%80%e8%aa%9e%e3%82%92%e6%9c%89%e5%8a%b9%e5%8c%96%e3%81%99%e3%82%8b" class="header-anchor"&gt;&lt;/a&gt;Flux 言語を有効化する
&lt;/h2&gt;&lt;p&gt;InfluxDB を Docker で動かしていたのですが、環境変数に以下を追加するだけで OK でした。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;INFLUXDB_HTTP_FLUX_ENABLED=true
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="サンプルコード"&gt;&lt;a href="#%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89" class="header-anchor"&gt;&lt;/a&gt;サンプルコード
&lt;/h2&gt;&lt;h3 id="データの書き込み-write_api"&gt;&lt;a href="#%e3%83%87%e3%83%bc%e3%82%bf%e3%81%ae%e6%9b%b8%e3%81%8d%e8%be%bc%e3%81%bf-write_api" class="header-anchor"&gt;&lt;/a&gt;データの書き込み (write_api)
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import asyncio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from influxdb_client.client.influxdb_client_async import InfluxDBClientAsync
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from influxdb_client.client.write.point import Point
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from influxdb_client.domain.write_precision import WritePrecision
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;if __name__ == &amp;#39;__main__&amp;#39;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; async def main():
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; url = &amp;#39;http://&amp;lt;url&amp;gt;:8086&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; username = &amp;#39;username&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; password = &amp;#39;password&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dbname = &amp;#39;dbname&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; rpname = &amp;#39;rpname&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; # https://zeppelin.apache.org/docs/0.10.1/interpreter/influxdb.html
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; bucket = f&amp;#39;{dbname}/{rpname}&amp;#39; # InfluxDB 1.8 では dbname/rpname がバケット名として使われる
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; token = f&amp;#39;{username}:{password}&amp;#39; # InfluxDB 1.8 では username:password がトークンとして使われる
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; org = &amp;#34;-&amp;#34; # InfluxDB 1.8 ではよくわからん
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; data = []
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; data.append({
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#39;fields&amp;#39;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#39;hoge&amp;#39;: 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#39;measurement&amp;#39;: &amp;#39;measurement&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#39;tags&amp;#39;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#39;hostname&amp;#39;: &amp;#39;hostname&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; points = [ Point.from_dict(i, WritePrecision.MS) for i in data ]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; async with InfluxDBClientAsync(url=url, token=token, org=org) as client:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; write_api = client.write_api()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; successfully = await write_api.write(bucket=bucket, record=points)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(successfully)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="データの読み込み-query_api"&gt;&lt;a href="#%e3%83%87%e3%83%bc%e3%82%bf%e3%81%ae%e8%aa%ad%e3%81%bf%e8%be%bc%e3%81%bf-query_api" class="header-anchor"&gt;&lt;/a&gt;データの読み込み (query_api)
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import asyncio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from influxdb_client.client.influxdb_client_async import InfluxDBClientAsync
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;if __name__ == &amp;#39;__main__&amp;#39;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; async def main():
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; url = &amp;#39;http://&amp;lt;url&amp;gt;:8086&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; username = &amp;#39;username&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; password = &amp;#39;password&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dbname = &amp;#39;dbname&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; rpname = &amp;#39;rpname&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; # https://zeppelin.apache.org/docs/0.10.1/interpreter/influxdb.html
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; bucket = f&amp;#39;{dbname}/{rpname}&amp;#39; # InfluxDB 1.8 では dbname/rpname がバケット名として使われる
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; token = f&amp;#39;{username}:{password}&amp;#39; # InfluxDB 1.8 では username:password がトークンとして使われる
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; org = &amp;#34;-&amp;#34; # InfluxDB 1.8 ではよくわからん
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; query = f&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; from(bucket: &amp;#34;{bucket}&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; range(start: -10m)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; filter(fn:(r) =&amp;gt; r._measurement == &amp;#34;measurement&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; filter(fn: (r) =&amp;gt; r[&amp;#34;_field&amp;#34;] == &amp;#34;field&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&amp;gt; aggregateWindow(every: 1m, fn: mean, createEmpty: false)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; async with InfluxDBClientAsync(url=url, token=token, org=org) as client:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; tables = await client.query_api().query(query=query)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; for table in tables:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(table)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; for record in table.records:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print (record.values)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; asyncio.run(main())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Flux については以下のページが参考になりました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qiita.com/riverplus/items/20456e4188a4c0f5f62d" target="_blank" rel="noopener"
 &gt;https://qiita.com/riverplus/items/20456e4188a4c0f5f62d&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://powersj.io/posts/influxdb-docker-dev/" target="_blank" rel="noopener"
 &gt;https://powersj.io/posts/influxdb-docker-dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/influxdata/influxdb-client-python#async-write-api" target="_blank" rel="noopener"
 &gt;https://github.com/influxdata/influxdb-client-python#async-write-api&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://influxdb-client.readthedocs.io/en/stable/api.html#queryapi" target="_blank" rel="noopener"
 &gt;https://influxdb-client.readthedocs.io/en/stable/api.html#queryapi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Grafana から Rocket.Chat へ通知を行う</title><link>https://blog-0847c6.gitlab.io/posts/2022/12/13/grafana-rocketchat/</link><pubDate>Tue, 13 Dec 2022 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2022/12/13/grafana-rocketchat/</guid><description>&lt;p&gt;Grafana 自体は Rocket.Chat に対応していませんが、Webhook を使うことで Rocket.Chat に通知できます。&lt;br&gt;
アラートの基本的な設定方法については以下を参照してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2022/11/grafana.html" target="_blank" rel="noopener"
 &gt;Grafana でアラートを設定する&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ここでは Rocket.Chat への通知の設定のみ記載します。&lt;/p&gt;
&lt;h2 id="rocketchat-側の設定"&gt;&lt;a href="#rocketchat-%e5%81%b4%e3%81%ae%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;Rocket.Chat 側の設定
&lt;/h2&gt;&lt;p&gt;管理画面のメニューから &lt;code&gt;サービス連携&lt;/code&gt; を選択し、&lt;code&gt;Incoming&lt;/code&gt; で新規作成を行います。&lt;br&gt;
スクリプトを有効にし、以下のスクリプトを記入します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;class Script {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; process_incoming_request({ request }) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; let color = &amp;#34;#00FF00&amp;#34;; // green
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; switch(request.content.state) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; case &amp;#39;ok&amp;#39;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; color = &amp;#39;#00FF00&amp;#39;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; break;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; case &amp;#39;paused&amp;#39;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; color = &amp;#39;#666666&amp;#39;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; break;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; case &amp;#39;alerting&amp;#39;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; color = &amp;#39;#FF0000&amp;#39;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; break;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; case &amp;#39;pending&amp;#39;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; color = &amp;#39;#CCCCCC&amp;#39;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; break;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; case &amp;#39;no_data&amp;#39;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; color = &amp;#39;#333333&amp;#39;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; break;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; default:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; color = &amp;#39;#666666&amp;#39;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; content:{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; text: request.content.title,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;attachments&amp;#34;: [{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;color&amp;#34;: color,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;title&amp;#34;: request.content.title,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;title_link&amp;#34;: request.content.ruleUrl,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;text&amp;#34;: request.content.message,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;image_url&amp;#34;: request.content.imageUrl,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;その他、投稿先チャンネルや投稿ユーザーなどの基本的な設定を行います。&lt;br&gt;
Grafana の設定で Webhook URL が必要になるのでコピーしておきます。&lt;/p&gt;
&lt;h2 id="grafana-側の設定"&gt;&lt;a href="#grafana-%e5%81%b4%e3%81%ae%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;Grafana 側の設定
&lt;/h2&gt;&lt;p&gt;Grafana のサイドメニューから &lt;code&gt;Alert rules&lt;/code&gt; を選択し、&lt;code&gt;Contact Points&lt;/code&gt; で以下の設定を行います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;New contact point&lt;/code&gt; をクリック&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Name&lt;/code&gt; にはわかりやすい名前を適当に入力する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Contact point type&lt;/code&gt; で &lt;code&gt;Webhook&lt;/code&gt; を選択する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Webhook URL&lt;/code&gt; に上記で取得した URL を入力する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rocket.Chat に関する設定は以上で完了です。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://gist.github.com/ATofighi/79895715ae0a8f5bdeff058a64012275" target="_blank" rel="noopener"
 &gt;https://gist.github.com/ATofighi/79895715ae0a8f5bdeff058a64012275&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Grafana から Slack へ通知を行う</title><link>https://blog-0847c6.gitlab.io/posts/2022/12/07/grafana-slack/</link><pubDate>Wed, 07 Dec 2022 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2022/12/07/grafana-slack/</guid><description>&lt;p&gt;Grafana のアラートで Slack のチャンネルへ通知を行う方法です。&lt;br&gt;
アラートの基本的な設定方法については以下を参照してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kuttsun.blogspot.com/2022/11/grafana.html" target="_blank" rel="noopener"
 &gt;Grafana でアラートを設定する&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ここでは Slack への通知の設定のみ記載します。&lt;/p&gt;
&lt;h2 id="webhook-url-の取得"&gt;&lt;a href="#webhook-url-%e3%81%ae%e5%8f%96%e5%be%97" class="header-anchor"&gt;&lt;/a&gt;Webhook URL の取得
&lt;/h2&gt;&lt;p&gt;まず、通知したい Slack のチャンネルの Webhook URL を取得します。
Webhook URL は、以下からワークスペースとチャンネルを指定して取得できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://slack.com/services/new/incoming-webhook" target="_blank" rel="noopener"
 &gt;https://slack.com/services/new/incoming-webhook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="contact-point-の設定"&gt;&lt;a href="#contact-point-%e3%81%ae%e8%a8%ad%e5%ae%9a" class="header-anchor"&gt;&lt;/a&gt;Contact Point の設定
&lt;/h2&gt;&lt;p&gt;Grafana のサイドメニューから &lt;code&gt;Alert rules&lt;/code&gt; を選択し、&lt;code&gt;Contact Points&lt;/code&gt; で以下の設定を行います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;New contact point&lt;/code&gt; をクリック&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Name&lt;/code&gt; にはわかりやすい名前を適当に入力する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Contact point type&lt;/code&gt; で &lt;code&gt;Slack&lt;/code&gt; を選択する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Webhook URL&lt;/code&gt; に上記で取得した URL を入力する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Slack に関する設定は以上です。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://fclout.hateblo.jp/entry/2020/06/20/Grafana%E3%81%8B%E3%82%89Slack%E3%81%B8%E9%80%9A%E7%9F%A5%E3%81%99%E3%82%8B" target="_blank" rel="noopener"
 &gt;https://fclout.hateblo.jp/entry/2020/06/20/Grafana%E3%81%8B%E3%82%89Slack%E3%81%B8%E9%80%9A%E7%9F%A5%E3%81%99%E3%82%8B&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ubuntu の Emergency Mode で日本語配列のキーボードを使う</title><link>https://blog-0847c6.gitlab.io/posts/2022/12/02/ubuntu/</link><pubDate>Fri, 02 Dec 2022 00:00:00 +0900</pubDate><guid>https://blog-0847c6.gitlab.io/posts/2022/12/02/ubuntu/</guid><description>&lt;p&gt;Ubuntu 18.04 が emergency mode で起動した時に、キーボードの配列が日本語配列になっていなくて困ったのでメモです。&lt;/p&gt;
&lt;p&gt;以下を実行すれば日本語配列のキーボードが使えるようになりました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;loadkeys&lt;/span&gt; &lt;span class="n"&gt;jp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;尚、上記のコマンドを入力するために、私の環境では以下のようにキーを押す必要がありました。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: center"&gt;入力したい文字&lt;/th&gt;
 &lt;th style="text-align: center"&gt;実際に押したキー&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;l&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;k&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;o&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;o&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;左下の ctrl&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;k&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;j&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;e&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;e&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;スペース&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;.&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;j&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;h&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;p&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;code&gt;p&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これが何の配列になっていたのかはわかりませんでした。&lt;/p&gt;
&lt;h2 id="参考-url"&gt;&lt;a href="#%e5%8f%82%e8%80%83-url" class="header-anchor"&gt;&lt;/a&gt;参考 URL
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kledgeb.blogspot.com/2016/05/ubuntu-1604-60.html" target="_blank" rel="noopener"
 &gt;https://kledgeb.blogspot.com/2016/05/ubuntu-1604-60.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>