Track an empty no-op docker-compose.override.yml (with a .gitignore negation)
so devcontainer.json's compose file list resolves without the initializeCommand
hack, which is removed. Add USER_UID/USER_GID build args and drop the sudo
chown from setup.sh. Correct the Elixir pin comment: the OTP suffix pins only
the major, so the Erlang patch may still differ from .tool-versions.
The dev container did not come up cleanly. This fixes the correctness
problems and fills in the missing developer ergonomics.
Correctness fixes:
* Erlang/OTP: base image was elixir:1.17-otp-27, but .tool-versions
pins erlang 26.2.5.5 / elixir 1.17.3-otp-26. Switched to
elixir:1.17-otp-26 so container builds match CI and local asdf.
* Postgres: bumped 13-alpine -> 16-alpine. AshPostgres declares
min_pg_version 15 in lib/wanderer_app/repo.ex, so 13 was below the
supported floor; 16 also matches production. The data volume is
renamed db-new -> db-pg16 because a PG13 data directory is not
readable by a PG16 server, so reusing the name would fail to start
rather than upgrade.
* host.docker.internal: replaced the common-utils feature's
networkArgs (which only applies at feature install time) with a
plain compose extra_hosts entry.
* Dropped `apt --fix-broken install` and the duplicated
jakebecker.elixir-ls extension id.
* setup.sh: the assets block was indented as if inside the ecto
conditional and never ran `yarn build`. Fixed and added an explicit
build step.
* setup.sh: chown deps/ and _build/ to the container user; they come
from the bind mount and carry host ownership.
Non-root user:
Added a `developer` user (uid/gid 1000, passwordless sudo) instead of
running as root, so files created in the bind-mounted workspace are
owned by the host user rather than root.
Build artifacts:
Removed the elixir-artifacts named volume. A named volume mounted
inside the bind mount masks the repo's own deps/ and _build/, and only
for the main working tree — git worktrees came up empty and recompiled
from scratch. Host and container now share _build; after changing the
OTP version, `rm -rf _build` once.
Database seeding:
setup.sh now runs priv/repo/seeds.exs only when the SDE reference data
is missing, checked with `mix run --no-start` so the check does not
boot the supervision tree and its outbound pollers.
Developer experience:
* zsh + oh-my-zsh with autosuggestions/syntax highlighting, persistent
shell history in a named volume, and mix/git aliases.
* gh CLI, ripgrep, tree, htop, lsof, git-lfs, inotify-tools.
* en_US.UTF-8 locale generated.
* post-start.sh prints environment info and checks Postgres.
* More VS Code extensions (Phoenix, Credo, GitLens, dotenv, Docker)
and _build/deps excluded from search.
* docker-compose.override.yml.example for host-specific mounts (SSH
keys, gh auth). The override is gitignored and auto-created empty by
initializeCommand, so it is optional.
* .devcontainer/ added to .dockerignore so it does not invalidate
production image build cache.