From 2f3294b89974681c57e5444f638e581f04406d23 Mon Sep 17 00:00:00 2001 From: Matchu Date: Tue, 29 Aug 2023 11:39:12 -0700 Subject: [PATCH 1/4] [WIP] Build a dev container Idk why, but unlike my previous experience with Rails devcontainers, this time the setup process is running so wildly slowly? Might just be a transient issue on my machine, maybe something that would be improved with a restart and trying again another time? Or could be something about the MySQL image that doesn't run great in this context? In any case, I'm just gonna set this down for now! --- .devcontainer/Dockerfile | 15 ++++++++++++ .devcontainer/create-db.sql | 5 ++++ .devcontainer/devcontainer.json | 39 ++++++++++++++++++++++++++++++++ .devcontainer/docker-compose.yml | 29 ++++++++++++++++++++++++ .devcontainer/post-create.sh | 13 +++++++++++ config/database.yml | 8 +++---- vendor/.gitignore | 1 + 7 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/create-db.sql create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/docker-compose.yml create mode 100755 .devcontainer/post-create.sh create mode 100644 vendor/.gitignore diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..2cc67040 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,15 @@ +FROM mcr.microsoft.com/devcontainers/ruby:1-3.1-bullseye + +# Default value to allow debug server to serve content over GitHub Codespace's port forwarding service +# The value is a comma-separated list of allowed domains +ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev,.preview.app.github.dev,.app.github.dev" + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment this line to install additional gems. +# RUN gem install + +# [Optional] Uncomment this line to install global node packages. +# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 diff --git a/.devcontainer/create-db.sql b/.devcontainer/create-db.sql new file mode 100644 index 00000000..b5a805a1 --- /dev/null +++ b/.devcontainer/create-db.sql @@ -0,0 +1,5 @@ +CREATE DATABASE openneo_impress; +GRANT ALL PRIVILEGES ON openneo_impress.* TO impress_dev; + +CREATE DATABASE openneo_id; +GRANT ALL PRIVILEGES ON openneo_id.* TO impress_dev; diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..cd9b5afe --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,39 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ruby-rails-postgres +{ + "name": "Dress to Impress", + "dockerComposeFile": "docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", + "features": { + "ghcr.io/devcontainers/features/node:1": { + "nodeGypDependencies": true, + "version": "lts" + } + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // This can be used to network with other containers or the host. + "forwardPorts": [3000], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": ".devcontainer/post-create.sh", + + // HACK: Out of the box, this dev container doesn't allow installation to the + // default GEM_HOME, because of a weird thing going on with RVM. Instead, we + // set a custom GEM_HOME and GEM_PATH in our home directory! + // https://github.com/devcontainers/templates/issues/188 + "containerEnv": { + "GEM_HOME": "~/.rubygems", + "GEM_PATH": "~/.rubygems" + } + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 00000000..87dae876 --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3' + +services: + app: + build: + context: .. + dockerfile: .devcontainer/Dockerfile + + volumes: + - ../..:/workspaces:cached + + # Overrides default command so things don't shut down after the process ends. + command: sleep infinity + + # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function. + network_mode: service:db + + # Use "forwardPorts" in **devcontainer.json** to forward an app port locally. + # (Adding the "ports" property to this file will not forward from a Codespace.) + + db: + image: mysql:latest + restart: unless-stopped + volumes: + - ./create-db.sql:/docker-entrypoint-initdb.d/create-db.sql + environment: + MYSQL_ROOT_PASSWORD: impress_dev + MYSQL_USER: impress_dev + MYSQL_PASSWORD: impress_dev diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100755 index 00000000..1828c430 --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -e # Quit if any part of this script fails. + +# Mark all git repositories as safe to execute, including cached gems. +# NOTE: This would be dangerous to run on a normal multi-user machine, +# but for a dev container that only we use, it should be fine! +git config --global safe.directory '*' + +# Install the app's Ruby gem dependencies. +bundle install + +# Set up the databases: create the schema, and load in some default data. +rake db:schema:load db:seed diff --git a/config/database.yml b/config/database.yml index c17385f8..e57ed12f 100644 --- a/config/database.yml +++ b/config/database.yml @@ -2,8 +2,8 @@ development: primary: adapter: mysql2 database: openneo_impress - username: openneo_impress - password: openneo_impress + username: impress_dev + password: impress_dev pool: 5 variables: sql_mode: TRADITIONAL @@ -11,8 +11,8 @@ development: openneo_id: adapter: mysql2 database: openneo_id - username: openneo_impress - password: openneo_impress + username: impress_dev + password: impress_dev pool: 2 variables: sql_mode: TRADITIONAL diff --git a/vendor/.gitignore b/vendor/.gitignore new file mode 100644 index 00000000..3bd6b832 --- /dev/null +++ b/vendor/.gitignore @@ -0,0 +1 @@ +/bundle \ No newline at end of file From e022e8dbfbec64910e4718d9e930667401c3a391 Mon Sep 17 00:00:00 2001 From: Emi Dunn-Rankin Date: Thu, 26 Oct 2023 00:04:20 +0000 Subject: [PATCH 2/4] Oops, fix bugs in dev container setup! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I missed two things: 1) `rake` wasn't available in the path (surprising but ok!), so I replaced it with the more modern and more portable `bin/rails` invocation. 2) Without specifying a `host`, Rails was trying to connect with the database over a socket instead of over a port. Here, we tell it where to actually connect! I think I'll need to make some tweaks here, since this isn't compatible with my _own_ local setup—maybe I'll revert `database.yml`, and have the dev container use the `DATABASE_URL` environment variable to override it? But whatever, this is working for now, and that's exciting to me! Note: On my machine, the install step hangs for a loooong time, to the point where I usually give up. On Codespaces, it also took a while at the same step (`Installing devise-encrpytable`), but eventually got through it. Maybe on my machine it would work if I'm more patient? Idk! But it's good to see it working on something!! --- .devcontainer/post-create.sh | 2 +- config/database.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 1828c430..d27e4297 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -10,4 +10,4 @@ git config --global safe.directory '*' bundle install # Set up the databases: create the schema, and load in some default data. -rake db:schema:load db:seed +bin/rails db:schema:load db:seed diff --git a/config/database.yml b/config/database.yml index e57ed12f..2fbc7152 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,6 +1,7 @@ development: primary: adapter: mysql2 + host: db database: openneo_impress username: impress_dev password: impress_dev @@ -10,6 +11,7 @@ development: openneo_id: adapter: mysql2 + host: db database: openneo_id username: impress_dev password: impress_dev From 6bbef7e75ee84658ef9a28f8a68f969831168142 Mon Sep 17 00:00:00 2001 From: Matchu Date: Thu, 26 Oct 2023 14:20:15 -0700 Subject: [PATCH 3/4] Move the `host: db` part of the dev container into its environment vars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Okay, so I've kept `database.yml` using the new username and password `impress_dev`, cuz I like that it helps clarify that it's dev stuff and is impossible to confuse with prod. (I updated my local setup to match!) But hardcoding `host: db` into here breaks my local setup where the database _isn't_ at the hostname `db`. So I add a way for new optional database URL environment variables to get merged in with these settings, and then configured the dev container to use that—and just in the most limited override possible, to avoid duplicating stuff we don't need to. (I could've just used the same names `DATABASE_URL_{PRIMARY,OPENNEO_ID}` for this, but idk, I think it's confusing to have the same one for both dev and prod, even though Rails _does_ basically do this; see below.) Normally, the environment variable `DATABASE_URL` just _does_ this, and you don't need to include a `url` key at all to get this behavior. But since we've got the legacy two-database thing going on, we do this instead! If we were to merge the `openneo_id.users` table into the primary database, we could simplify this! --- .devcontainer/devcontainer.json | 13 +++++++++---- config/database.yml | 8 ++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index cd9b5afe..56ca1e0f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -22,11 +22,16 @@ // Use 'postCreateCommand' to run commands after the container is created. "postCreateCommand": ".devcontainer/post-create.sh", - // HACK: Out of the box, this dev container doesn't allow installation to the - // default GEM_HOME, because of a weird thing going on with RVM. Instead, we - // set a custom GEM_HOME and GEM_PATH in our home directory! - // https://github.com/devcontainers/templates/issues/188 "containerEnv": { + // Because the database is hosted on the local network at the hostname `db`, + // we partially override `config/database.yml` to connect to `db`! + "DATABASE_URL_PRIMARY_DEV": "mysql2://db", + "DATABASE_URL_OPENNEO_ID_DEV": "mysql2://db", + + // HACK: Out of the box, this dev container doesn't allow installation to + // the default GEM_HOME, because of a weird thing going on with RVM. + // Instead, we set a custom GEM_HOME and GEM_PATH in our home directory! + // https://github.com/devcontainers/templates/issues/188 "GEM_HOME": "~/.rubygems", "GEM_PATH": "~/.rubygems" } diff --git a/config/database.yml b/config/database.yml index 2fbc7152..81a389e9 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,7 +1,9 @@ development: primary: + # You can override these default settings with this environment variable, + # fully or partially. We do this in the .devcontainer setup! + url: <%= ENV['DATABASE_URL_PRIMARY_DEV'] %> adapter: mysql2 - host: db database: openneo_impress username: impress_dev password: impress_dev @@ -10,8 +12,10 @@ development: sql_mode: TRADITIONAL openneo_id: + # You can override these default settings with this environment variable, + # fully or partially. We do this in the .devcontainer setup! + url: <%= ENV['DATABASE_URL_OPENNEO_ID_DEV'] %> adapter: mysql2 - host: db database: openneo_id username: impress_dev password: impress_dev From 421f11143d7ea0276ffbabf7fb786f4679effa34 Mon Sep 17 00:00:00 2001 From: Emi Dunn-Rankin Date: Thu, 26 Oct 2023 21:39:42 +0000 Subject: [PATCH 4/4] Build wardrobe-2020 JS during dev container setup Oh yeah right, let's `yarn install` and build as part of the `post-create.sh` script! I didn't have a command to do a one-time dev build of the assets yet (just one-time prod, or dev with reloading), so I added `yarn build:dev`! --- .devcontainer/post-create.sh | 6 ++++++ package.json | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index d27e4297..1aff43ad 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -11,3 +11,9 @@ bundle install # Set up the databases: create the schema, and load in some default data. bin/rails db:schema:load db:seed + +# Install the app's JS dependencies. +yarn install + +# Run a first-time build of the app's JS, in development mode. +yarn build:dev diff --git a/package.json b/package.json index 98488824..f341db16 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ }, "scripts": { "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=/assets --asset-names=[name]-[hash].digested --loader:.js=jsx --loader:.png=file --loader:.svg=file --loader:.min.js=text", - "dev": "yarn build --watch --public-path=/dev-assets" + "build:dev": "yarn build --public-path=/dev-assets", + "dev": "yarn build:dev --watch" } }