From 5accdd776cb06dc47eaf679425c45697a2e9d815 Mon Sep 17 00:00:00 2001 From: Luis Fernando Jimenez Date: Tue, 6 Aug 2024 01:28:35 +0200 Subject: [PATCH] Update deployment --- .dockerignore | 37 ++++++++++++++ .github/workflows/fly-deploy.yml | 18 +++++++ .node-version | 1 + .ruby-version | 2 +- Dockerfile | 84 ++++++++++++++++++++++++++++++++ Gemfile | 4 +- Gemfile.lock | 11 +++-- bin/docker-entrypoint | 5 ++ config/credentials.yml.enc | 2 +- config/dockerfile.yml | 8 +++ fly.toml | 30 ++++++++++++ 11 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/fly-deploy.yml create mode 100644 .node-version create mode 100644 Dockerfile create mode 100755 bin/docker-entrypoint create mode 100644 config/dockerfile.yml create mode 100644 fly.toml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9612375 --- /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 environment files (except templates). +/.env* +!/.env*.erb + +# Ignore all default key files. +/config/master.key +/config/credentials/*.key + +# 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/fly-deploy.yml b/.github/workflows/fly-deploy.yml new file mode 100644 index 0000000..b0c246e --- /dev/null +++ b/.github/workflows/fly-deploy.yml @@ -0,0 +1,18 @@ +# See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/ + +name: Fly Deploy +on: + push: + branches: + - main +jobs: + deploy: + name: Deploy app + runs-on: ubuntu-latest + concurrency: deploy-group # optional: ensure only one action runs at a time + steps: + - uses: actions/checkout@v4 + - uses: superfly/flyctl-actions/setup-flyctl@master + - run: flyctl deploy --remote-only + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..8ce7030 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +20.16.0 diff --git a/.ruby-version b/.ruby-version index 94ff29c..619b537 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.1 +3.3.3 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b76fbfd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,84 @@ +# syntax = docker/dockerfile:1 + +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile +ARG RUBY_VERSION=3.3.3 +FROM ruby:$RUBY_VERSION-slim as base + +LABEL fly_launch_runtime="rails" + +# Rails app lives here +WORKDIR /rails + +# Set production environment +ENV BUNDLE_DEPLOYMENT="1" \ + BUNDLE_PATH="/usr/local/bundle" \ + BUNDLE_WITHOUT="development:test" \ + RAILS_ENV="production" + +# 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 and node modules +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential curl libpq-dev node-gyp pkg-config python-is-python3 + +# Install Node.js +ARG NODE_VERSION=20.16.0 +ENV PATH=/usr/local/node/bin:$PATH +RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \ + /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \ + rm -rf /tmp/node-build-master + +# 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 + +# Install node modules +COPY --link package.json package-lock.json ./ +RUN npm install + +# 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 postgresql-client && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Copy built artifacts: gems, application +COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" +COPY --from=build /rails /rails + +# Run and own only the runtime files as a non-root user for security +RUN groupadd --system --gid 1000 rails && \ + useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ + chown -R 1000:1000 db log storage tmp +USER 1000:1000 + +# Deployment options +ENV RAILS_LOG_TO_STDOUT="1" \ + RAILS_SERVE_STATIC_FILES="true" + +# Entrypoint sets up the container. +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/Gemfile b/Gemfile index 3657e29..2edde1a 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '3.1.1' +ruby '3.3.3' # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" gem 'rails', '~> 7.0.2', '>= 7.0.2.2' @@ -77,3 +77,5 @@ end gem 'tailwindcss-rails', '~> 2.0' gem 'devise', '~> 4.8' + +gem "dockerfile-rails", ">= 1.6", :group => :development diff --git a/Gemfile.lock b/Gemfile.lock index 97db027..338862e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -96,6 +96,8 @@ GEM warden (~> 1.2.3) diff-lcs (1.5.0) digest (3.1.0) + dockerfile-rails (1.6.17) + rails (>= 3.0.0) erubi (1.10.0) globalid (1.0.0) activesupport (>= 5.0) @@ -120,6 +122,7 @@ GEM matrix (0.4.2) method_source (1.0.0) mini_mime (1.1.2) + mini_portile2 (2.8.7) minitest (5.15.0) msgpack (1.4.5) net-imap (0.2.3) @@ -138,9 +141,8 @@ GEM net-protocol timeout nio4r (2.5.8) - nokogiri (1.13.3-arm64-darwin) - racc (~> 1.4) - nokogiri (1.13.3-x86_64-linux) + nokogiri (1.13.3) + mini_portile2 (~> 2.8.0) racc (~> 1.4) orm_adapter (0.5.0) pg (1.3.4) @@ -255,6 +257,7 @@ DEPENDENCIES capybara debug devise (~> 4.8) + dockerfile-rails (>= 1.6) importmap-rails jbuilder pg (~> 1.1) @@ -271,7 +274,7 @@ DEPENDENCIES webdrivers RUBY VERSION - ruby 3.1.1p18 + ruby 3.3.3p89 BUNDLED WITH 2.3.8 diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint new file mode 100755 index 0000000..9dd92e3 --- /dev/null +++ b/bin/docker-entrypoint @@ -0,0 +1,5 @@ +#!/bin/bash -e + +# Add any container initialization steps here + +exec "${@}" diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index fa3b4da..4494c19 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -LPzzigNE+zbnmkfPZxeVP7HM17kggKDAZVev0RyXzXtddszSPIMgpqSUHmzhZmujq5yrPtphBoWeUH5qzsuLnK46Bck0i/C4R+TPvSKXOf4xC5wq0rutk0ftAQCrjOtpqNbTr9TX1oLJS4mszHA/9burfNxbJq0KD+Wu3rE5t9iA+T8ySRwAYvAgyhLytnqkqnYVSd2H5EqNiWURcIbA340+hl1d5kJgt0CTUwmuVAzadSKVWoMtX3+6xo+mJgBIHAF7VgP/EuOH3CtTDf6/fwUnbAOQGmvxk3m+JCEMQ4wgy0JzgItcssOPeeapJd6NHKf7pbu9Xu1IPgla5jZeiy/6hnNYLulWC3ijWr2aQq7wKHJ0C5grHp6vPouc3gVV+9RfYw7qE9sMUXP/aOOt7ZTZAqswFKK46E3n--xIJiVNuEqyeziE5o--LD0AzAgRk0E8YoQ7JZHuoA== \ No newline at end of file +I5tgLqyQK8SGPyrAlC/ZIcFV6riBc6tGuAdDUAJVt0C7+NXekOSJS1uD3XZBFtKF3GyUurgO9ere42Q2Rp4wr0KQsNSoRaIwqXXvmQZAN5IkDYLD9lqiXt09dnbF5yUhd3CNIavQ55QK97Ezyly7xtL8L52IfpTdTEVg9E7z6t+rDoZkFL/ftbLnW+q7WCzc1c899lDT5SxCiB38lB57VOlO3S+805ONb4Q/QyZVSm2Fyq3KkJErtyAVrbEMnoyM8ddbD/mnlvyeLLi9vK+AWiH3KXRvCNaCvY2jYiKw9S7YNwGRqywjQAe2ZaVeAjAxX0NVMVb97Y3p7BcHE2nZ7kg2HnOhUMyfimpICCho375VXs5VCsvGlMmjnTnzz8YAfqI2kZtN1wufx6q0/KN+8ithd+srzQjfiIAf--fGvimv/mtjq1887j--PITshC1Zhp0B527dFHVvCg== \ No newline at end of file diff --git a/config/dockerfile.yml b/config/dockerfile.yml new file mode 100644 index 0000000..e6e5e56 --- /dev/null +++ b/config/dockerfile.yml @@ -0,0 +1,8 @@ +# generated by dockerfile-rails + +--- +options: + label: + fly_launch_runtime: rails + postgresql: true + prepare: false diff --git a/fly.toml b/fly.toml new file mode 100644 index 0000000..a6e899f --- /dev/null +++ b/fly.toml @@ -0,0 +1,30 @@ +# fly.toml app configuration file generated for recipes-on-rails on 2024-08-05T21:37:02+02:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = 'recipes-on-rails' +primary_region = 'mad' +console_command = '/rails/bin/rails console' + +[build] + +[deploy] + release_command = './bin/rails db:prepare' + +[http_service] + internal_port = 3000 + force_https = true + auto_stop_machines = 'stop' + auto_start_machines = true + min_machines_running = 0 + processes = ['app'] + +[[vm]] + memory = '1gb' + cpu_kind = 'shared' + cpus = 1 + +[[statics]] + guest_path = '/rails/public' + url_prefix = '/'