From 5b6bc8334bef9d3bfa4f43e11f201871f36b4a50 Mon Sep 17 00:00:00 2001
From: Mostafa Ahangarha <ahangarha@riseup.net>
Date: Fri, 8 Dec 2023 08:01:35 +0330
Subject: [PATCH] Add cpln config (#13)

* Add config files based on RWRT

* Remove copying client directory

* Remove uglifier for js compression

* Add storage config

* Use right name for the app name in docs

* Set capacityAI to true

* Fix copy destination for package.json
---
 .controlplane/Dockerfile          |  40 +++++++++++
 .controlplane/controlplane.yml    |  19 +++++
 .controlplane/readme.md           | 113 ++++++++++++++++++++++++++++++
 .controlplane/templates/gvc.yml   |  18 +++++
 .controlplane/templates/rails.yml |  36 ++++++++++
 Gemfile                           |   2 -
 Gemfile.lock                      |   3 -
 config/environments/production.rb |   2 +-
 config/storage.yml                |   7 ++
 9 files changed, 234 insertions(+), 6 deletions(-)
 create mode 100644 .controlplane/Dockerfile
 create mode 100644 .controlplane/controlplane.yml
 create mode 100644 .controlplane/readme.md
 create mode 100644 .controlplane/templates/gvc.yml
 create mode 100644 .controlplane/templates/rails.yml
 create mode 100644 config/storage.yml

diff --git a/.controlplane/Dockerfile b/.controlplane/Dockerfile
new file mode 100644
index 0000000..1eb9037
--- /dev/null
+++ b/.controlplane/Dockerfile
@@ -0,0 +1,40 @@
+FROM ruby:3.1.2
+
+RUN apt-get update
+
+# install node and yarn
+RUN curl -sL https://deb.nodesource.com/setup_18.x | bash
+RUN apt-get install -y nodejs
+RUN npm install -g yarn
+
+WORKDIR /app
+
+# install ruby gems
+COPY Gemfile* ./
+
+RUN bundle config set without 'development test' && \
+    bundle config set with 'staging production' && \
+    bundle install --jobs=3 --retry=3
+
+# install node packages
+COPY package.json yarn.lock ./
+RUN yarn install
+
+# pick necessary app files
+COPY Gemfile* config.ru Rakefile babel.config.js postcss.config.js ./
+COPY app ./app
+COPY bin ./bin
+COPY config ./config
+COPY db ./db
+COPY lib ./lib
+COPY public ./public
+
+ENV RAILS_ENV=production
+ENV NODE_ENV=production
+
+# compiling assets requires any value for ENV of SECRET_KEY_BASE
+ENV SECRET_KEY_BASE=NOT_USED_NON_BLANK
+
+RUN rails assets:precompile
+
+CMD ["rails", "s"]
diff --git a/.controlplane/controlplane.yml b/.controlplane/controlplane.yml
new file mode 100644
index 0000000..37c35b5
--- /dev/null
+++ b/.controlplane/controlplane.yml
@@ -0,0 +1,19 @@
+# Configuration for "Heroku to CPLN playbook" custom scripts
+aliases:
+  common: &common
+    # Change this to your org name for staging. Production apps will use a different org
+    # for security.
+    cpln_org: shakacode-open-source-examples
+    # Change `shakacode-staging` to your-org-name-for-staging
+    # Example apps use only location. CPLN offers the ability to use multiple locations.
+    default_location: aws-us-east-2
+    # Configure the workload name used as a template for one-off scripts, like a Heroku one-off dyno.
+    one_off_workload: rails
+    # Like the entries in the Heroku Procfile that get deployed when the application code changes
+    # and the application image updates.
+    app_workloads:
+      - rails
+
+apps:
+  react-rails-example-app:
+    <<: *common
diff --git a/.controlplane/readme.md b/.controlplane/readme.md
new file mode 100644
index 0000000..a971e4f
--- /dev/null
+++ b/.controlplane/readme.md
@@ -0,0 +1,113 @@
+# Deploying tutorial app on Control Plane
+
+## Overview
+This simple example shows how to deploy a simple app on Control Plane using the `cpl` gem.
+
+To maximize simplicity,
+this example creates Postgres and Redis as workloads in the same GVC as the app.
+In a real app,
+you would likely use persistent,
+external resources,
+such as AWS RDS and AWS ElastiCache.
+
+You can see the definition of Postgres and Redis in the `.controlplane/templates` directory.
+
+## Prerequisites
+
+1. Ensure your
+[Control Plane](https://controlplane.com)
+account is set up.
+
+2. Set up an `organization` for testing in that account
+and modify `aliases.common.cpln_org` in `.controlplane/controlplane.yml`.
+
+3. Install Control Plane CLI (and configure access)
+[docs here](https://docs.controlplane.com/quickstart/quick-start-3-cli#getting-started-with-the-cli).
+You can update the `cpln` command line with the same command as installation,
+`npm install -g @controlplane/cli`.
+Then run `cpln login` to ensure access.
+
+4. Install
+[Heroku to Control Plane](https://github.com/shakacode/heroku-to-control-plane)
+playbook CLI
+[`cpl` gem](https://rubygems.org/gems/cpl)
+on your project's Gemfile or globally.
+
+5. This project has a `Dockerfile` for Control Plane in this directory.
+You can use it as an example for your project.
+Ensure that you have Docker running.
+
+## Tips
+Do not confuse the `cpl` CLI with the `cpln` CLI.
+The `cpl` CLI is the Heroku to Control Plane playbook CLI.
+The `cpln` CLI is the Control Plane CLI.
+
+## Project Configuration
+See the filese in the `./controlplane` directory.
+
+1. `/templates`: defines the objects created with the `cpl setup` command.
+2. `/controlplane.yml`: defines the organization, location, and app name.
+3. `Dockerfile`: defines the Docker image used to run the app on Control Plane.
+4. `entrypoint.sh`: defines the entrypoint script used to run the app on Control Plane.
+
+## Setup and run
+
+Check if the Control Plane organization and location are correct in `.controlplane/controlplane.yml`.
+You should be able to see this information in the Control Plane UI.
+
+```sh
+# Note, below commands use `cpl` which is the Heroku to Control Plane playbook script.
+
+# Provision all infrastructure on Control Plane.
+# app react-rails-example-app will be created per definition in .controlplane/controlplane.yml
+cpl apply-template gvc rails -a react-rails-example-app
+
+# Build and push docker image to Control Plane repository
+# Note, may take many minutes. Be patient.
+cpl build-image -a react-rails-example-app
+
+# Promote image to app after running `cpl build-image command`
+cpl deploy-image -a react-rails-example-app
+
+# See how app is starting up
+cpl logs -a react-rails-example-app
+
+# Open app in browser (once it has started up)
+cpl open -a react-rails-example-app
+```
+
+Notice that in the first attempt to build the image, you may get it interrupted with a message like this:
+
+```
+89c3244a87b2: Waiting
+80231db1194c: Waiting
+f1c1f2298584: Waiting
+ccba29d69370: Waiting
+unsupported:
+***  You are trying to push/pull to your org's private registry in Control Plane.  ***
+***  First, grant docker access the registry using the 'cpln' command:             ***
+
+       cpln image docker-login --org react-rails-example-app
+```
+
+Run the given command as instructed and repeat the `build-image` command.
+
+## Promoting code upgrades
+
+```sh
+# Build and push new image with sequential image tagging, e.g. 'ror-tutorial_123'
+cpl build-image -a react-rails-example-app
+
+# OR
+# Build and push with sequential image tagging and commit SHA, e.g. 'ror-tutorial_123_ABCD'
+cpl build-image -a react-rails-example-app --commit ABCD
+
+# Run database migrations (or other release tasks) with latest image,
+# while app is still running on previous image.
+# This is analogous to the release phase.
+cpl runner rails db:migrate -a react-rails-example-app --image latest
+
+# Pomote latest image to app
+cpl deploy-image -a react-rails-example-app
+```
+
diff --git a/.controlplane/templates/gvc.yml b/.controlplane/templates/gvc.yml
new file mode 100644
index 0000000..12cc335
--- /dev/null
+++ b/.controlplane/templates/gvc.yml
@@ -0,0 +1,18 @@
+# Template setup of the GVC, roughly corresponding to a Heroku app
+kind: gvc
+name: APP_GVC
+spec:
+  # For using templates for test apps, put ENV values here, stored in git repo.
+  # Production apps will have values configured manually after app creation.
+  env:
+    - name: RAILS_ENV
+      value: production
+    - name: NODE_ENV
+      value: production
+    - name: RAILS_SERVE_STATIC_FILES
+      value: 'true'
+
+  # Part of standard configuration
+  staticPlacement:
+    locationLinks:
+      - /org/APP_ORG/location/APP_LOCATION
diff --git a/.controlplane/templates/rails.yml b/.controlplane/templates/rails.yml
new file mode 100644
index 0000000..a677384
--- /dev/null
+++ b/.controlplane/templates/rails.yml
@@ -0,0 +1,36 @@
+# Template setup of Rails server workload, roughly corresponding to Heroku dyno
+# type within Procfile.
+kind: workload
+name: rails
+spec:
+  type: standard
+  containers:
+    - name: rails
+      # 300m is a good starting place for a test app. You can experiment with CPU configuration
+      # once your app is running.
+      cpu: 300m
+      env:
+        - name: LOG_LEVEL
+          value: debug
+      # Inherit other ENV values from GVC
+      inheritEnv: true
+      image: '/org/APP_ORG/image/APP_IMAGE'
+      # 512 corresponds to a standard 1x dyno type
+      memory: 512Mi
+      ports:
+        - number: 3000
+          protocol: http
+  defaultOptions:
+    # Start out like this for "test apps"
+    autoscaling:
+      # Max of 1 effectively disables autoscaling, so like a Heroku dyno count of 1
+      maxScale: 1
+    capacityAI: true
+  firewallConfig:
+    external:
+      # Default to allow public access to Rails server
+      inboundAllowCIDR:
+        - 0.0.0.0/0
+      # Could configure outbound for more security
+      outboundAllowCIDR:
+        - 0.0.0.0/0
diff --git a/Gemfile b/Gemfile
index 21ed879..389713d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -13,8 +13,6 @@ gem 'sqlite3'
 gem 'puma', '~> 5.0'
 # Use SCSS for stylesheets
 gem 'sass-rails', '~> 5.0'
-# Use Uglifier as compressor for JavaScript assets
-gem 'uglifier', '>= 1.3.0'
 # Transpile app-like JavaScript. Read more: https://github.com/shakacode/shakapacker
 gem 'shakapacker', '7.0.2'
 # See https://github.com/rails/execjs#readme for more supported runtimes
diff --git a/Gemfile.lock b/Gemfile.lock
index 4931d3d..b6b64fa 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -241,8 +241,6 @@ GEM
     turbolinks-source (5.2.0)
     tzinfo (2.0.6)
       concurrent-ruby (~> 1.0)
-    uglifier (4.2.0)
-      execjs (>= 0.3.0, < 3)
     web-console (4.2.0)
       actionview (>= 6.0.0)
       activemodel (>= 6.0.0)
@@ -275,7 +273,6 @@ DEPENDENCIES
   sqlite3
   turbolinks (~> 5)
   tzinfo-data
-  uglifier (>= 1.3.0)
   web-console (>= 3.3.0)
 
 BUNDLED WITH
diff --git a/config/environments/production.rb b/config/environments/production.rb
index ed7778f..dc63d34 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -24,7 +24,7 @@
   config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
 
   # Compress JavaScripts and CSS.
-  config.assets.js_compressor = :uglifier
+  # config.assets.js_compressor = :uglifier
   # config.assets.css_compressor = :sass
 
   # Do not fallback to assets pipeline if a precompiled asset is missed.
diff --git a/config/storage.yml b/config/storage.yml
new file mode 100644
index 0000000..695f17b
--- /dev/null
+++ b/config/storage.yml
@@ -0,0 +1,7 @@
+test:
+  service: Disk
+  root: <%= Rails.root.join("tmp/storage") %>
+
+local:
+  service: Disk
+  root: <%= Rails.root.join("storage") %>