I am able to successfully authenticate as the ‘admin’ account to dashboard.mindlamp.digital using our api endpoint created below api.mindlamp.temple.edu
.
However, I cannot create a successfully working user account. When I attempt to authenticate using a newly created user account I get an error and cannot login (see below).
I first tried creating a user account by using the web interface, navigating to the “Administrator” dropdown in the top left nav of the page and select “Manage Credentials”.
I then complete the form modal by providing a name, role (Clinician), and a password. I then click the “save credentials” check mark icon.
When I attempt to sign in to dashboard.lamp.digital using the newly created credentials I receive an error:
“researcher” accounts can be created and can authenticate but are immediately greeted with an indefinite spinner upon login. This happens across multiple browsers and platforms.
Can someone please help me identify and resolve what is causing the indefinite spinner and invalid logins? Our team is currently blocked and can’t make use of the mindlamp app platform.
I attempted to attach full logs as a zip file to this post but I received the error:
Sorry, new users can not upload attachments.
The full logs are available in this github gist. Click ‘view raw’ on each to see the full log.
Platform setup steps on Azure
I’ve followed the same steps on AWS and this yeilded the same results.
create single vm on cloud platform (azure)
Operating system: Linux (ubuntu 20.04)
Size: Standard D2s v3 (2 vcpus, 8 GiB memory)
Public IP address: 20.97.246.6
DNS name: tucla-mindlamp.eastus2.cloudapp.azure.com
Location: East US 2
clasrvadmin@cla-mindlamp:~/mindlamp$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal
clasrvadmin@cla-mindlamp:~/mindlamp$ docker --version
Docker version 20.10.8, build 3967b7d
DNS
clasrvadmin@cla-mindlamp:~/mindlamp$ dig mindlamp.temple.edu
; <<>> DiG 9.16.1-Ubuntu <<>> mindlamp.temple.edu
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51347
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;mindlamp.temple.edu. IN A
;; ANSWER SECTION:
mindlamp.temple.edu. 1677 IN CNAME tucla-mindlamp.eastus2.cloudapp.azure.com.
tucla-mindlamp.eastus2.cloudapp.azure.com. 10 IN A 20.97.246.6
;; Query time: 24 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Fri Sep 10 13:51:48 EDT 2021
;; MSG SIZE rcvd: 119
clasrvadmin@cla-mindlamp:~/mindlamp$ dig *.mindlamp.temple.edu
; <<>> DiG 9.16.1-Ubuntu <<>> *.mindlamp.temple.edu
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26043
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;*.mindlamp.temple.edu. IN A
;; ANSWER SECTION:
*.mindlamp.temple.edu. 1654 IN CNAME tucla-mindlamp.eastus2.cloudapp.azure.com.
tucla-mindlamp.eastus2.cloudapp.azure.com. 10 IN A 20.97.246.6
;; Query time: 16 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Fri Sep 10 13:52:40 EDT 2021
;; MSG SIZE rcvd: 121
Install all available updates
sudo apt update && sudo apt upgrade -y
set time & date
sudo timedatectl set-timezone America/New_York
Install Docker Engine
Install pre-reqs:
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
Add Docker’s official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
set up the stable repository:
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install docker engine:
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
Install docker-compose
:
sudo apt install docker-compose
add user to the docker group:
sudo usermod -aG docker clasrvadmin
configure storage
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 55.4M 1 loop /snap/core18/2128
loop1 7:1 0 70.3M 1 loop /snap/lxd/21029
loop2 7:2 0 32.3M 1 loop /snap/snapd/12883
sda 8:0 0 16G 0 disk
└─sda1 8:1 0 16G 0 part /mnt
sdb 8:16 0 30G 0 disk
├─sdb1 8:17 0 29.9G 0 part /
├─sdb14 8:30 0 4M 0 part
└─sdb15 8:31 0 106M 0 part /boot/efi
sdc 8:32 0 512G 0 disk
sr0 11:0 1 628K 0 rom
clasrvadmin@cla-mindlamp:~/mindlamp$ sudo fdisk /dev/sdc
Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x657997f1.
Command (m for help): p
Disk /dev/sdc: 512 GiB, 549755813888 bytes, 1073741824 sectors
Disk model: Virtual Disk
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x657997f1
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-1073741823, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-1073741823, default 1073741823):
Created a new partition 1 of type 'Linux' and of size 512 GiB.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
format the partition:
clasrvadmin@cla-mindlamp:~/mindlamp$ sudo mkfs.xfs /dev/sdc1
meta-data=/dev/sdc1 isize=512 agcount=4, agsize=33554368 blks
= sectsz=4096 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1
data = bsize=4096 blocks=134217472, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=65535, version=2
= sectsz=4096 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
create the /data
directory and mount the volume:
sudo mkdir /data
sudo mount /dev/sdc1 /data
verify the mount point:
clasrvadmin@cla-mindlamp:~/mindlamp$ df -h /dev/sdc1
Filesystem Size Used Avail Use% Mounted on
/dev/sdc1 512G 3.6G 509G 1% /data
get the uuid of the volume:
clasrvadmin@cla-mindlamp:~/mindlamp$ lsblk -o MOUNTPOINT,UUID | grep data
/data a182ea7f-8634-41fe-a228-7b60aa28d7ba
edit the fstab to automount /data
:
clasrvadmin@cla-mindlamp:~/mindlamp$ cat /etc/fstab
# CLOUD_IMG: This file was created/modified by the Cloud Image build process
UUID=8f9df8d8-d7d6-4be8-bc61-6b1122f2c581 / ext4 defaults,discard 0 1
UUID=EE50-6C37 /boot/efi vfat umask=0077 0 1
/dev/disk/cloud/azure_resource-part1 /mnt auto defaults,nofail,x-systemd.requires=cloud-init.service,comment=cloudconfig 02
UUID=a182ea7f-8634-41fe-a228-7b60aa28d7ba /data xfs defaults,nofail 0 2
Begin mindlamp app install
verify docker service is running:
clasrvadmin@cla-mindlamp:~$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2021-09-10 16:05:29 UTC; 5min ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 842 (dockerd)
Tasks: 8
Memory: 120.7M
CGroup: /system.slice/docker.service
└─842 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Sep 10 16:05:28 cla-mindlamp dockerd[842]: time="2021-09-10T16:05:28.494540003Z" level=warning msg="Your kernel does not support cg>
Sep 10 16:05:28 cla-mindlamp dockerd[842]: time="2021-09-10T16:05:28.494549803Z" level=warning msg="Your kernel does not support cg>
Sep 10 16:05:28 cla-mindlamp dockerd[842]: time="2021-09-10T16:05:28.495116214Z" level=info msg="Loading containers: start."
Sep 10 16:05:28 cla-mindlamp dockerd[842]: time="2021-09-10T16:05:28.819693596Z" level=info msg="Default bridge (docker0) is assign>
Sep 10 16:05:28 cla-mindlamp dockerd[842]: time="2021-09-10T16:05:28.913953062Z" level=info msg="Loading containers: done."
Sep 10 16:05:29 cla-mindlamp dockerd[842]: time="2021-09-10T16:05:29.113797406Z" level=warning msg="Not using native diff for overl>
Sep 10 16:05:29 cla-mindlamp dockerd[842]: time="2021-09-10T16:05:29.114036811Z" level=info msg="Docker daemon" commit=75249d8 grap>
Sep 10 16:05:29 cla-mindlamp dockerd[842]: time="2021-09-10T16:05:29.114617222Z" level=info msg="Daemon has completed initializatio>
Sep 10 16:05:29 cla-mindlamp dockerd[842]: time="2021-09-10T16:05:29.162998828Z" level=info msg="API listen on /run/docker.sock"
Sep 10 16:05:29 cla-mindlamp systemd[1]: Started Docker Application Container Engine.
we begin with “Deploying the LAMP Platform” on 9-10-2021
- Create a new docker overlay network called public to connect all externally accessible services:
docker network create --driver overlay --attachable public
Immediately this step fails for me with:
clasrvadmin@cla-mindlamp:~$ docker network create --driver overlay --attachable public
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
so we run docker swarm init
as instructed on the Preparing Resources on AWS page of the documentation. This can be found in the last step of part two under the section heading “For EC2 Instances Only”:
clasrvadmin@cla-mindlamp:~$ docker swarm init
Swarm initialized: current node (1eb05ch5e46vtgbj733a9b81e) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token <REDACTED> 10.0.0.4:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Now we can create the overlay network:
clasrvadmin@cla-mindlamp:~$ docker network create --driver overlay --attachable public
wvym0x8w3aa2ki1ugc1zwqtzj
traefik
the traefik.yml
file:
version: "3.7"
services:
traefik:
image: traefik:latest
command:
- "--log.level=INFO"
- "--accesslog=true"
- "--api=true"
- "--providers.docker=true"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedByDefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls.certResolver=default"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entryPoint.permanent=true"
- "--certificatesResolvers.default.acme.email=<REDACTED>"
- "--certificatesResolvers.default.acme.storage=/data/acme.json"
- "--certificatesResolvers.default.acme.tlsChallenge=true"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "traefik-ssl:/data/"
ports:
- target: 80
protocol: tcp
published: 80
mode: ingress
- target: 443
protocol: tcp
published: 443
mode: ingress
networks:
- public
deploy:
mode: replicated
placement:
constraints:
- node.role == manager
networks:
public:
external: true
volumes:
traefik-ssl:
clasrvadmin@cla-mindlamp:~/mindlamp$ docker stack deploy --compose-file traefik.yml router
Creating service router_traefik
clasrvadmin@cla-mindlamp:~/mindlamp$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4f1a9d214a15 traefik:latest "/entrypoint.sh --lo…" 6 seconds ago Up 5 seconds 80/tcp router_traefik.1.tz1dhkwkqv6wivbkex1j04b2i
Initialize lamp platform
Make sure the couchdb folder is created otherwise the database container will fail to start:
mkdir -p /data/couchdb
generate secrets:
clasrvadmin@cla-mindlamp:~/mindlamp$ openssl rand -hex 8 # DB_PASSWORD_HERE
<REDACTED>
clasrvadmin@cla-mindlamp:~/mindlamp$ openssl rand -hex 32 # 32_BIT_ENCRYPTION_KEY_HERE
<REDACTED>
clasrvadmin@cla-mindlamp:~/mindlamp$
The lamp.yml
file:
clasrvadmin@cla-mindlamp:~/mindlamp$ cat lamp.yml
version: '3.7'
services:
server:
image: bidmcdigitalpsychiatry/lamp-server:2020
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:3000 || exit 1
environment:
HTTPS: 'off'
ROOT_KEY: '<REDACTED>'
CDB: 'http://admin:<REDACTED>@database:5984/'
PUSH_API_GATEWAY: 'https://app-gateway.lamp.digital/'
PUSH_API_KEY: '<REDACTED>'
DASHBOARD_URL: 'dashboard.lamp.digital'
REDIS_HOST: 'redis://cache:6379/0'
NATS_SERVER: 'message_queue:4222'
networks:
- public
- default
deploy:
mode: replicated
update_config:
order: start-first
failure_action: rollback
labels:
traefik.enable: 'true'
traefik.docker.network: 'public'
traefik.http.routers.lamp_server.entryPoints: 'websecure'
traefik.http.routers.lamp_server.rule: 'Host(`api.mindlamp.temple.edu`)'
traefik.http.routers.lamp_server.tls.certresolver: 'default'
traefik.http.services.lamp_server.loadbalancer.server.port: 3000
placement:
constraints:
- node.role == manager
database:
image: apache/couchdb:3.1.1
healthcheck:
test: curl --fail --silent http://localhost:5984/_up || exit 1
environment:
COUCHDB_USER: 'admin'
COUCHDB_PASSWORD: '<REDACTED>'
volumes:
- /data/couchdb:/opt/couchdb/data
networks:
- public
deploy:
mode: replicated
update_config:
order: stop-first
failure_action: rollback
labels:
traefik.enable: 'true'
traefik.http.routers.lamp_database.entryPoints: 'websecure'
traefik.http.routers.lamp_database.rule: 'Host(`db.mindlamp.temple.edu`)'
traefik.http.routers.lamp_database.tls.certresolver: 'default'
traefik.http.services.lamp_database.loadbalancer.server.port: 5984
placement:
constraints:
- node.role == manager
cache:
image: redis:6.0.8-alpine
healthcheck:
test: redis-cli ping
deploy:
mode: replicated
update_config:
order: stop-first
failure_action: rollback
placement:
constraints:
- node.role == manager
message_queue:
image: nats:2.1.9-alpine3.12
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:8222/varz || exit 1
deploy:
mode: replicated
update_config:
order: start-first
failure_action: rollback
placement:
constraints:
- node.role == manager
networks:
public:
external: true
first attempt running the above via docker stack deploy
fails with:
clasrvadmin@cla-mindlamp:~/mindlamp$ docker stack deploy --compose-file lamp.yml lamp
services.server.logging Additional property max-file is not allowed
removing max-file
and max-size
because neither is permitted:
clasrvadmin@cla-mindlamp:~/mindlamp$ docker stack deploy --compose-file lamp.yml lamp
services.server.logging Additional property max-size is not allowed
removed the entire logging
block, now running:
clasrvadmin@cla-mindlamp:~/mindlamp$ docker stack deploy --compose-file lamp.yml lamp
Creating network lamp_default
Creating service lamp_message_queue
Creating service lamp_server
Creating service lamp_database
Creating service lamp_cache
testing the lamp platform
Following steps from the docs section labeled ‘testing’
verify the couchDB:
curl -k https://admin:<REDACTED>@db.mindlamp.temple.edu/
clasrvadmin@cla-mindlamp:~/mindlamp$ curl -k https://admin:<REDACTED>@db.mindlamp.temple.edu/
{"couchdb":"Welcome","version":"3.1.1","git_sha":"ce596c65d","uuid":"<REDACTED>","features":["access-ready","partitioned","pluggable-storage-engines","reshard","scheduler"],"vendor":{"name":"The Apache Software Foundation"}}
Verify the status of the LAMP Platform API Server:
clasrvadmin@cla-mindlamp:~/mindlamp$ curl -k https://api.mindlamp.temple.edu
{
"openapi": "3.0.0",
"info": {
"title": "LAMP Platform",
"description": "The LAMP Platform API.",
"termsOfService": "https://lamp.digital/terms-of-service/",
"version": "1.0.0",
"contact": {
"url": "https://digitalpsych.org/",
"email": "team@digitalpsych.org",
"name": "Division of Digital Psychiatry at Beth Israel Deaconess Medical Center."
}
},
...
Generate your server administrator password:
clasrvadmin@cla-mindlamp:~/mindlamp$ curl -k https://api.mindlamp.temple.edu/researcher -H 'Authorization: Basic admin:admin'
{
"error": "403.invalid-credentials"
}
note: This failed for me and I did not need to create a credential using the above method. The lamp_server service logs show that a default pw was already generated by the app:
lamp_server.1.4qe1x2eintgr@cla-mindlamp | 'Because no master configuration could be located, an initial administrator password was generated and saved for this installation.'
lamp_server.1.4qe1x2eintgr@cla-mindlamp | ┌────────────────────────┬────────────────────────────────────────────────────────────────────┐
lamp_server.1.4qe1x2eintgr@cla-mindlamp | │ (index) │ Values │
lamp_server.1.4qe1x2eintgr@cla-mindlamp | ├────────────────────────┼────────────────────────────────────────────────────────────────────┤
lamp_server.1.4qe1x2eintgr@cla-mindlamp | │ Administrator Password │ '<REDACTED>' │
lamp_server.1.4qe1x2eintgr@cla-mindlamp | └────────────────────────┴────────────────────────────────────────────────────────────────────┘
Check the Docker service logs for LAMP_server to locate your generated server administrator password:
docker service logs lamp_server | grep Administrator
Verify that the newly generated password (GENERATED_PASSWORD_HERE) works:
clasrvadmin@cla-mindlamp:~/mindlamp$ curl -k https://api.mindlamp.temple.edu/researcher -H 'Authorization: Basic admin:<REDACTED>'
{
"data": []
}
A failure here returns with 403.invalid-credentials
:
{
"error": "403.invalid-credentials"
}
The following is taken from the testing page of the docs. however, the referenced markdown link is not properly rendered and I don’t follow what should be done here. The text “Create Surveys” is bold but doesn’t link to anything in the docs. Searching the docs results in this URL: /consortium/admin/create_survey/ but it’s unclear to me if that is what operational testing of the app should entail at this stage:
Create a Researcher and a Participant using the browser management user interface to verify the setup works as expected. To jumpstart your instance of the LAMP Platform and test surveys or other activities, follow the instructions in Create Surveys and import the file below into the Researcher you just created.
[lamp_example_survey_battery_export.json](Testing the LAMP Platform/export.json)
If any of the above steps fails to complete successfully you will not be able to reach this step.
Accessing the App
Here I am following the guidance outlined for accessing an account:
Navigated to the lamp dashboard login page.
enter api.mindlamp.temple.edu for the api endpoint.
user: admin
pw: use the above admin pw generated and pulled from the server logs.