An app can be configured purely using code instead of adding all the configuration via the UI.

ShapeBlock looks for an .sb.yml or .sb.yaml file in the top level directory of your code base.

This is a YAML file where you can configure:

  • Build variables
  • Secrets
  • Environment variables
  • Volumes
  • Services
  • Init processes
  • Worker processes

It is not compulsory to have a .sb.yaml file in your app’s code base. You can still configure these parameters from the UI, this feature is offered as a convenience to quicly deploy an application.

Here’s a sample .sb.yml for a Flask application which uses Redis.

env_vars:
  FLASK_APP: app.py
  FLASK_RUN_HOST: 0.0.0.0
  FLASK_RUN_PORT: "8080"

services:
  data-cache:
    type: redis
    attach_as: separate_variables
  svc-1:
    type: redis
    attach_as: url

How to write your own

Build variables

These are buildpack specific variables which you provide for your application and they have the “key: value” syntax under the build_vars section.

If any value resembles an integer, boolean or a decimal, you have to enclose it in double quotes so that it is interpreted as a string.

For instance, the FLASK_RUN_PORT in the above example is an integer, but enclosed in quotes.

An example of a build variables section.

build_vars:
  BP_NODE_RUN_SCRIPTS: build
  BP_WEB_SERVER: nginx
  BP_WEB_SERVER_ROOT: build
  BP_WEB_SERVER_ENABLE_PUSH_STATE: "true"

Note the true boolean given as a string within double quotes.

Environment variables

These are runtime variables which are consumed by your application when it starts running. These can be provided under the env_vars section. The same syntax rules for build variables apply to runtime variables as well.

Secrets

This is a list of environment variables which are passed on as secrets. As opposed to environment and build variables, these don’t have any values. You will add the value of the secret when you create the application in the UI. Secrets are provided under the secrets section. Here’s an example.

secrets:
  - JWT_TOKEN
  - MAIL_API_KEY

Volumes

If you want to mount any persistent volumes in your application, you give those details here, under the volumes section. It has 3 parameters:

  • The name of the volume, which is the key
  • the absolute path where it will be mounted in the container(This must start with /workspace)
  • The size of the volume, an integer parameter. Units are in GiB and need not be specified.

An example volumes section.

volumes:
  public-files:
    mount_path: /workspace/data/public-files
    size: 2
  private-files:
    mount_path: /workspace/data/private
    size: 2

Services

You give any service which you want to consume in your application here. These services will be created and attached to your application. Services have 3 parameters:

  • name of the service, given as a key
  • type of service(only mysql, postgres, mongodb and redis are supported values)
  • how the service is attached to the app. It is attached as runtime environment variables in all cases. If the value of this parameter is separate_variables, all the service parameters will be attached as separate variables. If this parameter is url, the service parameters will be modelled as a URL string.

Ex: mysql://shapeblock:shapeblock@your-service-name/shapeblock

An example services section.

services:
  data-cache:
    type: redis
    attach_as: separate_variables
  app-db:
    type: mysql
    attach_as: url

Init processes

You can define init processes defined in your Procfile, along with the resource usage. These will be defined under the init section. Here’s an example of the same:

init:
  build-css:
    resources:
      cpu: "1000m"
      memory: "1Gi"
  migrate:
    resources:
      cpu: "500m"
      memory: "512Mi"

Please ensure that you have defined the build-css and migrate processes in your app’s Procfile.

These processes are temporary containers which run a task and exit before booting the main container. If any of your init processes fails, your application will fail to deploy. Ensure that these start and run within 2-3 minutes.

Worker processes

You can also define background worker jobs under the workers section. Similar to init processes, these should have entries in your app’s Procfile.

Here’s an example.

workers:
  celery:
    resources:
      cpu: "1000m"
      memory: "1Gi"
  celery-beat:
    resources:
      cpu: "500m"
      memory: "512Mi"

This will spawn 2 workers with the above resource specifications. They will run independent of your app container.