概要
ちょっと用事がありまして FastAPI のプロジェクトが必要でした。
「公式のテンプレートがあるじゃん!」なのですが、メンテが2020年6月で止まっており、 docker-compose up -d
しても動かなかったので、いろいろ手直ししてひとまず動くところまで持っていきました。
その修正点の備忘録です。(たまってるPRを当てていけば直りそうだけど)
ということで
プロジェクトを生成
プロジェクト生成は公式サイトの "how-to-use-it" に従いましょう。
で、プロジェクトを生成したら、ひとまずなにも考えずに docker-compose up -d
でコンテナ群を起動してみましょう。
想定通りであればエラーがでるはずです。
フロントの fork-ts-checker-webpack-plugin-v5
に関するエラー
フロント側で fork-ts-checker-webpack-plugin-v5
といったエラーが出た場合です。
エラー詳細
- Building for production...
ERROR Error: Cannot find module 'fork-ts-checker-webpack-plugin-v5'
Error: Cannot find module 'fork-ts-checker-webpack-plugin-v5'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:582:15)
at Function.Module._load (internal/modules/cjs/loader.js:508:25)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at api.chainWebpack.config (/app/node_modules/@vue/cli-plugin-typescript/index.js:106:16)
at webpackChainFns.forEach.fn (/app/node_modules/@vue/cli-service/lib/Service.js:236:40)
at Array.forEach (<anonymous>)
at Service.resolveChainableWebpackConfig (/app/node_modules/@vue/cli-service/lib/Service.js:236:26)
at PluginAPI.resolveChainableWebpackConfig (/app/node_modules/@vue/cli-service/lib/PluginAPI.js:145:25)
at module.exports (/app/node_modules/@vue/cli-service/lib/commands/build/resolveAppConfig.js:9:22)
at build (/app/node_modules/@vue/cli-service/lib/commands/build/index.js:147:50)
at api.registerCommand (/app/node_modules/@vue/cli-service/lib/commands/build/index.js:89:13)
at Service.run (/app/node_modules/@vue/cli-service/lib/Service.js:230:12)
at Object.<anonymous> (/app/node_modules/@vue/cli-service/bin/vue-cli-service.js:36:9)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! frontend@0.1.0 build: `vue-cli-service build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the frontend@0.1.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2023-05-04T04_01_39_533Z-debug.log
ERROR: Service 'frontend' failed to build : The command '/bin/sh -c npm run build' returned a non-zero code: 1
対策
ググると次のようなページがヒットします。
Node のバージョンに依存するようです。
Node のバージョンをあげたいのですが公式が v10 までしか対応していませんでした。
ということでネットの海をさまよったところ、フォークして v16 に対応している docker イメージがありましたのでこちらを使わせていただきましょう。
ということで修正します。
- FROM tiangolo/node-frontend:10 as build-stage
+ FROM greenaj/node-frontend:16 as build-stage
なぜか nginx.conf
のファイル名も変更されているのでそこも修正します。
FROM nginx:1.15
COPY --from=build-stage /app/dist/ /usr/share/nginx/html
- COPY --from=build-stage /nginx.conf /etc/nginx/conf.d/default.conf
+ COPY --from=build-stage /default.conf /etc/nginx/conf.d/default.conf
COPY ./nginx-backend-not-found.conf /etc/nginx/extra-conf.d/backend-not-found.conf
poetry に関する 404 Not Found のエラー
バックエンド側で 404: Not Found
といったエラーが出た場合です。
エラー詳細
Step 3/15 : RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && cd /usr/local/bin && ln -s /opt/poetry/bin/poetry && poetry config virtualenvs.create false
---> Running in 374e5a279887
File "<stdin>", line 1
404: Not Found
^
SyntaxError: invalid syntax
ERROR: Service 'celeryworker' failed to build : The command '/bin/sh -c curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && cd /usr/local/bin && ln -s /opt/poetry/bin/poetry && poetry config virtualenvs.create false' returned a non-zero code: 1
対策
poetry をインストールしようとしてるんですね。
だけど、インストール先の URL が変わったためエラーとなっているらしいです。
下記の通りにインストール先の URL を書き換えます。
バックエンドの dockerfile を2つとも書き換えます。
# Install Poetry
- RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && \
+ RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry python && \
cd /usr/local/bin && \
ln -s /opt/poetry/bin/poetry && \
poetry config virtualenvs.create false
# Install Poetry
- RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && \
+ RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry python && \
cd /usr/local/bin && \
ln -s /opt/poetry/bin/poetry && \
poetry config virtualenvs.create false
flower がエラーとなり起動しない
flower がエラーとなり起動しない場合です。
エラー詳細
Creating full-stack-fastapi-postgresql_db_1 ... done
Creating full-stack-fastapi-postgresql_flower_1 ... error
Creating full-stack-fastapi-postgresql_queue_1 ... done
Creating full-stack-fastapi-postgresql_frontend_1 ... done
Creating full-stack-fastapi-postgresql_proxy_1 ... done
Creating full-stack-fastapi-postgresql_pgadmin_1 ...
Creating full-stack-fastapi-postgresql_backend_1 ...
Creating full-stack-fastapi-postgresql_celeryworker_1 ...
ERROR: for full-stack-fastapi-postgresql_flower_1 Cannot start service flower: Creating full-stack-fastapi-postgresql_pgadmin_1 ... done
Creating full-stack-fastapi-postgresql_backend_1 ... done
Creating full-stack-fastapi-postgresql_celeryworker_1 ... done
ERROR: for flower Cannot start service flower: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "--broker=amqp://guest@queue:5672//": stat --broker=amqp://guest@queue:5672//: no such file or directory: unknown
ERROR: Encountered errors while bringing up the project.
対策
原因はわかりませんが、新しいバージョンだとダメらしいです。
ということで、ひとまず動かしたいのでコメントの記載にある古いバージョンで動かします。
flower:
- image: mher/flower
+ image: mher/flower:0.9.7
networks:
- ${TRAEFIK_PUBLIC_NETWORK?Variable not set}
- default
env_file:
バックエンドが AttributeError: module 'h11' has no attribute 'Event'
でエラー
ここまでくると、パット見で動いているように見えますが、実は動いていない場合があります。
docker-compose ps
で確認すると次のようになっていました。
Name Command State Ports
--------------------------------------------------------------------------------------------------------------
full-stack-fastapi- /start-reload.sh Exit 1
postgresql_backend_1
full-stack-fastapi- bash /worker-start.sh Exit 1
postgresql_celeryworker_1
full-stack-fastapi- docker-entrypoint.sh postgres Up 5432/tcp
postgresql_db_1
full-stack-fastapi- flower --broker=amqp://gue ... Up 0.0.0.0:5555->5555/tcp,:::5555->
postgresql_flower_1 5555/tcp
full-stack-fastapi- nginx -g daemon off; Up 80/tcp
postgresql_frontend_1
full-stack-fastapi- /entrypoint.sh Up 443/tcp, 0.0.0.0:5050->5050/tcp,
postgresql_pgadmin_1 :::5050->5050/tcp, 80/tcp
full-stack-fastapi- /entrypoint.sh --providers ... Up 0.0.0.0:80->80/tcp,:::80->80/tcp
postgresql_proxy_1 , 0.0.0.0:8090->8080/tcp,:::8090
->8080/tcp
full-stack-fastapi- docker-entrypoint.sh rabbi ... Up 15691/tcp, 15692/tcp, 25672/tcp,
postgresql_queue_1 4369/tcp, 5671/tcp, 5672/tcp
バックエンドと celeryworker が Exit 1 で落ちてます。
ということでバックエンドから docker-compose logs backend
で見ていきましょう。
見てみると AttributeError: module 'h11' has no attribute 'Event'
となっていました。
エラー詳細
backend_1 | File "/usr/local/lib/python3.7/site-packages/httpcore/_sync/__init__.py", line 1, in <module>
backend_1 | from .connection import HTTPConnection
backend_1 | File "/usr/local/lib/python3.7/site-packages/httpcore/_sync/connection.py", line 13, in <module>
backend_1 | from .http11 import HTTP11Connection
backend_1 | File "/usr/local/lib/python3.7/site-packages/httpcore/_sync/http11.py", line 44, in <module>
backend_1 | class HTTP11Connection(ConnectionInterface):
backend_1 | File "/usr/local/lib/python3.7/site-packages/httpcore/_sync/http11.py", line 144, in HTTP11Connection
backend_1 | self, event: h11.Event, timeout: Optional[float] = None
backend_1 | AttributeError: module 'h11' has no attribute 'Event'
対策
調べてみると httpcore というライブラリのバージョンに依存する問題のようです。
ということで httpcore のバージョンを古いもので固定しましょう。
pyproject.toml
に追記します。
[tool.poetry.dependencies]
python = "^3.7"
uvicorn = "^0.11.3"
fastapi = "^0.54.1"
...
python-jose = {extras = ["cryptography"], version = "^3.1.0"}
httpcore = "<=0.15"
importlib-metadata = "<5"
+ httpcore = "<=0.15"
書き換えたら docker-compose build backend
でリビルドしてから up しましょう。
celeryworker が AttributeError: 'EntryPoints' object has no attribute 'get'
でエラー
celeryworker が AttributeError: 'EntryPoints' object has no attribute 'get'
でエラーになる場合があります。
エラー詳細
celeryworker_1 | File "/usr/local/lib/python3.7/site-packages/celery/bin/base.py", line 16, in <module>
celeryworker_1 | from celery import VERSION_BANNER, Celery, maybe_patch_concurrency, signals
celeryworker_1 | File "/usr/local/lib/python3.7/site-packages/celery/signals.py", line 16, in <module>
celeryworker_1 | from .utils.dispatch import Signal
celeryworker_1 | File "/usr/local/lib/python3.7/site-packages/celery/utils/__init__.py", line 19, in <module>
celeryworker_1 | from .nodenames import nodename, nodesplit, worker_direct
celeryworker_1 | File "/usr/local/lib/python3.7/site-packages/celery/utils/nodenames.py", line 9, in <module>
celeryworker_1 | from kombu.entity import Exchange, Queue
celeryworker_1 | File "/usr/local/lib/python3.7/site-packages/kombu/entity.py", line 9, in <module>
celeryworker_1 | from .serialization import prepare_accept_content
celeryworker_1 | File "/usr/local/lib/python3.7/site-packages/kombu/serialization.py", line 456, in <module>
celeryworker_1 | for ep, args in entrypoints('kombu.serializers'): # pragma: no cover
celeryworker_1 | File "/usr/local/lib/python3.7/site-packages/kombu/utils/compat.py", line 93, in entrypoints
celeryworker_1 | for ep in importlib_metadata.entry_points().get(namespace, [])
celeryworker_1 | AttributeError: 'EntryPoints' object has no attribute 'get'
対策
こちらは importlib-metadata というライブラリのバージョンに依存する問題のようです。
ということで importlib-metadata のバージョンを古いもので固定しましょう。
pyproject.toml
に追記します。
[tool.poetry.dependencies]
python = "^3.7"
uvicorn = "^0.11.3"
fastapi = "^0.54.1"
...
python-jose = {extras = ["cryptography"], version = "^3.1.0"}
httpcore = "<=0.15"
importlib-metadata = "<5"
httpcore = "<=0.15"
+ importlib-metadata = "<5"
書き換えたら docker-compose build celeryworker
でリビルドしてから up しましょう。
動いた!
ここまで修正したら、一度リフレッシュしましょう。
docker-compose stop
docker-compose build
docker-compose up -d
これで docker-compose ps
を確認すると、すべてのサービスが Up しているはずです。
Name Command State Ports
--------------------------------------------------------------------------------------------------------------
full-stack-fastapi- /start-reload.sh Up 80/tcp, 0.0.0.0:8888->8888/tcp,::
postgresql_backend_1 :8888->8888/tcp
full-stack-fastapi- bash /worker-start.sh Up
postgresql_celeryworker_1
full-stack-fastapi- docker-entrypoint.sh postgres Up 5432/tcp
postgresql_db_1
full-stack-fastapi- flower --broker=amqp://gue ... Up 0.0.0.0:5555->5555/tcp,:::5555->5
postgresql_flower_1 555/tcp
full-stack-fastapi- nginx -g daemon off; Up 80/tcp
postgresql_frontend_1
full-stack-fastapi- /entrypoint.sh Up 443/tcp, 0.0.0.0:5050->5050/tcp,:
postgresql_pgadmin_1 ::5050->5050/tcp, 80/tcp
full-stack-fastapi- /entrypoint.sh --providers ... Up 0.0.0.0:80->80/tcp,:::80->80/tcp,
postgresql_proxy_1 0.0.0.0:8090->8080/tcp,:::8090->8
080/tcp
full-stack-fastapi- docker-entrypoint.sh rabbi ... Up 15691/tcp, 15692/tcp, 25672/tcp,
postgresql_queue_1 4369/tcp, 5671/tcp, 5672/tcp
以上です!お疲れさまでした!