3. Manual installation

If the default Agora installation with the installation wizard is not possible or is not approriate for the targeted environment and network configuration, a manual installation can be performend. The manual installation follows the same procedure as the installation wizard, but offers greater flexibility and insight into the underlying configurations, making it a suitable for users who prefer more control over the deployment process. Basic system- and network administration skills, as well as a basic knowledge about Docker containers are prerequisites for the manual installation.

The Agora installation uses 8 Docker containers which are linked to each other. Three of the containers are standard containers hosted in the official Docker Hub. The other five are hosted in the GyroTools Agora Registry and require authentication to access.

Container

Description

Source

agora_db

The offical postgres DB

Docker Hub

agora_mongo

The official mongo DB for parameter storage

Docker Hub

agora_redis

InMemory Key/Value database used as cache system

Docker Hub

agora_app

Agora Web Application

gtagora-registry.gyrotools.com

agora_web

Nginx Webserver configured for Agora

gtagora-registry.gyrotools.com

agora_tools

Tools used by Agora

gtagora-registry.gyrotools.com

agora_dicom_node

The dicom node

gtagora-registry.gyrotools.com

agora_auto_import

The auto import tool which watches a folder

gtagora-registry.gyrotools.com

Configuration and linkage of the containers is performed with the docker-compose tool. Manual configuration of the containers and the docker-compose file is possible, but only recommended for expert users.

The Agora Docker installation will presume Agora to be the only (web)-application running on the host. It will install a dedicated web server container (nginx) which will use ports 80 and 443 of the host system. If these ports are already occupied by other web applications, the Agora web container cannot be started. A manual configuration is then required.

3.1. Step-by-Step Instructions

  1. Open a bash terminal as root:

    sudo bash
    
  2. It is recommended to create a separate Agora user, which will then be utilized within the Docker containers to run all processes. Lets call it gtagora and get the user and group ID which will be used in the configuration file:

    useradd gtagora
    id gtagora
    
  3. Create all necessary docker volumes as bind mounts (see below for more details). Adapt the paths to your needs. The following example creates the volumes in the directory /data/agora/:

    mkdir -p /data/agora/db/
    mkdir -p /data/agora/mongo/
    mkdir -p /data/agora/log/
    mkdir -p /data/agora/nginx/
    mkdir -p /data/agora/data/
    
    docker volume create agora_db --opt type=none --opt device=/data/agora/db/ --opt o=bind
    docker volume create agora_mongo --opt type=none --opt device=/data/agora/mongo/ --opt o=bind
    docker volume create agora_log --opt type=none --opt device=/data/agora/log/ --opt o=bind
    docker volume create agora_nginx --opt type=none --opt device=/data/agora/nginx/ --opt o=bind
    docker volume create agora_data_1 --opt type=none --opt device=/data/agora/data/ --opt o=bind
    
  4. Download the Agora installer:

    curl -L http://download.gyrotools.com/download/getagora/gtagora -o /usr/bin/gtagora
    chmod +x /usr/bin/gtagora
    
  5. Display the available Agora versions and choose the latest version for the next step:

    gtagora versions
    
  6. Create a config.json file in the directory /etc/gyrotools/agora/ (or a location of your choice) and insert the following minimal configuration (see below for all config options):

    {
        "db": {
            "password": "agora"
        },
        "volumes": {
            "data": {
                "active": "agora_data_1",
                "previous": []
            }
        },
        "registry": {
          "username": "<PORTAL_USERNAME>",
          "password": "<PORTAL_PASSWORD_OR_ACCESS_TOKEN>"
        },
        "docker": {
          "user": {
            "gid": <GID_OF_GTAGORA_USER>,
            "uid": <UID_OF_GTAGORA_USER>
          }
        },
        "dicom": {
          "node": {
            "name": "gtAgora",
            "port": 3010
          }
        },
        "version": "<AGORA_VERSION>",
        "timezone": "Europe/Zurich"
    }
    

    For the docker registry use the same credentials as for the Gyrotools customer portal. Instead of the password you can also use your personal access token.

  7. Build the docker-compose.yml file from the config.json file:

    gtagora rebuild
    # or when the config file is in a different location
    # gtagora -c /path/to/config.json rebuild
    

    The docker-compose-yml file will be stored parallel to the config.json file. The file is located at /etc/gyrotools/agora/docker-compose.yml by default.

  8. Inspect the docker-compose-yml file and make changes if necessary. The file is a standard docker-compose file and can be edited with any text editor. The file is used to start the Agora containers.

    cat /etc/gyrotools/agora/docker-compose.yml
    
  9. Start Agora:

    docker compose -f /etc/gyrotools/agora/docker-compose.yml up -d
    

    The command will pull the containers from the online repositories and start the docker-compose project in daemon mode. Use docker ps or docker logs to check the state of all running containers.

Important

Configure Agora container to use a proxy server

The Agora license tool which runs inside the docker container, also requires the proxy configuration to access license.gyrotools.com. Like many other linux tools the license tool uses the http_proxy and https_proxy environment variables to get the proxy configuration Use the config.json configuration file to specify these two environment variables.

{
  ...
  ...
  ...
  "docker": {
    "environment": {
      "http_proxy": "http://<PROXY_USERNAME>:<PROXY_PASSWORD>@<PROXY_URL>:<PROXY_PORT>",
      "https_proxy": "http://<PROXY_USERNAME>:<PROXY_PASSWORD>@<PROXY_URL>:<PROXY_PORT>"
    },
    ...
    ...
    ...
  }
}

3.2. Docker Registry

The Agora containers are hosted in the private GyroTools Docker registry. The registry requires authentication to access. The credentials are the same as for the Gyrotools customer portal. If the credentials need to be stored in a file or in a script, it is recommended to use a personal access token instead of the password. The access token can be found in the profile settings of the GyroTools customer portal:

../../../_images/portal_profile.jpg

3.3. Configuration

The maximal config.json file with all the options is shown below. By default the file is located at /etc/gyrotools/agora/config.json but can be stored at any location if desired. The file is used to create the docker-compose-yml file. It is a standard JSON file and can be edited with any text editor.

{
  "name": "your_agora_instance_name",
  "version": "your_agora_version",
  "encryption_key": "your_encryption_key",
  "siteUrl": "your_site_url",
  "timezone": "your_timezone"
  "db": {
    "password": "your_db_password_here",
    "parameters": {}
  },
  "volumes": {
    "db": "db_volume_name",
    "mongo": "mongo_volume_name",
    "log": "log_volume_name",
    "nginx": "nginx_volume_name",
    "data": {
      "active": "active_data_volume_name",
      "previous": ["previous_data_volume_name_1", "previous_data_volume_name_2"],
      "options": {}
    },
    "extra": {},
    "options": {
      "permission": "fix"
    }
  },
  "dicom": {
    "node": {
      "name": "ae_title",
      "port": 1234
    }
  },
  "registry": {
    "username": "your_poral_username",
    "password": "your_portal_password",
    "url": "docker_registry_url",
    "auth": true
  },
  "docker": {
    "environment": {},
    "network": {
      "useSystemRootCAs": true,
      "rootCAPath": "/path/to/rootCA",
      "ports": {
        "https": 443,
        "http": 80,
        "bindTo": "your_bind_to_value"
      },
      "https": true
    },
    "user": {
      "gid": 123,
      "uid": 456
    }
  },
  "containers": {
    "permission-fixer": {
      "version": "permission_fixer_version",
      "name": "docker_permission_fixer_name"
    },
    "app": {
      "version": "app_version",
      "name": "docker_app_name"
    },
    "web": {
      "version": "web_version",
      "name": "docker_web_name"
    },
    "tools": {
      "version": "tools_version",
      "name": "docker_tools_name"
    },
    "postgres": {
      "version": "postgres_version",
      "name": "docker_postgres_name"
    },
    "redis": {
      "version": "redis_version",
      "name": "docker_redis_name"
    },
    "mongo": {
      "version": "mongo_version",
      "name": "docker_mongo_name"
    }
  },
  "plugins": {
    "path": "/path/to/plugins",
    "mattermost": {
      "path": "/path/to/mattermost",
      "adminPassword": "mattermost_admin_password",
      "containers": {
        "app": {
          "version": "mattermost_app_version",
          "name": "dcoker_mattermost_app_name"
        },
        "db": {
          "version": "mattermost_db_version",
          "name": "docker_mattermost_db_name"
        }
      }
    }
  },
}

The list below provides a description of all the options in the config.json file.

Database Configuration

  • db.password (string, required): The password for the postgres database. Has to be changed before starting up the database container the first time [default: agora]

  • db.parameters (object): Additional parameters for the database configuration [default: {}].

Volumes Configuration

  • volumes.db (string): The name of the database volume [default: agora_db].

  • volumes.mongo (string): The name of the MongoDB volume [default: agora_mongo].

  • volumes.log (string): The name of the log volume [default: agora_log].

  • volumes.nginx (string): The name of the Nginx volume [default: agora_nginx].

  • volumes.data.active (string, required): The name of the active data volume [default: agora_data_1].

  • volumes.data.previous (array): The name of the previous data volumes [default: [] ].

  • volumes.data.options (object): Additional options for the data volume.

  • volumes.options.permission (string, enum: fix, disabled): Permission options for volumes [default: fix].

  • volumes.extra (object): Extra volume configurations [default: {}].

Dicom Configuration

  • dicom.node.name (string): AE title of the Dicom node [default: gtAgora].

  • dicom.node.port (number): Port for the Dicom node [default: 3010].

Registry Configuration

  • registry.username (string): Username for accessing the docker registry (same as for the Gyrotools customer portal)

  • registry.password (string): Password for accessing the docker registry (same as for the Gyrotools customer portal)

  • registry.url (string): URL of the docker registry [default: gtagora-registry.gyrotools.com].

  • registry.auth (boolean): Flag indicating if authentication is required [default: true].

Docker Configuration

  • docker.environment (object): Environment variables for Docker [default: {}].

  • docker.network.useSystemRootCAs (boolean): Flag indicating if Docker should use system root CAs [default: false].

  • docker.network.rootCAPath (string): Path to the root CA for Docker [default: null].

  • docker.network.ports.https (number|string): Port for HTTPS connections [default: 443].

  • docker.network.ports.http (number|string): Port for HTTP connections [default: 80].

  • docker.network.ports.bindTo (string): Value to bind ports to [default: ''].

  • docker.network.https (boolean): Flag indicating if Docker should use HTTPS [default: true].

  • docker.user.gid (number): Group ID for Docker user to run all processes [default: 2000].

  • docker.user.uid (number): User ID for Docker user to run all processes [default: 2000].

Containers Configuration

  • containers.permission-fixer.version (string): Version of the permission fixer container [default: latest].

  • containers.permission-fixer.name (string): Name of the permission fixer container [default: tools/permission-fixer].

  • containers.app.version (string): Version of the app container [default: latest].

  • containers.app.name (string): Name of the app container [default: gtagora/app].

  • containers.web.version (string): Version of the web container [default: latest].

  • containers.web.name (string): Name of the web container [default: gtagora/web].

  • containers.tools.version (string): Version of the tools container [default: latest].

  • containers.tools.name (string): Name of the tools container [default: gtagora/agora_tools_service].

  • containers.postgres.version (string): Version of the PostgreSQL container [default: latest].

  • containers.postgres.name (string): Name of the PostgreSQL container [default: mirror/postgres].

  • containers.redis.version (string): Version of the Redis container [default: latest].

  • containers.redis.name (string): Name of the Redis container [default: mirror/redis].

  • containers.mongo.version (string): Version of the MongoDB container [default: latest].

  • containers.mongo.name (string): Name of the MongoDB container [default: mirror/mongo].

Plugins Configuration

  • plugins.path (string): Path to the plugins directory.

  • plugins.mattermost.path (string): Path to the Mattermost directory.

  • plugins.mattermost.adminPassword (string): Admin password for Mattermost.

  • plugins.mattermost.containers.app.version (string): Version of the Mattermost app container.

  • plugins.mattermost.containers.app.name (string): Name of the Mattermost app container.

  • plugins.mattermost.containers.db.version (string): Version of the Mattermost DB container.

  • plugins.mattermost.containers.db.name (string): Name of the Mattermost DB container.

Other Configuration

  • name (string): Name of the Agora instance.

  • version (string): Version of Agora. The current version can be found in the Gyrotools customer portal. Use exact version (e.g. 7.9.12)

  • encryption_key (string): Encryption key for Agora.

  • siteUrl (string): URL of the Agora server [default: https://agora.example.com].

  • timezone (string): Timezone configuration for Agora [default: America/Chicago]. A list of timezone can be found here: Timezones

3.3.1. Time zone

Agora tags all data with a time following a time zone. Choose your time zone from the list: Timezones.

3.3.2. Docker user

By default the installer will create a gtagora user and all processes will be started by this user. If you prefer to use another user, you can configure your own user with the docker.user.uid|gid option. The user and the group must already exists. Upon building the docker-compose.yml file with gtagora rebuild the installer will make sure that this user has write access to all storage locations.

{
   "db": {
        "password": "agora"
    },
    "volumes": {
        "db": "agora_db",
        "log": "agora_log",
        "data": {
            "active": "agora_data_1",
            "previous": []
        }
    },
    "registry": {
      "username": "test",
      "password": "1234"
    },
    "docker": {
        "user": {
            "uid": 1001,
            "gid": 1001
        }
    },
    "timezone": "Europe/Zurich"
}

3.3.3. Dicom node

Agora also acts as an Dicom node. To override the default configuration use the dicom.node.name|port settings. The port must be accessible from external Dicom servers. Check your firewall.

{
   "db": {
        "password": "agora"
    },
    "volumes": {
        "db": "agora_db",
        "log": "agora_log",
        "data": {
            "active": "agora_data_1",
            "previous": []
        }
    },
    "registry": {
      "username": "test",
      "password": "1234"
    },
    "dicom": {
        "node": {
            "name": "MyDicomNode",
            "port": 9999
        }
    },
    "timezone": "Europe/Zurich"
}

3.3.4. Create the docker-compose configuration

To create the docker-compose configuration, use the gtagora command line tool:

gtagora rebuild

This will generate the /etc/gyrotools/agora/docker-compose.yml configuration file from the config.json file. It will be created parallel to config.json (default path: /etc/gyrotools/agora/). A previously existing docker-compose configuration file will be overwritten.

Important

When ever the config.json has been changed, call gtagora rebuild to update the docker-compose.yml configuration file.

Caution

It is not recommended to edit the /etc/gyrotools/agora/docker-compose.yml file manually. Changes will be lost the next time you call gtagora rebuild.

3.4. Data storage

3.4.1. Docker Volumes

All Docker containers used in Agora are stateless. This means that no persistent data is stored inside the container. Persistent data is stored on bind mounted named volumes external to the Docker containers. A user-defined storage locations on the host machine or at NFS locations in the network should be specified when the volume is created.

The Agora containers require 5 bind mounted named volumes. These volumes have default names. You can change the names in the configuration file under “volumes”. It is recommended to store the database data on a fast storage system (SSD) and the uploaded data files on large-capacity (HDD, NFS) storage system.

The named volumes are:

agora_log

Location for all log files (use fast storage)

agora_db

Location for all database files. (use fast storage)

agora_mongo

Location for all parameter. (use fast storage)

agora_nginx

Location for the webserver configuration files and certificate

agora_data_1

Location for all file data uploaded to Agora. (use large-capacity storage)

Caution

Don’t change the name of the agora_data_1 volume after you have imported or uploaded any files. The Agora system will no longer find your files. You can add additional volumes for the data files (eg agora_data_2) if you run out of storage space. See below.

  • To create the volume agora_log for the log files and let Docker select the default storage location, use:

sudo mkdir /path/to/log/files/
sudo docker volume create agora_log --opt type=none --opt device=/path/to/log/files/ --opt o=bind
  • To inspect the volume and see the storage location (mount point):

sudo docker volume inspect agora_log

[
    {
        "CreatedAt": "2024-02-22T14:43:11Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/agora_log/_data",
        "Name": "agora_log",
        "Options": {
            "device": "/path/to/log/files/",
            "o": "bind",
            "type": "none"
        },
        "Scope": "local"
    }
]
  • To create the volume agora_db to store the database files and specify the storage location (use a fast storage when ever possible):

sudo mkdir /path/to/database/data/
sudo docker volume create agora_db --opt type=none --opt device=/path/to/database/data --opt o=bind
sudo docker volume inspect agora_db

[
    {
        "CreatedAt": "2018-05-20T12:11:13+02:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/agora_db/_data",
        "Name": "agora_db",
        "Options": {
            "device": "/path/to/database/data",
            "o": "bind",
            "type": "none"
        },
        "Scope": "local"
    }
]

Create the rest of the volumes in the same way as the two examples above.

3.4.2. Using NFS

When using NFS as a high-capacity storage it is recommended to mount the nfs share into the Agora host filesystem by using /etc/fstab. Then create a named volume that points to this location. There are a few pit falls that you should be aware of:

no_root_squash - NFS normally changes the root user to nobody. This is a good security measure when NFS shares are accessed by many different users. However, in our case only Agora will use the NFS share so it is safe to leave the root user. Without the no_root_squash setting, errors may occur when Agora tries to start the container or write files. Check the permission by accessing the desired folder as user root: cd /the/desired/data/folder/. Also check if the user gtagora (or the configured user) has write access in that folder by typing: touch /the/desired/data/folder/file.txt. If these checks fail you should adjust the permissions on these directories and/or set the docker user in the config.json to an user that has access on the NFS directory.

3.5. Start Agora

sudo gtagora start

This commands pulls the containers from the online repositories and starts the docker-compose project in daemon mode. Use docker ps or docker logs to check the state of all running containers.

Important

The fist pull takes a while as about 1.5 GB of data has to be downloaded.

For debugging purpose it is better to start Agora in a non-daemon mode. Use the docker-compose commands directly:

sudo docker compose -f /ect/gyrotools/agora/docker-compose.yml up

At the very first start Agora creates a new Admin user automatically.

User: admin
Password: gtagora

Caution

For security reasons change the default password of the administrator user immediately.

3.6. Stop Agora

sudo gtagora stop