#!/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