Set up for internal deployment

This commit is contained in:
Kevin McConnell
2024-09-30 16:12:32 +01:00
parent d38bab9664
commit e009874767
7 changed files with 115 additions and 4 deletions
+3 -3
View File
@@ -22,7 +22,7 @@ RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git libvips pkg-config
# Install application gems
COPY Gemfile Gemfile.lock ./
COPY Gemfile Gemfile.lock .ruby-version ./
RUN bundle install && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
bundle exec bootsnap precompile --gemfile
@@ -58,5 +58,5 @@ USER rails:rails
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]
EXPOSE 80 443
CMD ["./bin/thrust", "./bin/rails", "server"]
+1
View File
@@ -13,6 +13,7 @@ gem "turbo-rails"
gem "bootsnap", require: false
gem "puma", ">= 5.0"
gem "sqlite3", ">= 2.0"
gem "thruster", require: false
# Features
gem "bcrypt", "~> 3.1.7"
+6
View File
@@ -274,6 +274,11 @@ GEM
stringio (3.1.1)
strscan (3.1.0)
thor (1.3.2)
thruster (0.1.8)
thruster (0.1.8-aarch64-linux)
thruster (0.1.8-arm64-darwin)
thruster (0.1.8-x86_64-darwin)
thruster (0.1.8-x86_64-linux)
timeout (0.4.1)
turbo-rails (2.0.7)
actionpack (>= 6.0.0)
@@ -323,6 +328,7 @@ DEPENDENCIES
selenium-webdriver
sqlite3 (>= 2.0)
stimulus-rails
thruster
turbo-rails
RUBY VERSION
Executable
+72
View File
@@ -0,0 +1,72 @@
#!/usr/bin/env ruby
require "bundler/inline"
require "yaml"
gemfile do
source "https://rubygems.org"
gem "base64"
gem "bcrypt_pbkdf"
gem "ed25519"
gem "sshkit"
end
include SSHKit::DSL
config_variant = "-#{ARGV[0]}" if ARGV[0]
config = YAML.load_file("config/deploy#{config_variant}.yml")
HOSTS = [ config["host"] ]
REMOTE_USER = config["ssh_user"]
DOCKER_IMAGE_NAME = config["image"]
ARCH = config["arch"] || `arch`.strip
GIT_SHA = `git rev-parse HEAD`.strip
DOCKER_TAGGED_IMAGE_NAME = [ DOCKER_IMAGE_NAME, GIT_SHA ].join(":")
PORTS = [ "80:80", "443:443" ]
ENVS = { TLS_DOMAIN: config["ssl_domain"] }
ENV_FILE = ".fizzy-env"
SSHKit::Backend::Netssh.configure do |ssh|
ssh.connection_timeout = 30
ssh.ssh_options = { user: REMOTE_USER }
end
def announcing(message)
puts "\n\e[1;36m#{message}\e[0m"
yield
end
announcing "Building and pushing image..." do
versioning = "--build-arg APP_VERSION=#{GIT_SHA[...6]} --build-arg GIT_REVISION=#{GIT_SHA}"
on(:local) do
execute :docker, :build, "-t", DOCKER_TAGGED_IMAGE_NAME, versioning, "--platform", ARCH, "."
execute :docker, :push, DOCKER_TAGGED_IMAGE_NAME
end
end
announcing "Pulling image on remote..." do
on(HOSTS) do
execute :docker, :pull, DOCKER_TAGGED_IMAGE_NAME
end
end
announcing "Start container on remote..." do
restart_policy = "--restart unless-stopped"
labels = "--label #{DOCKER_IMAGE_NAME}"
ports = PORTS.map { |p| "-p #{p}" }.join(" ")
envs = ENVS.map { |k, v| "-e #{k}=#{v}" }.join(" ")
volume = "--mount 'type=volume,source=fizzy,target=/rails/storage'"
env_file = "--env-file #{ENV_FILE}"
on(HOSTS) do
execute :docker, :ps, "-q", "-f", "\"label=#{DOCKER_IMAGE_NAME}\"", "|", "xargs", "-r", "docker", "stop"
execute :docker, :run, "-d", labels, ports, envs, env_file, restart_policy, volume, DOCKER_TAGGED_IMAGE_NAME
end
end
announcing "Remove stopped containers from remote..." do
on(HOSTS) do
execute :docker, :container, :prune, "-f"
execute :docker, :image, :prune, "-af"
end
end
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash -e
# If running the rails server then create or migrate existing database
if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then
if [ "${1}" == "./bin/thrust" ] && [ "${2}" == "./bin/rails" ] && [ "${3}" == "server" ]; then
./bin/rails db:prepare
fi
Executable
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'thrust' is installed as part of a gem, and
# this file is here to facilitate running it.
#
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
bundle_binstub = File.expand_path("bundle", __dir__)
if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end
require "rubygems"
require "bundler/setup"
load Gem.bin_path("thruster", "thrust")
+5
View File
@@ -0,0 +1,5 @@
image: registry.kevinmcconnell.dev/fizzy
host: fizzy.37signals.works
ssl_domain: fizzy.37signals.works
ssh_user: root
arch: linux/amd64