Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#29] Deployment #30

Merged
merged 8 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -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
28 changes: 3 additions & 25 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
name: CI
on: [push, pull_request]
on: pull_request
jobs:
test:
runs-on: ubuntu-latest
services:
redis:
image: redis
ports: ['6379:6379']
options: --entrypoint redis-server
steps:
- uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2.2
- name: Build and run tests
env:
REDIS_URL: redis://localhost:6379/0
RAILS_ENV: test
run: |
sudo apt-get -yqq install libpq-dev
gem install bundler
bundle install --jobs 4 --retry 3
bundle exec rails db:prepare
bundle exec rails test:all
bundle exec rspec
call-test:
uses: ./.github/workflows/test.yml
17 changes: 17 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Deploy
on:
push:
branches:
- main
jobs:
call-test:
uses: ./.github/workflows/test.yml
deploy:
name: Deploy app
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
26 changes: 26 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
on: workflow_call
jobs:
test:
runs-on: ubuntu-latest
services:
redis:
image: redis
ports: ['6379:6379']
options: --entrypoint redis-server
steps:
- uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2.2
- name: Build and run tests
env:
REDIS_URL: redis://localhost:6379/0
RAILS_ENV: test
run: |
sudo apt-get -yqq install libpq-dev
gem install bundler
bundle install --jobs 4 --retry 3
bundle exec rails db:prepare
bundle exec rails test:all
bundle exec rspec
73 changes: 73 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# syntax = docker/dockerfile:1

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.2.2
FROM ruby:$RUBY_VERSION-slim as base

# Rails app lives here
WORKDIR /rails

# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_WITHOUT="development:test" \
BUNDLE_DEPLOYMENT="1"

# 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 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 && \
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 && \
mkdir /data && \
chown -R rails:rails db log storage tmp /data
USER rails:rails

# Deployment options
ENV DATABASE_URL="sqlite3:///data/production.sqlite3" \
RAILS_LOG_TO_STDOUT="1" \
RAILS_SERVE_STATIC_FILES="true" \
RUBY_YJIT_ENABLE="1"

# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
VOLUME /data
CMD ["./bin/rails", "server"]
3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ group :development do
gem "flog", require: false
gem "guard-rspec", require: false
gem "guard-minitest", "~> 2.4", require: false
gem "dockerfile-rails", ">= 1.5", require: false
end

group :test do
Expand All @@ -85,6 +86,4 @@ group :test do
gem "shoulda-matchers", "~> 5.0"
end


gem "devise", "~> 4.9"

7 changes: 7 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ GEM
responders
warden (~> 1.2.3)
diff-lcs (1.5.0)
dockerfile-rails (1.5.12)
rails (>= 3.0.0)
erubi (1.12.0)
factory_bot (6.4.0)
activesupport (>= 5.0.0)
Expand Down Expand Up @@ -187,6 +189,8 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.9)
nokogiri (1.15.4-aarch64-linux)
racc (~> 1.4)
nokogiri (1.15.4-arm64-darwin)
racc (~> 1.4)
nokogiri (1.15.4-x86_64-linux)
Expand Down Expand Up @@ -313,6 +317,7 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
sqlite3 (1.6.4-aarch64-linux)
sqlite3 (1.6.4-arm64-darwin)
sqlite3 (1.6.4-x86_64-linux)
stimulus-rails (1.2.2)
Expand Down Expand Up @@ -347,6 +352,7 @@ GEM
zeitwerk (2.6.11)

PLATFORMS
aarch64-linux
arm64-darwin-22
x86_64-linux

Expand All @@ -355,6 +361,7 @@ DEPENDENCIES
capybara
debug
devise (~> 4.9)
dockerfile-rails (>= 1.5)
factory_bot_rails (~> 6.4)
faker (~> 3.2.2)
flog
Expand Down
2 changes: 1 addition & 1 deletion app/mailers/application_mailer.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class ApplicationMailer < ActionMailer::Base
default from: "[email protected]"
default from: "[email protected]"
layout "mailer"
end
3 changes: 3 additions & 0 deletions app/views/home/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<h1>Welcome to Along!</h1>

<p>
A web application to make it easier to practice along to YouTube music instrument video lessons (where enabled).
</p>
<% if user_signed_in? %>
<%= link_to "Lessons", lessons_path %>
<% else %>
Expand Down
8 changes: 8 additions & 0 deletions bin/docker-entrypoint
Original file line number Diff line number Diff line change
@@ -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 "${@}"
2 changes: 1 addition & 1 deletion config/credentials.yml.enc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
GOC1Lj07cHH4WjwXaJ07M+YxXFjTBBrDuitMit6p3bvW8PbKc91aOVEqh6X3728ZOO2JQ5Mx0WptJCkJCsquW/Ug/0I14YT7uHPKfgozTjtqmMFbyIQn0jp36bxHcpvaVJSaUvitbsaizUWduIlutPImzo0N2eZrIBZissbdCoadbUvbaescUEvZrfqg6LxXi0ZqX8HhkXMIPvLIAJhlmECrBSC2n3bM4RTY+1VyKAu3+O7pnfuEw0GFeptrwJ46I2tDldvJKZgtupjkzYrQ4kVnnpSbfUM8a7BJQKG6KblbtipUo/7pyKdbn5bNoxY9z1vLqFacz+DqreqMmSUO1110R5N3dpZYVPUCsc6sBDu5u3ex4A71IGAl5TPT1eqiOZl8ooStGfqXr30pgYMHOjUcj07xtfK0wDEJ--cnvAMQVqO0RplpHk--pDV/e55w3yPjxTjKLQh/8g==
amhyRa5LGqZ3C+qu5WasK3LhzFwVtFyZn7Bt9LQlkiHFn6/YNMiau0svHTbx7JrxSCX0d5pb27wvt/bzYeo34DvtQSDC2gLG3o/+XChVRpAH1HWqhA12w7PPOfWFpdb06ALoTpoqpOPwWPEMFGHd0MR2yWxrjZ28Cb7M2xykS2TIOyjRxGpZ3OLsaq+WC9kQHo/UNB9LoKdWe8IRVbD/MgHnjjQ5AcvuGH/hw2t9woXJG9P3UYEzz37ViaoRxIj7HkdO2fd+FKHXQcpNzNZLQPeZSvMp7B4c6t/e7351WuDFB303G3ZQ/MlfoT/aDXV2tK3gNDE9EnneQJk/tGtTTEApHb9CjI4ulyWqlJ3JfivcM0mlEeUXTYaFw6wLL6yOr0+DZOYLf7d9773uZXk1qBLBGRVsY19ErRvYK46662HQkvUY7YUwdCkyc4zGmf9DzsitBXWct7V5qs8f7c6HrOmHy0NkTCJt88/2WxM/hyhlIHSjMDIPuHKxs3ZfCkNA56CqkxeLE35CbFQk+A==--zYgqCm4mQtsocYj3--Anx2lttZVTqPfO1BzH23wA==
2 changes: 1 addition & 1 deletion config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ test:

production:
<<: *default
database: db/production.sqlite3
database: /data/production.sqlite3
11 changes: 11 additions & 0 deletions config/dockerfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# generated by dockerfile-rails

---
options:
label:
fly_launch_runtime: rails
postgresql: true
prepare: false
sqlite3: true
sentry: true
yjit: true
12 changes: 12 additions & 0 deletions config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

config.secret_key_base = ENV["SECRET_KEY_BASE"]
# Code is not reloaded between requests.
config.cache_classes = true

Expand Down Expand Up @@ -63,6 +64,17 @@
# config.active_job.queue_name_prefix = "along_production"

config.action_mailer.perform_caching = false
config.action_mailer.delivery_method = :smtp

config.action_mailer.smtp_settings = {
:user_name => 'apikey', # This is the string literal 'apikey', NOT the ID of your API key
:password => Rails.application.credentials.sendgrid_api_key, # This is the secret sendgrid API key which was issued during API key creation
:domain => "mauriciofierro.dev",
:address => "smtp.sendgrid.net",
:port => 587,
:authentication => :plain,
:enable_starttls_auto => true
}

# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
Expand Down
33 changes: 33 additions & 0 deletions fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# fly.toml app configuration file generated for along on 2023-12-08T10:50:18-05:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = "along"
primary_region = "mia"
swap_size_mb = 1024
console_command = "/rails/bin/rails console"

[build]
dockerfile = "Dockerfile"

[env]
DATABASE_URL = "sqlite3:///data/production.sqlite3"

[[mounts]]
source = "data"
destination = "/data"
auto_extend_size_threshold = 0

[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
processes = ["app"]

[[vm]]
cpu_kind = "shared"
cpus = 1
memory_mb = 256