local-compose

Easily develop and deploy multi-service software on the same origin.

$ local-compose new hello-world react express

Same-origin

A reverse proxy routes web traffic through the same origin, so configuring CORS is unnecessary:
Same-origin routing »

Managed dependencies

Languages, packages, and databases are auto-installed and isolated from other projects:
Dependency management »

Docker compatible

One simple command configures your project to run with Docker Compose:
Docker compatibility »

Platform agnostic

Mac, Windows, and Linux developers can easily collaborate on the same project:
Installation »

Framework agnostic

Javascript, Python, and Ruby frameworks are included today and more are being added:
Creating a new project »

Host agnostic

Projects can be deployed on most hosts, and deploy script generators are provided for a few:
Deploying »

OS X / Linux Install

Open your terminal and run the following command (this will prompt you for your password):

Windows Install

Open an Administrator command prompt and run the following command (requires Chocolatey):

Table of contents


Creating a new project

You may use any of the following notations to create your project. Additional details about each notation are below.

$ local-compose new <project-name> <frontend> <backend>
$ local-compose new <project-name> <frontend | backend>
$ local-compose new <project-name> [-<frontend | backend> <name> <urlPathPrefix> [...]]

Supported frontend frameworks are react

Supported backend frameworks are express, django, flask, rails, sinatra

Shorthand A: One frontend and one backend service

$ local-compose new <project-name> <frontend> <backend>

Any requests to /api/* will resolve to the backend service, and all others will resolve to the frontend service. This is typically used for building a single-page app (SPA) frontend and a REST API backend.

Shorthand B: Single service

$ local-compose new <project-name> <frontend | backend>

All requests will resolve to the single service. This is typically used for static sites, or for services with built-in rendering engines like Rails or Django.

Verbose

$ local-compose new <project-name> [-<frontend | backend> <name> <urlPathPrefix> [...]]

This notation allows for complete flexibility. Define one service at a time by providing three parameters:

-<frontend | backend> The framework used by the service.
<name> The name of the service; used as the name of the directory inside the project root.
<urlPathPrefix> Used for routing. If /api is used, all requests to /api/* will go to this service.

This is typically used for projects with more than two services, but it can also be used as an alternative to the shorthand notation.

Same-origin routing

The same-origin policy states that, by default, all traffic must be served on the same protocol, host name, and port number in order for the browser to allow an AJAX or fetch request. This often creates a challenge for software running separate frontend and backend services, since those services typically run on different origins.

There are two common solutions to this problem. The first is to configure cross-origin resource sharing (CORS) to relax the same-origin policy. The second is to run a reverse proxy to listen to all traffic on a single origin, and define rules to specify where traffic should be forwarded based on the requested path.

local-compose automatically implements a reverse proxy with every project. When a request hits the proxy, we reference .local-compose/config to determine where it should be routed. Here's an exmample config for a react and express app:

version: 0.0.1
services:
    api:
        url-path-prefix: /api/
        platform: express
        port: 10501
    spa:
        url-path-prefix: /
        platform: react
        port: 10500

Routes are matched top-to-bottom, and requests are sent to the first matching route with the prefix stripped. With those rules in mind, here are some examples for how this configuration will be processed:

Requested Resolved Notes
/ / on spa
/hello /hello on spa
/api/widgets/1 /widgets/1 on api /api was stripped from the path
/api-test /api-test on spa /api needs a trailing slash to be routed to api

Dependency management

local-compose manages its own dependency installations, including programming languages, any packages downloaded for those languages, and postgres.

When you install local-compose, you will have the option to enable "path overrides," which allows you to access dependencies without prefixing. So instead of typing local-compose rails console, you could simply use rails console.

With path overrides turn on, a managed dependency will only be used if your working directory is within a local-compose project. Outside of your project, your system will use the default installation, or fail if there is none.

For example, if you call rails console from inside your project, you will be running the local-compose version of rails. If you call rails from outside your project, your system will look for a different installation, or fail if it cannot find one.

This behavior is designed to work alongside alternative installations that may have been provided by your system, installed manually, or managed by utilities like nvm, pyenv, or rvm.

Deploying

Your project can be usually deployed on any host that supports your framework's programming language, or any host that supports Docker. Although we do not offer formal support for deploying your project, we do document the general process, as well as the process for some specific hosts (coming soon).

General deploy process

Each directory in your project root should be deployed as an individual service. We recommend following the guidelines at your host for deploying each particular framework.

If your project has more than one service, your host must also support some method for dynamically routing traffic between each service on the same origin. The most common solution is to separately run a "reverse proxy" like nginx as an additional service. However, some hosts have started offering reverse proxy functionality without configuring an additional service. Either approach is acceptable.

If your project uses a database, you will also need to deploy a postgres database with your host. After the database is created, you must set an environment varaible called DATABASE_URL for any service that requires access.

Docker compatibility

Coming soon

This is the Clerk way…

Clerk builds best-practice solutions to boring development problems. Bring your framework, bring your host — we'll bring universal tools and services to accelerate your development.

©2019 Clerk Inc.