今回はローカルのDocker環境でsvelteKitとfastAPIを使用し、
Webアプリをデプロイするまでの手順を投稿します。
この方法以外にもやり方は、いろいろあると思いますが、
検証済みの方法なので参考にして下さい。
前回の投稿でFE(フロントエンド)のsvelteKitをDocker環境で構築しました。
今回はBE(バックエンド)との連携編です。
Docker環境でFastAPIのアプリケーションが動作していることが前提とします。
世の中にFastAPIの入門記事が溢れているので、BEの中身の学習は、他の記事を参考にしてください。
svelteKit側を注目して見ていきます。
※私がお世話になった記事はこちらになります。(迷ったら公式をまず見よう)
目標
- FastAPI部分の軽く説明
- FEのDockerの設定
- FEからBEへfetchして値を取得する
FastAPI部分の軽く説明
Dockerfileのポイント
- パッケージ管理ツールとしてpoetryを使用しています。
- poetryからuvicornを起動しています。
#python3.9のイメージをダウンロード
FROM python:3.9-buster
ENV PYTHONUNBUFFERED=1
WORKDIR /src
#pipを使ってpoetryをインストール
RUN pip install poetry
#poetryでライブラリをインストール(pyproject.tomlが既にある場合)
RUN poetry config virtualenvs.in-project true
RUN if [ -f pyproject.toml ]; then poetry install --no-root; fi
#uvicornのサーバーを立ち上げる
ENTRYPOINT ["poetry", "run", "uvicorn", "api.main:app", "--host", "0.0.0.0", "--reload"]
docker-compose.ymlのポイント
- networks FEとBEは別々のdocker-compose.ymlによって作成されるため、 デフォルトでは、別のnetworkとなります。 そのため、BEでnetwork(be_external)を作成し、FE側で作成したnetworkを使用することとなります。
version: '3'
services:
demo-app:
build: .
volumes:
- .dockervenv:/src/.venv
- .:/src
networks:
- external
ports:
- 8000:8000 #ホストマシンのポート8000をdocker内のポート8000に接続する
db:
image: mysql:8.0
platform: linux/x86_64
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' #rootアカウントをパスワードなしで作成
MYSQL_DATABASE: 'demo' #初期データベースとしてdemoを設定
TZ: 'Asia/Tokyo' #タイムゾーンを日本時間に設定
volumes:
- mysql_data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password # MYSQL8.0ではデフォルトが"caching_sha2_password"でドライバが非対応のため、変更
networks:
- external
ports:
- 33306:3306 #ホストマシンのポート33306をdocker内のポート3306に接続する
networks:
# internal: #DBを外部から接続できなくしたい場合は、networksをinternalに変更する
# driver: bridge
# internal: false
external:
driver: bridge
internal: false
name: be_external
volumes:
mysql_data:
↓ポイントとなる設定の詳細説明↓
driver:bridge
同じ Docker デーモン ホスト上で実行されているコンテナーに適用される。 同じホスト上の他のコンテナーと通信する必要があるコンテナーでアプリケーションを実行する場合によく使用される。 公式↓internal: false
内部ネットワーク上のコンテナーは相互に通信できますが、、他のネットワークとは通信できません。internal: trueを設定することで外部から分離されたnetworkを作成可能です。 ここでは明示的にfalseとしています。 公式↓https://docs.docker.com/reference/cli/docker/network/create/
name: be_external
Linux ブリッジを作成するときに使用するブリッジ名を"be_external"と指定しました。 FEではこの名前を使って、ここで作成したnetworkを使用することとなります。 公式↓https://docs.docker.com/reference/cli/docker/network/create/
FastAPIその他のポイント
今回は、FEからBEへfetchして取得した値を画面に表示するというところまで行います。
BEで注目していただきたいのは、main.pyでoriginsとadd_middlewareの設定をしていることです。
※Getリクエストをするだけなら、この設定は必要ないかも
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from api.routers import users,task
import uvicorn
app = FastAPI(swagger_ui_parameters={"docExpansion":"none"})
origins = [
"http://localhost:8000",
"http://127.0.0.1:5173",
"http://my-app:5173"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(users.router, tags=["users"])
app.include_router(task.router, tags=["task"])
@app.get("/")
async def hello():
return {"message": "hello world!"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8001)
FEのDockerの設定
いよいよ本題のFE側の設定に入ります。
※BE側でわからないことがあれば、他の記事を参考にして下さい。いつか見やすく更新します。
前回の作成したFEのDockerの設定を追加変更していきます。
先ほど、BE側で作成したnetworkを使用するように変更します。
version: '3.8'
services:
my-app:
image: svelte-app
build:
context: .
dockerfile: ./Dockerfile
environment:
- NODE_ENV=development
- PORT=5173
+ networks:
+ - external
ports:
- 5173:5173
volumes:
- ./src:/app/src
- ./static:/app/static
- ./vite.config.js:/app/vite.config.js
- ./tsconfig.json:/app/tsconfig.json
- ./svelte.config.js:/app/svelte.config.js
+networks:
+ external:
+ name: be_external
+ external: true
Dockerの設定でいじるこれだけです!
FEからBEへfetchして値を取得する
それでは、SvelteKitのソースを修正していきましょう。
src直下に+page.server.tsを作成し、fetchして値を取得する処理を追加します。
import { error } from "@sveltejs/kit";
interface Message {
message: string;
}
export async function load({fetch}){
const res = await fetch('http://demo-app:8000');
if(res.ok){
return await res.json() as Message;
} else {
throw error(404)
}
}
Dockerコンテナ同士のやりとりは、URLをコンテナ名にすることで可能です。
load({fetch})として、SvelteKitが持つサーバーサイドのfetchを使用しています。
(今回はあんまり効果を発揮しません)
※interfaceは外だしにしたほうがいいかもね
次にサーバーサイドで取得した値を+page.svelteで画面に表示します。
<script lang="ts">
export let data;
let message = data.message;
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
<p>message:{message}</p>
export let data;でサーバーサイドの値を受け取っています。
成功イメージ
BEから取得した、"hello world!"をFEで画面に表示することができました。
終わりに
今回も非常に簡単いですが、SvelteKitとFastAPIをDocker上でどうするようにしました。
詳細の解説は気が向いたら順次していきたいと思います。
よかったら、いいねと保存して下さい。
次回は、BEから取得したデータ一覧をSvelteでSkeletonのデータテーブルを使用して、画面に表示しようと思います。