-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
8 changed files
with
281 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#!/bin/sh | ||
|
||
# A sample post-deploy hook | ||
# | ||
# These environment variables are available: | ||
# KAMAL_RECORDED_AT | ||
# KAMAL_PERFORMER | ||
# KAMAL_VERSION | ||
# KAMAL_HOSTS | ||
# KAMAL_ROLE (if set) | ||
# KAMAL_DESTINATION (if set) | ||
# KAMAL_RUNTIME | ||
|
||
echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/sh | ||
|
||
echo "Rebooted Traefik on $KAMAL_HOSTS" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#!/bin/sh | ||
|
||
# A sample pre-build hook | ||
# | ||
# Checks: | ||
# 1. We have a clean checkout | ||
# 2. A remote is configured | ||
# 3. The branch has been pushed to the remote | ||
# 4. The version we are deploying matches the remote | ||
# | ||
# These environment variables are available: | ||
# KAMAL_RECORDED_AT | ||
# KAMAL_PERFORMER | ||
# KAMAL_VERSION | ||
# KAMAL_HOSTS | ||
# KAMAL_ROLE (if set) | ||
# KAMAL_DESTINATION (if set) | ||
|
||
if [ -n "$(git status --porcelain)" ]; then | ||
echo "Git checkout is not clean, aborting..." >&2 | ||
git status --porcelain >&2 | ||
exit 1 | ||
fi | ||
|
||
first_remote=$(git remote) | ||
|
||
if [ -z "$first_remote" ]; then | ||
echo "No git remote set, aborting..." >&2 | ||
exit 1 | ||
fi | ||
|
||
current_branch=$(git branch --show-current) | ||
|
||
if [ -z "$current_branch" ]; then | ||
echo "Not on a git branch, aborting..." >&2 | ||
exit 1 | ||
fi | ||
|
||
remote_head=$(git ls-remote $first_remote --tags $current_branch | cut -f1) | ||
|
||
if [ -z "$remote_head" ]; then | ||
echo "Branch not pushed to remote, aborting..." >&2 | ||
exit 1 | ||
fi | ||
|
||
if [ "$KAMAL_VERSION" != "$remote_head" ]; then | ||
echo "Version ($KAMAL_VERSION) does not match remote HEAD ($remote_head), aborting..." >&2 | ||
exit 1 | ||
fi | ||
|
||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#!/usr/bin/env ruby | ||
|
||
# A sample pre-connect check | ||
# | ||
# Warms DNS before connecting to hosts in parallel | ||
# | ||
# These environment variables are available: | ||
# KAMAL_RECORDED_AT | ||
# KAMAL_PERFORMER | ||
# KAMAL_VERSION | ||
# KAMAL_HOSTS | ||
# KAMAL_ROLE (if set) | ||
# KAMAL_DESTINATION (if set) | ||
# KAMAL_RUNTIME | ||
|
||
hosts = ENV["KAMAL_HOSTS"].split(",") | ||
results = nil | ||
max = 3 | ||
|
||
elapsed = Benchmark.realtime do | ||
results = hosts.map do |host| | ||
Thread.new do | ||
tries = 1 | ||
|
||
begin | ||
Socket.getaddrinfo(host, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) | ||
rescue SocketError | ||
if tries < max | ||
puts "Retrying DNS warmup: #{host}" | ||
tries += 1 | ||
sleep rand | ||
retry | ||
else | ||
puts "DNS warmup failed: #{host}" | ||
host | ||
end | ||
end | ||
|
||
tries | ||
end | ||
end.map(&:value) | ||
end | ||
|
||
retries = results.sum - hosts.size | ||
nopes = results.count { |r| r == max } | ||
|
||
puts "Prewarmed %d DNS lookups in %.2f sec: %d retries, %d failures" % [ hosts.size, elapsed, retries, nopes ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#!/usr/bin/env ruby | ||
|
||
# A sample pre-deploy hook | ||
# | ||
# Checks the Github status of the build, waiting for a pending build to complete for up to 720 seconds. | ||
# | ||
# Fails unless the combined status is "success" | ||
# | ||
# These environment variables are available: | ||
# KAMAL_RECORDED_AT | ||
# KAMAL_PERFORMER | ||
# KAMAL_VERSION | ||
# KAMAL_HOSTS | ||
# KAMAL_COMMAND | ||
# KAMAL_SUBCOMMAND | ||
# KAMAL_ROLE (if set) | ||
# KAMAL_DESTINATION (if set) | ||
|
||
# Only check the build status for production deployments | ||
if ENV["KAMAL_COMMAND"] == "rollback" || ENV["KAMAL_DESTINATION"] != "production" | ||
exit 0 | ||
end | ||
|
||
require "bundler/inline" | ||
|
||
# true = install gems so this is fast on repeat invocations | ||
gemfile(true, quiet: true) do | ||
source "https://rubygems.org" | ||
|
||
gem "octokit" | ||
gem "faraday-retry" | ||
end | ||
|
||
MAX_ATTEMPTS = 72 | ||
ATTEMPTS_GAP = 10 | ||
|
||
def exit_with_error(message) | ||
$stderr.puts message | ||
exit 1 | ||
end | ||
|
||
class GithubStatusChecks | ||
attr_reader :remote_url, :git_sha, :github_client, :combined_status | ||
|
||
def initialize | ||
@remote_url = `git config --get remote.origin.url`.strip.delete_prefix("https://github.com/") | ||
@git_sha = `git rev-parse HEAD`.strip | ||
@github_client = Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"]) | ||
refresh! | ||
end | ||
|
||
def refresh! | ||
@combined_status = github_client.combined_status(remote_url, git_sha) | ||
end | ||
|
||
def state | ||
combined_status[:state] | ||
end | ||
|
||
def first_status_url | ||
first_status = combined_status[:statuses].find { |status| status[:state] == state } | ||
first_status && first_status[:target_url] | ||
end | ||
|
||
def complete_count | ||
combined_status[:statuses].count { |status| status[:state] != "pending"} | ||
end | ||
|
||
def total_count | ||
combined_status[:statuses].count | ||
end | ||
|
||
def current_status | ||
if total_count > 0 | ||
"Completed #{complete_count}/#{total_count} checks, see #{first_status_url} ..." | ||
else | ||
"Build not started..." | ||
end | ||
end | ||
end | ||
|
||
|
||
$stdout.sync = true | ||
|
||
puts "Checking build status..." | ||
attempts = 0 | ||
checks = GithubStatusChecks.new | ||
|
||
begin | ||
loop do | ||
case checks.state | ||
when "success" | ||
puts "Checks passed, see #{checks.first_status_url}" | ||
exit 0 | ||
when "failure" | ||
exit_with_error "Checks failed, see #{checks.first_status_url}" | ||
when "pending" | ||
attempts += 1 | ||
end | ||
|
||
exit_with_error "Checks are still pending, gave up after #{MAX_ATTEMPTS * ATTEMPTS_GAP} seconds" if attempts == MAX_ATTEMPTS | ||
|
||
puts checks.current_status | ||
sleep(ATTEMPTS_GAP) | ||
checks.refresh! | ||
end | ||
rescue Octokit::NotFound | ||
exit_with_error "Build status could not be found" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/sh | ||
|
||
echo "Rebooting Traefik on $KAMAL_HOSTS..." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,12 @@ | ||
# Name of your application. Used to uniquely configure containers. | ||
service: daisy_on_rails | ||
service: daisy-on-rails | ||
|
||
# Name of the container image. | ||
image: adrienpoly/daisy_on_rails | ||
image: adrienpoly/daisy-on-rails | ||
|
||
# Deploy to these servers. | ||
servers: | ||
web: | ||
hosts: | ||
- 1.1.1.1 | ||
- 192.168.0.1 | ||
|
||
# Credentials for your image host. | ||
registry: | ||
|
@@ -20,15 +18,21 @@ registry: | |
password: | ||
- KAMAL_REGISTRY_PASSWORD | ||
|
||
# persist the sqlite database and rails storage directory accross deploys | ||
volumes: | ||
- "storage:/rails/storage" | ||
# Inject ENV variables into containers (secrets come from .env). | ||
# Remember to run `kamal env push` after making changes! | ||
env: | ||
clear: | ||
RUBY_YJIT_ENABLE: 1 | ||
RAILS_SERVE_STATIC_FILES: true | ||
secret: | ||
- RAILS_MASTER_KEY | ||
# Use a different ssh user than root | ||
ssh: | ||
user: root | ||
# ssh: | ||
# user: app | ||
|
||
# Configure builder setup. | ||
# builder: | ||
# args: | ||
|
@@ -38,15 +42,23 @@ ssh: | |
# remote: | ||
# arch: amd64 | ||
# host: ssh://[email protected] | ||
volumes: | ||
- "storage:/rails/storage" | ||
|
||
# Use accessory services (secrets come from .env). | ||
accessories: | ||
# files: | ||
# - config/mysql/production.cnf:/etc/mysql/my.cnf | ||
# - db/production.sql.erb:/docker-entrypoint-initdb.d/setup.sql | ||
# directories: | ||
# - data:/var/lib/mysql | ||
# accessories: | ||
# db: | ||
# image: mysql:8.0 | ||
# host: 192.168.0.2 | ||
# port: 3306 | ||
# env: | ||
# clear: | ||
# MYSQL_ROOT_HOST: '%' | ||
# secret: | ||
# - MYSQL_ROOT_PASSWORD | ||
# files: | ||
# - config/mysql/production.cnf:/etc/mysql/my.cnf | ||
# - db/production.sql:/docker-entrypoint-initdb.d/setup.sql | ||
# directories: | ||
# - data:/var/lib/mysql | ||
# redis: | ||
# image: redis:7.0 | ||
# host: 192.168.0.2 | ||
|
@@ -59,13 +71,29 @@ accessories: | |
# args: | ||
# accesslog: true | ||
# accesslog.format: json | ||
# labels: | ||
# traefik.tcp.routers.other.rule: "HostSNI(`*`)" | ||
# traefik.tcp.routers.other.entrypoints: search | ||
# traefik.tcp.services.other.loadbalancer.server.port: 7700 | ||
# traefik: | ||
# options: | ||
# publish: | ||
# - 80:80 | ||
# - "7700:7700 | ||
|
||
# Configure a custom healthcheck (default is /up on port 3000) | ||
# healthcheck: | ||
# path: /healthz | ||
# port: 4000 | ||
|
||
# Bridge fingerprinted assets, like JS and CSS, between versions to avoid | ||
# hitting 404 on in-flight requests. Combines all files from new and old | ||
# version inside the asset_path. | ||
asset_path: /rails/public/assets | ||
# Configure rolling deploys by setting a wait time between batches of restarts. | ||
# boot: | ||
# limit: 10 # Can also specify as a percentage of total hosts, such as "25%" | ||
# wait: 2 | ||
|
||
# Configure the role used to determine the primary_host. This host takes | ||
# deploy locks, runs health checks during the deploy, and follow logs, etc. | ||
# | ||
# Caution: there's no support for role renaming yet, so be careful to cleanup | ||
# the previous role on the deployed hosts. | ||
# primary_role: web | ||
|
||
# Controls if we abort when see a role with no hosts. Disabling this may be | ||
# useful for more complex deploy configurations. | ||
# | ||
# allow_empty_roles: false |