DevOps

Speed up your local development with Servable inline system design

Servable system design integrated Docker compose manager can automatically spin up your protocol's docker compose and expose it to your app in a breeze.

#servable
#protocols
#system design
#docker
#docker-compose

When developing a Node JS project for an API you will find yourself needing a couple of local endpoints for storing your files or accessing a database for example. Usually you'll either use a remote api made accessible to you by your team's DevOps or a local instance of the service running on Docker or Minikube. This approach comes with a few drawbacks:

  • The image configuration is specific to your machine and configuration, it is not versioned therefore any changes mande by the rest of your team will not be reflected locally.
  • You have to manually run and maintain a Docker compose and expose the port to your app

Servable System Design for Docker is here to help

Servable helps you by:

  • Letting you define on your protocol the system requirements for running not only your current Servable app, but also the extra services you need in a Docker compose file
  • By including the Docker compose file in the protocol, you make it de facto versioned and available to the rest of the team and the community
  • When Servable launches it automatically runs the desired Docker Compose configuration and stores all the files associated in the root of your Servable project at .system.
  • The .system folder is not versioned therefore what data you use for mocking or testing your API stays local
  • The .system folder can be backed up easily by copying it all along or sent to your peers to kickstart their development. It can also be versioned on your git repository even though we don't recommend it.
  • Servable automatically detects used ports and increments the target ports until a free published port is assigned. The resulting docker-compose will be stored at .system/<protocol>/docker-compose.yaml

The docker compose file in the /< protocol >/system/docker folder.

Here's an example of an app's design system:

services: app-cdn: image: bitnami/minio:latest restart: always ports: - 9010:9000 - 9011:9001 environment: MINIO_ROOT_USER: "MINIO_USERNAME_TO_CHANGE" MINIO_ROOT_PASSWORD: "MINIO_PASSWORD_TO_CHANGE" MINIO_SERVER_ACCESS_KEY: "<%= CHEATSHEET_MINIO_ACCESS_KEY %>" MINIO_SERVER_SECRET_KEY: "<%= CHEATSHEET_MINIO_SECRET %>" MINIO_DEFAULT_BUCKETS: "cheatsheets" volumes: - ./minio:/data x-servable-disabled: false app-extra-mongo: image: mongo restart: always command: mongod --bind_ip_all environment: MONGO_INITDB_ROOT_USERNAME: "<%= APP_MONGODB_USERNAME %>" MONGO_INITDB_ROOT_PASSWORD: "<%= APP_MONGODB_PASSWORD %>" MONGO_INITDB_DATABASE: "<%= APP_MONGODB_DATABASE %>" ports: - 27017:27017 volumes: - ./mongo/:/data/db mongo-gui: container_name: "mongo-gui" image: ugleiton/mongo-gui restart: always ports: - 4321:4321 environment: MONGO_URL: "mongodb://localhost:<:= app_extra_mongo_27017 :>" x-servable-disabled: true

In this example we have defined:

  • a minio deployment for storing files
  • a mongo database (note that this database is different from the one used by the engine)
  • a disabled mongo user interface for managing the mongo database

We can enable it by setting the custom servable docker var to false or by removing it:

... x-servable-disabled: false

Process env binding

In the previous example we have bound the app-extra-mongo environment to the env vars APP_MONGODB_USERNAME,APP_MONGODB_PASSWORD and APP_MONGODB_DATABASE. This happens automatically by using the ejs template "<%= MY_ENV_VAR %>". At runtime you will access your variable with usual process.env.MY_ENV_VAR This helps keep your code unchanged between environments and avoid undefined variables when moving from one evironement to another.

Published port binding

In the previous example the mongo-gui deployment's MONGO_URL is pointing to the published app-mongo 27017 port, which can be different if the port is already used. That is the reason for this custom binding template ejs template "<%= MY_DEPLOYMENT_PUBLISHED_PORT %>". Note: '-' need to be replaced by '_' in the template.

Note

  • It is recommended to declare services only in the docker-compose file. The version, the network and the name will be defined by Servable on runtime