Skip to content

Commit

Permalink
Add cpln config (#13)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
ahangarha authored Dec 8, 2023
1 parent 326e416 commit 5b6bc83
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 6 deletions.
40 changes: 40 additions & 0 deletions .controlplane/Dockerfile
Original file line number Diff line number Diff line change
@@ -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"]
19 changes: 19 additions & 0 deletions .controlplane/controlplane.yml
Original file line number Diff line number Diff line change
@@ -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
113 changes: 113 additions & 0 deletions .controlplane/readme.md
Original file line number Diff line number Diff line change
@@ -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
```

18 changes: 18 additions & 0 deletions .controlplane/templates/gvc.yml
Original file line number Diff line number Diff line change
@@ -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
36 changes: 36 additions & 0 deletions .controlplane/templates/rails.yml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 0 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -275,7 +273,6 @@ DEPENDENCIES
sqlite3
turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
web-console (>= 3.3.0)

BUNDLED WITH
Expand Down
2 changes: 1 addition & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions config/storage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>

local:
service: Disk
root: <%= Rails.root.join("storage") %>

0 comments on commit 5b6bc83

Please sign in to comment.