Docker Deployments

We offer docker deployments as part of the commercial plans. This allows on premise deployments for companies and organizations that do not want or cannot store their data in the cloud.

In order to access the docker image for on premise deployments you must have a commercial plan. See plans and pricing for more information.

Docker Engine

Docker instances are run inside a Docker Engine. There are many options for where and how to run a docker instance. Depending on which Docker Engine you are using, the formio server configuration will be different.

Using Cloud Hosted Docker

If you are using a cloud hosted Docker Engine, please follow the appropriate steps to set up the formio server Docker container.

Using a Linux Server

Docker Engine runs natively on the Linux architecture. Docker requires a 64-bit installation regardless of your Distrubution version. Additionally, your kernel must be 3.10 at minimum. The latest 3.10 minor version or a newer maintained version are also acceptable.

https://docs.docker.com/engine/installation/linux/ubuntulinux/

Quick install

To do a quick install, run the following command. It will download, configure and install the Docker Engine on Linux hosts.

sudo curl -sSL https://get.docker.com/ | sh

Any distrubutions running systemd, which includes Ubuntu 15.04 and later, should run this command to ensure that the Docker Engine is started on reboot.

systemctl enable docker

Optionally, If you would like to run docker commands without sudo, add your user to the docker group.

sudo usermod -aG docker myusername

Using a Mac OS X computer

Running Docker Engine on a Mac has two options. We highly recommend using Docker for Mac instead of Docker Toolbox. Docker for Mac will run Docker natively on a Mac instead of through a Virtualbox which greatly simplifies setting up and running containers.

Download and install Docker for Mac from https://docs.docker.com/docker-for-mac/

See Using a Virtualbox Docker Engine below if you want to use Docker Toolbox.

Other Operating Systems

Docker Engine can be run on many different systems. See Docker’s Official Documentation for more information on running Docker.

https://docs.docker.com/engine/understanding-docker/

Using a Virtualbox Docker Engine

While it is possible to run the formio server in a Docker Engine inside of Virtualbox, this configuration adds an additional level of abstraction and networking that complicates getting things running correctly. You can use the information below to run formio server in a Virtualbox but our ability to support the server will be reduced.

Running Containers

Accessing the docker image

Once on the commercial plan, you will have access to the docker repository. Our docker images are located on docker’s hub.

https://hub.docker.com/r/formio/formio-server/

Since the image is a private docker respository, you will need to log in with your docker account and test pulling the image. If you are unable to pull the image, please contact support with your username and account information.

docker login
docker pull formio/formio-server

Create a docker network to contain all the docker instances.

A typical Form.io installation includes a Redis, MongoDB, and a Node.js API Server. If your environment is fully dockerized, you can spin up the stack using the following example commands.

This will create an isolated network for just the formio services that are required to run the server. In addition, it will provide for an easy way to link the services together.

docker network create formio

Create the Mongo instance.

Run mongodb with a volume mount for data. This will store the data in the host machine at /opt/mongodb. If the mongodb instance is restarte or replaced, the data still exists and can be restarted with a different mongodb instance.

On Mac OS running native docker engine, be sure to add /opt/mongodb to File Sharing list in Docker->Preferences->File Sharing. You may use a different path if desired.

mkdir /opt/mongodb
# Double check permissions on /opt/mongodb
docker run -itd  \
  --name formio-mongo \
  --network formio \
  --volume /opt/mongodb:/data/db \
  --restart unless-stopped \
  mongo;

Create the Redis instance.

docker run -itd \
  --name formio-redis \
  --network formio \
  --restart unless-stopped \
  redis;

Start the formio-server instance.

Before running this command, replace all the CHANGEME secrets with your own custom random strings. This will ensure that the server remains secure.

Set protocol, port and domain to the address where they will be accessible on the external network. For development it is recommended to use port 3000 and for production, use port 80. Configure in your domain name system to point that domain to the server running this docker engine. If you want to support subdomains, set the wildcard subdomain to also point at the server. See #docker-dns for more information.

First time install Set ADMIN_EMAIL and ADMIN_PASS the first time formio-server is run in a mongodb collection to set the primary account information. ADMIN_EMAIL and ADMIN_PASS may be removed after the initial install.

docker run -itd \
  -e "ADMIN_EMAIL=admin@example.com" \
  -e "ADMIN_PASS=CHANGEME" \
  -e "JWT_SECRET=CHANGEME" \
  -e "DB_SECRET=CHANGEME" \
  -e "PROTOCOL=http" \
  --name formio-server \
  --network formio \
  --link formio-mongo:mongo \
  --link formio-redis:redis \
  --restart unless-stopped \
  -p 3000:80 \
  formio/formio-server;

NOTE If you are running this container in a production environment and have SSL enabled, then you will need to remove the Environment Variable PROTOCOL

Testing the installation

You should now have an instance of the formio-server running in your environment. To test it, go to http://localhost:3000. You should see a response with information about the primary project.

Configuring

The formio server is configured with environment variables. When using Docker, you can set these by using the -e flag. Many Docker hosting platforms have easier ways of setting environment variables for your docker containers.

While we provide many variables to use during a deployment, the recommended configuration should provide the following settings.

Setting Description Example
MONGO The MongoDB connection string to connect to your remote database. mongodb://:@aws-us-east-1-portal.234.dblayer.com:23423/formio?ssl=true
ADMIN_EMAIL The default administrator email admin@example.com
ADMIN_PASS The default administrator password [YOUR PASSWORD]
DB_SECRET The database encryption secret [DB SECRET]
JWT_SECRET The secret password for JWT token encryption. [TOKEN SECRET]

NOTE: If you are hosting your Form.io API platform without SSL (for testing ONLY), then you will also need to provide the environment variable PROTOCOL set to the value of http.

All Configuration Variables

Below are all the variables that you can set within your Docker deployment.

Setting Description Example
MONGO The MongoDB connection string to connect to your remote database. mongodb://:@aws-us-east-1-portal.234.dblayer.com:23423/formio?ssl=true
MONGO_HIGH_AVAILABILITY If your database is high availability (like from Mongo Cloud or Compose), then this needs to be set. 1
ADMIN_EMAIL The default administrator email admin@example.com
ADMIN_PASS The default administrator password [YOUR PASSWORD]
PROTOCOL The HTTP protocol to serve requests. Should be “http” or “https” http
DB_SECRET The database encryption secret [DB SECRET]
DB_SECRET_OLD If you need to change the DB_SECRET, set the old value here and it will decrypt with the old and encrypt with the new the next time the server is started. Once changed, you can remove the DB_SECRET_OLD. [OLD DB SECRET]
JWT_SECRET The secret password for JWT token encryption. [TOKEN SECRET]
JWT_EXPIRE_TIME The expiration for the JWT Tokens 240
REDIS_ADDR The address of the redis server. This is used for analytics for the Docker instance. localhost
REDIS_PORT The port of the redis server 6379
REDIS_PASS (Optional) If you redis server has a password, set it with this.  
EMAIL_OVERRIDE Provides a way to point all Email traffic to a server. {“transport”:”smtp”,”settings”:{“port”:2525,”host”:”smtp.mailtrap.io”,”auth”:{“user”:”23esdffd53ac”,”pass”:”324csdfsdf989a”}}}

Using environment variables with Docker

You can set any of these environment variables when you run your Docker deployment by providing the -e parameter. For example, you can run the deployment with some environments set like so.

docker run -d \
    -e "MONGO=mongodb://admin:blahblah@aws-us-east-1-portal.25.dblayer.com:234234,aws-us-east-1-portal.26.dblayer.com:234234/formio?ssl=true"\
    -e "MONGO_HIGH_AVAILABILITY=1"
    -e "ADMIN_EMAIL=admin@example.com"
    -e "ADMIN_PASS=CHANGEME"
    -e "DB_SECRET=CHANGEME"
    -e "JWT_SECRET=CHANGEME"\
    formio/formio-server

DNS Configuration

In order to run a docker version of the form.io server, a domain name needs to be set up for it. There are now two options for configuring DNS for your docker server. You can run it using subdomains for multiple projects or run on a single domain and have projects as subdirectories of that domain.

Subdomains

When using subdomains, the server DNS must have the following three domains set up and an additional one per project OR have a wildcard subdomain entry in the DNS server.

Every deployment needs the following 3 subdomains to function.

HostName Description
api.yourdomain.com This subdomain points to the core API of the Form.io platform.
formio.yourdomain.com This points to the Main Form.io project which is required to login and manage your deployment.
[YOURPROJECT].yourdomain.com This points to the project within the deployment, which is your applications Form.io project.

For the following scenarios, assume the following project was created on the docker instance.

{
    "title": "My Project",
    "name": "myproject",
    "_id": "55882653b213f00a2641585d"
}
Localhost

For local testing, localhost would seem like a logical solution, however, since formio server relies on subdomains to manage projects and localhost does NOT support subdomains, it becomes a lot of work to constantly add additional lines to the /etc/hosts file each time a project is created.

Instead, we recommend using a domain name with wildcard subdomain support already set up that points to 127.0.0.1. This will allow using a real domain name but will point at your localhost.

http://lvh.me is the domain we recommend. If you run the server and use this domain to point to it, the server with subdomains will work correctly.

To access a project, use the project name and lvh.me

GET http://lvh.me:3000/project/55882653b213f00a2641585d
GET http://myproject.lvh.me:3000/

If you do not want to use lvh.me or a similar domain, you may use the /etc/hosts file (or the Microsoft Windows equivalent).

To use localhost, add the following items and any other project subdomains created on the server.

127.0.0.1   localhost
127.0.0.1   formio.localhost
127.0.0.1   api.localhost
127.0.0.1   myproject.localhost

Then, to access the project, use one of the following methods

GET http://localhost:3000/project/55882653b213f00a2641585d
GET http://myproject.localhost:3000

Each time a new project is added to the server for testing, be sure to add another entry to /etc/hosts.

Public Domains

For publically available servers such as testing and production, set up a wildcard subdomain to point to the server. This will allow subdomains to route correctly to your server. For example, you should have something like this in your DNS settings:

*.example.com.   3600 IN  MX 10 host1.example.com.

See https://en.wikipedia.org/wiki/Wildcard_DNS_record for more information on setting up a wildcard DNS entry.

Then, to access the project, use one of the following methods

GET https://example.com/project/55882653b213f00a2641585d
GET https://myproject.example.com

For all domains other than localhost it is best practice to set up SSL Certificates and run the server over https. This both keeps communication secure and also some browsers are starting to require https for certain cross browser requests.

Subdirectories

When using Subdirectories to refer to projects, simply set up a single domain and point it to the server. All projects will become subdirectories of that domain instead of subdomains. Be sure to select “Subdirectory” from the Project Path Type in the environment switcher.

For example: https://myformio.mydomain.com

Project Path

Setting up for project path is identical to setting up for Subdirectories. Referring to the projects will be by absolute path instead of the project name alias.

Configuring SSL (https)

If you wish to enable SSL (https) configuration for your Docker deployment, then we recommend using NGINX as a reverse proxy to point to the Form.io Docker container. Follow these steps to get this working.

Now, you will need to configure your nginx.conf file. You will be setting up NGINX to serve as a reverse proxy to the Docker container. The following configuration is an example of what would work.

###
# A LOT OF OTHER CONFIGURATIONS MAY BE ABOVE THIS POINT.
###

server {
    listen       443 ssl;
    server_name  *.lvh.me;
    client_max_body_size 20M;
    ssl_certificate      /usr/local/etc/nginx/nginx.crt;
    ssl_certificate_key  /usr/local/etc/nginx/nginx.key;
    location / {
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;

        # Fix the “It appears that your reverse proxy set up is broken" error.
        proxy_pass          http://localhost:3000;
        proxy_read_timeout  90;
        proxy_redirect      http://localhost:3000 https://$host;
    }
}

###
# A LOT OF OTHER CONFIGURATIONS MAY BE BELOW THIS POINT
###

In this case, your Docker container would be listening to port 3000, and NGINX would serve as the reverse proxy to point to that container.

Once you start up your NGINX instance, you will now have an SSL connection into your Form.io Docker container!

Exploring

Once the server is setup, running and has the DNS configured for it, you can start exploring the server.

By default, the main endpoint will respond with the primary project installed on the server. For new installs, this is the formio project. This project is meant to manage “Administrator” level accounts for who can login and manage projects on the server.

GET http://localhost:3000

Response:

[
    {
        "_id":"5751c2df5717292c84f4211c",
        "name":"formio","title":"Formio",
        "description":"The primary project for new installs.",
        "url":"http://localhost:3000/project/5751c2df5717292c84f4211c",
        "alias":"http://formio.localhost:3000"
    }
]

Using either the url or alias properties plus “/form” (depending on whether your DNS is set up with subdomains or not), you can view the forms in the primary project.

GET http://localhost:3000/project/5751c2df5717292c84f4211c/form

Response:

[
  {
    "_id":"5751c2e05717292c84f42120",
    "title":"User",
    "type":"resource",
    "name":"user",
    "path":"user",
    "project":"5751c2df5717292c84f4211c",
    "components":[
      {
        "validate":{
          "required":true
        },
        "type":"email",
        "persistent":true,
        "unique":false,
        "protected":false,
        "defaultValue":"",
        "suffix":"",
        "prefix":"",
        "placeholder":"Enter your email address",
        "key":"email",
        "label":"Email",
        "inputType":"email",
        "tableView":true,
        "input":true
      },
      {
        "validate":{
          "required":true
        },
        "type":"password",
        "persistent":true,
        "protected":true,
        "suffix":"",
        "prefix":"",
        "placeholder":"Enter your password",
        "key":"password",
        "label":"Password",
        "inputType":"password",
        "tableView":false,
        "input":true
      },
      {
        "type":"button",
        "theme":"primary",
        "disableOnInvalid":true,
        "action":"submit",
        "block":false,
        "rightIcon":"",
        "leftIcon":"",
        "size":"md",
        "key":"submit",
        "tableView":false,
        "label":"Submit",
        "input":true
      }
    ]
  },
  {
    "_id":"5751c2e05717292c84f42121",
    "title":"User Login",
    "type":"form",
    "name":"userLogin",
    "path":"user/login",
    "project":"5751c2df5717292c84f4211c",
    "components":[
      {
        "validate":{
          "required":true
        },
        "type":"email",
        "persistent":true,
        "unique":false,
        "protected":false,
        "placeholder":"Enter your email address",
        "key":"email",
        "label":"Email",
        "inputType":"email",
        "tableView":true,
        "input":true
      },
      {
        "validate":{
          "required":true
        },
        "type":"password",
        "persistent":true,
        "protected":true,
        "placeholder":"Enter your password",
        "key":"password",
        "label":"Password",
        "inputType":"password",
        "tableView":false,
        "input":true
      },
      {
        "type":"button",
        "theme":"primary",
        "disableOnInvalid":true,
        "action":"submit",
        "block":false,
        "rightIcon":"",
        "leftIcon":"",
        "size":"md",
        "key":"submit",
        "tableView":false,
        "label":"Submit",
        "input":true
      }
    ]
  }
]

As we can see from the response by default there are two forms created within the primary project. The first is the User resource and the second is the User Login form. The User Login form allows users to log in and get an access token.

Using the information from these forms you can now log in and get an access token.

The path of the User Login form is “/user/login” so now we can construct the path to log in. Please note that you will need to add “/submission” to access the submissions of a form instead of the form definition itself. Any of the following will work (depending on DNS settings).

POST http://localhost:3000/project/5751c2df5717292c84f4211c/form/5751c2e05717292c84f42121/submission
POST http://localhost:3000/project/5751c2df5717292c84f4211c/user/login/submission
POST http://formio.localhost:3000/form/5751c2e05717292c84f42121/submission
POST http://formio.localhost:3000/user/login/submission

Payload:

{
  "data":{
    "email":ADMIN_EMAIL,
    "password":ADMIN_PASS
  }
}

(Be sure to set the Content-Type header to “application/json”)

Use the same ADMIN_EMAIL and ADMIN_PASS from the installation section above.

Response:

{
  "_id": "5751ddbe797c15868646d766",
  "modified": "2016-06-03T19:42:54.771Z",
  "form": "5751c2e05717292c84f42120",
  "data": {
    "email": "test@example.com"
  },
  "created": "2016-06-03T19:42:54.771Z",
  "externalIds": [],
  "access": [],
  "roles": [
    "5751ddbe797c15868646d75e"
  ],
  "owner": null
}

In addition, the response will have a “x-jwt-token” header. This is the most important part. In all further requests, if you use the x-jwt-token header with that value it will authenticate you as the admin user. Please note that the token does expire but every request returns a refreshed token.

Now that you have a jwt token, you can fully explore the API as an authenticated user. For example, to see what projects a user has deployed to the server, do this:

headers:
x-jwt-token: (very long jwt hash)
GET http://api.localhost:3000/project

Deploying

Use our formio-cli tool to deploy to the docker server. To install this, you will need Node.js installed.

Then type the following command on the command line.

npm install -g formio-cli

Now you can use the formio command to deploy a project from one server to another server.

formio deploy https://myproject.form.io http://myproject.localhost:3000

Each server will require authentication so you will be asked twice, once for the source server and once for the destination server.

PaaS Deployment

Now that you have deployed locally, the next step is to deploy your project within a live Platform as a Service (PaaS). There are many available services which provide Docker deployments such as Amazon AWS, IBM BlueMix, and may others. Read below full tutorials on how to deploy Form.io within those environments.