Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Plebeian-Technology/sway in…
Browse files Browse the repository at this point in the history
…to padawan
  • Loading branch information
dcordz committed Jun 7, 2024
2 parents be9fb33 + e77ba6c commit d6af4f3
Show file tree
Hide file tree
Showing 16 changed files with 214 additions and 40 deletions.
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v20.12.2
20.12.2
4 changes: 1 addition & 3 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ def route_component(route)

# https://www.leighhalliday.com/ruby-metaprogramming-method-missing
sig do
params(method_name: Symbol,
args: T::Array[T.nilable(T.any(T::Hash[T.untyped, T.untyped],
T.proc.returns(T::Hash[T.untyped, T.untyped])))]).void
params(method_name: Symbol, args: T.untyped).void
end
def method_missing(method_name, *args)
mn = method_name.to_s
Expand Down
2 changes: 1 addition & 1 deletion app/models/push_notification_subscription.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class PushNotificationSubscription < ApplicationRecord

scope :active, -> { where(subscribed: true) }

sig { params(message: String).returns(T.untyped) }
sig { params(message: T::Hash[String, T.untyped]).returns(T.untyped) }
def send_web_push_notification(message)
WebPush.payload_send(
message: JSON.generate(message),
Expand Down
10 changes: 9 additions & 1 deletion bin/docker-entrypoint
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
#!/bin/bash -e

./bin/rake sway:volume_setup

# If running the rails server then create or migrate existing database
if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then
echo "####################################################"
echo "docker-entrypoint -> Running rails db:migrate"
echo "####################################################"
# db:prepare - https://www.bigbinary.com/blog/rails-6-adds-rails-db-prepare-to-migrate-or-setup-a-database
./bin/rails db:prepare
./bin/rails db:migrate

echo "####################################################"
echo "docker-entrypoint -> Running rails db:seed"
echo "####################################################"
# Ensure seeds are run
./bin/rails db:seed
fi
Expand Down
2 changes: 1 addition & 1 deletion config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ class Application < Rails::Application
config.time_zone = 'UTC'
# config.eager_load_paths << Rails.root.join("extras")

config.force_ssl = true
config.force_ssl = false
end
end
1 change: 1 addition & 0 deletions config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ test:
production:
<<: *default
database: storage/production.sqlite3
# database: storage/prodswaysqlite/production.sqlite3

# Postgres
# production:
Expand Down
9 changes: 7 additions & 2 deletions config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
require "active_support/core_ext/integer/time"

Rails.application.configure do
config.active_record.sqlite3_production_warning = false

# Settings specified here will take precedence over those in config/application.rb.

# Code is not reloaded between requests.
Expand Down Expand Up @@ -50,7 +52,7 @@
# config.assume_ssl = true

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true
config.force_ssl = false

# Log to STDOUT by default
config.logger = ActiveSupport::Logger.new(STDOUT)
Expand Down Expand Up @@ -96,7 +98,10 @@
# https://guides.rubyonrails.org/security.html#dns-rebinding-and-host-header-attacks
config.hosts = [
# "example.com", # Allow requests from example.com
/.*\.sway\.vote/ # Allow requests from subdomains like `www.example.com`
/.*\.sway\.vote/, # Allow requests from subdomains like `www.example.com`
/.*\.fly\.dev/, # Allow requests from subdomains like `www.example.com`
'localhost',
'127.0.0.1'
]
# Skip DNS rebinding protection for the default health check endpoint.
config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
Expand Down
31 changes: 17 additions & 14 deletions config/puma.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# typed: false

# This configuration file will be evaluated by Puma. The top-level methods that
# are invoked here are part of Puma"s configuration DSL. For more information
# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.

puts ""
puts "##################################################################"
puts ""
puts ''
puts '##################################################################'
puts ''
puts "Puma starting with RAILS_ENV = #{ENV.fetch('RAILS_ENV')}"
puts ""
puts "##################################################################"
puts ""
puts ''
puts '##################################################################'
puts ''

# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
Expand All @@ -32,14 +33,16 @@
worker_timeout 3600 if ENV.fetch('RAILS_ENV', 'development') == 'development'

# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
# port ENV.fetch("PORT") { 3000 }

ssl_bind '0.0.0.0', ENV.fetch('PORT', 3000), {
key: 'config/ssl/key.pem',
cert: 'config/ssl/cert.pem',
verify_mode: 'none'
}
# if ENV.fetch('RAILS_ENV', 'development') == 'development'

if ENV['RAILS_ENV'] == 'production'
port ENV.fetch('PORT') { 3000 }
else
ssl_bind '0.0.0.0', ENV.fetch('PORT', 3000), {
key: 'config/ssl/key.pem',
cert: 'config/ssl/cert.pem',
verify_mode: 'none'
}
end

# Specifies the `environment` that Puma will run in.
environment ENV.fetch('RAILS_ENV') { 'development' }
Expand Down
4 changes: 3 additions & 1 deletion docker/dockerfiles/production.dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
ARG RUBY_VERSION=3.3.1
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim AS base

LABEL fly_launch_runtime="rails"

# Rails app lives here
WORKDIR /rails

Expand Down Expand Up @@ -74,4 +76,4 @@ ENTRYPOINT ["/rails/bin/docker-entrypoint"]
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000

CMD ["./bin/rails", "server", "-u", "puma"]
CMD ["./bin/rails", "server", "-u", "puma", "-b", "0.0.0.0", "-p", "3000", "-e", "production"]
8 changes: 8 additions & 0 deletions docker/dockerfiles/production.dockerfile.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Ignore git directory.
/.git/
/.github/

# Ignore vscode
/.vscode
Expand All @@ -20,6 +21,7 @@
/config/master.key
/config/credentials/*.key
/config/keys/
/config/ssl

# Ignore all logfiles and tempfiles.
/log/*
Expand All @@ -41,11 +43,15 @@
# Ignore terraform
/tf/

# Ignore litestream
/litestream/

# Ignore assets.
/node_modules/
/app/assets/builds/
#/app/assets/images/
#/public/*
/public/vite-test/

# Don't need views except layouts
/views
Expand Down Expand Up @@ -74,3 +80,5 @@

# DO ignore geojson files
**/**/.*geojson

fly.toml
58 changes: 58 additions & 0 deletions fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# fly.toml app configuration file generated for sway on 2024-06-07T10:24:01-04:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = 'sway'
primary_region = 'mia'
console_command = '/rails/bin/rails console'

[build]
image = 'ghcr.io/plebeian-technology/sway:latest'
#dockerfile = "docker/dockerfiles/production.dockerfile"
#ignorefile = "docker/dockerfiles/production.dockerfile.dockerignore"

[[mounts]]
source = 'prodswaysqlite'
destination = '/storage'

[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 1
max_machines_running = 3

[http_service.concurrency]
type = "requests"
soft_limit = 200
hard_limit = 250

[[http_service.checks]]
interval = '30s'
timeout = '5s'
grace_period = '10s'
method = 'GET'
path = '/up'

[checks]
[checks.status]
port = 3000
type = 'http'
interval = '10s'
timeout = '2s'
grace_period = '5s'
method = 'GET'
path = '/up'
protocol = 'http'
tls_skip_verify = false

[checks.status.headers]
X-Forwarded-Proto = 'https'

[[vm]]
#memory = '256mb'
memory = '1gb'
cpu_kind = 'shared'
cpus = 1
33 changes: 32 additions & 1 deletion lib/sway_google_cloud_storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,40 @@ def generate_put_signed_url_v4(bucket_name:, file_name:, content_type:)
)
end

def upload_file(bucket_name:, bucket_file_path:, local_file_path:)
return unless bucket_name && bucket_file_path && local_file_path

bucket = storage.bucket bucket_name, skip_lookup: true
bucket.create_file local_file_path, bucket_file_path
end

def download_file(bucket_name:, bucket_file_path:, local_file_path:)
return unless bucket_name && bucket_file_path && local_file_path

bucket = storage.bucket bucket_name, skip_lookup: true

file = bucket.file bucket_file_path

FileUtils.mkdir_p(local_file_path.split('/')[0..-2].join('/'))
file.download local_file_path
end

def download_directory(bucket_name:, bucket_directory_name:, local_directory_name:)
return unless bucket_name && bucket_directory_name && local_directory_name

bucket = storage.bucket bucket_name, skip_lookup: true

dir = bucket.files prefix: "#{bucket_directory_name}/"

dir.all do |f|
FileUtils.mkdir_p("#{local_directory_name}/#{f.name.split('/')[0..-2].join('/')}")
f.download "#{local_directory_name}/#{f.name}"
end
end

def delete_file(bucket_name:, file_name:)
return unless bucket_name && file_name
return if file_name.starts_with? "https://"
return if file_name.starts_with? 'https://'

bucket = storage.bucket bucket_name, skip_lookup: true
file = bucket.file file_name
Expand Down
25 changes: 25 additions & 0 deletions lib/tasks/fly.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# https://fly.io/docs/rails/advanced-guides/sqlite3/

# commands used to deploy a Rails application
namespace :fly do
# BUILD step:
# - changes to the filesystem made here DO get deployed
# - NO access to secrets, volumes, databases
# - Failures here prevent deployment
task build: 'assets:precompile'

# RELEASE step:
# - changes to the filesystem made here are DISCARDED
# - full access to secrets, databases
# - failures here prevent deployment
task :release

# SERVER step:
# - changes to the filesystem made here are deployed
# - full access to secrets, databases
# - failures here result in VM being stated, shutdown, and rolled back
# to last successful deploy (if any).
task server: 'db:migrate' do
sh 'bin/rails server'
end
end
21 changes: 21 additions & 0 deletions lib/tasks/sway.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require_relative '../sway_google_cloud_storage'

namespace :sway do
include SwayGoogleCloudStorage

desc 'Sets up a remote volume with files downloaded from a Google Cloud bucket'
task volume_setup: :environment do
download_directory(bucket_name: 'sway-sqlite', bucket_directory_name: 'seeds', local_directory_name: 'storage')
download_directory(bucket_name: 'sway-sqlite', bucket_directory_name: 'geojson', local_directory_name: 'storage')

if File.exist? 'storage/production.sqlite3'
puts 'Uploading production.db to google storage as backup.'
upload_file(bucket_name: 'sway-sqlite', bucket_file_path: 'production.sqlite3',
local_file_path: 'storage/production.sqlite3')
else
puts 'Getting production.db from google storage backup.'
download_file(bucket_name: 'sway-sqlite', bucket_file_path: 'production.sqlite3',
local_file_path: 'storage/production.sqlite3')
end
end
end
27 changes: 20 additions & 7 deletions scripts/deploy.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env zsh

export $(cat .env.github | xargs)

Expand All @@ -16,13 +16,26 @@ export $(cat .env.github | xargs)
SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:clobber
RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:clobber

./litestream/replicate.sh
if [[ "$1" = "google" ]]; then

gcloud storage cp --recursive $(pwd)/storage/geojson gs://sway-sqlite/
./litestream/replicate.sh

gcloud storage cp --recursive $(pwd)/storage/seeds/data gs://sway-sqlite/seeds/
gcloud storage cp --recursive $(pwd)/storage/geojson gs://sway-sqlite/

# Cloud Run requires AMD64 images
docker buildx build . -f docker/dockerfiles/production.dockerfile --platform linux/amd64 -t us-central1-docker.pkg.dev/sway-421916/sway/sway:latest --push --compress
gcloud storage cp --recursive $(pwd)/storage/seeds/data gs://sway-sqlite/seeds/

gcloud run deploy sway --project=sway-421916 --region=us-central1 --image=us-central1-docker.pkg.dev/sway-421916/sway/sway:latest --revision-suffix=${1}
# Cloud Run requires AMD64 images
docker buildx build . -f docker/dockerfiles/production.dockerfile --platform linux/amd64 -t us-central1-docker.pkg.dev/sway-421916/sway/sway:latest --push --compress

gcloud run deploy sway --project=sway-421916 --region=us-central1 --image=us-central1-docker.pkg.dev/sway-421916/sway/sway:latest --revision-suffix=${1}

elif [[ "$1" = "flyio" ]]; then

echo $GITHUB_ACCESS_TOKEN | docker login ghcr.io -u dcordz --password-stdin

docker buildx build . -f docker/dockerfiles/production.dockerfile --platform linux/amd64 -t ghcr.io/plebeian-technology/sway:latest --compress --push

# docker buildx build . -f docker/dockerfiles/production.dockerfile --platform linux/amd64 -t sway-prod:latest --compress

fly deploy
fi
Loading

0 comments on commit d6af4f3

Please sign in to comment.