hephaestus 0.1.3 → 0.2.2

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +27 -1
  4. data/bin/hephaestus +9 -3
  5. data/lib/hephaestus/app_builder.rb +26 -5
  6. data/lib/hephaestus/exit_on_failure.rb +4 -4
  7. data/lib/hephaestus/generators/app_generator.rb +148 -56
  8. data/lib/hephaestus/generators/config_generator.rb +30 -2
  9. data/lib/hephaestus/generators/core_generator.rb +30 -1
  10. data/lib/hephaestus/generators/deployment_generator.rb +9 -3
  11. data/lib/hephaestus/generators/lib_generator.rb +1 -0
  12. data/lib/hephaestus/generators/sorbet_generator.rb +1 -1
  13. data/lib/hephaestus/version.rb +1 -1
  14. data/lib/hephaestus.rb +8 -0
  15. data/templates/.dockerignore +39 -0
  16. data/templates/.env.sample +6 -0
  17. data/templates/.github/dependabot.yml +12 -7
  18. data/templates/.github/workflows/automerge.yml +5 -85
  19. data/templates/.github/workflows/deploy.yml +30 -0
  20. data/templates/.github/workflows/licenses.yml +11 -31
  21. data/templates/.github/workflows/lint.yml +14 -34
  22. data/templates/.github/workflows/security.yml +9 -32
  23. data/templates/.github/workflows/sorbet.yml +7 -37
  24. data/templates/.github/workflows/test.yml +7 -41
  25. data/templates/.licensed.yml +7 -3
  26. data/templates/.ruby-version +1 -0
  27. data/templates/Dockerfile +79 -0
  28. data/templates/Gemfile.erb +23 -26
  29. data/templates/Procfile.debug +1 -1
  30. data/templates/app/controllers/app_controller.rb +71 -0
  31. data/templates/app/controllers/application_controller.rb +14 -1
  32. data/templates/app/controllers/concerns/authable.rb +20 -2
  33. data/templates/app/controllers/settings_controller.rb +32 -2
  34. data/templates/app/jobs/update_yetto_job.rb +6 -7
  35. data/templates/app/lib/body_parameter/yetto_parameters.rb +32 -0
  36. data/templates/app/lib/path_parameter/settings_parameters.rb +22 -0
  37. data/templates/app/lib/plug_app/middleware/openapi_validation.rb +5 -5
  38. data/templates/app/lib/plug_app/middleware/tracing_attributes.rb +1 -1
  39. data/templates/app/services/http_service.rb +27 -0
  40. data/templates/app/services/yetto_service.rb +24 -32
  41. data/templates/app/views/settings/new.json.jbuilder +21 -0
  42. data/templates/bin/docker-entrypoint +14 -0
  43. data/templates/compose.yml +7 -0
  44. data/templates/config/initializers/environment.rb +5 -8
  45. data/templates/config/initializers/filter_parameter_logging.rb +3 -0
  46. data/templates/config/initializers/opentelemetry.rb +32 -0
  47. data/templates/config/locales/en.yml +32 -0
  48. data/templates/config/locales/settings/en.yml +5 -0
  49. data/templates/lib/plug_app/schemas/api/2023-03-06/components/schemas/yetto.json +2 -2
  50. data/templates/lib/plug_app/schemas/api/2023-03-06/openapi.json +4 -4
  51. data/templates/lib/plug_app/schemas/api/2023-03-06/paths/plug.json +1 -1
  52. data/templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/after_create_message.json +2 -2
  53. data/templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/after_create_plug_installation.json +2 -2
  54. data/templates/lib/tasks/test_tasks.rake +6 -2
  55. data/templates/script/edit-credentials +29 -0
  56. data/templates/script/hmac_text +1 -1
  57. data/templates/script/licenses +4 -48
  58. data/templates/script/server +62 -2
  59. data/templates/script/sorbet +7 -0
  60. data/templates/test/controllers/application_controller_test.rb +32 -0
  61. data/templates/test/controllers/settings_controller_test.rb +1 -1
  62. data/templates/test/controllers/yetto_controller_test.rb +1 -1
  63. data/templates/test/fixtures/files/fake_pem_file/fake.pem +27 -0
  64. data/templates/test/jobs/update_yetto_job_test.rb +3 -18
  65. data/templates/test/support/api.rb +1 -1
  66. data/templates/test/support/rails.rb +1 -1
  67. data/templates/test/support/webmocks/slack_webmock.rb +2 -2
  68. data/templates/test/support/webmocks/yetto_webmock.rb +119 -0
  69. data/templates/test/test_helper.rb +16 -3
  70. data/templates/vendor/fly/fly-production.toml +38 -0
  71. data/templates/vendor/fly/fly-staging.toml +33 -0
  72. metadata +39 -16
  73. data/templates/.env.test +0 -4
  74. data/templates/.github/actions/license/action.yml +0 -11
  75. data/templates/.github/actions/setup/action.yml +0 -10
  76. data/templates/.github/actions/sisyphus/action.yml +0 -11
  77. data/templates/.github/actions/sorbet/action.yml +0 -19
  78. data/templates/app/views/settings/index.json.jbuilder +0 -15
  79. data/templates/config/initializers/open_telemetry.rb +0 -27
  80. data/templates/script/security_checks/brakeman +0 -5
  81. data/templates/script/security_checks/bundle-audit +0 -5
  82. data/templates/script/server-debug +0 -5
  83. data/templates/script/typecheck +0 -44
  84. data/templates/test/fixtures/files/.keep +0 -0
  85. data/templates/test/support/webmocks/yetto.rb +0 -94
@@ -0,0 +1,39 @@
1
+ # See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.
2
+
3
+ # Ignore git directory.
4
+ # /.git/
5
+
6
+ # Ignore bundler config.
7
+ /.bundle
8
+
9
+ # Ignore all default key files.
10
+ /config/master.key
11
+ /config/credentials/*.key
12
+
13
+ # Ignore all environment files.
14
+ /.env*
15
+ !/.env.example
16
+
17
+ # Ignore all logfiles and tempfiles.
18
+ /log/*
19
+ /tmp/*
20
+ !/log/.keep
21
+ !/tmp/.keep
22
+
23
+ # Ignore pidfiles, but keep the directory.
24
+ /tmp/pids/*
25
+ !/tmp/pids/
26
+ !/tmp/pids/.keep
27
+
28
+ # Ignore storage (uploaded files in development and any SQLite databases).
29
+ /storage/*
30
+ !/storage/.keep
31
+ /tmp/storage/*
32
+ !/tmp/storage/
33
+ !/tmp/storage/.keep
34
+
35
+ # Ignore assets.
36
+ /node_modules/
37
+ /app/assets/builds/*
38
+ !/app/assets/builds/.keep
39
+ /public/assets
@@ -0,0 +1,6 @@
1
+ # RAILS_MASTER_KEY="GENERATE_A_NEW_KEY"
2
+ YETTO_PLUG_PEM="REPLACE_ME_WITH_YETTO_VALUE"
3
+ SIGNING_SECRET="super-secret"
4
+ YETTO_PLUG_ID="REPLACE_ME_WITH_YETTO_VALUE"
5
+
6
+ LD_PRELOAD_PATH="/usr/lib/aarch64-linux-gnu/libjemalloc.so.2"
@@ -3,20 +3,25 @@ updates:
3
3
  - package-ecosystem: "github-actions"
4
4
  directory: "/"
5
5
  schedule:
6
- interval: daily
6
+ interval: weekly
7
+ day: monday
7
8
  time: "09:00"
8
9
  timezone: "Etc/UTC"
10
+ groups:
11
+ github-actions:
12
+ patterns:
13
+ - "*"
9
14
  open-pull-requests-limit: 10
10
15
 
11
16
  - package-ecosystem: bundler
12
17
  directory: "/"
13
18
  schedule:
14
- interval: daily
19
+ interval: weekly
20
+ day: monday
15
21
  time: "09:00"
16
22
  timezone: "Etc/UTC"
17
23
  open-pull-requests-limit: 10
18
- allow:
19
- - dependency-name: "*"
20
- dependency-type: "production"
21
- - dependency-name: "sorbet*"
22
- dependency-type: "all"
24
+ groups:
25
+ bundler-dependencies:
26
+ patterns:
27
+ - "*"
@@ -1,4 +1,4 @@
1
- name: PR auto-{approve,merge}
1
+ name: Bot auto-{approve,merge}
2
2
 
3
3
  on:
4
4
  pull_request_target:
@@ -9,89 +9,9 @@ permissions:
9
9
 
10
10
  jobs:
11
11
  dependabot:
12
- name: Dependabot
13
- runs-on: ubuntu-latest
14
-
15
- env:
16
- RAILS_ENV: test
17
- REDIS_URL: redis://localhost:6379/0
18
- RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
19
- SLACK_LOG_URL: http://slack.com/the_log_room
20
-
21
- # Service containers to run; note that this is duplicated
22
- # in test.yml due to a limitation in GitHub Actions
23
- # (services can only be defined per job)
24
- services:
25
- redis:
26
- # Docker Hub image name
27
- image: redis:6.2-alpine
28
- ports: ["6379:6379"]
29
- # Set health checks to wait until redis has started
30
- options: >-
31
- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout
32
- 5s --health-retries 5
33
-
34
- if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
35
- steps:
36
- - name: Fetch Dependabot metadata
37
- id: dependabot-metadata
38
- uses: dependabot/fetch-metadata@v1
39
- with:
40
- github-token: "${{ secrets.GITHUB_TOKEN }}"
41
-
42
- - uses: actions/checkout@v3
43
- with:
44
- ref: ${{ github.head_ref }}
45
-
46
- - uses: ./.github/actions/sisyphus
47
-
48
- - uses: ./.github/actions/license
49
-
50
- - name: Commit licenses
51
- run: |
52
- git add .
53
- git commit -m "[auto-license]: Update license information" || true
54
- git push
55
-
56
- - uses: ./.github/actions/sorbet
57
-
58
- - name: Commit Sorbet
59
- run: |
60
- git add .
61
- git commit -m "[auto-rbi]: Update RBI files" || true
62
- git push
63
-
64
- - name: Approve Dependabot PR
65
- if: ${{steps.dependabot-metadata.outputs.update-type != 'version-update:semver-major'}}
66
- run: gh pr review --approve "$PR_URL"
67
- env:
68
- PR_URL: ${{github.event.pull_request.html_url}}
69
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
70
-
71
- - name: Merge Dependabot PR
72
- run: gh pr merge --auto --squash "$PR_URL"
73
- env:
74
- PR_URL: ${{ github.event.pull_request.html_url }}
75
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
12
+ uses: yettoapp/actions/.github/workflows/automerge_dependabot.yml@main
13
+ secrets: inherit
76
14
 
77
15
  sisyphusbot:
78
- name: Automated PRs
79
- runs-on: ubuntu-latest
80
-
81
- if: ${{ github.event.pull_request.user.login == 'sisyphusbot' }}
82
- steps:
83
- - uses: actions/checkout@v3
84
-
85
- - name: Approve Automated PR
86
- if: startsWith(github.event.pull_request.title, '[auto')
87
- run: gh pr review --approve "$PR_URL"
88
- env:
89
- PR_URL: ${{ github.event.pull_request.html_url }}
90
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
91
-
92
- - name: Merge Automated PR
93
- if: startsWith(github.event.pull_request.title, '[auto')
94
- run: gh pr merge --auto --squash "$PR_URL"
95
- env:
96
- PR_URL: ${{ github.event.pull_request.html_url }}
97
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16
+ uses: yettoapp/actions/.github/workflows/automerge_sisyphusbot.yml@main
17
+ secrets: inherit
@@ -0,0 +1,30 @@
1
+ name: Deployments
2
+ on:
3
+ push:
4
+ branches:
5
+ - production
6
+ workflow_dispatch:
7
+ inputs:
8
+ target:
9
+ required: true
10
+ type: choice
11
+ description: The name of the environment that you're deploying the application to
12
+ options:
13
+ - staging
14
+ - production
15
+ forced:
16
+ description: "Whether to perform the deploy regardless of test state."
17
+ required: false
18
+ type: boolean
19
+ default: false
20
+
21
+ jobs:
22
+ deployment:
23
+ name: Deploy app
24
+ uses: yettoapp/actions/.github/workflows/fly_deployment.yml@main
25
+ with:
26
+ target: ${{ github.event_name != 'workflow_dispatch' && 'production' || inputs.target }}
27
+ forced: ${{ github.event_name == 'workflow_dispatch' && inputs.forced || false }}
28
+ secrets:
29
+ gh_token: ${{ secrets.GH_DEPLOYMENTS_TOKEN }}
30
+ fly_token: ${{ inputs.target == 'staging' && secrets.FLY_STAGING_API_TOKEN || secrets.FLY_PRODUCTION_API_TOKEN }}
@@ -1,43 +1,23 @@
1
- name: Update licenses
1
+ name: License
2
2
 
3
3
  on:
4
- push:
4
+ pull_request_target:
5
5
  paths:
6
- - "**/Gemfile.lock"
7
- branches:
8
- - production
9
- - staging
10
- workflow_dispatch:
6
+ - "Gemfile.lock"
7
+ - "package-lock.json"
11
8
 
12
- permissions:
13
- contents: write
14
- pull-requests: write
9
+ env:
10
+ RAILS_ENV: test
15
11
 
16
12
  jobs:
17
- license-cache:
13
+ verify:
18
14
  runs-on: ubuntu-latest
19
-
20
15
  steps:
21
16
  - uses: actions/checkout@v3
22
17
  with:
23
- ref: ${{ github.ref }}
24
-
25
- - uses: ./.github/actions/license
26
-
27
- - name: Create Pull Request
28
- uses: peter-evans/create-pull-request@v4
29
- with:
18
+ ref: ${{ github.head_ref }}
30
19
  token: ${{ secrets.GH_SISYPHUS_YETTO_REPO_TOKEN }}
31
- commit-message: "[auto-license] Update license information"
32
- title: "[auto-license] Update license information"
33
- body: |
34
- - Update license information
35
-
36
- Auto-generated by [create-pull-request][1]
37
20
 
38
- [1]: https://github.com/peter-evans/create-pull-request
39
- branch: update-licenses
40
- committer: Sisyphus <sisyphus@yetto.app>
41
- author: Sisyphus <sisyphus@yetto.app>
42
- delete-branch: true
43
- labels: 'chore, github action'
21
+ - uses: yettoapp/actions/run-license-verify@main
22
+ with:
23
+ ruby: true
@@ -2,6 +2,8 @@ name: Linting
2
2
 
3
3
  on:
4
4
  pull_request:
5
+ paths:
6
+ - "**/*.rb"
5
7
 
6
8
  env:
7
9
  RAILS_ENV: test
@@ -12,41 +14,19 @@ jobs:
12
14
  steps:
13
15
  - uses: actions/checkout@v3
14
16
 
15
- # reads from .ruby-version
16
- - uses: ruby/setup-ruby@v1
17
+ - uses: yettoapp/actions/pr-contains-files@main
18
+ id: pr_contains_ruby
17
19
  with:
18
- bundler-cache: true
19
- rubygems: latest
20
+ pr_number: ${{ github.event.number }}
21
+ pattern: ".rb$"
22
+ github_token: ${{ secrets.GITHUB_TOKEN }}
20
23
 
21
- - name: Rubocop
22
- run: bundle exec rake rubocop
23
-
24
- ruby-types:
25
- runs-on: ubuntu-latest
26
- steps:
27
- - uses: actions/checkout@v3
28
-
29
- # reads from .ruby-version
30
- - uses: ruby/setup-ruby@v1
24
+ - name: Set up Ruby
25
+ if: ${{ steps.pr_contains_ruby.outputs.exists == 'true' }}
26
+ uses: yettoapp/actions/setup-languages@main
31
27
  with:
32
- bundler-cache: true
33
- rubygems: latest
34
-
35
- - name: Sorbet
36
- id: sorbet_tc
37
- run: bundle exec srb tc
38
-
39
- - name: Provide error message
40
- if: failure() && steps.sorbet_tc.outcome == 'failure'
41
- run: |
42
- echo "Run 'bundle exec srb tc -a' to auto-correct Sorbet checks."
28
+ ruby: true
43
29
 
44
- - name: Verifying Tapioca
45
- id: tapioca_verify
46
- run: script/typecheck --verify
47
-
48
- - name: Provide error message
49
- if: failure() && steps.tapioca_verify.outcome == 'failure'
50
- run: |
51
- echo "Run 'script/typecheck --update' to update Tapioca's RBI files."
52
- echo "Run 'script/typecheck --verify' to verify that Tapioca's RBI files are up-to-date."
30
+ - name: Rubocop
31
+ if: ${{ steps.pr_contains_ruby.outputs.exists == 'true' }}
32
+ run: bundle exec rake rubocop
@@ -1,38 +1,15 @@
1
1
  name: Security
2
2
 
3
3
  on:
4
- pull_request:
4
+ workflow_dispatch:
5
+ pull_request_target:
5
6
 
6
- env:
7
- RAILS_ENV: test
8
- BUNDLE_WITH: "ci"
7
+ permissions:
8
+ pull-requests: write
9
+ contents: write
9
10
 
10
11
  jobs:
11
- bundle-audit:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v3
15
- - uses: ruby/setup-ruby@v1
16
- with:
17
- bundler-cache: true
18
- rubygems: latest
19
-
20
- # Patch-level verification for bundler.
21
- - name: Run bundle-audit
22
- run: |
23
- script/security_checks/bundle-audit
24
-
25
- brakeman: # A static analysis security vulnerability scanner for Ruby on Rails applications
26
- runs-on: ubuntu-latest
27
- steps:
28
- - uses: actions/checkout@v3
29
-
30
- - uses: ruby/setup-ruby@v1
31
- with:
32
- bundler-cache: true
33
- rubygems: latest
34
-
35
- - name: brakeman report
36
- run: |
37
- script/security_checks/brakeman
38
- cat security-results.json
12
+ ruby:
13
+ uses: yettoapp/actions/.github/workflows/ruby_security_checks.yml@main
14
+ secrets:
15
+ token: ${{ secrets.GITHUB_TOKEN }}
@@ -1,49 +1,19 @@
1
- name: Update Sorbet files
1
+ name: Sorbet
2
2
 
3
3
  on:
4
- pull_request:
4
+ pull_request_target:
5
5
  paths:
6
- - '**.rb'
7
-
8
- permissions:
9
- contents: write
10
- pull-requests: write
6
+ - "**/*.rb"
7
+ - "Gemfile.lock"
11
8
 
12
9
  jobs:
13
- trigger_tapioca_pr:
10
+ update:
14
11
  runs-on: ubuntu-latest
15
12
 
16
- env:
17
- RAILS_ENV: test
18
- REDIS_URL: redis://localhost:6379/0
19
- RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
20
- SLACK_LOG_URL: http://slack.com/the_log_room
21
-
22
- # Service containers to run; note that this is duplicated
23
- # in test.yml due to a limitation in GitHub Actions
24
- # (services can only be defined per job)
25
- services:
26
- redis:
27
- # Docker Hub image name
28
- image: redis:6.2-alpine
29
- ports: ["6379:6379"]
30
- # Set health checks to wait until redis has started
31
- options: >-
32
- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout
33
- 5s --health-retries 5
34
-
35
- if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' }}
36
13
  steps:
37
14
  - uses: actions/checkout@v3
38
15
  with:
39
16
  ref: ${{ github.head_ref }}
17
+ token: ${{ secrets.GH_SISYPHUS_YETTO_REPO_TOKEN }}
40
18
 
41
- - uses: ./.github/actions/sisyphus
42
-
43
- - uses: ./.github/actions/sorbet
44
-
45
- - name: Commit Sorbet
46
- run: |
47
- git add .
48
- git commit -m "[auto-rbi]: Update RBI files" || true
49
- git push
19
+ - uses: yettoapp/actions/run-sorbet-update@main
@@ -1,53 +1,19 @@
1
1
  name: Test
2
2
 
3
3
  on:
4
- pull_request:
4
+ workflow_dispatch:
5
+ pull_request_target:
5
6
 
6
7
  jobs:
7
8
  test:
8
9
  runs-on: ubuntu-latest
9
10
 
10
- env:
11
- RAILS_ENV: test
12
- REDIS_URL: redis://localhost:6379/0
13
- RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
14
- SLACK_LOG_URL: http://slack.com/the_log_room
15
-
16
- # Service containers to run; note that this is duplicated
17
- # in sorbet.yml due to a limitation in GitHub Actions
18
- # (services can only be defined per job)
19
- services:
20
- redis:
21
- # Docker Hub image name
22
- image: redis:6.2-alpine
23
- ports: ["6379:6379"]
24
- # Set health checks to wait until redis has started
25
- options: >-
26
- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout
27
- 5s --health-retries 5
28
-
29
11
  steps:
30
12
  - uses: actions/checkout@v3
31
13
  with:
32
- ref: ${{github.ref}} # checkout branch not SHA
33
- fetch-depth: 0
34
-
35
- - uses: ./.github/actions/setup
36
-
37
- - name: Run tests
38
- run: |
39
- script/ci
40
-
41
- test-licenses:
42
- needs: test
43
- runs-on: ubuntu-latest
44
-
45
- if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' }}
46
- steps:
47
- - uses: actions/checkout@v3
48
-
49
- - uses: ./.github/actions/setup
50
-
51
- - name: Verifying licenses
52
- run: script/licenses --verify
14
+ ref: ${{ github.head_ref }}
15
+ token: ${{ secrets.GH_SISYPHUS_YETTO_REPO_TOKEN }}
53
16
 
17
+ - uses: yettoapp/actions/run-ruby-tests@main
18
+ with:
19
+ github_token: ${{ secrets.GH_SISYPHUS_YETTO_REPO_TOKEN }}
@@ -12,6 +12,9 @@ allowed:
12
12
  ignored:
13
13
  bundler:
14
14
  - bundler-audit # GPL-3.0; but also, only used in CI/test
15
+ - date # BSD-2-Clause
16
+ - net-protocol # BSD-2-Clause
17
+ - racc # BSD-2-Clause
15
18
  - ruby2_keywords # BSD-2-Clause; ignored because of custom LICENSE text
16
19
  - sidekiq # LGPL-3.0; ignored because of custom LICENSE text
17
20
 
@@ -20,14 +23,15 @@ reviewed:
20
23
  - activerecord # MIT
21
24
  - brakeman # BRAKEMAN PUBLIC USE LICENSE
22
25
  - concurrent-ruby # MIT
23
- - date # BSD-2-Clause
26
+ - dry-core # MIT
24
27
  - dry-transformer # MIT
28
+ - faraday-net_http # MIT
25
29
  - json # BSD-2-Clause
30
+ - jwt # MIT
26
31
  - net-imap # BSD-2-Clause
27
32
  - net-pop # BSD-2-Clause
28
- - net-protocol # BSD-2-Clause
29
33
  - net-smtp # BSD-2-Clause
30
- - racc # BSD-2-Clause
34
+ - nio4r # MIT
31
35
  - timeout # BSD-2-Clause
32
36
  - websocket-driver # Apache-2.0
33
37
  - websocket-extensions # Apache-2.0
@@ -0,0 +1 @@
1
+ <%= Hephaestus::RUBY_VERSION %>
@@ -0,0 +1,79 @@
1
+ # syntax = docker/dockerfile:1
2
+
3
+ # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
4
+ ARG RUBY_VERSION=3.2.1
5
+ FROM ruby:$RUBY_VERSION-slim as base
6
+
7
+ # Rails app lives here
8
+ WORKDIR /plug-github
9
+
10
+ # Set production environment
11
+ ARG RAILS_ENV="production"
12
+ ENV RAILS_ENV=${RAILS_ENV} \
13
+ BUNDLE_WITHOUT="staging:development:test" \
14
+ BUNDLE_DEPLOYMENT="1"
15
+
16
+ # Update gems and bundler
17
+ RUN gem update --system --no-document && \
18
+ gem install -N bundler
19
+
20
+
21
+ # Throw-away build stages to reduce size of final image
22
+ FROM base as prebuild
23
+
24
+ # Install packages needed to build gems
25
+ RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
26
+ --mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
27
+ apt-get update -qq && \
28
+ apt-get install --no-install-recommends -y build-essential curl git libpq-dev libvips pkg-config python-is-python3 ca-certificates iptables iproute2
29
+
30
+
31
+ FROM prebuild as build
32
+
33
+ # Install application gems
34
+ COPY --link Gemfile Gemfile.lock .ruby-version ./
35
+ RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
36
+ bundle config set app_config .bundle && \
37
+ bundle config set path /srv/vendor && \
38
+ bundle install && \
39
+ bundle exec bootsnap precompile --gemfile && \
40
+ bundle clean && \
41
+ mkdir -p vendor && \
42
+ bundle config set path vendor && \
43
+ cp -ar /srv/vendor .
44
+
45
+ # Copy application code
46
+ COPY --link . .
47
+
48
+ # Precompile bootsnap code for faster boot times
49
+ RUN bundle exec bootsnap precompile app/ lib/
50
+
51
+ # Adjust binfiles to set current working directory
52
+ RUN grep -l '#!/usr/bin/env ruby' /plug-app/bin/* | xargs sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)'
53
+
54
+ # Final stage for app image
55
+ FROM base
56
+
57
+ # Install packages needed for deployment
58
+ RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
59
+ --mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
60
+ apt-get update -qq && \
61
+ apt-get install --no-install-recommends -y imagemagick libvips postgresql-client sudo git
62
+
63
+ # Copy built artifacts: gems, application
64
+ COPY --from=build /usr/local/bundle /usr/local/bundle
65
+ COPY --from=build /plug-app /plug-app
66
+
67
+ # Deployment options
68
+ ENV RAILS_LOG_TO_STDOUT="1" \
69
+ RAILS_SERVE_STATIC_FILES="true" \
70
+ RUBY_YJIT_ENABLE="1" \
71
+ LD_PRELOAD=${LD_PRELOAD_PATH} \
72
+ MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true"
73
+
74
+ # Entrypoint sets up the container.
75
+ ENTRYPOINT ["/plug-app/bin/docker-entrypoint"]
76
+
77
+ # Start the server by default, this can be overwritten at runtime
78
+ EXPOSE 3000
79
+ CMD ["./bin/rails", "server"]