Deploy Prisma to DigitalOcean with Docker Machine
3 votes
184 views
by Nikolas Burk

Introduction

In this tutorial, you will learn how to create a Prisma server on DigitalOcean and deploy your Prisma services to it.

DigitalOcean is an easy-to-use provider of virtual servers. They offer configurable compute units of various sizes, called Droplets.

The setup described in this tutorial does not include features you would normally expect from production-ready servers, such as automated backups and active failover. We will add more guides in the future describing a more complete setup suitable for production use.

1. Install Docker & Docker Machine

The first thing you need to is install Docker and Docker Machine. The easiest way to install theses tools is by following the step in the Docker Docs directly.

Step 1

Follow the instructions (steps 1 through 3) at https://docs.docker.com/machine/install-machine/#install-machine-directly to install Docker as well as Docker Machine.

Once you're done, you should be able to run the following command which will output the version of docker-machine:

docker-machine -v

For example

docker-machine version 0.15.0, build b48dc28d

2. Register at DigitalOcean

Step 2

If you haven't already, you need to start by creating an account at for DigitalOcean. You can do so here.

Once you have your account available, you need to generate a personal access token which is needed to create your Droplet.

Step 3

Follow the instructions here to obtain your personal access token.

Make sure to save the token, it will soon disappear after creating it and you'll need it in the next step.

3. Create your DigitalOcean Droplet

You can now go ahead and create your Droplet. The personal access token from the previous step will be used to associate the Droplet with your DigitalOcean account.

Step 4

In your terminal, use docker-machine create to create your Droplet using the digitalocean driver. Note that you need to replace the __TOKEN__ placeholder with your personal access token from the previous step:

docker-machine create --driver digitalocean --digitalocean-access-token __TOKEN__ --digitalocean-size 1gb prisma

This will take a few minutes.

The --digitalocean-size 1gb argument indicates that the Droplet receives 1GB of memory. The last argument of the command, prisma, determines the name of the Droplet.

You will now have a running Droplet that can be controlled by docker-machine. You can list your current Droplets by running the following command:

docker-machine ls

4. Install Prisma on your Droplet

Now that you have your Droplet up and running, you can install Prisma on it. As the Prisma infrastructure runs on Docker, you could theoretically do this by using the Docker CLI directly. In that case, you could use the Docker Compose file as foundation and run the required commands (e.g. docker-compose up -d) yourself.

The Prisma CLI offers commands that you can use for convenience so you do not have to fiddle with Docker yourself. In this tutorial, you'll take advantage of these commands - under the hood they will simply configure your Docker environment and invoke the required CLI commands.

The docker CLI is a client that allows to create and manage your Docker containers on a dedicated host machine. By default, that host machine is your local machine (localhost). However, using docker-machine you can point the docker CLI to run against a different host. Meaning that all your docker commands (including docker-compose) can be executed to a remote machine over the internet.

So, the next step is to make sure your docker commands actually run against the remote DigitalOcean Droplet you just created. You can do so by setting a number of environment variables that'll be used by docker. But how do you know which environment variables - and what values to set? docker-machine to the rescue!

The following command prints the correct environment variables for you to set - in fact it even prints the commands that you need to execute in your terminal in order to set them correctly. Thank you docker-machine! 🙏

docker-machine env prisma

The output of that command looks somewhat similar to the following (depending on your shell and OS the commands to set environment variables might differ):

$ docker-machine env prisma
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://104.132.24.246:2376"
export DOCKER_CERT_PATH="/Users/johndoe/.docker/machine/machines/prisma"
export DOCKER_MACHINE_NAME="prisma"
# Run this command to configure your shell:
# eval $(docker-machine env prisma)
Step 5

Copy the last line of that output, excluding the # in the beginning (which indicates a comment) and paste it into your terminal:

eval $(docker-machine env prisma)

That's it - all your docker (and therefore prisma local) commands will now run against the DigitalOcean Droplet instead of your local machine!

To actually install Prisma on your Droplet, you need to perform the following steps (we'll go over them in detail afterwards):

  1. Create docker-compose.yml with proper configuration
  2. Create .env to configure the environment variables used by Docker
  3. Run docker-compose up -d to install Prisma on the Droplet

Let's get started!

Step 6

First, go ahead and create a new directory on your file system (on your local machine) where you'll place all the files for your project, you can call it prisma-digital-ocean-demo.

Step 7

Inside that directory, create a new file called docker-compose.yml and copy the following contents into it:

version: '3'
services:
  prisma:
    image: prismagraphql/prisma:1.12
    restart: always
    ports:
    - "4466:4466"
    environment:
      PRISMA_CONFIG: |
        port: 4466
        databases:
          default:
            connector: mysql
            active: true
            host: prisma-db
            port: 3306
            user: root
            password: prisma
  db:
    container_name: prisma-db
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: prisma

Note the comment in front of the environment.PRISMA_CONFIG.managementApiSecret property. For now, we don't provide a secret to the Prisma server which is going to enable everyone with access to the IP address of the Droplet to deploy and delete services to and from it! We'll add the security layer afterwards!

Note: To learn more about the variables configured here, check the corresponding reference docs.

With these files in place, you can go ahead and install Prisma!

Step 8

Inside the prisma-digital-ocean-demo directory, run the following command:

docker-compose up -d

Remember that thanks to Docker Machine, this command will now run against the remote host, i.e. your DigitalOcean Droplet. The -d option starts the container in detached mode, meaning it will run as a background process.

Awesome, you now have your Prisma server available on the DigitalOcean Droplet!

5. Deploy a Prisma service

You're now ready to deploy a Prisma service to your droplet

Step 9

Inside the prisma-digital-ocean-demo directory, run the following command:

prisma init hello-world
Step 10

From the interactive prompt, choose the Use other server option. Next, supply the host address to the prompt asking for the server endpoint. Last set a name for this service, in this case we will use hello-world and a stage from the interactive prompt in this case dev.

This creates a new directory that has the initial setup for a minimal Prisma service:

hello-world
  ├── datamodel.graphql - GraphQL SDL-based datamodel (foundation for database)
  └── prisma.yml - Prisma service definition

Next, you can go ahead and deploy the Prisma service.

Step 11

Navigate into the newly-created hello-world directory and deploy the service:

cd hello-world
prisma deploy

The CLI is now going to deploy the service to that droplet.

Step 12

The Prisma CLI in this case acts as a client for the Prisma Management API which is used to manage services on a specific seerrv. If you want to explore the Management API yourself, you can navigate your browser to http://__DROPLET_IP_ADDRESS__:4466/management. Similar to before, you'll have to replace the __DROPLET_IP_ADDRESS__ placeholder with the actual IP address of your DigitalOcean Droplet.

This is it! Your Prisma service is now running on your local server and can be access through the endpoint that was printed by the prisma deploy command! It will look similar to this: http://__DROPLET_IP_ADDRESS__:4466/hello-world/dev.

You can go ahead and send the following mutation and query to it:

mutation {
  createUser(data: {
    name: "Sarah"
  }) {
    id
  }
}
{
  users {
    id
    name
  }
}

6. Enable server authentication

As noted before, everyone with access to the endpoint of your server (http://__DROPLET_IP_ADDRESS__:4466/) will be able to access your server in any way they like. This means they can add new services or delete existing ones and also get full read/write-access to the application data from these services. This is a major security issue and should never be the case in any sort of production environment! Let's fix it.

Here's a quick overview of the steps you need to perform (like before, we'll go through each step in detail afterwards):

  1. Add a managementApiSecret to your docker-compose.yml and reapply your compose file with docker-compose up -d
  2. Redeploy the Prisma service

To generate a managementApiSecret, you can use any mechanism you wish.

version: '3'
services:
  prisma:
    image: prismagraphql/prisma:1.12
    restart: always
    ports:
    - "4466:4466"
    environment:
      PRISMA_CONFIG: |
        managementApiSecret: my-secret-secret
        port: 4466
        databases:
          default:
            connector: mysql
            active: true
            host: prisma-db
            port: 3306
            user: root
            password: prisma
  db:
    container_name: prisma-db
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: prisma
Step 13

Inside the prisma-digital-ocean-demo directory, run the following command to submit the new property along with its environment variable:

docker-compose up -d

Awesome - your server is now secured and only people who have access to your private key will be able to access it from now on!

Let's try and deploy the server without changing anything:

prisma deploy
Creating stage dev for service hello-world !
 ▸    Server at http://104.131.127.241:4466:4466 requires a cluster secret. Please provide it with the env var PRISMA_MANAGEMENT_API_SECRET

Perfect this is what we expected! Now you need to make the private key available to the CLI so your prisma deploy and similar commands can be properly authenticated.

Step 14

In the hello-world directory, create a .env file. prisma.yml understands variables from this file, add your PRISMA_MANAGEMENT_API_SECRET like so:

PRISMA_MANAGEMENT_API_SECRET=my-secret-secret

Now run prisma-deploy and you should be have a successful deploy!

That's it - from now on all deploys to the server will be authenticated using the PRISMA_MANAGEMENT_API_SECRET