あけましておめでとうございますもてぃ。
今年一発目の記事はElixirです。
僕はdockerが大好きで愛してやまないので、Elixir * PostgreSQL構成のdockerリポジトリを作りました。
その際はまった内容を備忘録として残しておきたいと思います。
環境
- wsl2 windows ubuntu
- elixir 1.14.2-slim image
- postgresql 14.1-alpine image
docker-compose.ymlの構成
こんな感じ。
version: '3' services: postgres: build: ./postgres image: ecto-database container_name: ecto-database environment: POSTGRES_HOST_AUTH_METHOD: 'trust' TZ: 'Asia/Tokyo' volumes: - ./postgres/init:/docker-entrypoint-initdb.d - ecto-data:/var/lib/postgresql/data ports: - '5555:5432' restart: always app: build: . image: ecto-app container_name: ecto-app volumes: - .:/app tty: true stdin_open: true restart: always depends_on: - postgres volumes: ecto-data: driver: local
ライブラリにはecto
とpostgrex
を使用してます。
ecto.create
app containerに対してmix ecto.create
を実行しています。
# docker exec -it ecto-app mix ecto.createでもおk % docker compose exec app mix ecto.create Compiling 3 files (.ex) Generated ecto_app app 05:34:55.399 [error] GenServer #PID<0.284.0> terminating ** (DBConnection.ConnectionError) tcp connect (postgres:5555): connection refused - :econnrefused (db_connection 2.4.3) lib/db_connection/connection.ex:100: DBConnection.Connection.connect/2 (connection 1.1.0) lib/connection.ex:622: Connection.enter_connect/5 (stdlib 4.2) proc_lib.erl:240: :proc_lib.init_p_do_apply/3 Last message: nil State: Postgrex.Protocol 05:34:55.407 [error] GenServer #PID<0.290.0> terminating ** (DBConnection.ConnectionError) tcp connect (postgres:5555): connection refused - :econnrefused (db_connection 2.4.3) lib/db_connection/connection.ex:100: DBConnection.Connection.connect/2 (connection 1.1.0) lib/connection.ex:622: Connection.enter_connect/5 (stdlib 4.2) proc_lib.erl:240: :proc_lib.init_p_do_apply/3 Last message: nil State: Postgrex.Protocol ** (Mix) The database for EctoApp.Repo couldn't be created: killed
いろいろ調べてみたら「postgresqlサーバーが立ち上がってない」だのいろいろ書かれてましたが、docker compose upで立ち上げたpostgresql コンテナは問題なく立ち上がってました。
docker-compose.ymlでentripointも設定して権限もしっかり付与しているので、ecto_appユーザーが接続できてないってこともないです。
念のため確認
% docker compose exec postgres psql -U ecto_app psql (14.1) Type "help" for help. ecto_app=# \du List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- ecto_app | Superuser, Create role, Create DB | {} postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} ecto_app=#
ちゃんと権限もありましたね。
configの見直し
接続設定はconfig/config.exs
に書かれてます。
import Config config :ecto_app, EctoApp.Repo, database: "ecto_app", username: "ecto_app", password: "ecto_app_psql", hostname: "localhost", port: "5555" config :ecto_app, ecto_repos: [EctoApp.Repo] if Mix.env() == :dev do config :mix_test_watch, tasks: [ "credo" ] end
もともとpostgresqlをローカルにいれていない自分は、DBが必要になったときに毎回postgresql用のdocker-compose.ymlを作っていて、そのtemplateを毎度使っていました。
その設定をそのまま上のconfig.exsに反映していたのがまずかったのです…。
解決策
docker-composeで立ち上げる際のポート、ホストはdocker network上で生成されるものにおき替える必要があります。
docker-composeをみるとdatabaseのホストはpostgres
、ポートはdocker network上では5432
を開放しています。なのでその通りにconfig.exs
を変更してあげる。
import Config config :ecto_app, EctoApp.Repo, database: "ecto_app", username: "ecto_app", password: "ecto_app_psql", hostname: "postgres", port: "5432" config :ecto_app, ecto_repos: [EctoApp.Repo] if Mix.env() == :dev do config :mix_test_watch, tasks: [ "credo" ] end
再度ecto.createしてみると…
% docker compose exec app mix ecto.create Compiling 3 files (.ex) Generated ecto_app app The database for EctoApp.Repo has already been created
なんかすでに作られてましたが、うまくコマンド実行できました。
終わり
postgresqlとelixirの簡単なdocker compose構成が出来上がりました。
これでphoenixにも応用できるはずなので、phoenix tutorialをやる際はちょっとこのリポジトリをいじって圧倒的環境構築したいとおもいます。
Elixir/Phoenix極めるぞー!
(今年の抱負はまた別の記事で)