nvoi 0.1.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.
Files changed (178) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +19 -0
  3. data/Gemfile +9 -0
  4. data/Gemfile.lock +151 -0
  5. data/Makefile +26 -0
  6. data/Rakefile +16 -0
  7. data/doc/config-schema.yaml +357 -0
  8. data/examples/apex-wildcard/deploy.yml +68 -0
  9. data/examples/golang/.gitignore +19 -0
  10. data/examples/golang/Dockerfile +43 -0
  11. data/examples/golang/README.md +59 -0
  12. data/examples/golang/deploy.enc +0 -0
  13. data/examples/golang/deploy.yml +54 -0
  14. data/examples/golang/go.mod +39 -0
  15. data/examples/golang/go.sum +96 -0
  16. data/examples/golang/main.go +177 -0
  17. data/examples/golang/models/user.go +17 -0
  18. data/examples/golang-postgres-multi/.gitignore +18 -0
  19. data/examples/golang-postgres-multi/Dockerfile +39 -0
  20. data/examples/golang-postgres-multi/README.md +211 -0
  21. data/examples/golang-postgres-multi/deploy.yml +67 -0
  22. data/examples/golang-postgres-multi/go.mod +45 -0
  23. data/examples/golang-postgres-multi/go.sum +108 -0
  24. data/examples/golang-postgres-multi/main.go +197 -0
  25. data/examples/golang-postgres-multi/models/user.go +17 -0
  26. data/examples/postgres-multi/.env.production.example +11 -0
  27. data/examples/postgres-multi/README.md +112 -0
  28. data/examples/postgres-multi/deploy.yml +74 -0
  29. data/examples/postgres-single/.env.production.example +11 -0
  30. data/examples/postgres-single/.gitignore +15 -0
  31. data/examples/postgres-single/Dockerfile +35 -0
  32. data/examples/postgres-single/README.md +76 -0
  33. data/examples/postgres-single/deploy.yml +56 -0
  34. data/examples/postgres-single/go.mod +45 -0
  35. data/examples/postgres-single/go.sum +108 -0
  36. data/examples/postgres-single/main.go +184 -0
  37. data/examples/rails-single/.dockerignore +51 -0
  38. data/examples/rails-single/.env.production.example +11 -0
  39. data/examples/rails-single/.github/dependabot.yml +12 -0
  40. data/examples/rails-single/.github/workflows/ci.yml +39 -0
  41. data/examples/rails-single/.gitignore +20 -0
  42. data/examples/rails-single/.node-version +1 -0
  43. data/examples/rails-single/.rubocop.yml +8 -0
  44. data/examples/rails-single/.ruby-version +1 -0
  45. data/examples/rails-single/Dockerfile +86 -0
  46. data/examples/rails-single/Gemfile +56 -0
  47. data/examples/rails-single/Gemfile.lock +350 -0
  48. data/examples/rails-single/Procfile.dev +3 -0
  49. data/examples/rails-single/README.md +17 -0
  50. data/examples/rails-single/Rakefile +6 -0
  51. data/examples/rails-single/app/assets/builds/.keep +0 -0
  52. data/examples/rails-single/app/assets/images/.keep +0 -0
  53. data/examples/rails-single/app/assets/stylesheets/application.tailwind.css +1 -0
  54. data/examples/rails-single/app/controllers/application_controller.rb +4 -0
  55. data/examples/rails-single/app/controllers/concerns/.keep +0 -0
  56. data/examples/rails-single/app/controllers/users_controller.rb +19 -0
  57. data/examples/rails-single/app/helpers/application_helper.rb +2 -0
  58. data/examples/rails-single/app/javascript/application.js +3 -0
  59. data/examples/rails-single/app/javascript/controllers/application.js +9 -0
  60. data/examples/rails-single/app/javascript/controllers/hello_controller.js +7 -0
  61. data/examples/rails-single/app/javascript/controllers/index.js +8 -0
  62. data/examples/rails-single/app/jobs/application_job.rb +7 -0
  63. data/examples/rails-single/app/mailers/application_mailer.rb +4 -0
  64. data/examples/rails-single/app/models/application_record.rb +3 -0
  65. data/examples/rails-single/app/models/concerns/.keep +0 -0
  66. data/examples/rails-single/app/models/user.rb +2 -0
  67. data/examples/rails-single/app/views/layouts/application.html.erb +28 -0
  68. data/examples/rails-single/app/views/layouts/mailer.html.erb +13 -0
  69. data/examples/rails-single/app/views/layouts/mailer.text.erb +1 -0
  70. data/examples/rails-single/app/views/pwa/manifest.json.erb +22 -0
  71. data/examples/rails-single/app/views/pwa/service-worker.js +26 -0
  72. data/examples/rails-single/app/views/users/index.html.erb +38 -0
  73. data/examples/rails-single/bin/brakeman +7 -0
  74. data/examples/rails-single/bin/bundle +109 -0
  75. data/examples/rails-single/bin/dev +11 -0
  76. data/examples/rails-single/bin/docker-entrypoint +14 -0
  77. data/examples/rails-single/bin/jobs +6 -0
  78. data/examples/rails-single/bin/kamal +27 -0
  79. data/examples/rails-single/bin/rails +4 -0
  80. data/examples/rails-single/bin/rake +4 -0
  81. data/examples/rails-single/bin/rubocop +8 -0
  82. data/examples/rails-single/bin/setup +37 -0
  83. data/examples/rails-single/bin/thrust +5 -0
  84. data/examples/rails-single/bun.lock +224 -0
  85. data/examples/rails-single/config/application.rb +42 -0
  86. data/examples/rails-single/config/boot.rb +4 -0
  87. data/examples/rails-single/config/cable.yml +17 -0
  88. data/examples/rails-single/config/cache.yml +16 -0
  89. data/examples/rails-single/config/credentials.yml.enc +1 -0
  90. data/examples/rails-single/config/database.yml +100 -0
  91. data/examples/rails-single/config/environment.rb +5 -0
  92. data/examples/rails-single/config/environments/development.rb +69 -0
  93. data/examples/rails-single/config/environments/production.rb +87 -0
  94. data/examples/rails-single/config/environments/test.rb +50 -0
  95. data/examples/rails-single/config/initializers/assets.rb +7 -0
  96. data/examples/rails-single/config/initializers/content_security_policy.rb +25 -0
  97. data/examples/rails-single/config/initializers/filter_parameter_logging.rb +8 -0
  98. data/examples/rails-single/config/initializers/inflections.rb +16 -0
  99. data/examples/rails-single/config/locales/en.yml +31 -0
  100. data/examples/rails-single/config/puma.rb +41 -0
  101. data/examples/rails-single/config/queue.yml +18 -0
  102. data/examples/rails-single/config/recurring.yml +15 -0
  103. data/examples/rails-single/config/routes.rb +4 -0
  104. data/examples/rails-single/config.ru +6 -0
  105. data/examples/rails-single/db/cable_schema.rb +11 -0
  106. data/examples/rails-single/db/cache_schema.rb +12 -0
  107. data/examples/rails-single/db/migrate/20251123095526_create_users.rb +10 -0
  108. data/examples/rails-single/db/queue_schema.rb +129 -0
  109. data/examples/rails-single/db/seeds.rb +9 -0
  110. data/examples/rails-single/deploy.yml +57 -0
  111. data/examples/rails-single/lib/tasks/.keep +0 -0
  112. data/examples/rails-single/log/.keep +0 -0
  113. data/examples/rails-single/package.json +17 -0
  114. data/examples/rails-single/public/400.html +114 -0
  115. data/examples/rails-single/public/404.html +114 -0
  116. data/examples/rails-single/public/406-unsupported-browser.html +114 -0
  117. data/examples/rails-single/public/422.html +114 -0
  118. data/examples/rails-single/public/500.html +114 -0
  119. data/examples/rails-single/public/icon.png +0 -0
  120. data/examples/rails-single/public/icon.svg +3 -0
  121. data/examples/rails-single/public/robots.txt +1 -0
  122. data/examples/rails-single/script/.keep +0 -0
  123. data/examples/rails-single/vendor/.keep +0 -0
  124. data/examples/rails-single/yarn.lock +188 -0
  125. data/exe/nvoi +6 -0
  126. data/lib/nvoi/cli.rb +190 -0
  127. data/lib/nvoi/cloudflare/client.rb +287 -0
  128. data/lib/nvoi/config/config.rb +248 -0
  129. data/lib/nvoi/config/env_resolver.rb +63 -0
  130. data/lib/nvoi/config/loader.rb +102 -0
  131. data/lib/nvoi/config/naming.rb +196 -0
  132. data/lib/nvoi/config/ssh_keys.rb +82 -0
  133. data/lib/nvoi/config/types.rb +274 -0
  134. data/lib/nvoi/constants.rb +59 -0
  135. data/lib/nvoi/credentials/crypto.rb +88 -0
  136. data/lib/nvoi/credentials/editor.rb +272 -0
  137. data/lib/nvoi/credentials/manager.rb +173 -0
  138. data/lib/nvoi/deployer/cleaner.rb +36 -0
  139. data/lib/nvoi/deployer/image_builder.rb +23 -0
  140. data/lib/nvoi/deployer/infrastructure.rb +126 -0
  141. data/lib/nvoi/deployer/orchestrator.rb +146 -0
  142. data/lib/nvoi/deployer/retry.rb +67 -0
  143. data/lib/nvoi/deployer/service_deployer.rb +311 -0
  144. data/lib/nvoi/deployer/tunnel_manager.rb +57 -0
  145. data/lib/nvoi/deployer/types.rb +8 -0
  146. data/lib/nvoi/errors.rb +67 -0
  147. data/lib/nvoi/k8s/renderer.rb +44 -0
  148. data/lib/nvoi/k8s/templates.rb +29 -0
  149. data/lib/nvoi/logger.rb +72 -0
  150. data/lib/nvoi/providers/aws.rb +403 -0
  151. data/lib/nvoi/providers/base.rb +111 -0
  152. data/lib/nvoi/providers/hetzner.rb +288 -0
  153. data/lib/nvoi/providers/hetzner_client.rb +170 -0
  154. data/lib/nvoi/remote/docker_manager.rb +203 -0
  155. data/lib/nvoi/remote/ssh_executor.rb +72 -0
  156. data/lib/nvoi/remote/volume_manager.rb +103 -0
  157. data/lib/nvoi/service/delete.rb +234 -0
  158. data/lib/nvoi/service/deploy.rb +80 -0
  159. data/lib/nvoi/service/exec.rb +144 -0
  160. data/lib/nvoi/service/provider.rb +36 -0
  161. data/lib/nvoi/steps/application_deployer.rb +26 -0
  162. data/lib/nvoi/steps/database_provisioner.rb +60 -0
  163. data/lib/nvoi/steps/k3s_cluster_setup.rb +105 -0
  164. data/lib/nvoi/steps/k3s_provisioner.rb +351 -0
  165. data/lib/nvoi/steps/server_provisioner.rb +43 -0
  166. data/lib/nvoi/steps/services_provisioner.rb +29 -0
  167. data/lib/nvoi/steps/tunnel_configurator.rb +66 -0
  168. data/lib/nvoi/steps/volume_provisioner.rb +154 -0
  169. data/lib/nvoi/version.rb +5 -0
  170. data/lib/nvoi.rb +79 -0
  171. data/templates/app-deployment.yaml.erb +102 -0
  172. data/templates/app-ingress.yaml.erb +20 -0
  173. data/templates/app-secret.yaml.erb +10 -0
  174. data/templates/app-service.yaml.erb +12 -0
  175. data/templates/db-statefulset.yaml.erb +76 -0
  176. data/templates/service-deployment.yaml.erb +91 -0
  177. data/templates/worker-deployment.yaml.erb +50 -0
  178. metadata +361 -0
@@ -0,0 +1,350 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ actioncable (8.0.4)
5
+ actionpack (= 8.0.4)
6
+ activesupport (= 8.0.4)
7
+ nio4r (~> 2.0)
8
+ websocket-driver (>= 0.6.1)
9
+ zeitwerk (~> 2.6)
10
+ actionmailbox (8.0.4)
11
+ actionpack (= 8.0.4)
12
+ activejob (= 8.0.4)
13
+ activerecord (= 8.0.4)
14
+ activestorage (= 8.0.4)
15
+ activesupport (= 8.0.4)
16
+ mail (>= 2.8.0)
17
+ actionmailer (8.0.4)
18
+ actionpack (= 8.0.4)
19
+ actionview (= 8.0.4)
20
+ activejob (= 8.0.4)
21
+ activesupport (= 8.0.4)
22
+ mail (>= 2.8.0)
23
+ rails-dom-testing (~> 2.2)
24
+ actionpack (8.0.4)
25
+ actionview (= 8.0.4)
26
+ activesupport (= 8.0.4)
27
+ nokogiri (>= 1.8.5)
28
+ rack (>= 2.2.4)
29
+ rack-session (>= 1.0.1)
30
+ rack-test (>= 0.6.3)
31
+ rails-dom-testing (~> 2.2)
32
+ rails-html-sanitizer (~> 1.6)
33
+ useragent (~> 0.16)
34
+ actiontext (8.0.4)
35
+ actionpack (= 8.0.4)
36
+ activerecord (= 8.0.4)
37
+ activestorage (= 8.0.4)
38
+ activesupport (= 8.0.4)
39
+ globalid (>= 0.6.0)
40
+ nokogiri (>= 1.8.5)
41
+ actionview (8.0.4)
42
+ activesupport (= 8.0.4)
43
+ builder (~> 3.1)
44
+ erubi (~> 1.11)
45
+ rails-dom-testing (~> 2.2)
46
+ rails-html-sanitizer (~> 1.6)
47
+ activejob (8.0.4)
48
+ activesupport (= 8.0.4)
49
+ globalid (>= 0.3.6)
50
+ activemodel (8.0.4)
51
+ activesupport (= 8.0.4)
52
+ activerecord (8.0.4)
53
+ activemodel (= 8.0.4)
54
+ activesupport (= 8.0.4)
55
+ timeout (>= 0.4.0)
56
+ activestorage (8.0.4)
57
+ actionpack (= 8.0.4)
58
+ activejob (= 8.0.4)
59
+ activerecord (= 8.0.4)
60
+ activesupport (= 8.0.4)
61
+ marcel (~> 1.0)
62
+ activesupport (8.0.4)
63
+ base64
64
+ benchmark (>= 0.3)
65
+ bigdecimal
66
+ concurrent-ruby (~> 1.0, >= 1.3.1)
67
+ connection_pool (>= 2.2.5)
68
+ drb
69
+ i18n (>= 1.6, < 2)
70
+ logger (>= 1.4.2)
71
+ minitest (>= 5.1)
72
+ securerandom (>= 0.3)
73
+ tzinfo (~> 2.0, >= 2.0.5)
74
+ uri (>= 0.13.1)
75
+ ast (2.4.3)
76
+ base64 (0.3.0)
77
+ bcrypt_pbkdf (1.1.1)
78
+ bcrypt_pbkdf (1.1.1-arm64-darwin)
79
+ benchmark (0.5.0)
80
+ bigdecimal (3.3.1)
81
+ bindex (0.8.1)
82
+ bootsnap (1.19.0)
83
+ msgpack (~> 1.2)
84
+ brakeman (7.1.1)
85
+ racc
86
+ builder (3.3.0)
87
+ concurrent-ruby (1.3.5)
88
+ connection_pool (2.5.4)
89
+ crass (1.0.6)
90
+ cssbundling-rails (1.4.3)
91
+ railties (>= 6.0.0)
92
+ date (3.5.0)
93
+ debug (1.11.0)
94
+ irb (~> 1.10)
95
+ reline (>= 0.3.8)
96
+ dotenv (3.1.8)
97
+ drb (2.2.3)
98
+ ed25519 (1.4.0)
99
+ erb (6.0.0)
100
+ erubi (1.13.1)
101
+ et-orbi (1.4.0)
102
+ tzinfo
103
+ fugit (1.12.1)
104
+ et-orbi (~> 1.4)
105
+ raabro (~> 1.4)
106
+ globalid (1.3.0)
107
+ activesupport (>= 6.1)
108
+ i18n (1.14.7)
109
+ concurrent-ruby (~> 1.0)
110
+ io-console (0.8.1)
111
+ irb (1.15.3)
112
+ pp (>= 0.6.0)
113
+ rdoc (>= 4.0.0)
114
+ reline (>= 0.4.2)
115
+ jbuilder (2.14.1)
116
+ actionview (>= 7.0.0)
117
+ activesupport (>= 7.0.0)
118
+ jsbundling-rails (1.3.1)
119
+ railties (>= 6.0.0)
120
+ json (2.16.0)
121
+ kamal (2.8.2)
122
+ activesupport (>= 7.0)
123
+ base64 (~> 0.2)
124
+ bcrypt_pbkdf (~> 1.0)
125
+ concurrent-ruby (~> 1.2)
126
+ dotenv (~> 3.1)
127
+ ed25519 (~> 1.4)
128
+ net-ssh (~> 7.3)
129
+ sshkit (>= 1.23.0, < 2.0)
130
+ thor (~> 1.3)
131
+ zeitwerk (>= 2.6.18, < 3.0)
132
+ language_server-protocol (3.17.0.5)
133
+ lint_roller (1.1.0)
134
+ logger (1.7.0)
135
+ loofah (2.24.1)
136
+ crass (~> 1.0.2)
137
+ nokogiri (>= 1.12.0)
138
+ mail (2.9.0)
139
+ logger
140
+ mini_mime (>= 0.1.1)
141
+ net-imap
142
+ net-pop
143
+ net-smtp
144
+ marcel (1.1.0)
145
+ mini_mime (1.1.5)
146
+ minitest (5.26.2)
147
+ msgpack (1.8.0)
148
+ net-imap (0.5.12)
149
+ date
150
+ net-protocol
151
+ net-pop (0.1.2)
152
+ net-protocol
153
+ net-protocol (0.2.2)
154
+ timeout
155
+ net-scp (4.1.0)
156
+ net-ssh (>= 2.6.5, < 8.0.0)
157
+ net-sftp (4.0.0)
158
+ net-ssh (>= 5.0.0, < 8.0.0)
159
+ net-smtp (0.5.1)
160
+ net-protocol
161
+ net-ssh (7.3.0)
162
+ nio4r (2.7.5)
163
+ nokogiri (1.18.10-aarch64-linux-gnu)
164
+ racc (~> 1.4)
165
+ nokogiri (1.18.10-arm64-darwin)
166
+ racc (~> 1.4)
167
+ nokogiri (1.18.10-x86_64-linux-gnu)
168
+ racc (~> 1.4)
169
+ ostruct (0.6.3)
170
+ parallel (1.27.0)
171
+ parser (3.3.10.0)
172
+ ast (~> 2.4.1)
173
+ racc
174
+ pg (1.6.2-aarch64-linux)
175
+ pg (1.6.2-arm64-darwin)
176
+ pg (1.6.2-x86_64-linux)
177
+ pp (0.6.3)
178
+ prettyprint
179
+ prettyprint (0.2.0)
180
+ prism (1.6.0)
181
+ propshaft (1.3.1)
182
+ actionpack (>= 7.0.0)
183
+ activesupport (>= 7.0.0)
184
+ rack
185
+ psych (5.2.6)
186
+ date
187
+ stringio
188
+ puma (7.1.0)
189
+ nio4r (~> 2.0)
190
+ raabro (1.4.0)
191
+ racc (1.8.1)
192
+ rack (3.2.4)
193
+ rack-session (2.1.1)
194
+ base64 (>= 0.1.0)
195
+ rack (>= 3.0.0)
196
+ rack-test (2.2.0)
197
+ rack (>= 1.3)
198
+ rackup (2.2.1)
199
+ rack (>= 3)
200
+ rails (8.0.4)
201
+ actioncable (= 8.0.4)
202
+ actionmailbox (= 8.0.4)
203
+ actionmailer (= 8.0.4)
204
+ actionpack (= 8.0.4)
205
+ actiontext (= 8.0.4)
206
+ actionview (= 8.0.4)
207
+ activejob (= 8.0.4)
208
+ activemodel (= 8.0.4)
209
+ activerecord (= 8.0.4)
210
+ activestorage (= 8.0.4)
211
+ activesupport (= 8.0.4)
212
+ bundler (>= 1.15.0)
213
+ railties (= 8.0.4)
214
+ rails-dom-testing (2.3.0)
215
+ activesupport (>= 5.0.0)
216
+ minitest
217
+ nokogiri (>= 1.6)
218
+ rails-html-sanitizer (1.6.2)
219
+ loofah (~> 2.21)
220
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
221
+ railties (8.0.4)
222
+ actionpack (= 8.0.4)
223
+ activesupport (= 8.0.4)
224
+ irb (~> 1.13)
225
+ rackup (>= 1.0.0)
226
+ rake (>= 12.2)
227
+ thor (~> 1.0, >= 1.2.2)
228
+ tsort (>= 0.2)
229
+ zeitwerk (~> 2.6)
230
+ rainbow (3.1.1)
231
+ rake (13.3.1)
232
+ rdoc (6.15.1)
233
+ erb
234
+ psych (>= 4.0.0)
235
+ tsort
236
+ regexp_parser (2.11.3)
237
+ reline (0.6.3)
238
+ io-console (~> 0.5)
239
+ rubocop (1.81.7)
240
+ json (~> 2.3)
241
+ language_server-protocol (~> 3.17.0.2)
242
+ lint_roller (~> 1.1.0)
243
+ parallel (~> 1.10)
244
+ parser (>= 3.3.0.2)
245
+ rainbow (>= 2.2.2, < 4.0)
246
+ regexp_parser (>= 2.9.3, < 3.0)
247
+ rubocop-ast (>= 1.47.1, < 2.0)
248
+ ruby-progressbar (~> 1.7)
249
+ unicode-display_width (>= 2.4.0, < 4.0)
250
+ rubocop-ast (1.48.0)
251
+ parser (>= 3.3.7.2)
252
+ prism (~> 1.4)
253
+ rubocop-performance (1.26.1)
254
+ lint_roller (~> 1.1)
255
+ rubocop (>= 1.75.0, < 2.0)
256
+ rubocop-ast (>= 1.47.1, < 2.0)
257
+ rubocop-rails (2.34.0)
258
+ activesupport (>= 4.2.0)
259
+ lint_roller (~> 1.1)
260
+ rack (>= 1.1)
261
+ rubocop (>= 1.75.0, < 2.0)
262
+ rubocop-ast (>= 1.44.0, < 2.0)
263
+ rubocop-rails-omakase (1.1.0)
264
+ rubocop (>= 1.72)
265
+ rubocop-performance (>= 1.24)
266
+ rubocop-rails (>= 2.30)
267
+ ruby-progressbar (1.13.0)
268
+ securerandom (0.4.1)
269
+ solid_cable (3.0.12)
270
+ actioncable (>= 7.2)
271
+ activejob (>= 7.2)
272
+ activerecord (>= 7.2)
273
+ railties (>= 7.2)
274
+ solid_cache (1.0.10)
275
+ activejob (>= 7.2)
276
+ activerecord (>= 7.2)
277
+ railties (>= 7.2)
278
+ solid_queue (1.2.4)
279
+ activejob (>= 7.1)
280
+ activerecord (>= 7.1)
281
+ concurrent-ruby (>= 1.3.1)
282
+ fugit (~> 1.11)
283
+ railties (>= 7.1)
284
+ thor (>= 1.3.1)
285
+ sshkit (1.24.0)
286
+ base64
287
+ logger
288
+ net-scp (>= 1.1.2)
289
+ net-sftp (>= 2.1.2)
290
+ net-ssh (>= 2.8.0)
291
+ ostruct
292
+ stimulus-rails (1.3.4)
293
+ railties (>= 6.0.0)
294
+ stringio (3.1.8)
295
+ thor (1.4.0)
296
+ thruster (0.1.16-aarch64-linux)
297
+ thruster (0.1.16-arm64-darwin)
298
+ thruster (0.1.16-x86_64-linux)
299
+ timeout (0.4.4)
300
+ tsort (0.2.0)
301
+ turbo-rails (2.0.20)
302
+ actionpack (>= 7.1.0)
303
+ railties (>= 7.1.0)
304
+ tzinfo (2.0.6)
305
+ concurrent-ruby (~> 1.0)
306
+ unicode-display_width (3.2.0)
307
+ unicode-emoji (~> 4.1)
308
+ unicode-emoji (4.1.0)
309
+ uri (1.1.1)
310
+ useragent (0.16.11)
311
+ web-console (4.2.1)
312
+ actionview (>= 6.0.0)
313
+ activemodel (>= 6.0.0)
314
+ bindex (>= 0.4.0)
315
+ railties (>= 6.0.0)
316
+ websocket-driver (0.8.0)
317
+ base64
318
+ websocket-extensions (>= 0.1.0)
319
+ websocket-extensions (0.1.5)
320
+ zeitwerk (2.7.3)
321
+
322
+ PLATFORMS
323
+ aarch64-linux
324
+ arm64-darwin-24
325
+ x86_64-linux
326
+
327
+ DEPENDENCIES
328
+ bootsnap
329
+ brakeman
330
+ cssbundling-rails
331
+ debug
332
+ jbuilder
333
+ jsbundling-rails
334
+ kamal
335
+ pg (~> 1.1)
336
+ propshaft
337
+ puma (>= 5.0)
338
+ rails (~> 8.0.4)
339
+ rubocop-rails-omakase
340
+ solid_cable
341
+ solid_cache
342
+ solid_queue
343
+ stimulus-rails
344
+ thruster
345
+ turbo-rails
346
+ tzinfo-data
347
+ web-console
348
+
349
+ BUNDLED WITH
350
+ 2.4.19
@@ -0,0 +1,3 @@
1
+ web: env RUBY_DEBUG_OPEN=true bin/rails server
2
+ js: yarn build --watch
3
+ css: bun run build:css --watch
@@ -0,0 +1,17 @@
1
+ # Rails Single Server Example
2
+
3
+ Rails 8 app with PostgreSQL and Solid Trifecta on a single server.
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ cp .env.production.example .env.production
9
+ # Fill in credentials
10
+ nvoi deploy
11
+ ```
12
+
13
+ ## What it does
14
+
15
+ - Creates a new user on every page visit
16
+ - Lists all users
17
+ - Runs Solid Queue worker as separate process
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative "config/application"
5
+
6
+ Rails.application.load_tasks
File without changes
File without changes
@@ -0,0 +1 @@
1
+ @import "tailwindcss";
@@ -0,0 +1,4 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
3
+ allow_browser versions: :modern
4
+ end
@@ -0,0 +1,19 @@
1
+ class UsersController < ApplicationController
2
+ def index
3
+ # Create a new user on every visit
4
+ @new_user = User.create!(
5
+ name: generate_random_name,
6
+ email: "user-#{Time.now.to_i}-#{rand(1000)}@example.com"
7
+ )
8
+
9
+ @users = User.all.order(created_at: :desc)
10
+ end
11
+
12
+ private
13
+
14
+ def generate_random_name
15
+ first_names = %w[Alice Bob Charlie Diana Eve Frank Grace Henry Ivy Jack]
16
+ last_names = %w[Smith Johnson Williams Brown Jones Garcia Miller Davis Rodriguez Martinez]
17
+ "#{first_names.sample} #{last_names.sample}"
18
+ end
19
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,3 @@
1
+ // Entry point for the build script in your package.json
2
+ import "@hotwired/turbo-rails"
3
+ import "./controllers"
@@ -0,0 +1,9 @@
1
+ import { Application } from "@hotwired/stimulus"
2
+
3
+ const application = Application.start()
4
+
5
+ // Configure Stimulus development experience
6
+ application.debug = false
7
+ window.Stimulus = application
8
+
9
+ export { application }
@@ -0,0 +1,7 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ connect() {
5
+ this.element.textContent = "Hello World!"
6
+ }
7
+ }
@@ -0,0 +1,8 @@
1
+ // This file is auto-generated by ./bin/rails stimulus:manifest:update
2
+ // Run that command whenever you add a new controller or create them with
3
+ // ./bin/rails generate stimulus controllerName
4
+
5
+ import { application } from "./application"
6
+
7
+ import HelloController from "./hello_controller"
8
+ application.register("hello", HelloController)
@@ -0,0 +1,7 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ # Automatically retry jobs that encountered a deadlock
3
+ # retry_on ActiveRecord::Deadlocked
4
+
5
+ # Most jobs are safe to ignore if the underlying records are no longer available
6
+ # discard_on ActiveJob::DeserializationError
7
+ end
@@ -0,0 +1,4 @@
1
+ class ApplicationMailer < ActionMailer::Base
2
+ default from: "from@example.com"
3
+ layout "mailer"
4
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ primary_abstract_class
3
+ end
File without changes
@@ -0,0 +1,2 @@
1
+ class User < ApplicationRecord
2
+ end
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= content_for(:title) || "Rails Single" %></title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <meta name="apple-mobile-web-app-capable" content="yes">
7
+ <meta name="mobile-web-app-capable" content="yes">
8
+ <%= csrf_meta_tags %>
9
+ <%= csp_meta_tag %>
10
+
11
+ <%= yield :head %>
12
+
13
+ <%# Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!) %>
14
+ <%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %>
15
+
16
+ <link rel="icon" href="/icon.png" type="image/png">
17
+ <link rel="icon" href="/icon.svg" type="image/svg+xml">
18
+ <link rel="apple-touch-icon" href="/icon.png">
19
+
20
+ <%# Includes all stylesheet files in app/assets/stylesheets %>
21
+ <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
22
+ <%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module" %>
23
+ </head>
24
+
25
+ <body>
26
+ <%= yield %>
27
+ </body>
28
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+ <style>
6
+ /* Email styles need to be inline */
7
+ </style>
8
+ </head>
9
+
10
+ <body>
11
+ <%= yield %>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
1
+ <%= yield %>
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "RailsSingle",
3
+ "icons": [
4
+ {
5
+ "src": "/icon.png",
6
+ "type": "image/png",
7
+ "sizes": "512x512"
8
+ },
9
+ {
10
+ "src": "/icon.png",
11
+ "type": "image/png",
12
+ "sizes": "512x512",
13
+ "purpose": "maskable"
14
+ }
15
+ ],
16
+ "start_url": "/",
17
+ "display": "standalone",
18
+ "scope": "/",
19
+ "description": "RailsSingle.",
20
+ "theme_color": "red",
21
+ "background_color": "red"
22
+ }
@@ -0,0 +1,26 @@
1
+ // Add a service worker for processing Web Push notifications:
2
+ //
3
+ // self.addEventListener("push", async (event) => {
4
+ // const { title, options } = await event.data.json()
5
+ // event.waitUntil(self.registration.showNotification(title, options))
6
+ // })
7
+ //
8
+ // self.addEventListener("notificationclick", function(event) {
9
+ // event.notification.close()
10
+ // event.waitUntil(
11
+ // clients.matchAll({ type: "window" }).then((clientList) => {
12
+ // for (let i = 0; i < clientList.length; i++) {
13
+ // let client = clientList[i]
14
+ // let clientPath = (new URL(client.url)).pathname
15
+ //
16
+ // if (clientPath == event.notification.data.path && "focus" in client) {
17
+ // return client.focus()
18
+ // }
19
+ // }
20
+ //
21
+ // if (clients.openWindow) {
22
+ // return clients.openWindow(event.notification.data.path)
23
+ // }
24
+ // })
25
+ // )
26
+ // })
@@ -0,0 +1,38 @@
1
+ <div class="min-h-screen bg-gray-100 py-8">
2
+ <div class="max-w-4xl mx-auto px-4">
3
+ <h1 class="text-3xl font-bold text-gray-900 mb-8">Rails Single Server Demo</h1>
4
+
5
+ <div class="bg-green-50 border border-green-200 rounded-lg p-4 mb-8">
6
+ <h2 class="text-lg font-semibold text-green-800 mb-2">✨ New User Created!</h2>
7
+ <p class="text-green-700">
8
+ <strong><%= @new_user.name %></strong> (<%= @new_user.email %>)
9
+ </p>
10
+ </div>
11
+
12
+ <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-8">
13
+ <h2 class="text-lg font-semibold text-blue-800 mb-2">🖥️ Server Info</h2>
14
+ <p class="text-blue-700">Hostname: <strong><%= Socket.gethostname %></strong></p>
15
+ <p class="text-blue-700">Rails: <strong><%= Rails.version %></strong></p>
16
+ <p class="text-blue-700">Ruby: <strong><%= RUBY_VERSION %></strong></p>
17
+ </div>
18
+
19
+ <div class="bg-white shadow rounded-lg overflow-hidden">
20
+ <div class="px-4 py-5 border-b border-gray-200">
21
+ <h2 class="text-lg font-semibold text-gray-900">All Users (<%= @users.count %>)</h2>
22
+ </div>
23
+ <ul class="divide-y divide-gray-200">
24
+ <% @users.each do |user| %>
25
+ <li class="px-4 py-4 flex justify-between items-center <%= user.id == @new_user.id ? 'bg-green-50' : '' %>">
26
+ <div>
27
+ <p class="font-medium text-gray-900"><%= user.name %></p>
28
+ <p class="text-sm text-gray-500"><%= user.email %></p>
29
+ </div>
30
+ <span class="text-xs text-gray-400"><%= time_ago_in_words(user.created_at) %> ago</span>
31
+ </li>
32
+ <% end %>
33
+ </ul>
34
+ </div>
35
+
36
+ <p class="mt-8 text-center text-gray-500 text-sm">Refresh the page to create another user!</p>
37
+ </div>
38
+ </div>
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "bundler/setup"
4
+
5
+ ARGV.unshift("--ensure-latest")
6
+
7
+ load Gem.bin_path("brakeman", "brakeman")