<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>松本 侑真 — #docker</title><description>「docker」タグの記事フィード</description><link>https://yuuma.dev/</link><item><title>Uvicornを用いたFlaskの本番起動について</title><link>https://yuuma.dev/blog/flask-uvicorn/</link><guid isPermaLink="true">https://yuuma.dev/blog/flask-uvicorn/</guid><description>Flaskで作成したAPIを本番環境で起動する方法について説明します。Traefikをリバースプロキシとして利用し、UvicornでFlaskアプリケーションを起動します。</description><pubDate>Sat, 14 Feb 2026 13:04:43 GMT</pubDate><content:encoded>&lt;!-- cmd+option+v: ImagePaste --&gt;
&lt;p&gt;&lt;picture&gt;
  &lt;source srcset=&quot;/blog/img/flask-uvicorn/2026-02-15-02-27-53.avif&quot; type=&quot;image/avif&quot;&gt;
  &lt;source srcset=&quot;/blog/img/flask-uvicorn/2026-02-15-02-27-53.webp&quot; type=&quot;image/webp&quot;&gt;
  &lt;img src=&quot;https://yuuma.dev/blog/img/flask-uvicorn/2026-02-15-02-27-53.png&quot; alt=&quot;2026-02-15-02-27-53&quot; style=&quot;max-height:480px;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;h2 id=&quot;想定する基本的なディレクトリ構成&quot;&gt;&lt;a href=&quot;#想定する基本的なディレクトリ構成&quot; class=&quot;heading-link&quot;&gt;想定する基本的なディレクトリ構成&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;flaskアプリのディレクトリ構成&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#0DB9D7&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;├─&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; templates&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;│&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;   ├─&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; index.html&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;│&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;   └─&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; result.html&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;├─&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; Dockerfile&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;├─&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; app.py&lt;/span&gt;&lt;span style=&quot;color:#6A737D;--shiki-light-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic&quot;&gt;      # Flaskアプリケーションのエントリーポイント&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;├─&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; asgi.py&lt;/span&gt;&lt;span style=&quot;color:#6A737D;--shiki-light-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic&quot;&gt;     # ASGIアプリ化を行うためのファイル&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;├─&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; compose.yml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;├─&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; pyproject.toml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;└─&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; uv.lock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-3&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;app.py&lt;/code&gt; にはFlaskアプリケーションのコードが記述されています。
これらは &lt;code&gt;uv&lt;/code&gt; で管理されているプロジェクトとしています。&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;app.py&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#7DCFFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; flask &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#7DCFFF&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; Flask&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; render_template&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;app &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt; Flask&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#C0CAF5&quot;&gt;__name__&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt; solve_problem&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;    results &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#E0AF68&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; results&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#89DDFF&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E36209;--shiki-dark:#E0AF68&quot;&gt; methods&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;GET&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt; index&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt; render_template&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;index.html&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#89DDFF&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;/solve&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E36209;--shiki-dark:#E0AF68&quot;&gt; methods&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;POST&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt; solve&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;    results &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt; solve_problem&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt; render_template&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;result.html&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E36209;--shiki-dark:#E0AF68&quot;&gt; results&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#C0CAF5&quot;&gt;results&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#C0CAF5&quot;&gt; __name__&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;__main__&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;    app&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E36209;--shiki-dark:#E0AF68&quot;&gt;debug&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E36209;--shiki-dark:#E0AF68&quot;&gt; port&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt;5000&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E36209;--shiki-dark:#E0AF68&quot;&gt; threaded&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-4&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;アプリ開発時のflaskの起動方法&quot;&gt;&lt;a href=&quot;#アプリ開発時のflaskの起動方法&quot; class=&quot;heading-link&quot;&gt;アプリ開発時のFlaskの起動方法&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv run&lt;/code&gt; コマンドで開発サーバーを起動します。&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;uv&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; flask&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-5&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;このコマンドを実行すると、Flaskに内蔵されている簡易サーバー (Werkzeug) が起動し、&lt;code&gt;http://localhost:5000&lt;/code&gt; でアプリケーションにアクセスできるようになります。&lt;/p&gt;
&lt;p&gt;しかしWerkzeugは開発用のサーバーであり、本番環境での使用は推奨されていません。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;セキュリティ的に脆弱である&lt;/li&gt;
&lt;li&gt;パフォーマンスが低い&lt;/li&gt;
&lt;li&gt;安定性や運用機能がない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ことが理由です。&lt;/p&gt;
&lt;h2 id=&quot;本番環境でのflask起動方法&quot;&gt;&lt;a href=&quot;#本番環境でのflask起動方法&quot; class=&quot;heading-link&quot;&gt;本番環境でのFlask起動方法&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;本番環境では、&lt;code&gt;Gunicorn&lt;/code&gt; や &lt;code&gt;uWSGI&lt;/code&gt; といったWSGIサーバー、あるいは &lt;code&gt;Uvicorn&lt;/code&gt; といったASGIサーバーを使用してFlaskアプリケーションを起動します。
これらはPython向けの本番用サーバーモジュールで、本番運用を想定したセキュリティやパフォーマンスを提供します。&lt;/p&gt;
&lt;h3 id=&quot;uvicornを用いたflaskの起動&quot;&gt;&lt;a href=&quot;#uvicornを用いたflaskの起動&quot; class=&quot;heading-link&quot;&gt;Uvicornを用いたFlaskの起動&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h3&gt;
&lt;details class=&quot;callout callout-important&quot; open&gt;
&lt;summary class=&quot;callout-title callout-title-important&quot;&gt;&lt;svg fill=&quot;none&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; stroke=&quot;currentColor&quot; viewBox=&quot;0 0 24 24&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: visible; color: currentcolor;&quot;&gt;&lt;path fill=&quot;currentColor&quot; fill-rule=&quot;evenodd&quot; d=&quot;M11.484 2.17a.75.75 0 0 1 1.032 0 11.209 11.209 0 0 0 7.877 3.08.75.75 0 0 1 .722.515 12.74 12.74 0 0 1 .635 3.985c0 5.942-4.064 10.933-9.563 12.348a.749.749 0 0 1-.374 0C6.314 20.683 2.25 15.692 2.25 9.75c0-1.39.223-2.73.635-3.985a.75.75 0 0 1 .722-.516l.143.001c2.996 0 5.718-1.17 7.734-3.08ZM12 8.25a.75.75 0 0 1 .75.75v3.75a.75.75 0 0 1-1.5 0V9a.75.75 0 0 1 .75-.75ZM12 15a.75.75 0 0 0-.75.75v.008c0 .414.336.75.75.75h.008a.75.75 0 0 0 .75-.75v-.008a.75.75 0 0 0-.75-.75H12Z&quot; clip-rule=&quot;evenodd&quot;&gt;&lt;/path&gt;&lt;/svg&gt;Important&lt;/summary&gt;
&lt;p&gt;結論：&lt;code&gt;Flask&lt;/code&gt; をASGIアプリ化すれば &lt;code&gt;Uvicorn&lt;/code&gt; で起動できる。&lt;/p&gt;
&lt;/details&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;asgi.py（ASGI変換コード）&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#7DCFFF&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; os&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#7DCFFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; asgiref&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;wsgi &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#7DCFFF&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; WsgiToAsgi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#7DCFFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; app &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#7DCFFF&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; app &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#7DCFFF&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; flask_app &lt;/span&gt;&lt;span style=&quot;color:#6A737D;--shiki-light-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic&quot;&gt;# Flask APPのインポート&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;app &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt; WsgiToAsgi&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#C0CAF5&quot;&gt;flask_app&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-6&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;Uvicornでの起動コマンド&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt;uv&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; uvicorn&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; asgi:app&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#89DDFF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#E0AF68&quot;&gt;    --host&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt; 0.0.0.0&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#89DDFF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#E0AF68&quot;&gt;    --port&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt; 8000&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#89DDFF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#E0AF68&quot;&gt;    --workers&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-7&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;traefikをリバースプロキシとして利用する&quot;&gt;&lt;a href=&quot;#traefikをリバースプロキシとして利用する&quot; class=&quot;heading-link&quot;&gt;Traefikをリバースプロキシとして利用する&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;既にTraefikをコンテナで起動して、&lt;code&gt;app-gallery&lt;/code&gt; ネットワークに接続している前提とします。&lt;/p&gt;
&lt;p&gt;Flaskアプリケーションを起動するための &lt;code&gt;compose.yml&lt;/code&gt; には、Traefikのルーティング設定を行うためのラベルを追加します。&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;compose.yml（Traefikを用いたパスルーティング）&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;  gallery&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;    build&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;      context&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt; .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;      dockerfile&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; Dockerfile&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;    networks&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;app-gallery&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;    env_file&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;      -&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt; .env&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;    labels&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;      -&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.enable=true&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;      -&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.routers.${APP_ID}.rule=Host(`${APP_HOST}`) &amp;#x26;&amp;#x26; PathPrefix(`/${APP_ID}`)&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;      -&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.routers.${APP_ID}.entrypoints=web&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#6A737D;--shiki-light-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic&quot;&gt; # 80番ポートから来た通信のみを処理する&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;      -&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.services.${APP_ID}.loadbalancer.server.port=${APP_PORT}&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D;--shiki-light-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic&quot;&gt;      # - &quot;traefik.http.middlewares.${APP_ID}-strip.stripprefix.prefixes=/${APP_ID}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D;--shiki-light-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic&quot;&gt;      # - &quot;traefik.http.routers.${APP_ID}.middlewares=${APP_ID}-strip&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;networks&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;  app-gallery&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22863A;--shiki-dark:#F7768E&quot;&gt;    external&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt; true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-8&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;以下でこれらの設定内容を説明します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ルーティング条件&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Hostが &lt;code&gt;${APP_HOST}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;かつ、パスが &lt;code&gt;/${APP_ID}&lt;/code&gt; で始まる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ルクエストだけをこのサービスに流す&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.routers.${APP_ID}.rule=Host(`${APP_HOST}`) &amp;#x26;&amp;#x26; PathPrefix(`/${APP_ID}`)&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-9&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;転送先ポート&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Flaskアプリの起動コマンドで指定したポートをTraefikに伝える&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.services.${APP_ID}.loadbalancer.server.port=${APP_PORT}&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-10&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;traefikのルーティングに対応させたミドルウェア設定&quot;&gt;&lt;a href=&quot;#traefikのルーティングに対応させたミドルウェア設定&quot; class=&quot;heading-link&quot;&gt;Traefikのルーティングに対応させたミドルウェア設定&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Traefikを使うことで、&lt;code&gt;host/${APP_ID}&lt;/code&gt; というパスでFlaskアプリケーションにアクセスできるようになります。&lt;/p&gt;
&lt;p&gt;一方で、Flaskアプリケーション側ではリクエストのパスが &lt;code&gt;/${APP_ID}&lt;/code&gt; から始まることを想定していないため、ルーティングエラーが発生してしまいます。&lt;/p&gt;
&lt;p&gt;これらの問題を解決するために、Flaskアプリケーション側でリクエストのパスから &lt;code&gt;/${APP_ID}&lt;/code&gt; を取り除くミドルウェアを実装します。&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;app.py（ミドルウェア部分を抜粋）&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;app &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt; Flask&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#C0CAF5&quot;&gt;__name__&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#C0CAF5&quot;&gt; PrefixMiddleware&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#0DB9D7&quot;&gt; __init__&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E0AF68&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E0AF68&quot;&gt; app&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E0AF68&quot;&gt; prefix&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#F7768E&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;app &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#F7768E&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;prefix &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; prefix&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt;rstrip&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#0DB9D7&quot;&gt; __call__&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E0AF68&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E0AF68&quot;&gt; environ&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E0AF68&quot;&gt; start_response&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#F7768E&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;prefix&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;            environ&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;SCRIPT_NAME&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#F7768E&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;prefix&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;            path &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; environ&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;PATH_INFO&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; path&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt;startswith&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#F7768E&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#C0CAF5&quot;&gt;prefix&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;                environ&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;PATH_INFO&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; path&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#0DB9D7&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#F7768E&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#C0CAF5&quot;&gt;prefix&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt; or&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#F7768E&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#C0CAF5&quot;&gt;environ&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#C0CAF5&quot;&gt; start_response&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt;APP_ID&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt; os&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt;getenv&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;APP_ID&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt;strip&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt; APP_ID&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;    app&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#A9B1D6&quot;&gt;wsgi_app &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt; PrefixMiddleware&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#C0CAF5&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#C0CAF5&quot;&gt;wsgi_app&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#89DDFF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E36209;--shiki-dark:#E0AF68&quot;&gt; prefix&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#89DDFF&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#FF9E64&quot;&gt; APP_ID&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-11&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;prefixmiddleware-でやっていること&quot;&gt;&lt;a href=&quot;#prefixmiddleware-でやっていること&quot; class=&quot;heading-link&quot;&gt;PrefixMiddleware でやっていること&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h3&gt;
&lt;details class=&quot;callout callout-important&quot; open&gt;
&lt;summary class=&quot;callout-title callout-title-important&quot;&gt;&lt;svg fill=&quot;none&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; stroke=&quot;currentColor&quot; viewBox=&quot;0 0 24 24&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: visible; color: currentcolor;&quot;&gt;&lt;path fill=&quot;currentColor&quot; fill-rule=&quot;evenodd&quot; d=&quot;M11.484 2.17a.75.75 0 0 1 1.032 0 11.209 11.209 0 0 0 7.877 3.08.75.75 0 0 1 .722.515 12.74 12.74 0 0 1 .635 3.985c0 5.942-4.064 10.933-9.563 12.348a.749.749 0 0 1-.374 0C6.314 20.683 2.25 15.692 2.25 9.75c0-1.39.223-2.73.635-3.985a.75.75 0 0 1 .722-.516l.143.001c2.996 0 5.718-1.17 7.734-3.08ZM12 8.25a.75.75 0 0 1 .75.75v3.75a.75.75 0 0 1-1.5 0V9a.75.75 0 0 1 .75-.75ZM12 15a.75.75 0 0 0-.75.75v.008c0 .414.336.75.75.75h.008a.75.75 0 0 0 .75-.75v-.008a.75.75 0 0 0-.75-.75H12Z&quot; clip-rule=&quot;evenodd&quot;&gt;&lt;/path&gt;&lt;/svg&gt;Important&lt;/summary&gt;
&lt;p&gt;WSGIの　&lt;code&gt;environ&lt;/code&gt; は「リクエスト情報」ですが、ここで2つのキーを調整しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SCRIPT_NAME&lt;/code&gt; : アプリケーションのルートパスを指定するためのキー&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PATH_INFO&lt;/code&gt; : ルーティングの対象となるパスを指定する&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;PATH_INFO&lt;/code&gt; から prefix: &lt;code&gt;/${APP_ID}&lt;/code&gt; を剥がす&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;例：Traefikから来るのが &lt;code&gt;PATH_INFO=&apos;/APP_ID/some/path&apos;&lt;/code&gt;であれば、middlewareで &lt;code&gt;PATH_INFO=&apos;/some/path&apos;&lt;/code&gt; に変換する。&lt;/p&gt;
&lt;p&gt;これにより、Flaskアプリ上で&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;app.py&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#89DDFF&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;/some/path&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt; some_path&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#E0AF68&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-12&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;と定義したままであっても、Traefik経由で &lt;code&gt;host/APP_ID/some/path&lt;/code&gt; にアクセスしたときに正しくルーティングされるようになります。&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;code&gt;SCRIPT_NAME&lt;/code&gt; に prefix: &lt;code&gt;/${APP_ID}&lt;/code&gt; を設定する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;SCRIPT_NAME&lt;/code&gt; は、FlaskアプリケーションがURLを生成する際に使用する、アプリケーションのルートパスを指定するためのキーです。&lt;/p&gt;
&lt;p&gt;例えば、Flaskアプリケーション内で&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;app.py&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#89DDFF&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#89DDFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;/some/path&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#7AA2F7&quot;&gt; some_path&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#BB9AF7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#7AA2F7&quot;&gt; url_for&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;some_path&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-13&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;と定義している場合、&lt;code&gt;url_for(&apos;some_path&apos;)&lt;/code&gt; は &lt;code&gt;&apos;/APP_ID/some/path&apos;&lt;/code&gt; を返すようになります。&lt;/p&gt;
&lt;p&gt;特にHTMLテンプレート内で &lt;code&gt;url_for&lt;/code&gt; を使用してパスを生成して、publicなファイルを参照する場合、この設定がないと、生成されるURLが &lt;code&gt;&apos;/static/somefile&apos;&lt;/code&gt; のようになってしまい、Traefik経由でアクセスしたときに正しくファイルが参照できなくなります。&lt;/p&gt;
&lt;h3 id=&quot;パスの処理はtraefikとflaskのどちらで行うべき&quot;&gt;&lt;a href=&quot;#パスの処理はtraefikとflaskのどちらで行うべき&quot; class=&quot;heading-link&quot;&gt;パスの処理はTraefikとFlaskのどちらで行うべき？&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Traefikの &lt;code&gt;StripPrefix&lt;/code&gt; ミドルウェアを使用して、Traefik側でパスの処理を行う方法もあります。&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.middlewares.${APP_ID}-strip.stripprefix.prefixes=/${APP_ID}&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.routers.${APP_ID}.middlewares=${APP_ID}-strip&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-14&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;compose.yaml&lt;/code&gt; でコメントアウトしたこれら2行を有効化すると、アプリに届く次点で &lt;code&gt;PATH_INFO&lt;/code&gt; から &lt;code&gt;/${APP_ID}&lt;/code&gt; が剥がされた状態になります。&lt;/p&gt;
&lt;p&gt;一方で、 &lt;code&gt;SCRIPT_NAME&lt;/code&gt; は基本的に何もしない限り空文字列のままになるので、PublicファイルへのURL生成（&lt;code&gt;url_for&lt;/code&gt;）に問題が発生します。&lt;/p&gt;
&lt;p&gt;これを回避するためには、Traefikのmiddleware部分で&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D;--shiki-light-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic&quot;&gt;# middleware 1: パスから prefix を剥がす&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.middlewares.${APP_ID}-strip.stripprefix.prefixes=/${APP_ID}&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D;--shiki-light-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic&quot;&gt;# middleware 2: X-Forwarded-Prefix をつける（リクエストにヘッダー追加）&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.middlewares.${APP_ID}-xfp.headers.customrequestheaders.X-Forwarded-Prefix=/${APP_ID}&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D;--shiki-light-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic&quot;&gt;# ルーターに middleware を追加する&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#9ABDF5&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECE6A&quot;&gt;traefik.http.routers.${APP_ID}.middlewares=${APP_ID}-strip,${APP_ID}-xfp&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#89DDFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-15&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;という設定を行います。
&lt;code&gt;X-Forwarded-Prefix: /${APP_ID}&lt;/code&gt; というヘッダーがリクエストに追加され、これをFlaskアプリで読み込んで &lt;code&gt;SCRIPT_NAME&lt;/code&gt; に設定することが可能となります。&lt;/p&gt;
&lt;p&gt;この方針であれば、Flaskアプリにおいては、&lt;code&gt;${APP_ID}&lt;/code&gt; などの環境変数を意識せずに、通常のルーティング定義やURL生成が可能になります。&lt;/p&gt;
&lt;p&gt;ただし、HTTPリクエストのヘッダーを意識しないといけないのが面倒で、Traefik経由でのリクエストか、そうでないのかの区別がつきにくく、ローカルでの開発やテストがやりにくくなる可能性もあります。&lt;/p&gt;
&lt;p&gt;前者のFlask側でパスの処理を全て行う方針であれば、&lt;code&gt;${APP_ID}&lt;/code&gt; が空かどうかの条件分岐を入れるだけで、ローカル環境と本番環境を同じコードベースで運用できるというメリットもあります。&lt;/p&gt;
&lt;p&gt;また、Flaskでのmiddlewareは結局必要となるので、どちらでパスの処理を行うかは好みの問題かなと思います。&lt;/p&gt;
&lt;h2 id=&quot;余談wsgiとasgiの違い&quot;&gt;&lt;a href=&quot;#余談wsgiとasgiの違い&quot; class=&quot;heading-link&quot;&gt;（余談）WSGIとASGIの違い&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;




















&lt;div class=&quot;table-block&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;種類&lt;/th&gt;&lt;th&gt;特徴&lt;/th&gt;&lt;th&gt;得意なこと&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;WSGI&lt;/td&gt;&lt;td&gt;同期処理に特化したサーバー&lt;/td&gt;&lt;td&gt;CPU中心の同期処理。シンプルな構成が可能。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ASGI&lt;/td&gt;&lt;td&gt;同期・非同期両方に対応したサーバー&lt;/td&gt;&lt;td&gt;APIサーバーやWebSocket用途。長時間接続やリアルタイム通信が可能。&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;WSGI&lt;/code&gt; の基本思想は、同期モデル (blocking) に基づく処理を行うことです。
1つのリクエストが1スレッド or プロセスで処理され、リクエストの処理が完了するまで次のリクエストは待機します。&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;WSGIのリクエスト処理モデル&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Request&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Worker（1つのリクエストがブロックする）&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Response&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-16&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;一方、&lt;code&gt;ASGI&lt;/code&gt; は非同期モデル (non-blocking) に基づく処理を行うことができます。&lt;/p&gt;
&lt;div class=&quot;remark-code-container&quot;&gt;&lt;div class=&quot;remark-code-title&quot;&gt;ASGIのリクエスト処理モデル&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light tokyo-night&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#1a1b26;color:#24292e;--shiki-dark:#a9b1d6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Request&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Event Loop&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;I/O待ち中に他リクエスト処理&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Response&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;button class=&quot;code-copy-button&quot; id=&quot;code-copy-button-17&quot; type=&quot;button&quot; aria-label=&quot;コードをコピー&quot;&gt;&lt;svg fill=&quot;currentColor&quot; stroke-width=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 512 512&quot; height=&quot;1em&quot; width=&quot;1em&quot; style=&quot;overflow: &amp;#x27;visible&amp;#x27;, color: &amp;#x27;currentcolor&amp;#x27;&quot;&gt;&lt;rect width=&quot;336&quot; height=&quot;336&quot; x=&quot;128&quot; y=&quot;128&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; rx=&quot;57&quot; ry=&quot;57&quot;&gt;&lt;/rect&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;32&quot; d=&quot;m383.5 128 .5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;複数のリクエストを同時に処理できるため、APIサーバーやWebSocketなどのリアルタイム通信に適しています。&lt;/p&gt;</content:encoded></item><item><title>Platform Engineerに関して</title><link>https://yuuma.dev/blog/platform-engineer/</link><guid isPermaLink="true">https://yuuma.dev/blog/platform-engineer/</guid><description>自分の志向とPlatform Engineerという職業についての考察。Platform Engineeringとは何かを整理しながら、自分がなぜこの職域に関心を持つのかを分析した。</description><pubDate>Sat, 31 Jan 2026 22:50:42 GMT</pubDate><content:encoded>&lt;!-- cmd+option+v: ImagePaste --&gt;
&lt;p&gt;&lt;picture&gt;
  &lt;source srcset=&quot;/blog/img/platform-engineer/2026-01-31-23-28-52.avif&quot; type=&quot;image/avif&quot;&gt;
  &lt;source srcset=&quot;/blog/img/platform-engineer/2026-01-31-23-28-52.webp&quot; type=&quot;image/webp&quot;&gt;
  &lt;img src=&quot;https://yuuma.dev/blog/img/platform-engineer/2026-01-31-23-28-52.png&quot; alt=&quot;2026-01-31-23-28-52&quot; style=&quot;max-height:480px;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;h2 id=&quot;要約&quot;&gt;&lt;a href=&quot;#要約&quot; class=&quot;heading-link&quot;&gt;要約&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Platform Engineeringは、DevOpsの普及が生んだ認知負荷の問題への回答として登場した&lt;/li&gt;
&lt;li&gt;自分の志向（責任分離をはっきりとしたアーキテクチャ、ミスを犯さない構造の事前設計、何しても良い最強の基盤を作りたい）はこの思想と重なる部分が大きい&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;platform-engineeringとは何か&quot;&gt;&lt;a href=&quot;#platform-engineeringとは何か&quot; class=&quot;heading-link&quot;&gt;Platform Engineeringとは何か&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;2009年頃から DevOps という考え方が広まりました。
「You build it, you run it（作ったチームが動かせ）」という原則で、開発と運用の壁をなくすことでデプロイ頻度が上がり、障害対応も速くなりました。&lt;/p&gt;
&lt;div class=&quot;remark-link-card-plus__container&quot;&gt;
  &lt;a href=&quot;https://logmi.jp/main/technology/325995&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;remark-link-card-plus__card&quot;&gt;
    &lt;div class=&quot;remark-link-card-plus__main&quot;&gt;
  &lt;div class=&quot;remark-link-card-plus__content&quot;&gt;
    &lt;div class=&quot;remark-link-card-plus__title&quot;&gt;「コード書きました、あとはよろしく」では優れたソフトウェアは生まれない　コンテナのスペシャリストが語る、運用性を損なう8つの実装例 | ログミーBusiness&lt;/div&gt;
    &lt;div class=&quot;remark-link-card-plus__description&quot;&gt;You build it, you run it原トリ氏：（スライドの「You build it, you run it」を指して）この言葉、聞いたこと、見たことがある方がいるかもしれません。これは、2006年にACM（Associatio...&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;remark-link-card-plus__meta&quot;&gt;
    &lt;img src=&quot;https://static.logmi.jp/asset/favicon.ico&quot; class=&quot;remark-link-card-plus__favicon&quot; width=&quot;14&quot; height=&quot;14&quot; alt=&quot;&quot;&gt;
    &lt;span class=&quot;remark-link-card-plus__url&quot;&gt;logmi.jp&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;remark-link-card-plus__thumbnail&quot;&gt;
  &lt;img src=&quot;https://images.logmi.jp/media/article/325995/images/Eb8ajn2PJegaHTdvpjBnKq.png&quot; class=&quot;remark-link-card-plus__image&quot; alt=&quot;&quot;&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;DevOps の考えは、「運用性に優れたソフトウェアは重要である」という思想に基づいます。上記のサイトにおいて、運用性を損なう実装の例として&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スケールアウトできない、しにくいアプリ実装&lt;/li&gt;
&lt;li&gt;依存パッケージ解決を自動化出来ない&lt;/li&gt;
&lt;li&gt;安全に停止できない&lt;/li&gt;
&lt;li&gt;起動処理が長い&lt;/li&gt;
&lt;li&gt;ビルド/パッケージング前に手作業が必要&lt;/li&gt;
&lt;li&gt;設定値を実行時に外部から注入できない&lt;/li&gt;
&lt;li&gt;ログをファイルにしか出力できない&lt;/li&gt;
&lt;li&gt;Read レプリカを使えない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;といったものが挙げられています。&lt;/p&gt;
&lt;p&gt;これらの実装を避けるため、DevOps の原則を全チームに適用し続けた結果、別の問題が出てきました。各チームが CI/CD を個別に構築し、Dockerfile を管理し、Kubernetes のマニフェストを書く。チームごとにやり方が違う。再利用できない。新しいメンバーは膨大な社内ドキュメントを読まないと最初のデプロイができない、という状況です。&lt;/p&gt;
&lt;p&gt;このような状況をソフトウェアエンジニアリングの世界では、「偶有的複雑さ（Accidental Complexity）」という言葉で表現することがあるようです。本質的に難しいわけではないのに、構造の問題で複雑になってしまっている。開発者がインフラ・セキュリティ・監視・デプロイを全て理解しながら機能開発もこなすのは、認知リソース的に無理があります。&lt;/p&gt;
&lt;p&gt;Platform Engineering は、この問題への回答として生まれた考え方であり、その中心にある概念が Internal Developer Platform（IDP）です。&lt;/p&gt;
&lt;p&gt;IDP とは、開発者が自分のアプリをデプロイ・運用するために使う、社内製の開発者向けプラットフォームのことで、GitHub や Vercel のような体験を社内で提供するものだと考えるとわかりやすいかもしれません。&lt;/p&gt;
&lt;p&gt;IDP を設計するとき、「どこまで抽象化するか」が最も難しい問いになります。抽象化しすぎると柔軟性が失われる（Golden Cage と呼ばれます）。抽象化しなさすぎると認知負荷は減らない。このバランスを取るために生まれた概念が Golden Path です。Spotify が提唱したもので、「正しいやり方を、最も楽なやり方にする。ただし、それだけに強制はしない」という考え方を持っています。開発者は Golden Path から外れることもできるけれど、それに従えばセキュリティや監視やデプロイが自動的に整った状態でスタートできる。ルールではなく、舗装路（Paved Road）だということです。
また Platform as a Product という視点も重要で、社内向けのツールであっても開発者体験と継続的な改善を考えることがこの職の特徴だと思います。&lt;/p&gt;
&lt;h2 id=&quot;自分の志向との重なり&quot;&gt;&lt;a href=&quot;#自分の志向との重なり&quot; class=&quot;heading-link&quot;&gt;自分の志向との重なり&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;自分がこの領域に関心を持つ理由を整理すると、次のことが言えます。&lt;/p&gt;
&lt;p&gt;システムの中での責任の分離と、ミスを犯しにくい構造を事前に設計しておくことに、一貫した関心があります。「動くものを作る」こと以上に「どういう構造にすればミスが起きにくいか」「どの層が何を保証するか」を考えることに面白さを感じています。&lt;/p&gt;
&lt;p&gt;それをもっと具体的なイメージで言うと、「自分が最強のデプロイ基盤を作る。あとはその上で何でも作っていい」という状態を達成したい気持ちがあります。スケーリングや安全性の保証をプラットフォーム側に閉じ込め、その設計を自分が引き受ける。他のエンジニアが基盤を意識せずに動けるようになる状態です。そこには技術的な面白さと、ユーザー体験向上に直接関われることへの喜びの両方があります。&lt;/p&gt;
&lt;p&gt;研究室サーバー上での PoC アプリの大量デプロイ基盤を構築した経験が、この志向を一番よく表していると思います。開発者には &lt;code&gt;Dockerfile&lt;/code&gt; と &lt;code&gt;entrypoint.sh&lt;/code&gt; だけを書いてもらい、Traefik によるルーティング・HTTPS・デプロイ手順・障害時の挙動はプラットフォーム側で担う設計にしました。「開発者が何をして良くて、何をしてはいけないか」の境界を設計することが、自分の作業の中心でした。&lt;/p&gt;
&lt;p&gt;この志向は Platform Engineering の思想と重なる部分が大きいと感じています。&lt;/p&gt;
&lt;h2 id=&quot;自分のやりたいこと&quot;&gt;&lt;a href=&quot;#自分のやりたいこと&quot; class=&quot;heading-link&quot;&gt;自分のやりたいこと&lt;/a&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;自分は、学術と産業の橋渡しをソフトウェアエンジニアリングの観点から取り組むことに興味があります。アーキテクチャ設計やエンジニアリングの観点から先進技術の標準化を主導すること、一人で完結した開発を行うのではなく、誰かと一緒により良い仕組みを作っていくことが、自分のやりたいことに近いと思っています。&lt;/p&gt;
&lt;p&gt;Platform Engineer という職はその志向と重なる部分が大きいですが、唯一の答えというわけではありません。今は「この方向はありかもしれない」という位置づけで考えています。&lt;/p&gt;
&lt;p&gt;近いうちに Clean Architecture を読んでみます。&lt;/p&gt;
&lt;div class=&quot;remark-link-card-plus__container&quot;&gt;
  &lt;a href=&quot;https://tatsu-zine.com/books/clean-architecture&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;remark-link-card-plus__card&quot;&gt;
    &lt;div class=&quot;remark-link-card-plus__main&quot;&gt;
  &lt;div class=&quot;remark-link-card-plus__content&quot;&gt;
    &lt;div class=&quot;remark-link-card-plus__title&quot;&gt;Clean Architecture  達人に学ぶソフトウェアの構造と設計&lt;/div&gt;
    &lt;div class=&quot;remark-link-card-plus__description&quot;&gt;アーキテクチャのルールはどれも同じである! どんな種類のシステムでもソフトウェアアーキテクチャのルールは同じ。ソフトウェアアーキテクチャのルールとは、プログラムの構成要素をどのように組み立てるかのルールである。時代を超越した不変のルールたちを紹介する。&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;remark-link-card-plus__meta&quot;&gt;
    &lt;img src=&quot;https://tatsu-zine.com/favicon.ico&quot; class=&quot;remark-link-card-plus__favicon&quot; width=&quot;14&quot; height=&quot;14&quot; alt=&quot;&quot;&gt;
    &lt;span class=&quot;remark-link-card-plus__url&quot;&gt;tatsu-zine.com&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;remark-link-card-plus__thumbnail&quot;&gt;
  &lt;img src=&quot;https://tatsu-zine.com/images/books/980/cover_l.jpg&quot; class=&quot;remark-link-card-plus__image&quot; alt=&quot;&quot;&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;</content:encoded></item></channel></rss>