ferryboat 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/bin/console +11 -0
- data/bin/ferryboat +32 -0
- data/bin/setup +8 -0
- data/lib/ferryboat/cli.rb +0 -0
- data/lib/ferryboat/config.rb +90 -0
- data/lib/ferryboat/deployer.rb +0 -0
- data/lib/ferryboat/kamal.rb +33 -0
- data/lib/ferryboat/version.rb +1 -1
- data/lib/ferryboat.rb +0 -2
- metadata +14 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdc6d5593bb5c8e80755aa06380ddd8f3096d1569d7a7fc5561f9c943e9c9fc3
|
4
|
+
data.tar.gz: cdbb2b13faabcd143ba1c38b2a0571c6bb384a7b582cc7f7a72239b74b0c69ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 349532f647384780b9c39d9753589139aeec49067399b507b0d20b72574afdca1e2a46a8bd878d676027bb87f0ce7f7b8e4fed8c883882bd4cc86384d75636ee
|
7
|
+
data.tar.gz: 705168fb7067e2cb0a6cb942fe8d558aa8026459f48c2f4c2f66e47d46d40da94418aa41802e08f25ca09da4ce2950734450ae8351ec124f8766ac54fceac635
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Ferryboat ⚓️
|
2
2
|
|
3
|
-
**Ferryboat** is a lightweight deployment tool built by **21tycoons** for teams who want **zero-downtime deployments** without the complexity of Kubernetes or heavyweight DevOps stacks.
|
3
|
+
**Ferryboat** is a lightweight deployment tool built by **21tycoons** for teams who want **zero-downtime deployments** for marketing/static sites without the complexity of Kubernetes or heavyweight DevOps stacks.
|
4
4
|
|
5
5
|
It’s designed for marketing sites, micro-apps, and fast-moving projects that need **confidence in production** while staying **simple, portable, and developer-friendly**.
|
6
6
|
|
@@ -12,7 +12,7 @@ It’s designed for marketing sites, micro-apps, and fast-moving projects that n
|
|
12
12
|
- **Staging environments baked in**
|
13
13
|
- **Lightweight backups** of container volumes
|
14
14
|
- **GitHub integration** for pulling and building images
|
15
|
-
- **Simple CLI**
|
15
|
+
- **Simple CLI**
|
16
16
|
- **Config-driven** via `ferryboat.yml`
|
17
17
|
|
18
18
|
---
|
data/bin/console
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "ferryboat"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
require "irb"
|
11
|
+
IRB.start(__FILE__)
|
data/bin/ferryboat
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
$stdout.sync = true
|
5
|
+
|
6
|
+
# Quiet thread exceptions
|
7
|
+
Thread.report_on_exception = false
|
8
|
+
|
9
|
+
# Be nice on Ctrl-C and TERM
|
10
|
+
Signal.trap("INT") { exit 0 }
|
11
|
+
Signal.trap("TERM") { exit 0 }
|
12
|
+
Signal.trap("PIPE") { exit 0 } rescue nil
|
13
|
+
|
14
|
+
begin
|
15
|
+
require "ferryboat"
|
16
|
+
require "ferryboat/cli" # explicit for reliability
|
17
|
+
rescue LoadError => e
|
18
|
+
warn "ferryboat: failed to load library: #{e.message}"
|
19
|
+
warn e.backtrace.join("\n") if ENV["FERRY_DEBUG"] == "1"
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
|
23
|
+
begin
|
24
|
+
Ferryboat::Cli.start(ARGV)
|
25
|
+
rescue SystemExit => e
|
26
|
+
# Respect Thor's exit codes
|
27
|
+
exit e.status
|
28
|
+
rescue => e
|
29
|
+
warn "ferryboat: #{e.message}"
|
30
|
+
warn e.backtrace.join("\n") if ENV["FERRY_DEBUG"] == "1"
|
31
|
+
exit 1
|
32
|
+
end
|
data/bin/setup
ADDED
File without changes
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module Ferryboat
|
6
|
+
class Config
|
7
|
+
attr_reader :env, :service, :image_repo, :domain, :host,
|
8
|
+
:provider, :git_url, :git_branch,
|
9
|
+
:health_path, :health_timeout, :detect_timeout,
|
10
|
+
:auto_backup
|
11
|
+
|
12
|
+
REQUIRED_KEYS = %i[service image_repo domain].freeze
|
13
|
+
|
14
|
+
def self.from_env(env: ENV.fetch("FERRY_ENV", "production"))
|
15
|
+
new(
|
16
|
+
env: env,
|
17
|
+
service: ENV.fetch("FERRY_SERVICE", nil),
|
18
|
+
image_repo: ENV.fetch("FERRY_IMAGE", nil),
|
19
|
+
domain: ENV.fetch("FERRY_DOMAIN", nil),
|
20
|
+
host: ENV.fetch("FERRY_HOST", "localhost"),
|
21
|
+
provider: ENV.fetch("FERRY_PROVIDER", "docker"), # docker|kamal
|
22
|
+
git_url: ENV["GIT_URL"],
|
23
|
+
git_branch: ENV.fetch("GIT_BRANCH", "main"),
|
24
|
+
health_path: ENV.fetch("FERRY_HEALTH_PATH", "/up"),
|
25
|
+
health_timeout: Integer(ENV.fetch("FERRY_HEALTH_TIMEOUT", "120")),
|
26
|
+
detect_timeout: Integer(ENV.fetch("FERRY_TRAEFIK_DETECT_TIMEOUT", "60")),
|
27
|
+
auto_backup: ENV["FERRY_AUTO_BACKUP"] == "true"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Optional YAML loader (keeps env override semantics)
|
32
|
+
def self.from_file(path, env: "production")
|
33
|
+
data = YAML.load_file(path)
|
34
|
+
cfg = (data[env] || {})
|
35
|
+
new(
|
36
|
+
env: env,
|
37
|
+
service: ENV["FERRY_SERVICE"] || cfg["service"],
|
38
|
+
image_repo: ENV["FERRY_IMAGE"] || cfg["image_repo"] || cfg["docker_registry"],
|
39
|
+
domain: ENV["FERRY_DOMAIN"] || cfg["domain"],
|
40
|
+
host: ENV["FERRY_HOST"] || cfg["host"] || "localhost",
|
41
|
+
provider: ENV["FERRY_PROVIDER"] || cfg["provider"] || "docker",
|
42
|
+
git_url: ENV["GIT_URL"] || cfg["git_url"],
|
43
|
+
git_branch: ENV["GIT_BRANCH"] || cfg["git_branch"] || "main",
|
44
|
+
health_path: ENV["FERRY_HEALTH_PATH"] || cfg["health_path"] || "/up",
|
45
|
+
health_timeout: Integer(ENV["FERRY_HEALTH_TIMEOUT"] || cfg["health_timeout"] || 120),
|
46
|
+
detect_timeout: Integer(ENV["FERRY_TRAEFIK_DETECT_TIMEOUT"] || cfg["detect_timeout"] || 60),
|
47
|
+
auto_backup: (ENV["FERRY_AUTO_BACKUP"] || cfg["auto_backup"]).to_s == "true"
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize(env:, service:, image_repo:, domain:, host:, provider:, git_url:, git_branch:, health_path:, health_timeout:, detect_timeout:, auto_backup:)
|
52
|
+
@env, @service, @image_repo, @domain = env, service, image_repo, domain
|
53
|
+
@host, @provider = host, provider
|
54
|
+
@git_url, @git_branch = git_url, git_branch
|
55
|
+
@health_path, @health_timeout, @detect_timeout = health_path, health_timeout, detect_timeout
|
56
|
+
@auto_backup = auto_backup
|
57
|
+
validate!
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate!
|
61
|
+
missing = []
|
62
|
+
missing << :service if blank?(service)
|
63
|
+
missing << :image_repo if blank?(image_repo)
|
64
|
+
missing << :domain if blank?(domain)
|
65
|
+
return true if missing.empty?
|
66
|
+
raise ArgumentError, "Missing required config: #{missing.join(', ')}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def provider_runner
|
70
|
+
case provider
|
71
|
+
when "kamal" then Ferryboat::Deployer::KamalRunner.new
|
72
|
+
when "docker" then Ferryboat::Deployer::DockerRunner.new
|
73
|
+
else raise ArgumentError, "Unknown provider: #{provider.inspect}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_h
|
78
|
+
{
|
79
|
+
env: env, service: service, image_repo: image_repo, domain: domain,
|
80
|
+
host: host, provider: provider, git_url: git_url, git_branch: git_branch,
|
81
|
+
health_path: health_path, health_timeout: health_timeout,
|
82
|
+
detect_timeout: detect_timeout, auto_backup: auto_backup
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def blank?(s) = s.nil? || s.to_s.strip.empty?
|
89
|
+
end
|
90
|
+
end
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ferryboat
|
4
|
+
# Wraps Kamal CLI commands for remote execution
|
5
|
+
class Kamal
|
6
|
+
def initialize(app: nil, reuse: true)
|
7
|
+
@app = app || ENV.fetch("FERRY_SERVICE")
|
8
|
+
@reuse = reuse
|
9
|
+
end
|
10
|
+
|
11
|
+
# run a raw kamal command
|
12
|
+
def run(*args)
|
13
|
+
cmd = ["kamal"]
|
14
|
+
cmd << "app" << "exec"
|
15
|
+
cmd << "--reuse" if @reuse
|
16
|
+
cmd << "--app" << @app if @app
|
17
|
+
cmd << "--" << "/bin/sh" << "-lc" << %("#{args.join(' ')}")
|
18
|
+
sh cmd.join(" ")
|
19
|
+
end
|
20
|
+
|
21
|
+
# convenience: docker subcommand
|
22
|
+
def docker(*args)
|
23
|
+
run("docker", *args)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def sh(cmd)
|
29
|
+
puts "→ #{cmd}"
|
30
|
+
system(cmd)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/ferryboat/version.rb
CHANGED
data/lib/ferryboat.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ferryboat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 21tycoons
|
8
|
-
bindir:
|
8
|
+
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-08-
|
10
|
+
date: 2025-08-20 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: thor
|
@@ -38,18 +38,26 @@ dependencies:
|
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '1.0'
|
40
40
|
description: |
|
41
|
-
Ferryboat is a deployment solution focused on simplicity and reliability.
|
41
|
+
Ferryboat is a deployment solution for marketing/static sites focused on simplicity and reliability.
|
42
42
|
It supports zero-downtime rollouts, staging environments, and basic volume
|
43
43
|
backups. Designed to work with Docker and SSH, it helps teams deliver code
|
44
44
|
safely to production without unnecessary complexity.
|
45
45
|
email:
|
46
46
|
- liroy@tycooncrm.com
|
47
|
-
executables:
|
47
|
+
executables:
|
48
|
+
- ferryboat
|
48
49
|
extensions: []
|
49
50
|
extra_rdoc_files: []
|
50
51
|
files:
|
51
52
|
- README.md
|
53
|
+
- bin/console
|
54
|
+
- bin/ferryboat
|
55
|
+
- bin/setup
|
52
56
|
- lib/ferryboat.rb
|
57
|
+
- lib/ferryboat/cli.rb
|
58
|
+
- lib/ferryboat/config.rb
|
59
|
+
- lib/ferryboat/deployer.rb
|
60
|
+
- lib/ferryboat/kamal.rb
|
53
61
|
- lib/ferryboat/version.rb
|
54
62
|
homepage: https://github.com/21tycoons/ferryboat
|
55
63
|
licenses:
|
@@ -71,5 +79,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
79
|
requirements: []
|
72
80
|
rubygems_version: 3.6.5
|
73
81
|
specification_version: 4
|
74
|
-
summary: Lightweight zero-downtime deployment tool.
|
82
|
+
summary: Lightweight zero-downtime deployment tool for marketing/static sites.
|
75
83
|
test_files: []
|