はじめに
Haskellで関数型PG言語に出会い、挫折を繰り返し、Elmに出会って満足していた自分ですが、やっぱりHaskellでバックエンドを作りたくなるのがFuncational Programmerの性ってものです(たぶん)
Haskellを知ってから15年くらい経ち、その界隈の技術と私の知識もだいぶ進んだだろう、ということで、改めてMade by Full Functionarl Programming LanguageなWebアプリを作り、かつAWSで公開する取り組みを開始しました。
具体的な目標
- Webアプリを作る
- バックエンドをHaskellで作って
- フロントエンドをElmで作り
- それをAWSを使ってデプロイ、公開する
構成
- バックエンドはServantで作成
- 可能ならDBアクセスも実装する
- フロントエンドはElmで作る
- これらをDockerにまとめてAWSにデプロイする
実は、ここまでDockerにほぼノータッチで過ごしてきたので、その学習も兼ねています。
免責事項
この記事は完成しない可能性があります!!
ここからが、やったこと
開発PC
- MacBook Air M1, 2020 Sequoia 15.2
Gitリポジトリ
何はともあれ、ローカル環境で動作する最小のWebアプリを作成
Haskellと言えばstack。
これを使ってローカルで起動する最低限のWebアプリを作ります。
ここでの成果物はこれ。
https://github.com/jabaraster/servant-elm-study/blob/f062c63a9c362b643111cd789a693b5bf40d8cd5
今回は静的ファイルの配信も必要なのですがその実現にかなり遠回り。
終わってみればServantが提供しているserveDirectoryFileServer
などの関数を使えばいいのですが、そこに気付くのに時間がかかった!
server :: Server API
server =
indexHandler
:<|> serveDirectoryFileServer "./static" -- ここ!
:<|> usersHandler
全体的な構成としては
- フロントエンドでビルドした成果物のフォルダを
- Servantの
serverDirectioryFileServer
にて公開
となります。
Dockerでの公開するためのビルド環境の構築
ここからが難しい。
こちらの記事を足がかりにして進めます。
https://qiita.com/lambda_funtaro/items/5ac47f83616f8c07d4db
大雑把な目標は
- まずmuslを使ってシングルバイナリを作って
- それを動かすDockerfileを書く
というものになる・・・と思う。
シングルバイナリを作る設定
※今ココ!
stackにはDockerを使ってビルドする機能があります。
stack.yamlに書く方法もあるのですが、まずはstack build
コマンドでDockerイメージを指定する方法を使います。
stack build \
--ghc-options ' -static -optl-static -optl-pthread -fPIC' \
--docker --docker-image "utdemir/ghc-musl:v25-ghc944" \
--no-nix
ここで困ったことが発生。
ghcをダウンロードするときに、コンテント長が想定と異なる、と言って怒られます。
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
Preparing to install GHC (musl) to an isolated location. This will not interfere with any system-level installation.
Preparing to download ghc-musl-9.6.6 ...
Download expectation failure: ContentLength header
Expected: 224131196
Actual: 198860724
For: https://downloads.haskell.org/ghc/9.6.6/ghc-9.6.6-x86_64-alpine3_12-linux.tar.xz
GHC9.6.6に関するバイナリの一覧はこちら
にあります。ここで確認したところ、
- ダウンロードしようとしているファイルはghc-9.6.6-x86_64-alpine3_12-linux.tar.xzなのに
- コンテント長はghc-9.6.6-x86_64-alpine3_12-linux-static.tar.xzのものを見ている
ということが分かります。
が、これがなぜ起こるのか、どうやって解消させるのかが分からない。
stack.yamlにはskip-ghc-check
というオプションもあり、これをtrueにしてみましたが、
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
wai-app-static > configure
wai-app-static > Configuring wai-app-static-3.1.9...
wai-app-static > build with ghc-9.4.4
wai-app-static > Preprocessing library for wai-app-static-3.1.9..
wai-app-static > Building library for wai-app-static-3.1.9..
wai-app-static > [1 of 9] Compiling WaiAppStatic.Types
wai-app-static > [2 of 9] Compiling Util
wai-app-static > [3 of 9] Compiling WaiAppStatic.Listing
wai-app-static > [4 of 9] Compiling WaiAppStatic.Storage.Filesystem
wai-app-static > [5 of 9] Compiling WaiAppStatic.Storage.Embedded.TH
wai-app-static > [6 of 9] Compiling WaiAppStatic.Storage.Embedded.Runtime
wai-app-static > [7 of 9] Compiling WaiAppStatic.Storage.Embedded
wai-app-static > [8 of 9] Compiling Network.Wai.Application.Static
Progress 1/3
Error: [S-7282]
Stack failed to execute the build plan.
While executing the build plan, Stack encountered the error:
[S-7011]
While building package wai-app-static-3.1.9 (scroll up to its section to see the error) using:
/xxxxxxxxxx/.stack/setup-exe-cache/x86_64-linux-dk85569e7f830e7dc606115fd702e078fb/Cabal-simple_DY68M0FN_3.8.1.0_ghc-9.4.4 --verbose=1 --builddir=.stack-work/dist/x86_64-linux-dk85569e7f830e7dc606115fd702e078fb/ghc-9.4.4 build --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure (-11)
2024/12/19時点ではここまで。
進展したら追記します。
追記がなかったら力尽きたと察してください。