diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ca0f731 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,37 @@ +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. + +# Ignore git directory. +/.git/ + +# Ignore bundler config. +/.bundle + +# Ignore all default key files. +/config/master.key +/config/credentials/*.key + +# Ignore all environment files. +/.env* +!/.env.example + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/.keep + +# Ignore assets. +/node_modules/ +/app/assets/builds/* +!/app/assets/builds/.keep +/public/assets diff --git a/.github/workflows/rubyonrails.yaml b/.github/workflows/rubyonrails.yaml index ab2050d..f7098bc 100644 --- a/.github/workflows/rubyonrails.yaml +++ b/.github/workflows/rubyonrails.yaml @@ -4,7 +4,7 @@ # # This workflow will install a prebuilt Ruby version, install dependencies, and # run tests and linters. -name: "Ruby on Rails CI" +name: "Ruby on Rails CI/CD" on: push: branches: [ "main" ] # Jos repositoriosi päähaara ei ole main, muuta nämä @@ -25,10 +25,11 @@ jobs: env: RAILS_ENV: test DATABASE_URL: "postgres://rails:password@localhost:5432/rails_test" + steps: - name: Checkout code uses: actions/checkout@v3 - # Add or replace dependency steps here + - name: Install Ruby and gems uses: ruby/setup-ruby@v1 with: @@ -38,3 +39,7 @@ jobs: - name: Run RuboCop run: bundle exec rubocop --parallel + - uses: superfly/flyctl-actions/setup-flyctl@master + - run: flyctl deploy --remote-only + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} diff --git a/Dockerfile b/Dockerfile index 4f5745d..ab5d1bc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,71 @@ -FROM ruby:3.1.2 +# syntax = docker/dockerfile:1 -ENV PORT 3000 -EXPOSE $PORT +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile +ARG RUBY_VERSION=3.1.2 +FROM ruby:$RUBY_VERSION-slim as base -WORKDIR /home/app +LABEL fly_launch_runtime="rails" -RUN apt-get update && apt-get install -y npm && npm install -g yarn +# Rails app lives here +WORKDIR /rails -COPY Gemfile Gemfile.lock ./ -RUN bundle install -COPY . . +# Set production environment +ENV RAILS_ENV="production" \ + BUNDLE_WITHOUT="development:test" \ + BUNDLE_DEPLOYMENT="1" -ENTRYPOINT ["/bin/bash"] -CMD ["startup.sh"] +# Update gems and bundler +RUN gem update --system --no-document && \ + gem install -N bundler + + +# 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 libpq-dev pkg-config + +# Install application gems +COPY --link Gemfile Gemfile.lock ./ +RUN bundle install && \ + bundle exec bootsnap precompile --gemfile && \ + rm -rf ~/.bundle/ $BUNDLE_PATH/ruby/*/cache $BUNDLE_PATH/ruby/*/bundler/gems/*/.git + +# Copy application code +COPY --link . . + +# 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 ./bin/rails assets:precompile + + +# Final stage for app image +FROM base + +# Install packages needed for deployment +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y curl libsqlite3-0 postgresql-client && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Copy built artifacts: gems, application +COPY --from=build /usr/local/bundle /usr/local/bundle +COPY --from=build /rails /rails + +# 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 + +# Deployment options +ENV RAILS_LOG_TO_STDOUT="1" \ + RAILS_SERVE_STATIC_FILES="true" + +# Entrypoint prepares the database. +ENTRYPOINT ["/rails/bin/docker-entrypoint"] + +# Start the server by default, this can be overwritten at runtime +EXPOSE 3000 +CMD ["./bin/rails", "server"] diff --git a/Dockerfile.self-host b/Dockerfile.self-host new file mode 100644 index 0000000..4f5745d --- /dev/null +++ b/Dockerfile.self-host @@ -0,0 +1,15 @@ +FROM ruby:3.1.2 + +ENV PORT 3000 +EXPOSE $PORT + +WORKDIR /home/app + +RUN apt-get update && apt-get install -y npm && npm install -g yarn + +COPY Gemfile Gemfile.lock ./ +RUN bundle install +COPY . . + +ENTRYPOINT ["/bin/bash"] +CMD ["startup.sh"] diff --git a/Gemfile b/Gemfile index b5ed088..dbb0073 100644 --- a/Gemfile +++ b/Gemfile @@ -86,3 +86,9 @@ end group :production do gem "pg" end + +gem "dockerfile-rails", ">= 1.5", :group => :development + +gem "sentry-ruby", "~> 5.13" + +gem "sentry-rails", "~> 5.13" diff --git a/Gemfile.lock b/Gemfile.lock index 9dd63d9..dc84519 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -93,6 +93,8 @@ GEM reline (>= 0.3.1) diff-lcs (1.5.0) docile (1.4.0) + dockerfile-rails (1.5.12) + rails (>= 3.0.0) erubi (1.12.0) factory_bot (6.2.1) activesupport (>= 5.0.0) @@ -236,6 +238,11 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) + sentry-rails (5.13.0) + railties (>= 5.0) + sentry-ruby (~> 5.13.0) + sentry-ruby (5.13.0) + concurrent-ruby (~> 1.0, >= 1.0.2) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) @@ -287,6 +294,7 @@ DEPENDENCIES bootsnap capybara debug + dockerfile-rails (>= 1.5) factory_bot_rails importmap-rails jbuilder @@ -298,6 +306,8 @@ DEPENDENCIES rspec-rails rubocop selenium-webdriver + sentry-rails (~> 5.13) + sentry-ruby (~> 5.13) simplecov sprockets-rails sqlite3 diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint new file mode 100755 index 0000000..dffd4ba --- /dev/null +++ b/bin/docker-entrypoint @@ -0,0 +1,8 @@ +#!/bin/bash -e + +# If running the rails server then create or migrate existing database +if [ "${*}" == "./bin/rails server" ]; then + ./bin/rails db:prepare +fi + +exec "${@}" diff --git a/config/dockerfile.yml b/config/dockerfile.yml new file mode 100644 index 0000000..80ca92c --- /dev/null +++ b/config/dockerfile.yml @@ -0,0 +1,7 @@ +# generated by dockerfile-rails + +--- +options: + label: + fly_launch_runtime: rails + sentry: true diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb new file mode 100644 index 0000000..209d75d --- /dev/null +++ b/config/initializers/sentry.rb @@ -0,0 +1,17 @@ +if ENV["SENTRY_DSN"] + +Sentry.init do |config| + config.dsn = ENV["SENTRY_DSN"] + config.breadcrumbs_logger = [:active_support_logger, :http_logger] + + # Set traces_sample_rate to 1.0 to capture 100% + # of transactions for performance monitoring. + # We recommend adjusting this value in production. + config.traces_sample_rate = 1.0 + # or + config.traces_sampler = lambda do |context| + true + end +end + +end diff --git a/fly.toml b/fly.toml new file mode 100644 index 0000000..cd5ded6 --- /dev/null +++ b/fly.toml @@ -0,0 +1,22 @@ +# fly.toml app configuration file generated for brewery on 2023-11-11T18:24:26+02:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = "brewery" +primary_region = "arn" +console_command = "/rails/bin/rails console" + +[build] + +[http_service] + internal_port = 3000 + force_https = true + auto_stop_machines = true + auto_start_machines = true + min_machines_running = 0 + processes = ["app"] + +[[statics]] + guest_path = "/rails/public" + url_prefix = "/"