WSL2ファイルシステム上にSvelteをおいてDockerで環境を作る
#svelte #docker #wsl #開発 #備忘
最終メモ
WSLとDockerとSvelteとIDEの噛み合いが悪い
Hyper-VのDockerでやり直してみる
Svelte + SvelteKitのおべんきょをしていて、本番用の環境構築を無料のサービスを使って行なう章がある。
そのままその通りにやってもいいんやけど、最終的には好きな環境で好きなように本番環境を動かしたいので、
最初からDockerで環境を作る練習をしておく。
ちょっと前まではHyper-V上でDockerを動かしていたが、それの調子が悪くなってWSL2に変えた。
WSL2ってことはLinux上にあるってことで、Windows側のファイルシステムだと遅くなってしまうので、
WSLファイルシステム上にプロジェクトフォルダをおいて、そこで開発し、Dockerを動かしたい。
ってことで、それに必要な手順をメモっておく。
プロジェクト作成
\\wsl.localhost\Ubuntu\ でWSLのルートディレクトリにアクセスできるので、
そこからホームディレクトリに移動してプロジェクトを作る
$ npm create svelte@latest test-project
'\\wsl.localhost\Ubuntu\home\tsuchinaga\projects\test-project'
上記の現在のディレクトリで CMD.EXE を開始しました。
UNC パスはサポートされません。Windows ディレクトリを既定で使用します。
?!
何か出てるけど、とりあえずそのあとも動きそうなので動かしてみる
最後まで選択してプロジェクトを作成しようとしたところ
Error: EPERM: operation not permitted, mkdir 'C:\Windows\test-project'
UNCパスがサポートされてないところから、なんか特殊な動きになってる気がする
適当なドライブに割り当てたらいけるんかな?
ってことで、WSLの頭文字をとってWドライブに \\wsl.localhost\Ubuntu\ を割り当て。
再度実行
$ npm create svelte@latest test-project
┌ Welcome to SvelteKit!
│
◇ Which Svelte app template?
│ Skeleton project
│
◇ Add type checking with TypeScript?
│ Yes, using TypeScript syntax
│
◇ Select additional options (use arrow keys/space bar)
│ Add ESLint for code linting
│
└ Your project is ready!
通った!
初回セットアップ
依存パッケージをインストールし、一度動かしておきたい。
ってことで、Windows側のCMDからWドライブにマウントしたディレクトリに移動し、
$ npm install
$ npm run dev
を実行してみる。
$ npm install
は途中のインジケーターが表示されないけど、採取的には全部インストール出来たっぽい。
ただし
$ npm run dev
は、エラーがでた。
> test-project@0.0.1 dev
> vite dev
node:internal/errors:563
ErrorCaptureStackTrace(err);
^
Error: EISDIR: illegal operation on a directory, watch 'W:/home/tsuchinaga/projects/tsuchinaga/test-project/vite.config.ts'
たぶん、ファイルシステム越しに監視がうまくできないとかだと思う
もしくは権限?
ってことで、WSLの中にはいってから、改めてコマンドを実行する
$ wsl
$ cd ~/projects/tsuchinaga/test-project
$ npm install
$ npm run dev
VITE v5.4.1 ready in 344 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
とりあえず動いた。
たぶんこのアドレスはWSL内のアドレスなので、Windwos側からは繋がらないと思う。
これを繋げられるようにするには、一工夫いると思うけど、
最終的にはDocker上で動かして、Dockerの外のポートにポートフォワーディングするはずなのでここでは何もしない。
$ npm install
もDocker内でできちゃうはずなので、ここでやる必要があったかは微妙!
Gitの設定
プロジェクトのディレクトリに入って、
$ git init
これは通る。
ただ、initial commitしようとすると、ディレクトリの所有権どうこうでダメーってでる。
$ git status
fatal: detected dubious ownership in repository at '//wsl.localhost/Ubuntu/home/tsuchinaga/projects/tsuchinaga/test-project'
この時は、 //wsl.localhost でアクセスしてることになってるのね
ここで、git configで許可するコマンドを実行するんやけど、実行ログ取るの忘れてた
.gitignoreに.ideaをいれてIntelliJ関連を除外し、initial commitをいれる
docker-compose.ymlの準備
最低限必要だと分かっているのはnodeが実行できるアプリケーションサーバーと、
データベースが動かせるデータベースサーバー
実践 Svelte入門 エンジニア選書 でSvelteに入門する では、MongoDBが使われているので、
データベースはMongoDBにする。
立ち上げて動作確認するけど、どうも正しくvolumesのマウントが出来ていない気がする
試しにWSL上ではなく、WindowsのCドライブ内などにでプロジェクトを作ってdocker-composeを作ったら、volumesも反映されていた。
なんかよくわからんけど、WSL2上に諸々用意するのは悪手なのか?
とりあえず動くものを用意した
code:docker-compose.yml
services:
test-project:
image: node:22-slim
container_name: "test-project"
ports:
- "8080:5173"
working_dir: "/app"
volumes:
- "./:/app"
environment:
- TZ=Asia/Tokyo
tty: true
command: "npm run dev -- --host"
$ npm run dev -- --host
で立てているので、コンテナを立ち上げたらすぐにブラウザから8080でアプリケーションにアクセスできる
-- --host は 最初の -- がviteに渡すオプションで、 --host はローカルネットワークからならアクセスできるって言う設定っぽい
本番環境ではbuildして立ち上げる必要があるので、本番では別のcommandを設定する必要がある。
docker-compose.ymlで切り替えるか、Dockerfileで切り替えるかは後ほど考える。
buildして立ち上げる必要があるのはなぜか、については正直よくわかっていない。
ただ下記には、本来のパフォーマンスが発揮できない的なことが書かれている。
参考: 【SvelteKit 入門】作業の前に
ホットリロードするためにビルダーが常駐していて、それがなんかあって~みたいなことがあるのかも。
実際に立ち上げてソースを修正しても反映されていない?反映されてもリビルドされていない?
もっかいwslの中にnodeを準備して、プロジェクト作成からwslの中でやってみる
WSL内でプロジェクト作成
$ wsl
$ node -v
Command 'node' not found, but can be installed with:
sudo apt install nodejs
$ sudo apt install nodejs
$ node -v
v12.22.9
$ npm -v
10.2.4
$ cd ~/project/tsuchinaga
$ npm create svelte@latest test-project
'\\wsl.localhost\Ubuntu\home\tsuchinaga\projects\tsuchinaga'
上記の現在のディレクトリで CMD.EXE を開始しました。
UNC パスはサポートされません。Windows ディレクトリを既定で使用します。
中からやってもやっぱりこれは出るのかー
先にdockerコンテナを立ち上げて、その中でプロジェクトを作ってみる。
とりあえずディレクトリだけ作って、docker-compose.ymlだけ設置
code:docker-compose.yml
services:
test-project:
image: node:22-slim
container_name: "test-project"
ports:
- "8080:5173"
working_dir: "/app"
volumes:
- "./:/app"
environment:
- TZ=Asia/Tokyo
tty: true
test-project-db:
image: mongo:latest
container_name: test-project-db
working_dir: "/db"
environment:
- TZ=Asia/Tokyo
- MONGO_INITDB_DATABASE=test-project
tty: true
App側のコンテナに入って、
$ npm create svelte@latest test-project
$ cd test-project
$ npm install
ここで関係ないけど、IntelliJのターミナルからだと、docker内で行なった操作がうまく反映されない
Windows側にファイルを置くと、docker側からファイルの変更が見えない
WSL側にファイルを置くと、WindowsのIDE側からファイルの変更が見えない
Wドライブに\\wsl.localhost\ を割り当てて参照してるから?
docker-compose up -d --build しても、volumesが動作していない
やっぱりWSLではなく、Hyper-Vで動かした方がいいのかもしれない
adapterの設定
いくつかの解説をみていると、Svelteはどこかしらのホスティングサービスを利用することが多いっぽい。
マジで?ほんまに?と疑いたくなるけど、そうっぽい。
JavaとかGoとかPHPとか、バックエンド寄りの開発が多いからそう感じているだけか、
知らんまにホスティングが主流になっているのに取り残されているだけか……。
とりあえず自分の慣れた方法に寄せるために、NodeJSがインストールされているサーバで動かすことを考える。
となると、デフォルトのadapterで動くか分からない。
このadapterってのは、だいたいはホスティングサービスで動くようなのが自動で入っているっぽい。
Nodeで動かすならこれーというのが決まっているので、それに切り替えておく。
参考: Adapters • Docs • SvelteKit
Nodeが入っているサーバーで動かすなら、@sveltejs/adapter-node を入れる必要があるっぽい
参考: Node サーバー • Docs • SvelteKit
ってことで、はずは該当のパッケージをインストール
$ npm install -D @sveltejs/adapter-node
code:svelte.config.js
- import adapter from '@sveltejs/adapter-auto';
+ import adapter from '@sveltejs/adapter-node';
これだけっぽい。
export default { ... } ってのを追加しなさいよーってのも書いてあったけど、
これは最初から書かれているから新たに追加する必要はなさそう。
そのうち、.env絡みの設定も出てくると思うけど、それはそのときにしよう。
MongoDBとの接続
何はともあれ、動き続けるシステムとしてデータベースは必須なので、
書籍をもとにDBとの接続をやっていく。
とりあえずアプリ側にクライアントがないとどうしようもないので、
MongoAPIError: URI must include hostname, domain name, and tld
指定してるけどなーとおもい、mongodbの該当のソースコードを見に行くと、
code:connection_string.js
if (options.srvHost.split('.').length < 3) {
// TODO(NODE-3484): Replace with MongoConnectionStringError
throw new error_1.MongoAPIError('URI must include hostname, domain name, and tld');
}
ホスト部分が . で区切られてないとだめらしい
しかも最低2個必要っぽい
思いつく対応は下記2つ
docker-compose.ymlでコンテナにピリオドが含まれている名前を付ける
mongodb以外のドライバ・ライブラリを使う
SRV関数の中でエラーになっているので、接続時に+srvを外して使う
などなど、色々試行錯誤した結果、下記で通るようになった
+srvは外し、SRVレコードではなく、TXTレコードとしてアクセス
これによって、ピリオドが必須じゃなくなった
docker-compose.ymlで管理者ユーザー設定を削除
認証が通らなかったので、とりあえず認証を外して処理を通すようにした
dockerネットワーク内の通信やからいいかなーってかんじ
更新履歴
2024/08/20 かきおわり
2024/08/17 かきはじめ