From 6a912b7d8cd034f24cb730e3c6ab2f8009eded79 Mon Sep 17 00:00:00 2001 From: Gareth Date: Wed, 30 Jul 2025 20:12:53 -0400 Subject: [PATCH 01/13] Added cmake dep to dockerfile and added script for db:schema:load that runs only if the schema is different than the latest migration --- Dockerfile | 2 +- Dockerfile.ubuntu | 3 ++- compose.yaml | 2 ++ script/load_schema.sh | 15 +++++++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100755 script/load_schema.sh diff --git a/Dockerfile b/Dockerfile index abe1123c25..5db0d1fb33 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ FROM base AS development-base RUN apk add --no-cache --virtual .build-deps \ build-base postgresql-dev git nodejs yarn && \ apk add --no-cache --virtual .dev-utils \ - bash curl less vim chromium-chromedriver zlib-dev openssl-dev \ + bash curl less vim chromium-chromedriver zlib-dev openssl-dev cmake\ readline-dev yaml-dev sqlite-dev libxml2-dev libxslt-dev libffi-dev vips-dev && \ curl -o /usr/local/bin/wait-for-it https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh && \ chmod +x /usr/local/bin/wait-for-it diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu index d6fb889d0b..4d67450b24 100644 --- a/Dockerfile.ubuntu +++ b/Dockerfile.ubuntu @@ -25,7 +25,8 @@ RUN apt-get update && apt-get install -y \ libjemalloc-dev \ libssl-dev \ ca-certificates \ - gnupg + gnupg \ + cmake # Setup ENV variables ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:/usr/local/src/nodenv/shims:/usr/local/src/nodenv/bin:$PATH diff --git a/compose.yaml b/compose.yaml index 5572e3e4ef..ebaf7d5514 100644 --- a/compose.yaml +++ b/compose.yaml @@ -38,6 +38,8 @@ services: bash -c "rm -f tmp/pids/server.pid && (bundle check || bundle install) && bundle exec rake db:create && + chmod +x ./script/load_schema.sh && + ./script/load_schema.sh && yarn install && bundle exec foreman start -f Procfile.docker" volumes: diff --git a/script/load_schema.sh b/script/load_schema.sh new file mode 100755 index 0000000000..3cc4b3950b --- /dev/null +++ b/script/load_schema.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e + +echo "๐Ÿ” Checking if schema is missing or outdated..." + +# Get the current DB version +DB_VERSION=$(bundle exec rails db:version | grep 'Current version' | awk '{print $NF}') +FILE_VERSION=$(grep 'version:' db/schema.rb | awk '{print $2}') + +if [ -z "$DB_VERSION" ] || [ "$DB_VERSION" != "$FILE_VERSION" ]; then + echo "๐Ÿงพ Schema mismatch detected (DB=$DB_VERSION, File=$FILE_VERSION). Running db:schema:load..." + bundle exec rails db:schema:load +else + echo "โœ… Schema is up to date (version $DB_VERSION)." +fi From addf36a30487c66a045895245bec07d5da51a4ea Mon Sep 17 00:00:00 2001 From: Gareth Date: Wed, 30 Jul 2025 20:44:05 -0400 Subject: [PATCH 02/13] dummy commit for docker token check --- script/load_schema.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/load_schema.sh b/script/load_schema.sh index 3cc4b3950b..ef238ca288 100755 --- a/script/load_schema.sh +++ b/script/load_schema.sh @@ -13,3 +13,5 @@ if [ -z "$DB_VERSION" ] || [ "$DB_VERSION" != "$FILE_VERSION" ]; then else echo "โœ… Schema is up to date (version $DB_VERSION)." fi + +#################### \ No newline at end of file From d34f8900d701e4ba26d0d4efb6acb90250ea886a Mon Sep 17 00:00:00 2001 From: Gareth Date: Wed, 6 Aug 2025 15:05:45 -0400 Subject: [PATCH 03/13] divided foreman queued services into 3 containers. Web was exiting seemingly at random and seems to be a conflict between web, web-pack, and sidekiq being run through foreman. The division into 3 dev containers has been very consistent in building the project correctly --- compose.yaml | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/compose.yaml b/compose.yaml index ebaf7d5514..fa76337d1e 100644 --- a/compose.yaml +++ b/compose.yaml @@ -18,7 +18,6 @@ services: build: . ports: - 3000:3000 - - 3035:3035 volumes: - .:/usr/src/app - gems:/bundles @@ -30,6 +29,7 @@ services: - redis environment: DOCKER: true + DEV_CACHING: true OFN_DB_HOST: db OFN_REDIS_URL: redis://redis/ OFN_REDIS_JOBS_URL: redis://redis @@ -37,11 +37,41 @@ services: command: > bash -c "rm -f tmp/pids/server.pid && (bundle check || bundle install) && - bundle exec rake db:create && + bundle exec rails db:create && chmod +x ./script/load_schema.sh && ./script/load_schema.sh && yarn install && - bundle exec foreman start -f Procfile.docker" + bundle exec rails s -b 0.0.0.0 -p 3000" + + sidekiq: + build: . + command: bundle exec sidekiq + depends_on: + - db + - redis + volumes: + - .:/usr/src/app + - gems:/bundles + environment: + DOCKER: true + DEV_CACHING: true + OFN_DB_HOST: db + OFN_REDIS_URL: redis://redis/ + OFN_REDIS_JOBS_URL: redis://redis + OFN_REDIS_TEST_URL: redis://redis/3 + + webpack: + build: . + command: ./bin/webpack-dev-server + depends_on: + - web + ports: + - "3035:3035" + volumes: + - .:/usr/src/app + - gems:/bundles + environment: + WEBPACKER_DEV_SERVER_HOST: 0.0.0.0 volumes: gems: postgres: From 3750898c44ccea13c87e62e8c1a85c5ae3d2250b Mon Sep 17 00:00:00 2001 From: Gareth Date: Wed, 6 Aug 2025 15:21:30 -0400 Subject: [PATCH 04/13] Looks like db:prepare never fully ran and that's why it did not work. The issue seems to be using foreman with web, webpack, and sidekiq in the same script. Though not dependent on each other, the build order or port assignment was causing web to exit early upon build --- compose.yaml | 4 +--- db/schema.rb | 2 +- script/load_schema.sh | 17 ----------------- 3 files changed, 2 insertions(+), 21 deletions(-) delete mode 100755 script/load_schema.sh diff --git a/compose.yaml b/compose.yaml index fa76337d1e..2d33e88fd7 100644 --- a/compose.yaml +++ b/compose.yaml @@ -37,9 +37,7 @@ services: command: > bash -c "rm -f tmp/pids/server.pid && (bundle check || bundle install) && - bundle exec rails db:create && - chmod +x ./script/load_schema.sh && - ./script/load_schema.sh && + bundle exec rails db:prepare && yarn install && bundle exec rails s -b 0.0.0.0 -p 3000" diff --git a/db/schema.rb b/db/schema.rb index 641f3c4c61..16a093975c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2025_03_04_234657) do +ActiveRecord::Schema[7.0].define(version: 2025_07_09_012346) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" enable_extension "plpgsql" diff --git a/script/load_schema.sh b/script/load_schema.sh deleted file mode 100755 index ef238ca288..0000000000 --- a/script/load_schema.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -set -e - -echo "๐Ÿ” Checking if schema is missing or outdated..." - -# Get the current DB version -DB_VERSION=$(bundle exec rails db:version | grep 'Current version' | awk '{print $NF}') -FILE_VERSION=$(grep 'version:' db/schema.rb | awk '{print $2}') - -if [ -z "$DB_VERSION" ] || [ "$DB_VERSION" != "$FILE_VERSION" ]; then - echo "๐Ÿงพ Schema mismatch detected (DB=$DB_VERSION, File=$FILE_VERSION). Running db:schema:load..." - bundle exec rails db:schema:load -else - echo "โœ… Schema is up to date (version $DB_VERSION)." -fi - -#################### \ No newline at end of file From cb02cd39feb6bec2785dfae98c49f3e94e432294 Mon Sep 17 00:00:00 2001 From: Gareth Date: Fri, 15 Aug 2025 12:27:10 -0400 Subject: [PATCH 05/13] Reverting unexpected change to schema.rb as requested --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 16a093975c..641f3c4c61 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2025_07_09_012346) do +ActiveRecord::Schema[7.0].define(version: 2025_03_04_234657) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" enable_extension "plpgsql" From 74368f939b4a524cff270ed2a51aba64f135c686 Mon Sep 17 00:00:00 2001 From: Gareth Date: Fri, 15 Aug 2025 14:23:13 -0400 Subject: [PATCH 06/13] By creating the db in the container on composition, the first migration file rejects the schema of the empty database. All I had to do was remove db creation from docker so that db:prepare will default to creating open_food_network_dev from schema.rb rather than perceiving a mismatch from the precreated docker db --- compose.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/compose.yaml b/compose.yaml index 2d33e88fd7..7ba4f2cc18 100644 --- a/compose.yaml +++ b/compose.yaml @@ -5,7 +5,6 @@ services: environment: POSTGRES_PASSWORD: f00d POSTGRES_USER: ofn - POSTGRES_DB: open_food_network_dev ports: - 5432:5432 volumes: From c7ae47053e8ec75a555eeb233a706a02adfa0301 Mon Sep 17 00:00:00 2001 From: Gareth Date: Mon, 18 Aug 2025 11:38:57 -0400 Subject: [PATCH 07/13] Added health check to avoid docker container racing --- compose.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compose.yaml b/compose.yaml index 7ba4f2cc18..7fe10ca149 100644 --- a/compose.yaml +++ b/compose.yaml @@ -9,6 +9,10 @@ services: - 5432:5432 volumes: - 'postgres:/var/lib/postgresql/data' + healthcheck: + test: ["CMD-SHELL", "PG_PASSWORD=$$POSTGRES_PASSWORD pg_isready -U $$POSTGRES_USER"] + interval: 5s + timeout: 10s redis: image: redis web: @@ -24,8 +28,10 @@ services: - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro depends_on: - - db - - redis + db: + condition: service_healthy + redis: + condition: service_started environment: DOCKER: true DEV_CACHING: true From e1e4aeac1f232b5c21408d70a0a68ab25175408e Mon Sep 17 00:00:00 2001 From: Gareth Date: Mon, 18 Aug 2025 11:52:52 -0400 Subject: [PATCH 08/13] Added conditions to sidekiq too as it races db as well. Everything seems functional now --- compose.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compose.yaml b/compose.yaml index 7fe10ca149..3e104a6495 100644 --- a/compose.yaml +++ b/compose.yaml @@ -50,8 +50,10 @@ services: build: . command: bundle exec sidekiq depends_on: - - db - - redis + db: + condition: service_healthy + redis: + condition: service_started volumes: - .:/usr/src/app - gems:/bundles From b95d798a27dadf34cae29336e0d8772b38c85d66 Mon Sep 17 00:00:00 2001 From: Gareth Date: Mon, 18 Aug 2025 12:24:27 -0400 Subject: [PATCH 09/13] Fixed webpack service so that web relies on its bundles. This has re-enabled JS --- compose.yaml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compose.yaml b/compose.yaml index 3e104a6495..1dc150c50a 100644 --- a/compose.yaml +++ b/compose.yaml @@ -10,9 +10,11 @@ services: volumes: - 'postgres:/var/lib/postgresql/data' healthcheck: - test: ["CMD-SHELL", "PG_PASSWORD=$$POSTGRES_PASSWORD pg_isready -U $$POSTGRES_USER"] + test: ["CMD-SHELL", "PGPASSWORD=$$POSTGRES_PASSWORD pg_isready -q -h 127.0.0.1 -p 5432 -U $$POSTGRES_USER || exit 1"] interval: 5s timeout: 10s + retries: 10 + redis: image: redis web: @@ -32,6 +34,8 @@ services: condition: service_healthy redis: condition: service_started + webpack: + condition: service_started environment: DOCKER: true DEV_CACHING: true @@ -39,6 +43,10 @@ services: OFN_REDIS_URL: redis://redis/ OFN_REDIS_JOBS_URL: redis://redis OFN_REDIS_TEST_URL: redis://redis/3 + WEBPACKER_DEV_SERVER_HOST: webpack + WEBPACKER_DEV_SERVER_PORT: 3035 + WEBPACKER_DEV_SERVER_PUBLIC: localhost:3035 + command: > bash -c "rm -f tmp/pids/server.pid && (bundle check || bundle install) && @@ -68,8 +76,6 @@ services: webpack: build: . command: ./bin/webpack-dev-server - depends_on: - - web ports: - "3035:3035" volumes: From b69eb9bdff07823864fd9d40a165427c67333f0f Mon Sep 17 00:00:00 2001 From: Gareth Date: Wed, 20 Aug 2025 08:48:21 -0400 Subject: [PATCH 10/13] Specified BUNDLE_PATH AND BUNDLE_APP_CONFIG in Dockerfile --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5db0d1fb33..f4162a434b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,9 @@ FROM ruby:3.1.4-alpine3.19 AS base ENV LANG=C.UTF-8 \ LC_ALL=C.UTF-8 \ TZ=Europe/London \ - RAILS_ROOT=/usr/src/app + RAILS_ROOT=/usr/src/app \ + BUNDLE_PATH=/bundles \ + BUNDLE_APP_CONFIG=/bundles RUN apk --no-cache upgrade && \ apk add --no-cache tzdata postgresql-client imagemagick imagemagick-jpeg && \ apk add --no-cache --virtual wkhtmltopdf From 2d064bab64e0e0bbb4f1002ebc4f823c070068a1 Mon Sep 17 00:00:00 2001 From: Gareth Date: Wed, 20 Aug 2025 10:13:20 -0400 Subject: [PATCH 11/13] Created a bundler service that runs once removing responsibilities from any other services. The bundler service always runs install which should still be pretty fast if nothing or only a few gems have changed. A healthcheck won't work unless bundler runs continuously which is impractical. Instead, a checksum is generated on bundle install and sentinels in the other services have a definite confirmation that bundle is complete. The nice thing about this approach is that web, webpack, and sidekiq (which share the same bundles dependencies) will not concurrently run bundle install solving dep install redundancies. --- compose.yaml | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/compose.yaml b/compose.yaml index 1dc150c50a..ef6f18762c 100644 --- a/compose.yaml +++ b/compose.yaml @@ -17,6 +17,18 @@ services: redis: image: redis + + bundler: + build: . + # Runs once: installs gems into /bundles, writes a checksum sentinel, then exits + command: > + sh -lc 'bundle check || bundle install --jobs 4 --retry 3 --quiet; + sha256sum Gemfile.lock > /bundles/.Gemfile.lock.sha' + volumes: + - .:/usr/src/app + - gems:/bundles + restart: "no" + web: tty: true stdin_open: true @@ -48,15 +60,17 @@ services: WEBPACKER_DEV_SERVER_PUBLIC: localhost:3035 command: > - bash -c "rm -f tmp/pids/server.pid && - (bundle check || bundle install) && - bundle exec rails db:prepare && - yarn install && - bundle exec rails s -b 0.0.0.0 -p 3000" + sh -lc 'rm -f tmp/pids/server.pid; + until [ -f /bundles/.Gemfile.lock.sha ] && sha256sum -c /bundles/.Gemfile.lock.sha >/dev/null 2>&1; do sleep 0.5; done; + bundle exec rails db:prepare && + yarn install && + exec bundle exec rails s -b 0.0.0.0 -p 3000' sidekiq: build: . - command: bundle exec sidekiq + command: > + sh -lc 'until [ -f /bundles/.Gemfile.lock.sha ] && sha256sum -c /bundles/.Gemfile.lock.sha >/dev/null 2>&1; do sleep 0.5; done; + exec bundle exec sidekiq' depends_on: db: condition: service_healthy @@ -75,12 +89,20 @@ services: webpack: build: . - command: ./bin/webpack-dev-server + command: > + sh -lc 'until [ -f /bundles/.Gemfile.lock.sha ] && sha256sum -c /bundles/.Gemfile.lock.sha >/dev/null 2>&1; do sleep 0.5; done; + exec ./bin/webpack-dev-server' ports: - "3035:3035" volumes: - .:/usr/src/app - gems:/bundles + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:3035/webpack-dev-server >/dev/null || wget -qO- http://localhost:3035/sockjs-node/info >/dev/null"] + interval: 5s + timeout: 3s + retries: 30 + environment: WEBPACKER_DEV_SERVER_HOST: 0.0.0.0 volumes: From 6f9dcf7e27aceba73bd71114e176e11a246f6742 Mon Sep 17 00:00:00 2001 From: Gareth Date: Wed, 20 Aug 2025 11:04:40 -0400 Subject: [PATCH 12/13] remove bundle check --- compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yaml b/compose.yaml index ef6f18762c..b1195eabdb 100644 --- a/compose.yaml +++ b/compose.yaml @@ -22,7 +22,7 @@ services: build: . # Runs once: installs gems into /bundles, writes a checksum sentinel, then exits command: > - sh -lc 'bundle check || bundle install --jobs 4 --retry 3 --quiet; + sh -lc 'bundle install --jobs 4 --retry 3 --quiet; sha256sum Gemfile.lock > /bundles/.Gemfile.lock.sha' volumes: - .:/usr/src/app