diff --git a/Dockerfile b/Dockerfile index 8c6652b..343e93e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,62 +1,25 @@ -# syntax = docker/dockerfile:1 - # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile ARG RUBY_VERSION=3.2.2 -FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base - -# Rails app lives here -WORKDIR /rails - -# Set production environment -ENV RAILS_ENV="production" \ - BUNDLE_DEPLOYMENT="1" \ - BUNDLE_PATH="/usr/local/bundle" \ - BUNDLE_WITHOUT="development" - - -# Throw-away build stage to reduce size of final image -FROM base as build - -# Install packages needed to build gems -RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y build-essential git libpq-dev libvips pkg-config - -# Install application gems -COPY Gemfile Gemfile.lock ./ -RUN bundle install && \ - rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ - bundle exec bootsnap precompile --gemfile - -# Copy application code -COPY . . - -# Precompile bootsnap code for faster boot times -RUN bundle exec bootsnap precompile app/ lib/ -# Precompiling assets for production without requiring secret RAILS_MASTER_KEY -RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile +FROM ruby:$RUBY_VERSION +# Setup default directory +RUN mkdir /var/source +WORKDIR /var/source -# Final stage for app image -FROM base +# Install rails and dependencies +RUN gem install rails bundler -# Install packages needed for deployment -RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y curl libvips postgresql-client && \ - rm -rf /var/lib/apt/lists /var/cache/apt/archives +# Install the Heroku CLI +RUN curl https://cli-assets.heroku.com/install-ubuntu.sh | sh -# Copy built artifacts: gems, application -COPY --from=build /usr/local/bundle /usr/local/bundle -COPY --from=build /rails /rails +# Install node 22 +RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash +RUN apt-get install -y nodejs -# Run and own only the runtime files as a non-root user for security -RUN useradd rails --create-home --shell /bin/bash && \ - chown -R rails:rails db log storage tmp -USER rails:rails +# Install playwright driver +RUN npx playwright install chromium --with-deps -# Entrypoint prepares the database. -ENTRYPOINT ["/rails/bin/docker-entrypoint"] +COPY docker/rails_entrypoint.sh /entrypoint.sh -# Start the server by default, this can be overwritten at runtime -EXPOSE 3000 -CMD ["./bin/rails", "server"] +ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/README.md b/README.md index 12dea9b..359f4c4 100644 --- a/README.md +++ b/README.md @@ -9,22 +9,36 @@ development and testing purposes. ### Prerequisites -Ruby (see .ruby-version) and PostgreSQL. +Docker ### Local setup 1. Clone the repo + 2. Navigate to the root directory of the project. -3. `bundle install` to install Ruby dependencies. -4. `rails db:create db:schema:load` to set up the database. -5. `bin/dev` to start a local development server. -Most features should work locally though for some you may need to add the appropriate credentials - see the `.env.test` for an example. You may need to set up accounts for the relevant services or contact a maintainer for the keys. +3. Install Ruby dependencies and start the local development server. +```shell +docker compose build +docker compose up +``` + +4. Run the database migrations and seed the database +```shell +docker compose exec app.local bash +rails db:schema:load +``` + +The local development server will now be accessible at http://localhost:3000. + +Most features should work locally though for some you may need to add the appropriate credentials - +see the `.env.template` for an example. You may need to set up accounts for the relevant services - +or contact a maintainer for the keys. ### Running tests -- `rails test` to run unit tests. -- `rails test:system` to run system/end-to-end tests. +- `docker compose exec app.local rails test` to run unit tests. +- `docker compose exec app.local rails test:system` to run system/end-to-end tests. ## Deployment diff --git a/app/models/user.rb b/app/models/user.rb index d2f9bf5..959b9a0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -32,12 +32,11 @@ class User < ApplicationRecord .having("COUNT(CASE WHEN messages.clicked_at IS NULL THEN 1 END) = 2") } - enum timing: { + enum :timing, morning: "morning", afternoon: "afternoon", evening: "evening", no_preference: "no_preference" - } def child_age_in_months_today (Time.now.year * 12 + Time.now.month) - (child_birthday.year * 12 + child_birthday.month) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..163040f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,39 @@ +services: + app.local: + build: . + restart: unless-stopped + ports: + - "3000:3000" + volumes: + - ".:/var/source" + - "./storage/bundle:/usr/local/bundle" + environment: + DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL: true + DATABASE_URL: "postgres://pgsql:password@pgsql:5432" + USE_MAILHOG: true + MAILHOG_HOST: mailhog + SYSTEM_TEST_DRIVER: playwright + depends_on: + - pgsql + + pgsql: + image: postgres + restart: unless-stopped + ports: + - 5433:5432 + volumes: + - ./storage/postgres:/var/lib/postgresql/data + - ./docker/postgres_setup.sql:/docker-entrypoint-initdb.d/10-database-setup.sql + environment: + POSTGRES_USER: pgsql + POSTGRES_PASSWORD: password + + tailwind: + build: . + entrypoint: /var/source/bin/rails tailwindcss:watch[always] + restart: unless-stopped + volumes: + - ".:/var/source" + - "./storage/bundle:/usr/local/bundle" + depends_on: + - app.local diff --git a/docker/postgres_setup.sql b/docker/postgres_setup.sql new file mode 100644 index 0000000..d8db410 --- /dev/null +++ b/docker/postgres_setup.sql @@ -0,0 +1,3 @@ +CREATE DATABASE afs_tiny_happy_people_development; +CREATE DATABASE afs_tiny_happy_people_test; +CREATE DATABASE afs_tiny_happy_people_production; diff --git a/docker/rails_entrypoint.sh b/docker/rails_entrypoint.sh new file mode 100755 index 0000000..d087539 --- /dev/null +++ b/docker/rails_entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# Ensure the correct dependencies are installed +if ! bundler check | grep "The Gemfile's dependencies are satisfied" + then + bundler install +fi + +# Remove server lock file +rm /var/source/tmp/pids/server.pid + +/var/source/bin/rails server -b 0.0.0.0