update dev docker config and readme#279
Conversation
Follows the psyrep pattern: one shared Dockerfile used by both `docker compose up` and VS Code devcontainer flows. - Switch base image from ghcr.io/rails/devcontainer/images/ruby to rockylinux:9, matching our RHEL9 production hosts - Move Dockerfile and .bashrc from .devcontainer/ to docker/ - Add root docker-compose.yml with web + db services - Slim .devcontainer/docker-compose.yml to a thin override (sleep infinity, SKIP_BUNDLE_INSTALL=true) - Point .devcontainer/devcontainer.json at both compose files and drop devcontainer features now handled by the Dockerfile - Use env_file: .env on the web service so contributors can switch to test mode by editing a single line in .env
- Drop the PORT=5100 override; use Puma's default (3000). Updates .env.example, Procfile.test, cypress.config.js, and the npm scripts in package.json. Devcontainer forwardPorts was already 3000, so everything is consistent now. - Default USER_LOOKUP_SKELETON=1 in .env.example so dev mode uses the stubbed LDAP lookup out of the box. Contributors can work without UMN VPN; flip to real LDAP by removing the line. - Incidental package-lock.json churn (peer: true flags stripped from some entries; npm version drift, unrelated behavior change).
- Restructure Getting Started around two paths: VS Code Dev Container (recommended, with IDE integration) or plain `docker compose up` - Document USER_LOOKUP_SKELETON=1 for working without UMN VPN - Split Cypress testing into headless (in-container) and interactive (from host) modes; explain that Cypress GUI can't run inside a container and walk through the host-side flow - Drop the Manual Setup section; rbenv/manual config instructions were out of date (database.yml and ldap.yml are env-driven now) - Remove stale GitHub release badge pointing at tterb/PlayMusic
sstephenson/ruby-build is the old repo URL; GitHub currently redirects it to rbenv/ruby-build. Use the canonical URL directly so the build doesn't depend on GitHub's redirect service.
The devcontainer override was hardcoding RAILS_ENV: development, which takes precedence over env_file in Compose. That blocked our documented Cypress workflow (set RAILS_ENV=test in .env, docker compose up) for devcontainer users. .env already defaults RAILS_ENV to development, so the override was redundant.
- Normalize test server port from 5017 to 3000, matching the rest of the repo. - Pin the MySQL service to mysql/mysql-server:8.0 (matching docker-compose.yml and production) instead of the floating `mysql` tag. Add MYSQL_ROOT_HOST="%" so remote TCP connections from the runner work against the Oracle image. - Add actions/setup-node@v4 pinning Node 22 (matching our Dockerfile) with npm cache enabled; previously relied on whatever Node ships on the runner. - Switch from yarn to npm: `yarn install --frozen-lockfile` -> `npm ci`. The repo is already npm-based (package-lock.json, no yarn.lock); yarn was a vestige. Delete the unused bin/yarn shim too. Left explicit bundle install and `-e test` on the rails server call; they're redundant but the repo prefers explicitness here.
There was a problem hiding this comment.
Pull request overview
This PR updates the local development environment to rely primarily on Docker Compose (with the VS Code devcontainer as a thin wrapper), normalizes Rails/Cypress to port 3000, defaults development to mocking LDAP, and migrates CI from Yarn to npm.
Changes:
- Add a Rocky Linux–based Docker dev image + a new root
docker-compose.ymlfor local/devcontainer workflows. - Normalize dev/E2E ports to 3000 and update Cypress config/scripts accordingly.
- Switch CI JS dependency install from Yarn to
npm ciand refresh README/dev docs (including LDAP mocking default).
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
package.json |
Updates E2E scripts to target port 3000 and default Rails server port. |
docker/Dockerfile |
Adds a new dev image with Ruby/Node/Chromium and a non-root user. |
docker/.bashrc |
Removes mise activation from the container shell setup. |
docker-compose.yml |
Introduces Compose services for db (MySQL) and web (Rails) for dev. |
cypress.config.js |
Updates Cypress baseUrl to http://localhost:3000. |
bin/yarn |
Removes the Yarn shim script. |
README.md |
Rewrites setup/testing instructions for Docker/devcontainers + Cypress GUI guidance. |
Procfile.test |
Switches the test Rails server to default port (3000). |
.github/workflows/test.yml |
Switches CI JS install to npm and updates MySQL service + Cypress port. |
.env.example |
Updates APP_URL to 3000 and enables LDAP mocking by default. |
.devcontainer/docker-compose.yml |
Makes the devcontainer an override of the main Compose setup. |
.devcontainer/devcontainer.json |
Points devcontainer at the root Compose setup and forwards ports 3000/3306. |
.devcontainer/Dockerfile |
Removes the previous Rails devcontainer base image Dockerfile. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| # Install Ruby from source | ||
| RUN git clone https://github.com/rbenv/ruby-build.git /tmp/ruby-build && \ | ||
| /tmp/ruby-build/install.sh chdir=/tmp/ruby-build && \ |
There was a problem hiding this comment.
The ruby-build install step looks incorrect: /tmp/ruby-build/install.sh chdir=/tmp/ruby-build passes an argument that ruby-build’s install.sh treats as an install prefix, which will install ruby-build into an unexpected path and likely break the subsequent ruby-build ${RUBY_VERSION} /usr/local invocation. Run install.sh without that argument (or pass a real prefix like /usr/local) so ruby-build ends up on PATH for the rest of the build.
| /tmp/ruby-build/install.sh chdir=/tmp/ruby-build && \ | |
| /tmp/ruby-build/install.sh /usr/local && \ |
| - CMD | ||
| - mysqladmin | ||
| - ping | ||
| - "-p${DB_PASSWORD}" |
There was a problem hiding this comment.
.env.example sets DB_PASSWORD= (empty), but the db healthcheck runs mysqladmin ping -p${DB_PASSWORD} which becomes -p and prompts for a password, causing the healthcheck to fail and web to never start (it depends on service_healthy). Either provide a non-empty default DB_PASSWORD, or change the healthcheck to not pass -p when the password is empty (e.g., use --password= or conditionally include the flag).
| - "-p${DB_PASSWORD}" | |
| - "--password=${DB_PASSWORD}" |
| gem install bundler | ||
| bundle install |
There was a problem hiding this comment.
CI installs Bundler without a version (gem install bundler), but Gemfile.lock pins BUNDLED WITH 2.5.23. Installing a different Bundler version can cause lockfile/version mismatch errors and also duplicates work already handled by ruby/setup-ruby with bundler-cache: true. Prefer removing the manual Bundler install + bundle install, or pin it to the lockfile version (e.g., gem install bundler -v 2.5.23).
| gem install bundler | |
| bundle install |
| #### Headless (Docker or devcontainer) | ||
|
|
||
| Boots a test server and runs the full suite: | ||
|
|
||
| ```sh | ||
| # open cypress | ||
| yarn cypress open | ||
| docker compose exec web npm run test:e2e | ||
| ``` |
There was a problem hiding this comment.
The documented headless E2E command (docker compose exec web npm run test:e2e) will run inside the already-running web service, which is started by docker compose up with a Rails server bound to port 3000. Since test:e2e also starts its own Rails server on the default port (3000), this is likely to fail with “address already in use”. Consider updating the docs to run E2E in a separate one-off container (e.g., docker compose run --rm web npm run test:e2e) or use a dedicated test port for the E2E server.
| EXPOSE 3000 | ||
|
|
There was a problem hiding this comment.
EXPOSE 3000 is declared twice in this Dockerfile. Keeping a single EXPOSE improves readability and avoids confusion about whether multiple ports are intended.
| EXPOSE 3000 |
| ruby \ | ||
| ruby-devel \ |
There was a problem hiding this comment.
This image installs distro Ruby (dnf install ruby ruby-devel) and then also builds Ruby from source into /usr/local. That redundancy increases image size and can make it unclear which Ruby/Bundler is actually being used at runtime. Consider removing the Rocky ruby* packages if you intend to always use the ruby-build Ruby, or drop the source build if the distro Ruby is sufficient.
| ruby \ | |
| ruby-devel \ |
cmcfadden
left a comment
There was a problem hiding this comment.
I'm fine with fully banishing dev containers from our lives ;)
Devcontainers don't easily support cypress gui debugging. This PR makes it easier to start things with a traditional
docker compose up, and then use the host's cypress gui tools.psyreps Docker and devcontainer config to Z, which has the added benefit of making our dev environment closer to prod. Devcontainer is now just a thin wrapper for the docker setup to avoid drift.3000to cut down on port remapping indirection.USER_LOOKUP_SKELETON=1)