fly-rails 0.3.5
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 +7 -0
- data/LICENSE +202 -0
- data/README.md +100 -0
- data/Rakefile +3 -0
- data/lib/fly-rails/actions.rb +652 -0
- data/lib/fly-rails/deploy.rb +42 -0
- data/lib/fly-rails/dsl.rb +92 -0
- data/lib/fly-rails/generators.rb +3 -0
- data/lib/fly-rails/hcl.rb +99 -0
- data/lib/fly-rails/machines.rb +209 -0
- data/lib/fly-rails/platforms.rb +10 -0
- data/lib/fly-rails/scanner.rb +68 -0
- data/lib/fly-rails/utils.rb +66 -0
- data/lib/fly-rails/version.rb +3 -0
- data/lib/fly-rails.rb +27 -0
- data/lib/generators/fly/app_generator.rb +72 -0
- data/lib/generators/fly/config_generator.rb +19 -0
- data/lib/generators/fly/terraform_generator.rb +36 -0
- data/lib/generators/templates/Dockerfile.erb +270 -0
- data/lib/generators/templates/Procfile.fly.erb +3 -0
- data/lib/generators/templates/dockerignore.erb +16 -0
- data/lib/generators/templates/fly.rake.erb +101 -0
- data/lib/generators/templates/fly.rb.erb +27 -0
- data/lib/generators/templates/fly.toml.erb +81 -0
- data/lib/generators/templates/hook_detached_process.erb +7 -0
- data/lib/generators/templates/litefs.yml.erb +14 -0
- data/lib/generators/templates/main.tf.erb +101 -0
- data/lib/generators/templates/nginx.conf.erb +77 -0
- data/lib/generators/templates/patches/action_cable.rb +20 -0
- data/lib/tasks/fly.rake +178 -0
- data/lib/tasks/mock.rake +17 -0
- metadata +87 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'fly-rails/actions'
|
2
|
+
|
3
|
+
module Fly::Generators
|
4
|
+
class TerraformGenerator < Rails::Generators::Base
|
5
|
+
include FlyIoRails::Utils
|
6
|
+
|
7
|
+
class_option :name, type: :string, required: false
|
8
|
+
class_option :org, type: :string, default: 'personal'
|
9
|
+
class_option :region, type: :array, repeatable: true, default: []
|
10
|
+
|
11
|
+
class_option :litefs, type: :boolean, default: false
|
12
|
+
class_option :passenger, type: :boolean, default: false
|
13
|
+
class_option :serverless, type: :boolean, default: false
|
14
|
+
|
15
|
+
def terraform
|
16
|
+
source_paths.push File.expand_path('../templates', __dir__)
|
17
|
+
|
18
|
+
create_app(**options.symbolize_keys)
|
19
|
+
|
20
|
+
action = Fly::Actions.new(@app, options)
|
21
|
+
|
22
|
+
action.generate_toml
|
23
|
+
action.generate_dockerfile
|
24
|
+
action.generate_dockerignore
|
25
|
+
action.generate_nginx_conf
|
26
|
+
action.generate_terraform
|
27
|
+
action.generate_raketask
|
28
|
+
action.generate_procfile
|
29
|
+
action.generate_patches
|
30
|
+
|
31
|
+
action.generate_key
|
32
|
+
|
33
|
+
tee 'terraform init'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
# syntax = docker/dockerfile:1
|
2
|
+
|
3
|
+
FROM <%= @image %> as base
|
4
|
+
LABEL fly_launch_runtime="rails"
|
5
|
+
|
6
|
+
ENV RAILS_ENV=production
|
7
|
+
<% if @anycable or not @passenger -%>
|
8
|
+
ENV RAILS_LOG_TO_STDOUT true
|
9
|
+
<% end -%>
|
10
|
+
<% unless @passenger -%>
|
11
|
+
ENV RAILS_SERVE_STATIC_FILES true
|
12
|
+
<% end -%>
|
13
|
+
ENV PORT 8080
|
14
|
+
|
15
|
+
RUN mkdir /app
|
16
|
+
WORKDIR /app
|
17
|
+
|
18
|
+
<% if @node -%>
|
19
|
+
RUN curl https://get.volta.sh | bash
|
20
|
+
ENV VOLTA_HOME /root/.volta
|
21
|
+
ENV PATH $VOLTA_HOME/bin:/usr/local/bin:$PATH
|
22
|
+
RUN volta install node@<%= @node_version %> yarn@<%= @yarn_version %> && \
|
23
|
+
gem update --system --no-document && \
|
24
|
+
gem install --no-document bundler --version <%= @bundler_version %>
|
25
|
+
|
26
|
+
<% else -%>
|
27
|
+
RUN gem update --system --no-document && \
|
28
|
+
gem install --no-document bundler --version <%= @bundler_version %>
|
29
|
+
|
30
|
+
<% end -%>
|
31
|
+
#######################################################################
|
32
|
+
|
33
|
+
# install packages only needed at build time
|
34
|
+
|
35
|
+
FROM base as build_deps
|
36
|
+
|
37
|
+
<%
|
38
|
+
@build_packages = %w(git build-essential wget curl gzip xz-utils)
|
39
|
+
@build_packages << 'libpq-dev' if @postgresql
|
40
|
+
@build_packages << 'libsqlite3-dev' if @sqlite3
|
41
|
+
@build_packages << 'default-libmysqlclient-dev' if @mysql
|
42
|
+
@build_packages += %w[pkg-config libmagickwand-dev] if @rmagick
|
43
|
+
-%>
|
44
|
+
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
45
|
+
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
|
46
|
+
apt-get update -qq && \
|
47
|
+
apt-get install --no-install-recommends --yes \
|
48
|
+
<%= @build_packages.join(' ') %>
|
49
|
+
|
50
|
+
#######################################################################
|
51
|
+
|
52
|
+
# install gems
|
53
|
+
|
54
|
+
FROM build_deps as gems
|
55
|
+
|
56
|
+
COPY Gemfile* ./
|
57
|
+
RUN --mount=type=cache,id=dev-gem-cache,sharing=locked,target=/srv/vendor \
|
58
|
+
bundle config set app_config .bundle && \
|
59
|
+
bundle config set without 'development test' && \
|
60
|
+
bundle lock --add-platform x86_64-linux && \
|
61
|
+
bundle config set path /srv/vendor && \
|
62
|
+
bundle install && \
|
63
|
+
mkdir -p vendor && \
|
64
|
+
bundle config set path vendor && \
|
65
|
+
cp -ar /srv/vendor .
|
66
|
+
|
67
|
+
<% if @node -%>
|
68
|
+
#######################################################################
|
69
|
+
|
70
|
+
# install node modules
|
71
|
+
|
72
|
+
FROM build_deps as node_modules
|
73
|
+
|
74
|
+
<% if @puppeteer -%>
|
75
|
+
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
|
76
|
+
|
77
|
+
<% end -%>
|
78
|
+
COPY package*json ./
|
79
|
+
<% if @yarn -%>
|
80
|
+
COPY yarn.* ./
|
81
|
+
RUN yarn install
|
82
|
+
<% else -%>
|
83
|
+
RUN npm install
|
84
|
+
<% end -%>
|
85
|
+
|
86
|
+
<% end -%>
|
87
|
+
#######################################################################
|
88
|
+
<% if @litefs -%>
|
89
|
+
|
90
|
+
# Fetch the LiteFS binary
|
91
|
+
FROM flyio/litefs:pr-109 AS litefs
|
92
|
+
|
93
|
+
#######################################################################
|
94
|
+
<% end -%>
|
95
|
+
<% if @anycable -%>
|
96
|
+
|
97
|
+
# Build anycable
|
98
|
+
FROM golang:1.18 as go
|
99
|
+
RUN GOBIN=/usr/local/bin/ go install github.com/anycable/anycable-go/cmd/anycable-go@latest
|
100
|
+
|
101
|
+
#######################################################################
|
102
|
+
<% end -%>
|
103
|
+
|
104
|
+
# install deployment packages
|
105
|
+
|
106
|
+
FROM base
|
107
|
+
|
108
|
+
<% if @passenger -%>
|
109
|
+
# add passenger repository
|
110
|
+
RUN apt-get install -y dirmngr gnupg apt-transport-https ca-certificates curl && \
|
111
|
+
curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt | \
|
112
|
+
gpg --dearmor > /etc/apt/trusted.gpg.d/phusion.gpg && \
|
113
|
+
sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger $(sed -n 's/VERSION_CODENAME=\(.*\)$/\1/p' /etc/os-release) main > /etc/apt/sources.list.d/passenger.list'
|
114
|
+
|
115
|
+
<% end -%>
|
116
|
+
<% if @puppeteer -%>
|
117
|
+
# add google chrome repository
|
118
|
+
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
|
119
|
+
&& echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list
|
120
|
+
|
121
|
+
<% end -%>
|
122
|
+
<% if @postgresql -%>
|
123
|
+
# add postgres repository
|
124
|
+
RUN curl -sSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
|
125
|
+
&& echo "deb http://apt.postgresql.org/pub/repos/apt/ $(sed -n 's/VERSION_CODENAME=\(.*\)$/\1/p' /etc/os-release)-pgdg main" 14 > /etc/apt/sources.list.d/pgdg.list
|
126
|
+
<% end -%>
|
127
|
+
# nginx: <%= @nginx.inspect %>
|
128
|
+
<%
|
129
|
+
@deploy_packages = []
|
130
|
+
@deploy_packages << 'nginx' if @nginx
|
131
|
+
@deploy_packages += %w(passenger libnginx-mod-http-passenger) if @passenger
|
132
|
+
@deploy_packages << 'postgresql-client-14' if @postgresql
|
133
|
+
@deploy_packages << 'libsqlite3-0' if @sqlite3
|
134
|
+
@deploy_packages << 'default-mysql-client' if @mysql
|
135
|
+
@deploy_packages << 'google-chrome-stable' if @puppeteer
|
136
|
+
@deploy_packages << 'imagemagick' if @rmagick
|
137
|
+
@deploy_packages << 'libvips42' if @image_processing
|
138
|
+
@deploy_packages << 'nodejs' if not @node and @bootstrap
|
139
|
+
@deploy_packages << 'fuse' if @litefs
|
140
|
+
@deploy_packages << 'ruby-foreman' if @procs.length > 1
|
141
|
+
@deploy_packages << 'redis-server' if @redis == :internal
|
142
|
+
@deploy_packages << 'gettext-base' if @nats
|
143
|
+
@deploy_packages += %w(avahi-daemon avahi-utils libnss-mdns) if @avahi
|
144
|
+
-%>
|
145
|
+
RUN --mount=type=cache,id=prod-apt-cache,sharing=locked,target=/var/cache/apt \
|
146
|
+
--mount=type=cache,id=prod-apt-lib,sharing=locked,target=/var/lib/apt \
|
147
|
+
apt-get update -qq && \
|
148
|
+
apt-get install --no-install-recommends --yes \
|
149
|
+
<%= @deploy_packages.join(' ') %>
|
150
|
+
|
151
|
+
<% if @redis == :internal -%>
|
152
|
+
# configure redis
|
153
|
+
RUN sed -i 's/^daemonize yes/daemonize no/' /etc/redis/redis.conf &&\
|
154
|
+
sed -i 's/^bind/# bind/' /etc/redis/redis.conf &&\
|
155
|
+
sed -i 's/^protected-mode yes/protected-mode no/' /etc/redis/redis.conf &&\
|
156
|
+
sed -i 's/^logfile/# logfile/' /etc/redis/redis.conf
|
157
|
+
|
158
|
+
<% end -%>
|
159
|
+
# copy installed gems
|
160
|
+
COPY --from=gems /app /app
|
161
|
+
COPY --from=gems /usr/lib/fullstaq-ruby/versions /usr/lib/fullstaq-ruby/versions
|
162
|
+
COPY --from=gems /usr/local/bundle /usr/local/bundle
|
163
|
+
|
164
|
+
<% if @node -%>
|
165
|
+
# copy installed node modules
|
166
|
+
COPY --from=node_modules /app/node_modules /app/node_modules
|
167
|
+
|
168
|
+
<% end -%>
|
169
|
+
<% if @anycable -%>
|
170
|
+
# copy anycable-go
|
171
|
+
COPY --from=go /usr/local/bin/anycable-go /usr/local/bin/anycable-go
|
172
|
+
|
173
|
+
<% end -%>
|
174
|
+
<% if @litefs -%>
|
175
|
+
# copy litefs binary
|
176
|
+
COPY --from=litefs /usr/local/bin/litefs /usr/local/bin/litefs
|
177
|
+
|
178
|
+
# Copy our LiteFS configuration.
|
179
|
+
ADD config/litefs.yml /etc/litefs.yml
|
180
|
+
|
181
|
+
# Create mount point
|
182
|
+
RUN mkdir /data
|
183
|
+
|
184
|
+
<% end -%>
|
185
|
+
<% if @nats -%>
|
186
|
+
# install nats
|
187
|
+
RUN mkdir /etc/nats
|
188
|
+
COPY --from=nats:latest /nats-server /usr/local/bin/nats-server
|
189
|
+
COPY --from=nats:latest /nats-server.conf /etc/nats/nats-server.conf
|
190
|
+
|
191
|
+
<% end -%>
|
192
|
+
#######################################################################
|
193
|
+
<% if @avahi -%>
|
194
|
+
|
195
|
+
# configure avahi for ipv6
|
196
|
+
RUN sed -i 's/mdns4_minimal/mdns_minimal/' /etc/nsswitch.conf
|
197
|
+
<% end -%>
|
198
|
+
<% if @nginx -%>
|
199
|
+
<% if @passenger -%>
|
200
|
+
|
201
|
+
# configure nginx/passenger
|
202
|
+
<% if @passenger -%>
|
203
|
+
<% unless @avahi or @nats -%>
|
204
|
+
COPY config/nginx.conf /etc/nginx/sites-available/rails.conf
|
205
|
+
<% end -%>
|
206
|
+
RUN rm /etc/nginx/sites-enabled/default && \
|
207
|
+
ln -s /etc/nginx/sites-available/rails.conf /etc/nginx/sites-enabled/ && \
|
208
|
+
sed -i 's/user .*;/user root;/' /etc/nginx/nginx.conf && \
|
209
|
+
sed -i '/^include/i include /etc/nginx/main.d/*.conf;' /etc/nginx/nginx.conf && \
|
210
|
+
mkdir /etc/nginx/main.d && \
|
211
|
+
echo 'env RAILS_MASTER_KEY;' >> /etc/nginx/main.d/env.conf &&\
|
212
|
+
<% if @redis -%>
|
213
|
+
echo 'env REDIS_URL;' >> /etc/nginx/main.d/env.conf &&\
|
214
|
+
<% end -%>
|
215
|
+
<% if @anycable -%>
|
216
|
+
echo 'env ANYCABLE_RPC_HOST;' >> /etc/nginx/main.d/env.conf &&\
|
217
|
+
echo 'env CABLE_URL;' >> /etc/nginx/main.d/env.conf &&\
|
218
|
+
<% end -%>
|
219
|
+
echo 'env RAILS_LOG_TO_STDOUT;' >> /etc/nginx/main.d/env.conf
|
220
|
+
<% if @serverless -%>
|
221
|
+
COPY config/hook_detached_process /etc/nginx/
|
222
|
+
<% end -%>
|
223
|
+
<% end -%>
|
224
|
+
<% else -%>
|
225
|
+
|
226
|
+
# configure nginx/passenger
|
227
|
+
COPY <<-"EOF" /etc/nginx/sites-available/rails.conf
|
228
|
+
<%= render 'nginx.conf.erb' %>
|
229
|
+
EOF
|
230
|
+
RUN rm /etc/nginx/sites-enabled/default && \
|
231
|
+
ln -s /etc/nginx/sites-available/rails.conf /etc/nginx/sites-enabled/
|
232
|
+
<% end -%>
|
233
|
+
<% end -%>
|
234
|
+
|
235
|
+
<% if @procs.length > 1 and not @eject -%>
|
236
|
+
# Define processes
|
237
|
+
COPY <<-"EOF" ./Procfile.fly
|
238
|
+
<%= render 'Procfile.fly.erb' %>
|
239
|
+
EOF
|
240
|
+
|
241
|
+
<% end -%>
|
242
|
+
<% unless @eject -%>
|
243
|
+
# Define tasks
|
244
|
+
COPY <<-"EOF" ./lib/tasks/fly.rake
|
245
|
+
<%= render 'fly.rake.erb' %>
|
246
|
+
EOF
|
247
|
+
|
248
|
+
<% end -%>
|
249
|
+
# Deploy your application
|
250
|
+
COPY . .
|
251
|
+
<% if @bundle_add -%>
|
252
|
+
COPY --from=gems /app/Gemfile* ./
|
253
|
+
<% end -%>
|
254
|
+
|
255
|
+
# Adjust binstubs to run on Linux and set current working directory
|
256
|
+
RUN chmod +x /app/bin/* && \
|
257
|
+
sed -i 's/ruby.exe/ruby\r*/' /app/bin/* && \
|
258
|
+
sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)' /app/bin/*
|
259
|
+
|
260
|
+
# Run build task defined in config/fly.rb
|
261
|
+
RUN SECRET_KEY_BASE=1 bin/rails fly:build
|
262
|
+
|
263
|
+
# Start server
|
264
|
+
<% if @litefs
|
265
|
+
@server_command="litefs"
|
266
|
+
else
|
267
|
+
@server_command="bin/rails fly:server"
|
268
|
+
end
|
269
|
+
-%>
|
270
|
+
CMD <%= @server_command.split(' ').inspect %>
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# commands used to deploy a Rails application
|
2
|
+
namespace :fly do
|
3
|
+
# BUILD step:
|
4
|
+
# - changes to the filesystem made here DO get deployed
|
5
|
+
# - NO access to secrets, volumes, databases
|
6
|
+
# - Failures here prevent deployment
|
7
|
+
task :build => 'assets:precompile'
|
8
|
+
|
9
|
+
<% unless @litefs -%>
|
10
|
+
# RELEASE step:
|
11
|
+
# - changes to the filesystem made here are DISCARDED
|
12
|
+
# - full access to secrets, databases
|
13
|
+
# - failures here prevent deployment
|
14
|
+
<%- if @sqlite3 -%>
|
15
|
+
task :release
|
16
|
+
<%- else -%>
|
17
|
+
task :release => 'db:migrate'
|
18
|
+
<%- end -%>
|
19
|
+
|
20
|
+
<% end -%>
|
21
|
+
<% if @avahi or @nats -%>
|
22
|
+
task :env do
|
23
|
+
<% if @redis -%>
|
24
|
+
if ENV['NATS_SERVER']
|
25
|
+
redis_host = "#{ENV['FLY_REGION']}-redis.local"
|
26
|
+
else
|
27
|
+
redis_host = 'localhost'
|
28
|
+
end
|
29
|
+
|
30
|
+
ENV['REDIS_URL'] = "redis://#{redis_host}:6379/1"
|
31
|
+
<% end -%>
|
32
|
+
<% if @anycable -%>
|
33
|
+
ENV['ANYCABLE_GO_RPC_HOST'] = "#{ENV['FLY_REGION']}-anycable-rpc.local:50051"
|
34
|
+
<% end -%>
|
35
|
+
end
|
36
|
+
|
37
|
+
<% end -%>
|
38
|
+
# SERVER step:
|
39
|
+
# - changes to the filesystem made here are deployed
|
40
|
+
# - full access to secrets, databases
|
41
|
+
# - failures here result in VM being stated, shutdown, and rolled back
|
42
|
+
# to last successful deploy (if any).
|
43
|
+
<%= begin
|
44
|
+
deps = [:swapfile]
|
45
|
+
deps << 'db:migrate' if @sqlite3
|
46
|
+
deps = deps.first if deps.length == 1
|
47
|
+
|
48
|
+
if @procs.length > 1 and (@avahi or @nats)
|
49
|
+
"task :server, [:formation] => #{deps.inspect} do |task, args|"
|
50
|
+
else
|
51
|
+
"task :server => #{deps.inspect} do"
|
52
|
+
end
|
53
|
+
end %>
|
54
|
+
rm_f 'tmp/pids/server.pid' if File.exist? 'tmp/pids/server.pid'
|
55
|
+
<%- if @procs.length > 1 -%>
|
56
|
+
<%- if @avahi or @nats -%>
|
57
|
+
<%- if @passenger -%>
|
58
|
+
sh 'envsubst < config/nginx.conf > /etc/nginx/sites-available/rails.conf'
|
59
|
+
<%- end -%>
|
60
|
+
formation = args[:formation].gsub!(';', ',')
|
61
|
+
<%- if @avahi -%>
|
62
|
+
Rake::Task['fly:avahi_publish'].invoke(formation)
|
63
|
+
<%- end -%>
|
64
|
+
<%- if @nats -%>
|
65
|
+
Rake::Task['fly:nats_publish'].invoke(formation) if ENV['NATS_SERVER']
|
66
|
+
<%- end -%>
|
67
|
+
Bundler.with_original_env do
|
68
|
+
Rake::Task['fly:env'].invoke
|
69
|
+
sh "foreman start --procfile=Procfile.fly --formation=#{formation}"
|
70
|
+
end
|
71
|
+
<%- else -%>
|
72
|
+
Bundler.with_original_env do
|
73
|
+
sh "foreman start --procfile=Procfile.fly"
|
74
|
+
end
|
75
|
+
<%- end -%>
|
76
|
+
<%- else -%>
|
77
|
+
sh <%= @procs.values.first.inspect %>
|
78
|
+
<%- end -%>
|
79
|
+
end
|
80
|
+
|
81
|
+
# optional SWAPFILE task:
|
82
|
+
# - adjust fallocate size as needed
|
83
|
+
# - performance critical applications should scale memory to the
|
84
|
+
# point where swap is rarely used. 'fly scale help' for details.
|
85
|
+
# - disable by removing dependency on the :server task, thus:
|
86
|
+
<%- if @sqlite3 -%>
|
87
|
+
# task :server => 'db:migrate' do
|
88
|
+
<%- else -%>
|
89
|
+
# task :server do
|
90
|
+
<%- end -%>
|
91
|
+
task :swapfile do
|
92
|
+
sh 'fallocate -l 512M /swapfile'
|
93
|
+
sh 'chmod 0600 /swapfile'
|
94
|
+
sh 'mkswap /swapfile'
|
95
|
+
sh 'echo 10 > /proc/sys/vm/swappiness'
|
96
|
+
sh 'swapon /swapfile'
|
97
|
+
<% if @redis == :internal -%>
|
98
|
+
sh 'echo 1 > /proc/sys/vm/overcommit_memory'
|
99
|
+
<% end -%>
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
image <%= @image.inspect %>
|
2
|
+
|
3
|
+
machine do
|
4
|
+
cpus 1
|
5
|
+
cpu_kind 'shared'
|
6
|
+
memory_mb 256
|
7
|
+
end
|
8
|
+
<% if @sqlite3 -%>
|
9
|
+
|
10
|
+
sqlite3 do
|
11
|
+
size 3
|
12
|
+
end
|
13
|
+
<% end -%>
|
14
|
+
<% if @postgresql -%>
|
15
|
+
|
16
|
+
postgres do
|
17
|
+
vm_size 'shared-cpu-1x'
|
18
|
+
volume_size 1
|
19
|
+
initial_cluster_size 1
|
20
|
+
end
|
21
|
+
<% end -%>
|
22
|
+
<% if @redis -%>
|
23
|
+
|
24
|
+
redis do
|
25
|
+
plan "Free"
|
26
|
+
end
|
27
|
+
<% end -%>
|
@@ -0,0 +1,81 @@
|
|
1
|
+
app = "<%= @app %>"
|
2
|
+
<% if @nomad -%>
|
3
|
+
kill_signal = "SIGINT"
|
4
|
+
kill_timeout = 5
|
5
|
+
<% unless @avahi or @nats -%>
|
6
|
+
processes = []
|
7
|
+
<% end -%>
|
8
|
+
|
9
|
+
[build]
|
10
|
+
[build.args]
|
11
|
+
BUILD_COMMAND = "bin/rails fly:build"
|
12
|
+
<% if @litefs -%>
|
13
|
+
SERVER_COMMAND = "litefs"
|
14
|
+
<% else -%>
|
15
|
+
SERVER_COMMAND = "bin/rails fly:server"
|
16
|
+
|
17
|
+
[deploy]
|
18
|
+
release_command = "bin/rails fly:release"
|
19
|
+
<% end -%>
|
20
|
+
|
21
|
+
[env]
|
22
|
+
PORT = "8080"
|
23
|
+
<% if @sqlite3 -%>
|
24
|
+
<% if @litefs -%>
|
25
|
+
DATABASE_URL = "sqlite3:///data/production.sqlite3"
|
26
|
+
<% else -%>
|
27
|
+
DATABASE_URL = "sqlite3:///mnt/volume/production.sqlite3"
|
28
|
+
<% end -%>
|
29
|
+
<% if @avahi or @nats -%>
|
30
|
+
|
31
|
+
[processes]
|
32
|
+
app = "bin/rails fly:server[<%= @procs.keys.map {|key| "#{key}=1"}.join(';') %>]"
|
33
|
+
<% end -%>
|
34
|
+
|
35
|
+
[mounts]
|
36
|
+
source = <%= "#{app.gsub('-', '_')}_volume".inspect %>
|
37
|
+
destination = "/mnt/volume"
|
38
|
+
<% end -%>
|
39
|
+
|
40
|
+
[experimental]
|
41
|
+
allowed_public_ports = []
|
42
|
+
auto_rollback = true
|
43
|
+
<% if @litefs -%>
|
44
|
+
enable_consul = true
|
45
|
+
<% end -%>
|
46
|
+
|
47
|
+
[[services]]
|
48
|
+
http_checks = []
|
49
|
+
internal_port = 8080
|
50
|
+
processes = ["app"]
|
51
|
+
protocol = "tcp"
|
52
|
+
script_checks = []
|
53
|
+
[services.concurrency]
|
54
|
+
<% if @cable -%>
|
55
|
+
hard_limit = 2500
|
56
|
+
soft_limit = 2000
|
57
|
+
<% else -%>
|
58
|
+
hard_limit = 25
|
59
|
+
soft_limit = 20
|
60
|
+
<% end -%>
|
61
|
+
type = "connections"
|
62
|
+
|
63
|
+
[[services.ports]]
|
64
|
+
force_https = true
|
65
|
+
handlers = ["http"]
|
66
|
+
port = 80
|
67
|
+
|
68
|
+
[[services.ports]]
|
69
|
+
handlers = ["tls", "http"]
|
70
|
+
port = 443
|
71
|
+
|
72
|
+
[[services.tcp_checks]]
|
73
|
+
grace_period = "1s"
|
74
|
+
interval = "15s"
|
75
|
+
restart_limit = 0
|
76
|
+
timeout = "2s"
|
77
|
+
|
78
|
+
[[statics]]
|
79
|
+
guest_path = "/app/public"
|
80
|
+
url_prefix = "/"
|
81
|
+
<% end -%>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# The path to where the SQLite database will be accessed.
|
2
|
+
mount-dir: "/data"
|
3
|
+
|
4
|
+
# The path to where the underlying volume mount is.
|
5
|
+
data-dir: "/mnt/volume"
|
6
|
+
|
7
|
+
# Execute this subprocess once LiteFS connects to the cluster.
|
8
|
+
exec: "bin/rails fly:server"
|
9
|
+
|
10
|
+
# These environment variables will be available in your Fly.io application.
|
11
|
+
# You must specify "experiement.enable_consul" for FLY_CONSUL_URL to be available.
|
12
|
+
consul:
|
13
|
+
url: "${FLY_CONSUL_URL}"
|
14
|
+
advertise-url: "http://${HOSTNAME}.vm.${FLY_APP_NAME}.internal:20202"
|
@@ -0,0 +1,101 @@
|
|
1
|
+
terraform {
|
2
|
+
required_providers {
|
3
|
+
fly = {
|
4
|
+
source = "fly-apps/fly"
|
5
|
+
version = "0.0.20"
|
6
|
+
}
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
variable "image_ref" {
|
11
|
+
type = string
|
12
|
+
description = "docker images containing the application"
|
13
|
+
}
|
14
|
+
|
15
|
+
/* uncomment if you want an internal tunnel
|
16
|
+
provider "fly" {
|
17
|
+
useinternaltunnel = true
|
18
|
+
internaltunnelorg = <%= (@org || "personal").inspect %>
|
19
|
+
internaltunnelregion = <%= (@regions.first || 'iad').inspect %>
|
20
|
+
}
|
21
|
+
*/
|
22
|
+
|
23
|
+
# Allocate an IPv4 address
|
24
|
+
resource "fly_ip" "<%= @appName %>Ipv4" {
|
25
|
+
app = <%= @app.inspect %>
|
26
|
+
type = "v4"
|
27
|
+
}
|
28
|
+
|
29
|
+
# Allocate an IPv6 address
|
30
|
+
resource "fly_ip" "<%= @appName %>Ipv6" {
|
31
|
+
app = <%= @app.inspect %>
|
32
|
+
type = "v6"
|
33
|
+
}
|
34
|
+
|
35
|
+
<% unless @sqlite3 -%>
|
36
|
+
/* Uncomment this if you want a volume
|
37
|
+
<% end -%>
|
38
|
+
resource "fly_volume" "<%= @appName %>Volume" {
|
39
|
+
for_each = toset(<%= @regions.inspect %>)
|
40
|
+
region = each.value
|
41
|
+
|
42
|
+
name = "<%= @appName %>Volume"
|
43
|
+
app = <%= @app.inspect %>
|
44
|
+
size = 3
|
45
|
+
}
|
46
|
+
<% unless @sqlite3 -%>
|
47
|
+
*/
|
48
|
+
<% end -%>
|
49
|
+
|
50
|
+
# Start a fly machine
|
51
|
+
resource "fly_machine" "<%= @appName %>Machine" {
|
52
|
+
for_each = toset(<%= @regions.inspect %>)
|
53
|
+
region = each.value
|
54
|
+
|
55
|
+
app = <%= @app.inspect %>
|
56
|
+
name = "<%= @app %>-${each.value}"
|
57
|
+
image = var.image_ref
|
58
|
+
|
59
|
+
# Scale application resources
|
60
|
+
cpus = 1
|
61
|
+
cputype = "shared"
|
62
|
+
memorymb = 256
|
63
|
+
|
64
|
+
# map http[s] external ports 443 and 80 to internal port 8080
|
65
|
+
services = [
|
66
|
+
{
|
67
|
+
ports = [
|
68
|
+
{
|
69
|
+
port = 443
|
70
|
+
handlers = ["tls", "http"]
|
71
|
+
},
|
72
|
+
{
|
73
|
+
port = 80
|
74
|
+
handlers = ["http"]
|
75
|
+
}
|
76
|
+
]
|
77
|
+
|
78
|
+
protocol = "tcp"
|
79
|
+
internal_port = 8080
|
80
|
+
}
|
81
|
+
]
|
82
|
+
|
83
|
+
<%- if @sqlite3 -%>
|
84
|
+
env = {
|
85
|
+
DATABASE_URL = "sqlite3:///mnt/db/production.sqlite3"
|
86
|
+
}
|
87
|
+
|
88
|
+
mounts = [
|
89
|
+
{
|
90
|
+
volume = "<%= @appName %>Volume"
|
91
|
+
path = "/mnt/db"
|
92
|
+
}
|
93
|
+
]
|
94
|
+
|
95
|
+
depends_on = [fly_volume.<%= @appName %>Volume]
|
96
|
+
<%- else -%>
|
97
|
+
/* Uncomment this if you want a volume
|
98
|
+
depends_on = [fly_volume.<%= @appName %>Volume]
|
99
|
+
*/
|
100
|
+
<%- end -%>
|
101
|
+
}
|