hephaestus 0.1.3 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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"]