The Maestrano Enterprise Engine can be included in a Rails project to bootstrap an instance of Maestrano Enterprise Express.
The goal of this engine is to provide a base that you can easily extend with custom style or logic.
- Install
- Upgrade
- Configuration
- Emailing Platform
- Intercom
- Active Job Backend
- Building the Frontend
- Modifying the style - Theme Previewer
- Extending the Frontend
- Adding a custom font
- Adding a favicon
- Replacing the Frontend
- Extending the Backend
- Overriding Models and Controllers with the Decorator Pattern
- Generating a database extension
- Deploying
- Deploy a Puma stack on EC2 via Webistrano/Capistrano
- Sample nginx config for I18n
- Health Checks
- Contributing
Install
One step install (recommended)
You can generate a complete rails project using the application template:
rails new [project_name] -TOJ -m https://raw.githubusercontent.com/maestrano/mno-enterprise/master/rails-template/mnoe-app-template.rb
For more details see the template README.
Manual Install
Create a new rails project:
rails new name-enterprise
Add mno-enterprise to your Gemfile.
# Maestrano Enterprise Engine
gem 'mno-enterprise', '~> 3.0'
Run the install script
rails g mno_enterprise:install
The install script will perform three things:
- Generate an initializer for Maestrano Enterprise (config/initializers/mno_enterprise.rb)
- Install and build the mno-enterprise-angular frontend
- Install and build the admin dashboard frontend
- Create a /frontend directory in your application for all frontend customisations/overrides
Manual Node setup (optional): Building the frontend requires you to have nodejs and yarn installed. While the rake task will attempt to install these dependencies, you may want to install these manually prior to running the install task. See the nodejs and yarn websites for instructions on how install them on your machine.
Once node is installed, you can run the following commands to ensure that all dependencies are installed:
bin/rake mnoe:frontend:install_dependencies
Upgrade
We follow Semantic Versioning so upgrading to a compatible version should be straightforward.
For major upgrade between versions see UPGRADING.
Configuration
Emailing platform
Maestrano Enterprise supports either Mandrill or SparkPost as well as regular SMTP.
You can use either provider as long as your account has the required templates.
If you want to copy the default templates to your own account you can use the tools in tools/emails
.
Mandrill
# Gemfile
gem 'mandrill-api', '~> 1.0.53'
# config/application.yml
MANDRILL_API_KEY: api_key
# config/initializers/mno_enterprise.rb
MnoEnterprise.configure do |config|
config.mail_adapter = :mandrill
end
SparkPost
# Gemfile
gem 'sparkpost', '~> 0.1.4'
# config/application.yml
SPARKPOST_API_KEY: api_key
# config/initializers/mno_enterprise.rb
MnoEnterprise.configure do |config|
config.mail_adapter = :sparkpost
end
SMTP
It's also possible to use a regular SMTP server. In this case, Maestrano Enterprise will use the templates bundled within the gem, see the next section to customise them.
# Gemfile
gem 'premailer-rails'
# config/application.rb
Rails.application.configure do
# Email configuration
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: ENV['SMTP_HOST'],
port: ENV['SMTP_PORT'],
domain: ENV['SMTP_DOMAIN'],
user_name: ENV['SMTP_USERNAME'],
password: ENV['SMTP_PASSWORD'],
authentication: 'plain',
enable_starttls_auto: true
}
end
# config/environments/<production|uat>.rb
Rails.application.configure do
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default_url_options = { host: host_domain, port: port_number }
config.action_mailer.asset_host = your_apps_root_url
end
# config/initializers/mno_enterprise.rb
MnoEnterprise.configure do |config|
config.mail_adapter = :smtp
end
# config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( mno_enterprise/mail.css )
In this example, the SMTP server settings are passed via environment variables. See sample configurations below.
Gmail
If you don't have access to a SMTP server, a personal Gmail account can be used as an alternative. The Gmail account should be set to allow "less secure apps".
# config/application.yml
SMTP_HOST: smtp.gmail.com
SMTP_PORT: 587
SMTP_DOMAIN: gmail.com
SMTP_USERNAME: user@gmail.com
SMTP_PASSWORD: password
Mailgun
Mailgun provides an SMTP mode and allow you to manage multiple domain within the same account.
# config/application.yml
SMTP_HOST: smtp.mailgun.org
SMTP_PORT: 587
SMTP_DOMAIN: mg.acme-enterprise-mnoe-uat.maestrano.io
SMTP_USERNAME:
SMTP_PASSWORD:
Customization of mail templates
- You can override the default mail templates by adding template files (
template-name.html.erb
,template-name.text.erb
) to the mail view directory (/app/views/system_notifications
). - Logo can also be overridden by adding your own logo image (
main-logo.png
) to the image assets directory (/app/assets/images/mno_enterprise
). - Write your own stylesheet by adding a
mail.css
file to the stylesheets directory (/app/assets/stylesheets/mno_enterprise
). The css rules you write will be applied to all the mail templates including the default ones.
Intercom
Intercom is already integrated in mno-enterprise, you just need to enable it!
Add the gem to your Gemfile
gem 'intercom', '~> 3.5.4'
Expose the following environments variables (via application.yml
or your preferred method)
INTERCOM_APP_ID
INTERCOM_TOKEN
If you want to enable secure mode (recommended), expose INTERCOM_API_SECRET
.
If you built your app with an older version of mno-enterprise, double-check that config/initializer/mno-enteprise.rb
contains the following lines:
# Intercom
config.intercom_app_id = ENV['INTERCOM_APP_ID']
config.intercom_api_secret = ENV['INTERCOM_API_SECRET']
config.intercom_token = ENV['INTERCOM_TOKEN']
(Deprecated) Using API Keys
Expose the following environments variables (via application.yml
or your preferred method)
INTERCOM_APP_ID
INTERCOM_API_KEY
INTERCOM_API_SECRET
If you built your app with an older version of mno-enterprise, double-check that config/initializer/mno-enteprise.rb
contains the following lines:
# Intercom
config.intercom_app_id = ENV['INTERCOM_APP_ID']
config.intercom_api_secret = ENV['INTERCOM_API_SECRET']
config.intercom_api_key = ENV['INTERCOM_API_KEY']
Active Job Backend
Maestrano Enterprise uses Active Job to process background jobs such as logging event or emails.
By default if no adapter is set, the jobs are immediately executed.
To see an up-to-date list of all queueing backend supported by Active Job see the documentation for Active Job
Sucker Punch
This is the easiest as it runs within the application process, so you don't have to maintain a separate process to run background jobs.
Add this line to your application's Gemfile
:
gem 'sucker_punch', '~> 2.0'
To enable backward compatibility with ActiveJob 4.2, create the following initializer:
# config/initializers/sucker_punch.rb
require 'sucker_punch/async_syntax'
Then in config/application.rb
:
# Use Sucker Punch for ActiveJob
config.active_job.queue_adapter = :sucker_punch
Sidekiq
This is more involved as you need to manage a separate process (the sidekiq worker) and add Redis to your stack.
Here's a quick start guide, see https://github.com/mperham/sidekiq/wiki/Active-Job for more details.
Add this line to your application's Gemfile
:
gem 'sidekiq'
Create a config/sidekiq.yml
:
---
:queues:
- default
- mailers
In config/application.rb
:
# Use Sidekiq for ActiveJob
config.active_job.queue_adapter = :sidekiq
Run the worker process, if you use a Procfile
you can add the following line to it:
worker: bundle exec sidekiq
To enable the web interface only for admin, add to your Gemfile
:
gem 'sinatra', '~> 1.4.7', require: false
and to config/routes.rb
:
Rails.application.routes.draw do
...
#================================================
# Sidekiq admin interface
#================================================
require 'sidekiq/web'
authenticate :user, -> (u) { u.admin_role == 'admin' } do
mount Sidekiq::Web, at: '/sidekiq'
end
...
end
Building the frontend
The Maestrano Enterprise frontend is a Single Page Application (SPA) that is separate from the Rails project. The source code for this frontend can be found on the mno-enterprise-angular Github repository
Build the frontend by running the following command:
bin/rake mnoe:frontend:build
This will create a "dashboard" directory under the /public folder with the compiled frontend.
Building the frontend is only required if you modify the CSS and/or JavaScripts files under /frontend.
Upgrading the frontend
To upgrade the frontend version, edit the package.json
file if needed, then run:
bin/rake mnoe:frontend:update
This will upgrade the frontend version, respecting the constraint in package.json
, and rebuild it.
Modifying the style - Theme Previewer
The Maestrano Enterprise Express frontend is bundled with a Theme Previewer allowing you to easily modify and save the style of an Express instance without reloading the page.
The Theme Previewer is available by accessing the following path: /dashboard/theme-previewer.html
e.g.: http://localhost:7000/dashboard/theme-previewer.html
Under the hood this Theme Previewer will modify the LESS files located under the /frontend directory.
Two types of "save" actions are available in the Theme Previewer.
Save:
This action will temporarily save the current style in /frontend/src/app/stylesheets/theme-previewer-tmp.less so as to keep it across page reloads on the Theme Previewer only. This action will NOT publish the style, meaning that it will NOT apply the style to the /dashboard/index.html page.
Publish:
This action will save the current style in /frontend/src/app/stylesheets/theme-previewer-published.less and rebuild the whole frontend. This action WILL publish the style, meaning that it WILL apply the style to the /dashboard/index.html page.
Extending the Frontend
You can easily override or extend the Frontend by adding files to the /frontend directory. All files in this directory will be taken into account during the frontend build and will override the base files of the mno-enterprise-angular project. You can also override the login page background adding an image and gif loaders, which is managed by rails, including the files into the path ../app/assets/images/mno_enterprise. You can generate really cool gifs for this task in pages like http://loading.io/ .
Files in this folder MUST follow the mno-enterprise-angular directory structure. For example, you can override the application layout by creating /frontend/src/app/views/layout.html in your project - it will override the original src/app/views/layout.yml file of the mno-enterprise-angular project.
You can also add new files to this directory such as adding new views. This allows you to easily extend the current frontend to suit your needs.
While extending the frontend, you can run this command to start the frontend using gulp serve and automatically override the original files with the ones in the frontend folder(be aware it does not take into account images or folders):
foreman start -f Procfile.dev
This will accelerate your development as the gulp serve task use BrowserSync to reload the browser any time a file is changed.
Adding a custom font
It is possible to add custom fonts, shared all over the rails application screens and the AngularJS SPA.
Simply copy the font files under the directory /frontend/src/fonts/
of your host application and create a font-faces.less
file containing your font-face definitions.
An example of a project using a custom font can be seen on the mno-enterprise-demo project.
NB: Your host project may have been generated or created before the implementation of this feature, in this case make sure the file /app/assets/stylesheets/main.less
contains:
// Import custom fonts
//--------------------------------------------
@import "../../../frontend/src/fonts/font-faces";
Adding favicon
Use http://www.favicon-generator.org/ to generate all the favicon and put them in frontend/src/images/favicons
Replacing the Frontend
In some cases you may decide that the current mno-enterprise-angular frontend is not appropriate at all.
In this case we recommend cloning or copying the mno-enterprise-angular repository in a new repository so as to keep the directory structure and build (Gulp) process. From there you can completely change the frontend appearance to fit your needs.
Once done you can replace the frontend source by specifying your frontend github repository in the /package.json file. You can then build it by running the usual:
bin/rake mnoe:frontend:build
Extending the Backend
Overriding Models and Controllers with the Decorator Pattern
mno-enteprise
follows the decorator pattern recommended in the Engine Rails guide
Using ActiveSupport::Concern
Most of mno-enteprise
classes use ActiveSupport::Concern
making it really easy to extend them.
For example look at the following MnoEnterprise::Organization
class:
module MnoEnterprise
class Organization < BaseResource
include MnoEnterprise::Concerns::Models::Organization
end
end
Let's say we want to add an extra method, a scope and not allow removal of users:
# foobar-enterprise/app/models/mno_enterprise/organization.rb
module MnoEnterprise
class Organization < BaseResource
include MnoEnterprise::Concerns::Models::Organization
scope :big, -> { where('size.gt': 10) }
def monkey_patched?
true
end
# PATCH: do nothing
def remove_user(user)
end
end
end
Using Class#class_eval
Sometime the class you want to extend does not use a Concern. In this case, you can use Class#class_eval
.
For example, to override the after_sign_in_path
:
# foobar-enterprise/app/decorators/controllers/mno_enterprise/application_controller_decorator.rb
MnoEnterprise::ApplicationController.class_eval do
# Patch: return to custom url
def after_sign_in_path_for(resource)
"my_custom_url"
end
end
All decorators matching the glob Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb")
are automatically loaded.
Generating a database extension
If you want to add fields to existing models, you can create a database extension for it.
rails g mno_enterprise:database_extension Model field:type
eg:
rails g mno_enterprise:database_extension Organization growth_type:string
Deploying
Deploy a Puma stack on EC2 via Webistrano/Capistrano
IMPORTANT NOTE: These are legacy instructions. They will soon be replaced by Docker instructions.
First, prepare your server. You will find a pre-made AMI on our AWS accounts called "AppServer" or "Rails Stack" that you can use.
Then, setup your new project via webistrano/capistrano.
When you're done, you can prepare the project by running the following generator for each environment your need to deploy (uat, production etc.)
# rails g mno_enterprise:puma_stack <environment>
$ rails g mno_enterprise:puma_stack production
This generator creates a script folder with all the configuration files required by nginx, puma, upstart and monit.
Perform a deploy:update via webistrano/capistrano (which will certainly fail). The whole codebase will be copied to the server.
Login to the server then run the following setup script
# sh /apps/<project-name>/current/scripts/<environment>/setup.sh
$ sh /apps/my-super-app/current/scripts/production/setup.sh
This script will setup a bunch of symlinks for nginx, upstart and monit pointing to the config files located under the scripts directory created previously.
That's it. You should be done!
Sample nginx config for I18n
We need to accept URIs like /en/dashboard
and serve public/dashboard/index.html
.
A simple combination of location regex and try_files does the trick.
server {
listen 80;
server_name mnoe.mno.local;
root /apps/<%= app_name %>/current/public;
index index.html index.htm;
location ~* "^/[A-Za-z]{2}/dashboard(.*)" {
try_files /dashboard$1/index.html /dashboard$1.html /dashboard$1 @backend;
}
try_files $uri/index.html $uri.html $uri @backend;
Health Checks
There are various endpoints to perform health checks:
/mnoe/ping
: A simple check to see that the app is up. Returns {status: 'Ok'}
/mnoe/version
: Version check. It will returns the version of the different components (app & mnoe gem):
{
"app-version": "9061048-6811c4a",
"mno-enterprise-version": "0.0.1",
"env": "test",
"mno-api-host": "https://api-hub.maestrano.com"
}
/mnoe/health_check
& /mnoe/health_check/full
: Complete health check (cache, smtp, database, ...).
See health_check and the initalizer for the default configuration.
You can override it by creating an initalizer in the host app, eg:
# my-mnoe-app/config/initializers/health_check.rb
HealthCheck.setup do |config|
# You can customize which checks happen on a standard health check
config.standard_checks = %w(cache site)
# You can set what tests are run with the 'full' or 'all' parameter
config.full_checks = %w(cache site custom database migrations)
end
Contributing
Contributing to MnoEnterprise
We love pull requests from everyone. Here are some ways you can contribute:
- by using alpha, beta, and prerelease versions
- by reporting bugs
- by suggesting new features
- by writing or editing documentation
- by writing specifications
- by writing code ( no patch is too small : fix typos, add comments, clean up inconsistent whitespace )
- by refactoring code
- by closing issues
- by reviewing patches
Submitting an Issue
We use the GitHub issue tracker to track bugs and features. Before submitting a bug report or feature request, check to make sure it hasn't already been submitted. When submitting a bug report, please include a Gist that includes a stack trace and any details that may be necessary to reproduce the bug, including your gem version, Ruby version, and operating system. Ideally, a bug report should include a pull request with failing specs.
Submitting a Pull Request
- Fork the official repository.
- Create a topic branch.
- Write tests for your feature/bug.
- Implement your feature or bug fix.
- Run the specs with:
bundle exec rake test
- Add, commit, and push your changes.
- Submit a pull request.
Notes
- Please add tests if you changed code. Contributions without tests won't be accepted.
- Please don't update the Gem version.
Inspired by https://github.com/thoughtbot/factory_girl/blob/master/CONTRIBUTING.md