Skip to content

Docker setup

Dario Salvi edited this page Oct 28, 2021 · 13 revisions

Setting up a Mobistudy server with Docker

This is a step-by-step guide to setting up a running Mobistudy server with Docker. It assumes a good understanding of Docker, but it is also meant to be used by those who are learning. As there is a not a solution that will satisfy all possible requirements, here we show some possible setups.

Mobistudy comes with 2 Docker images, one for MobistudyAPI and one for MobistudyWeb. In addition, it needs ArangoDB to be running and accessible from MobistudyAPI and, depending on the cases, a reverse proxy for serving both the web and the API.

Preaparing the server

We suppose that the server has some Debian-like Linux installed. Different instructions are needed for other environments.

Install docker

This is a summary of https://docs.docker.com/install/linux/docker-ce/ubuntu/. On other opearting systems, follow Docker's official guides.

Uninstall older versions:

sudo apt-get remove docker docker-engine docker.io containerd runc

Add dependencies:

sudo apt-get update

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -

install docker, stable release:

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Check that it's installed:

docker run hello-world

Run Docker on boot:

sudo systemctl enable docker

Allow non root users to run Docker (see https://docs.docker.com/install/linux/linux-postinstall/). Create the docker group

sudo groupadd docker

add your user to the group

sudo usermod -aG docker USER

You can check with

id USER

Now logout and login again and run:

docker run hello-world

You should be good to go.

Clone the repos

We assume git is installed as command line tool. If not, install it. See this guide for Ubuntu.

git clone https://github.com/Mobistudy/MobistudyAPI.git ./API
git clone https://github.com/Mobistudy/MobistudyWeb.git ./WEB

Setup encryption at rest

Create an encrypted volume

Download veracrypt console from: https://www.veracrypt.fr/en/Downloads.html

Install the package if it exists (sudo apt install ./name.deb), or use the manual installation process otherwise.

Follow the instructions here.

Create an encrypted volume with:

veracrypt -t -c

Next:

  • Choose 1: normal.
  • Enter a path, for example ./mobidata
  • Enter size of the volume: for example 10G
  • Encryptiuon algorithm: AES
  • Hash algorithm: SHA-512
  • Filesystem: Ext4
  • Leave PIM and keyfile path emtpy.

Create a folder where to mount the encrypted volume, for example:

sudo mkdir ./datamnt

Next, mount the encrypted volume:

veracrypt PATH_TO_VOLUME_FILE ./datamnt

Enter the password and skip PIM andd keyfile.

This will likely mount the folder as root and you won't be able to write in it, so change the owner and group back to the current user:

chown USER datamnt
chown :GROUP datamnt

Now you should be able to cd into datamnt and read and write files there.

(optional) Tell docker to use the encrypted folder

This may be needed if you want to keep data into containers or volumes.

Create a directory inside datamnt called docker

mkdir docker

Instructions taken from here:

sudo service docker stop

Add a file named daemon.json under the directory /etc/docker. The file should have this content:

{ 
   "data-root": "/path/to/your/docker" 
}

Copy the content of the old folder:

sudo rsync -aP /var/lib/docker/ /path/to/your/docker

Start docker:

sudo service docker start

Setup containers

Create a virtual network

We need a virtual network, let's call it mobinet

docker network create mobinet

Start ArangoDB

First create either a volume or a folder inside the encrypted partition where to store the database data permanently

Run a Docker container with ArangoDB, make sure the root password is well set:

docker run -e ARANGO_ROOT_PASSWORD=xxxxxxxxx -d \
      -v path/to/folder/or/volume:/var/lib/arangodb3 \
      --name mobidb \
      --net=mobinet \
      arangodb:3.7

Check that it's runninng with:

docker ps

If it's the first time you run it, you need to initialise the database. Open the arango shell with:

docker exec -it mobidb arangosh --server.password xxxxxxxxx 

And then run the following script:

db._createDatabase("mobistudy");
var users = require("@arangodb/users");
users.save("mobistudy", "xxxxxxxxx");
users.grantDatabase("mobistudy", "mobistudy");

Exit with exit.

Compile and run the API

First create either a volume or a folder inside the encrypted partition where to store the server logs data permanently.

Compile the mobistudy API:

docker build -t mobistudyapi .

Then you run the API with the following. Make sure to set all passwords correctly

docker run -d \
    -v path/to/folder/or/volume:/usr/src/app/logs \
    -v path/to/folder/or/volume:/usr/src/app/tmp \
    -v path/to/folder/or/volume:/usr/src/app/tasksuploads \
	--net=mobinet \
    -e WEB_CLUSTER=true \
    -e LOGS_FOLDER=logs \
    -e LOGS_ROTATIONSIZE=5M \
	-e LOGS_LEVEL=30 \
    -e AUTH_SECRET="xxxxx" \
    -e AUTH_TOKEN_EXPIRES="30 days" \
	-e AUTH_ADMIN_EMAIL="[email protected]" \
	-e AUTH_ADMIN_PASSWORD="aaaaaaaa" \
	-e DB_HOST="mobidb" \
	-e DB_PORT=8529 \
    -e DB_NAME="mobistudy" \
    -e DB_USER="mobistudy" \
    -e DB_PASSWORD="xxxxxxxxx" \
    -e OUTLOOK_EMAIL="[email protected]"\
    -e OUTLOOK_USER="UUUUUUU" \ 
    -e OUTLOOK_PASSWORD="zzzzzzzz" \
    -e OWP_API_KEY="qqqqqqqqq" \
    -e AMBEE_API_KEY="ppppppppp" \
    -e MSAFETY_WEBHOOKAUTHKEY="ssssssssss" \
    -e MSAFETY_PUBLICKEY="pppppppppppp" \
    -e MSAFETY_PRIVATEKEY="uuuuuuuuuuu" \
    --name mobiapi \
    mobistudyapi

If you connect to host/api you should now see a reply.

Notice that we did specify the DB host as mobidb, which is automatically created by Docker within the network.

Mount points

There are 3 folders where data is stored:

  • /usr/src/app/logs
  • /usr/src/app/tmp
  • /usr/src/app/tasksuploads

You can mount them on a local folder or a Docker volume. Make sure those are in an encrypted disk or folder!

If you use Docker volumes and want to look into them, you can list the files with:

docker run --rm -i -v=volumeName:/tmp/myvolume busybox find /tmp/myvolume

And open one file with:

docker run --rm -i -v=volumeName:/tmp/myvolume busybox cat /tmp/myvolume/app.log

Configuration variables

You can pass configuration variables as environemnt variables, or as in a configuration file or as Docker secrets. This is the full list of variables:

Variable Type Default Secret
WEB_PORT integer 8080 NO
WEB_CLUSTER boolean true NO
LOGS_FOLDER string 'logs' NO
LOGS_ROTATIONSIZE string '1M' NO
LOGS_CONSOLE boolean false NO
LOGS_LEVEL integer 30 NO
AUTH_SECRET string NA YES
AUTH_TOKEN_EXPIRES string '30 days' NO
AUTH_ADMIN_EMAIL string NA YES
AUTH_ADMIN_PASSWORD string NA YES
DB_HOST string 'localhost' NO
DB_PORT integer 8529 NO
DB_NAME string NA YES
DB_USER string NA YES
DB_PASSWORD string NA YES
OUTLOOK_USER string NA YES
OUTLOOK_PASSWORD string NA YES
OUTLOOK_EMAIL string NA NO
OWP_API_KEY string NA YES
AMBEE_API_KEY string NA YES
MSAFETY_WEBHOOKAUTHKEY string NA YES

AUTH_ADMIN_EMAIL and AUTH_ADMIN_PASSWORD are used at the first start, to generate an admin user that can be used to access the website the first time.

In a production environment, it is recommendable to use Docker secrets instead of environment variables when possible. The variables that can be passed as Docker secret are flagged in the "Secret" column.

Add web interface and reverse proxy

We will use Caddy as reverse proxy also because it support Letsencrypt certificates.

Compile the web interface container:

docker build -t mobistudyweb .

Then create a caddyfile somewhere on your system, like the following:

# Simple HTTP (not secure)
:80
root * /var/www
reverse_proxy /api/* mobiapi:8080 {
 header_up Host {http.reverse_proxy.upstream.hostport}
}
reverse_proxy /datadownload/* mobiapi:8080 {
 header_up Host {http.reverse_proxy.upstream.hostport}
}
file_server
encode zstd gzip

Run it:

docker run  -d \
-p 80:80 \
-v path/to/Caddyfile:/etc/caddy/Caddyfile \
-v path/to/folder/or/volume:/data \
--net=mobinet \
--name mobiweb \
mobistudyweb

To support Letsencrypt (assuming youor DNS is configured to app.mobistudy.org):

app.mobistudy.org
root * /var/www
reverse_proxy /api/* mobiapi:8080 {
 header_up Host {http.reverse_proxy.upstream.hostport}
}
reverse_proxy /datadownload/* mobiapi:8080 {
 header_up Host {http.reverse_proxy.upstream.hostport}
}
file_server
encode zstd gzip

and run it on the HTTPS port instead

docker run  -d \
-p 443:443 \
-v path/to/Caddyfile:/etc/caddy/Caddyfile \
-v path/to/folder/or/volume:/data \
--net=mobinet \
--name mobiweb \
mobistudyweb

Setup backups

TBD

Clean up Docker mess

If you need to cleanup docker stuff:

docker rm $(docker ps -a -q)
docker rmi $(docker images -q)
docker system prune -a
docker system prune --volumes

Be aware that removing the docker instances will remove also the persistent files, therefore the DB and the logfiles unless you have placed these outside of the containers.

Restart the server

If you need to restart the machine, once you've logged onto it:

Mount the Veracrypt volume:

veracrypt PATH_TO_VOLUME_FILE ./datamnt

skip PIM and keyfile, say No to "Protect hidden volume" and use the current user's password when asked for "Enter your user password or administrator password"

Then restart the Docker containers:

docker start mobidb
docker start mobiapi
docker start mobiweb