Skip to content

Popular Frameworks

With customization of cnc, Coherence supports any technology or framework that you can imagine. Here, we're demonstrating common configurations for popular frameworks to make it easy to get started. Read more about configuration here.

React Example

services:
  dashboard:
    x-cnc:
      type: frontend
      assets_path: dist
      build: ["yarn", "build"]
    build:
      context: .

Django Example

A few important things to think about for Django:

  • Install dj-database-url package to easily get the right database configuration. You can add this to your requirements.txt file.
  • Add the CNC_ENVIRONMENT_DOMAIN and CNC_ENVIRONMENT_DOMAIN to the ALLOWED_HOSTS settings to prevent CORS issues.
  • You can configure the command to use another python WSGI server like gunicorn as well by changing the command in the yaml configuration below.

See the Environment Variables docs for more info on the variables mentioned above.

services:
  app:
    command: "python manage.py runserver 0.0.0.0:$PORT"
    x-cnc:
      type: backend
      workers:
      - name: default-queue-worker
        # REDIS_URL will be populated by the redis service below by CNC
        command: "rq worker --with-scheduler --url $REDIS_URL"
        system:
          cpu: 1
          memory: 1G
        replicas: 1
    build:
      context: .
  db:
    x-cnc:
      type: database
      version: 15
    image: postgres
  redis:
    x-cnc:
      type: cache
    image: redis

Rails Example

If you use the Nixpacks builder (the Coherence default if you don't define a Dockerfile) than the asset precomile step will be handled for you. If you write a Dockerfile be sure to include it. The /root/.profile command is needed due to how nixpacks handles ruby gem installs. You can remove that command (including the && - meaning just use bundle directly) if you use your own Dockerfile and ruby gems are available on the PATH by default.

See an example of setting up a Ruby on Rails app

services:
  rails:
    x-cnc:
      type: backend
      migrate: [".", "/root/.profile", "&&", "bundle", "exec", "rails", "server:migrate"]
      system:
        memory: 2G
        cpu: 2
    build:
      context: .
    command: [".", "/root/.profile", "&&", "bundle", "exec", "rails", "server", "-e",  "production", "-b", "0.0.0.0"]
  db1:
    x-cnc:
      type: database
      version: 14
    image: postgres

You will also want to modify the database.yml (and any other initializers you use, like S3/GCS for storage or redis for cache) to read their config from the appropriate Coherence-supplied environment variables. See the Environment Variables docs for more info on the variables. Here's a simply database.yml example:

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  url: <%= ENV["DATABASE_URL"] %>

test:
  <<: *default
  url: <%= ENV["DATABASE_URL"] %>

production:
  <<: *default
  url: <%= ENV["DATABASE_URL"] %>

You'll also want to edit the application.rb initializer and edit the allowed hosts of your app. You might already have some entries for this in environment settings (e.g. development) so be careful not to break those. These are a bit loose but are intended as an example (but they'll work):

  config.hosts = [
    IPAddr.new("10.0.0.0/8")
  ]
  config.hosts << /.*\.cncsites\.com\z/

Last, you'll also need to set any relevant environment variables required by your app, for example the SECRET_KEY_BASE variable. You can use the Coherence Variables UI to set these.

flask example

flask is a popular python web framework. This is a simple example, assuming your app does not need a database and that your app.py file runs the flask server on the PORT environment variable provided by Coherence when it is run via python. You can configure the dev or prod commands to use flask run or another python WSGI server like gunicorn as well by changing the commands in the yaml configuration below.

You can also add a database and cache easily, see the other examples on this page including the redwood and Rails examples above for syntax, nothing special needs to be done for flask itself, aside from listening to the appropriate variables to configure your database connections, e.g. DATABASE_URL.

services:
  backend:
    x-cnc:
      type: backend
    build:
      context: .
    command: "python app.py"

FastAPI example

FastAPI is a popular python web framework. In this example, you've got a postgres database and are using uvicorn to serve the application. You'd change the app:app reference to follow the path to your actual app instance as per the FastAPI docs.

The /opt/venv/bin/activate command is needed due to how nixpacks handles python installs. You can remove that command (including the &&) if you use your own Dockerfile and python packages are available on the PATH by default.

x-cnc:
  resources:
  - name: db1
    engine: postgres
    version: 15
    type: database
services:
  backend:
    x-cnc:
      type: backend
    build:
      context: .
    command: [".", "/opt/venv/bin/activate", "&&", "uvicorn", "app:app", "--port=$PORT", "--host=0.0.0.0", "--reload"]

Next.js Example

There are 2 common configurations used for Next.js. One is static export where your site ends up as single page app served from a CDN. The other (more common) configuration is where you run a server process and this configuration supports functionality such as server-side rendering, API routes, and database-backed services. See more in the Next docs.

See an example of setting up a server type

services:
  backend:
    x-cnc:
      type: backend
    build:
      context: .
    command: "npm run start"

For deploying a single page app, use a frontend service type.

services:
  frontend:
    command: ["npm", "run", "export"]
    x-cnc:
      type: frontend
    build:
      context: .

streamlit example

streamlit is a popular python framework for full-stack, data-driven apps. You'll also want to check the filename in the command below and replace streamlit_app.py with your own app.

For database connection secrets, we recommend to use Coherence Variables and use the values in generating a Connection on streamlit (for most databases this means using the kwargs in the streamlit experimental_connection).

You can see a YouTube walk-though of setting up a streamlit app from scrach

services:
  streamlit:
    command: ["streamlit", "run", "streamlit_app.py", "--server.port=$PORT", "--server.address=0.0.0.0"]
    x-cnc:
      type: backend
    build:
      context: .

You might also want to use a Dockerfile like this (otherwise we will use nixpacks and you need to do the venv commands similar to the Django example above):

FROM python:3.9-slim

WORKDIR /app

RUN apt-get update && apt-get install -y \
    build-essential \
    curl \
    software-properties-common \
    git \
    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip3 install -r requirements.txt
COPY . .

Refine

Refine is a meta-framework for react admin apps. For the most part, it should be just like a standard react app as above. You can see a live walk-thru video setting up a refine example app below!

services:
  dashboard:
    x-cnc:
      type: frontend
      assets_path: dist
      build: ["yarn", "build"]
    build:
      context: .