Skip to content

Deploying Services

In this article, we will walk you through the steps on how to deploy any service on MedStack Control using the MedStack API. We will use PostgreSQL database as an example of the service that we will deploy on MedStack Control as a docker container. With this guide, you will learn how to use the MedStack API to deploy and, manage services. By the end of this article, you will have a better understanding of how to deploy your own services on MedStack Control using the MedStack API. This article will through the steps of creating volumes, secrets and then how to use them with the service that you are deploying.

Below are set of high level steps to create a PostgreSQL database service using MedStack API.

  1. Generate API Token : To generate an API token, refer to the instructions provided in the "Getting Started" article.
  2. Retrieve the COMPANY ID using the API: To retrieve the COMPANY ID using API, refer to the "Getting Started" article.
  3. Retrieve the CLUSTER ID using the API: To retrieve the CLUSTER ID using API, refer to the "Getting Started" article.
  4. Create a Docker Secret using API to store the PostgreSQL database user password
  5. Create a Volume to store the PostgreSQL DB data using the API
  6. Create a Service using MedStack API

Create a Docker Secret using API to store the PostgreSQL database user password

curl -u JBO5z2Ex78p6LmlKV6GyrnwD:HMySkImRY7I0oKX0TWBHWhjSiC9mRQnf --request POST \
  --url https://api.medstack.co/v1/companies/company_YA/clusters/cluster_LB3DGPQx/secrets \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --data '
  {
    "name": "Postgres_Password_Secret",
    "data": "myS3cur3Passw0rd"
  }'

The --data option is used to specify the data that is being sent in the request body. In this case, the request body is a JSON object with two properties: name and data. The name property represent the name of the secret and has a value of "Postgres_Password_Secret" and the data property represents the value stored inside the secret and has a value of "myS3cur3Passw0rd".

Output:

{
  "id":"secret_o3iaiq5rchg0va9p3iaz2uh3t",
  "object":"secret",
  "name":"Postgres_Password_Secret",
  "created":"2023-03-23 23:52:13 UTC"
}

Create a Volume to store the PostgreSQL DB data using the API

curl -u JBO5z2Ex78p6LmlKV6GyrnwD:HMySkImRY7I0oKX0TWBHWhjSiC9mRQnf --request POST \
  --url https://api.medstack.co/v1/companies/company_YA/clusters/cluster_LB3DGPQx/volumes \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --data '
  {
    "name": "my_postgres_data_volume"
  }'

In this case the request body is a JSON object with only one property: name. The name property represents the name of volume to be created inside MedStack Control and has a value of "my_postgres_data_volume".

Output:

{
  "id":"volume_my_postgres_data_volume",
  "object":"volume",
  "name":"my_postgres_data_volume",
  "created":"2023-03-23 23:53:47 UTC",
  "service_usage":[]
}

Create a Service using MedStack API

curl -u JBO5z2Ex78p6LmlKV6GyrnwD:HMySkImRY7I0oKX0TWBHWhjSiC9mRQnf --request POST \
  --url https://api.medstack.co/v1/companies/company_YA/clusters/cluster_LB3DGPQx/services  \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --data '
  {
    "secrets": [
    {
       "name": "Postgres_Password_Secret",
       "file_name": "/postgres_password",
       "uid": "0",
       "gid": "0",
       "mode": "400"
    }
  ],
  "mounts": [
    {
      "source": "my_postgres_data_volume",
      "target": "/var/lib/postgresql/data",
      "readonly": false
    }
  ],
    "environment_variables": [
      {
        "key": "POSTGRES_PASSWORD_FILE",
        "value": "/postgres_password"
      },
      {
        "key": "POSTGRES_USER",
        "value": "myuser"
      },
      {
        "key": "POSTGRES_DB",
        "value": "newPgDb"
      }
    ],
      "placement_constraints": [
      "node.labels.db == true"
  ],
    "name": "my-postgres-db",
    "image": "postgres:latest",
    "replicas": 1,
    "port": 5432
  }'

In this case the body contains many properties. Here are the list of properties:

  • secrets: This property is an array of objects that represent the secrets that the service needs. In this case, there is only one secret object with properties name, file_name, uid, gid, and mode.
  • mounts: This property is an array of objects that represent the volumes that the service needs to mount. In this case, there is only one volume object with properties source, target, and readonly.
    • The mount maps the specific location of the data folder for the service to the volume created in the previous section. In this case, /var/lib/postgresql/data data folder is mapped to the "my_postgres_data_volume" volume.
  • environment_variables: This property is an array of objects that represent the environment variables that the service needs. In this case, there are three environment variable objects with properties key and value.
    • The first object is the POSTGRES_PASSWORD_FILE pointing to the file generated as part of the secrets.
    • The second object is the POSTGRES_USER representing the postgres user.
    • The third object is the POSTGRES_DB representing the name of the database created when postgres container first starts up.
  • placement_constraints: This property is an array of constraints that specify where the service should be placed. In this case, there is only one constraint that specifies that the service should be placed on a node with the label db set to true.
  • name: This property specifies the name of the service.
  • image: This property specifies the Docker image that the service will use.
  • replicas: This property specifies the number of replicas that the service should have.
  • port: This property specifies the port number that the service should listen on.

Output:

{
  "id": "service_0nge17vm5j05zvjgg4ml2frip",
  "object": "service",
  "name": "my-postgres-db",
  "image": "postgres:latest@sha256:542f83919d1aa39230742a01a7dbfbe84a5c7c84c27269670ff84c0e8bb656e8",
  "replicas": 1,
  "command": "",
  "args": "",
  "hosts": [],
  "port": 5432,
  "secrets": [
    {
      "id": "k5x9o23qb6vgkzdqjm8naods9",
      "name": "Postgres_Password_Secret",
      "file_name": "/postgres_password",
      "uid": "0",
      "gid": "0",
      "mode": "400"
    }
  ],
  "configs": [],
  "environment_variables": [
    {
      "key": "POSTGRES_PASSWORD_FILE",
      "value": "/postgres_password"
    },
    {
      "key": "POSTGRES_USER",
      "value": "myuser"
    },
    {
      "key": "POSTGRES_DB",
      "value": "newPgDb"
    }
  ],
  "mounts": [
    {
      "target": "/var/lib/postgresql/data",
      "source": "my_postgres_data_volume",
      "readonly": false
    }
  ],
  "placement_constraints": ["node.labels.db == true"]
}