Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cpln config #13

Merged
merged 15 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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") %>