LAMP Consortium

Docker Stack - Can't create users, researchers result in spinner

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:

2021-09-10_15-50

“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

  1. 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.

Hi Lido, we had a similar problem back in May 2021, I’m copying some suggestions we got via email from Aditya Vaidyam, which helped for us. Best of luck.

This is likely because your backend is not updated

It should be as simple as using “docker service update —force LAMP_server” or pressing the “Update” button in the Portainer console and checking the “Pull latest image version” box. @Rebecca should be able to assist with this process if anything is amiss. In addition, please make sure to check that your Docker Stack file is up to date.

Another team actually had the same issue and shared some findings with us that helped resolve the problem. Please ensure that you are using the image “ghcr.io/bidmcdigitalpsychiatry/lamp-server:2021” — this should be the most correct label. In the past we have had two different image labels which due to various issues would not update to the latest version consistently, but that will not be a problem here.

You may need to add the Redis cache component that was recently introduced to the server. Our documentation has been updated to add that to the docker-compose.yml file. Once configured (should be a simple copy/paste), it should work as expected.

Thank you @laurelmorris!

I somehow missed that I was using the 2020 label. Pretty certain I copy/pasted directly from the docs when configuring everything. Glad to see they are updated now.

Can confirm the web UI is now working to create researchers and login as them after I updated the image label in lamp.yml to bidmcdigitalpsychiatry/lamp-server:2021 and ran:

clasrvadmin@cla-mindlamp:~/mindlamp$ docker service update --force lamp_server
lamp_server
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged

My full lamp.yml is now:

version: '3.7'
services:
  server:
    image: bidmcdigitalpsychiatry/lamp-server:2021
    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

Re-dployed with:

docker stack deploy --compose-file lamp.yml lamp

docker ps now shows the new label in use for the image:

clasrvadmin@cla-mindlamp:~/mindlamp$ docker ps
CONTAINER ID   IMAGE                                     COMMAND                  CREATED         STATUS                   PORTS                          NAMES
aacf6828d003   bidmcdigitalpsychiatry/lamp-server:2021   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes (healthy)   3000/tcp                       lamp_server.1.s02r8vwigllxudxbicn07armc
97ae8603909b   nats:2.1.9-alpine3.12                     "docker-entrypoint.s…"   4 minutes ago   Up 4 minutes (healthy)   4222/tcp, 6222/tcp, 8222/tcp   lamp_message_queue.1.knncllgvfsdte0kz1hfz0t0or
2b986129f9f2   redis:6.0.8-alpine                        "docker-entrypoint.s…"   4 minutes ago   Up 4 minutes (healthy)   6379/tcp                       lamp_cache.1.6wq41r4jhzi9k7fe1ibjtpkrd
f11be96e2c3e   apache/couchdb:3.1.1                      "tini -- /docker-ent…"   4 minutes ago   Up 4 minutes (healthy)   4369/tcp, 5984/tcp, 9100/tcp   lamp_database.1.x1iybm1fxyi9z6gu3ugxfgc8r
8525699dd165   traefik:latest                            "/entrypoint.sh --lo…"   2 days ago      Up 2 days                80/tcp                         router_traefik.1.z1f4z7ysh0zofk3q54mi2dgbe

thank you for following up on this!