diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cd4a460b845fa96c346ce545eaac736a7274082c..f9228f3ca8af8c3cd27d1faf5e41449e3e232f23 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -17,9 +17,9 @@ before_script:
   - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
 
 .test: &test
-  image: igwn/base:buster
+  image: igwn/base:bullseye
   services:
-    - postgres:12.5
+    - postgres:13.11
     - memcached
   variables:
     AWS_SES_ACCESS_KEY_ID: "fake_aws_id"
@@ -66,7 +66,6 @@ before_script:
     - apt-get -yqq update
     - apt-get -o dir::cache::archives="${APT_CACHE_DIR}" install -yqq
           git
-          libmariadbclient-dev
           libldap2-dev
           libsasl2-dev
           libssl-dev
@@ -78,11 +77,10 @@ before_script:
           pkg-config 
           libpng-dev 
           libfreetype6-dev 
-          libmariadb-dev-compat 
           libxslt-dev
           ${PYTHON}-pip
-          postgresql-12 
-          postgresql-client-12 
+          postgresql-13
+          postgresql-client-13
           libpq-dev
     # upgrade pip (requirement for lalsuite)
     - ${PYTHON} -m pip install --upgrade pip
diff --git a/Dockerfile b/Dockerfile
index d3522149d8c6ab0456d1a8dfabbae3e8610b9201..71879d3404a14be6ac9ecd05a48e26ddb036c139 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,16 +1,15 @@
-FROM igwn/base:buster
+FROM igwn/base:bullseye
 LABEL name="LIGO GraceDB Django application" \
       maintainer="alexander.pace@ligo.org" \
-      date="20200807"
+      date="20230802"
 ARG SETTINGS_MODULE="config.settings.container.dev"
 
 COPY docker/SWITCHaai-swdistrib.gpg /etc/apt/trusted.gpg.d
 COPY docker/backports.pref /etc/apt/preferences.d
-RUN echo 'deb http://pkg.switch.ch/switchaai/debian buster main' > /etc/apt/sources.list.d/shibboleth.list
-RUN echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/backports.list
-RUN echo 'deb http://apt.postgresql.org/pub/repos/apt buster-pgdg main' > /etc/apt/sources.list.d/pgdg.list
+RUN echo 'deb http://deb.debian.org/debian bullseye-backports main' > /etc/apt/sources.list.d/backports.list
+RUN echo 'deb http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main' > /etc/apt/sources.list.d/pgdg.list
 RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
-RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
+RUN curl -sL https://deb.nodesource.com/setup_18.x | bash -
 RUN apt-get update && \
     apt-get install --install-recommends --assume-yes \
         apache2 \
@@ -18,6 +17,7 @@ RUN apt-get update && \
         git \
         krb5-user \
         libkrb5-dev \
+        libapache2-mod-shib \
         libapache2-mod-xsendfile \
         libldap2-dev \
         libsasl2-dev \
@@ -33,16 +33,16 @@ RUN apt-get update && \
         nodejs \
         osg-ca-certs \
         php \
-        php7.3-mysql \
-        php7.3-pgsql \
-        php7.3-mbstring \
-        postgresql-client-12 \
-        python3.7 \
-        python3.7-dev \
+        php7.4-pgsql \
+        php7.4-mbstring \
+        postgresql-client-13 \
+        python3.9 \
+        python3.9-dev \
         python3-libxml2 \
         python3-pip \
         procps \
-        shibboleth \
+        shibboleth-sp-common \
+        shibboleth-sp-utils \
         libssl-dev \
         swig \
         htop \
diff --git a/config/settings/base.py b/config/settings/base.py
index 937aee4ca6653739700e3ca2b28beb5cb5a0613f..9cd09afa83c6034f6fe6747f6113754522da28e1 100644
--- a/config/settings/base.py
+++ b/config/settings/base.py
@@ -36,7 +36,7 @@ INFO_BANNER_MESSAGE = "TEST MESSAGE"
 BETA_REPORTS_LINK = False
 
 # Version ---------------------------------------------------------------------
-PROJECT_VERSION = '2.21.8'
+PROJECT_VERSION = '2.22.0'
 
 # Unauthenticated access ------------------------------------------------------
 # This variable should eventually control whether unauthenticated access is
diff --git a/docker/cleanup b/docker/cleanup
index 3e8c520ac69e0fa9a8c8d0927ce6c70b8d103f31..9ae066580b28afec2e15d516b99b3659d6463c00 100644
--- a/docker/cleanup
+++ b/docker/cleanup
@@ -1,8 +1,7 @@
 #!/bin/sh
 
-python3 /app/gracedb_project/manage.py update_user_accounts_from_ligo_ldap kagra
-python3 /app/gracedb_project/manage.py update_user_accounts_from_ligo_ldap ligo
-python3 /app/gracedb_project/manage.py remove_inactive_alerts
-python3 /app/gracedb_project/manage.py clearsessions
-python3 /app/gracedb_project/manage.py vacuum
-python3 /app/gracedb_project/manage.py vacuum_full
+python3 /app/gracedb_project/manage.py update_user_accounts_from_ligo_ldap kagra 2>&1 | grep -v segment
+python3 /app/gracedb_project/manage.py update_user_accounts_from_ligo_ldap ligo 2>&1 | grep -v segment
+python3 /app/gracedb_project/manage.py remove_inactive_alerts 2>&1 | grep -v segment
+python3 /app/gracedb_project/manage.py clearsessions 2>&1 | grep -v segment
+PGPASSWORD=$DJANGO_DB_PASSWORD psql -h $DJANGO_DB_HOST -U $DJANGO_DB_USER -c "VACUUM VERBOSE ANALYZE;" $DJANGO_DB_NAME
diff --git a/gracedb/ligoauth/management/commands/update_user_accounts_from_ligo_ldap.py b/gracedb/ligoauth/management/commands/update_user_accounts_from_ligo_ldap.py
index fd2378ada93ee3c50c31823fab2331279b49d719..01b0b59549d8a83d0403df5abcd439a23e63e45a 100644
--- a/gracedb/ligoauth/management/commands/update_user_accounts_from_ligo_ldap.py
+++ b/gracedb/ligoauth/management/commands/update_user_accounts_from_ligo_ldap.py
@@ -479,9 +479,6 @@ class LdapKagraResultProcessor(LdapPersonResultProcessor):
         self.assign_genericldapuser_to_cert(ldap_x509_subjects)
 
         # Get certs to add and remove
-        # certs_to_add = ldap_x509_subjects.difference(db_x509_subjects)
-        # certs_to_remove = db_x509_subjects.difference(ldap_x509_subjects)
-
         certs_to_add = ldap_x509_subjects - db_x509_subjects
         certs_to_remove = db_x509_subjects - ldap_x509_subjects
 
@@ -635,8 +632,6 @@ class KagraPeopleLdap(LigoPeopleLdap):
             raise TypeError(err_msg)
 
         # Return result data that has been filtered with DNs:
-
-        #return self.get_kagra_users_with_dns(result_data)
         return result_data
     
 
@@ -644,7 +639,6 @@ class KagraPeopleLdap(LigoPeopleLdap):
 # NOTE: not using robot OU right now since we are waiting
 # for some auth infrastructure changes to be able to properly group
 # certificates into a user account
-#LDAP_CLASSES = {l.name: l for l in (LigoPeopleLdap,)}
 LDAP_CLASSES = {l.name: l for l in (LigoPeopleLdap, KagraPeopleLdap,)}
 
 
@@ -662,8 +656,8 @@ class Command(BaseCommand):
             raise ValueError('Not properly set up for robot OU')
         verbose = not options['quiet']
         if verbose:
-            self.stdout.write('Refreshing users from LIGO LDAP at {0}' \
-                .format(datetime.datetime.utcnow()))
+            self.stdout.write('Refreshing users from {0} LDAP at {1}' \
+                .format(options['ldap'], datetime.datetime.utcnow()))
 
         # Set up ldap connection
         ldap_connection = LDAP_CLASSES[options['ldap']](verbose=verbose)
diff --git a/requirements.txt b/requirements.txt
index 949c70a233f50d7eff4db0f0699bc336ca47d5dc..3a4ce4c6ed42dcba8c8e47c69108795a500c91f7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,11 +1,11 @@
 adc-streaming==2.3.1
 aws-xray-sdk==2.11.0
 ConcurrentLogHandler==0.9.1
-cryptography==40.0.1
-Django==3.2.18
-django-computedfields==0.2.1
-django-debug-toolbar==3.2.2
-django-extensions==3.2.1
+cryptography==41.0.3
+Django==3.2.20
+django-computedfields==0.2.3
+django-debug-toolbar==4.1.0
+django-extensions==3.2.3
 django-guardian==2.4.0
 django-model-utils==4.2.0
 django-postgres-vacuum==2020.12.24
@@ -15,10 +15,10 @@ django-twilio==0.13.2
 django-user-sessions==2.0.0
 djangorestframework==3.12.2
 djangorestframework-guardian==0.3.0
-dnspython==1.15.0
-flake8==3.8.0
-gpstime==0.5.5
-gssapi==1.6.14
+dnspython==2.4.1
+flake8==3.9.2
+gpstime==0.6.2
+gssapi==1.8.2
 #gunicorn==20.1.0
 # Run the fixed version of gunicorn until a release comes out:
 # https://github.com/benoitc/gunicorn/issues/2917
@@ -26,39 +26,39 @@ git+https://github.com/benoitc/gunicorn.git@a423fca8e5bf78f64ee10e0e754b7b65eabc
 hop-client==0.8.0
 html5lib==1.1.0
 igwn-alert-overseer==0.6.0
-ipdb==0.13.6
-ipython==7.21.0
+ipdb==0.13.13
+ipython==8.14.0
 #jwt==1.3.1
-Jinja2==3.0.1
+Jinja2==3.1.2
 lalsuite==6.82
 python-ligo-lw==1.8.3
-lxml==4.6.0
+lxml==4.9.3
 matplotlib==3.3.4
 mock==2.0.0
-numpy==1.20.0
-packaging==17.1
-phonenumbers==8.13.16
-plotly==4.14.3
-psycopg2==2.8.6
-PyJWT==2.3.0
-python-ldap==3.3.1
+numpy==1.25.2
+packaging==23.1
+phonenumbers==8.13.18
+plotly==5.15.0
+psycopg2==2.9.6
+PyJWT==2.8.0
+python-ldap==3.4.3
 pymemcache==4.0.0
 #pyopenssl==23.0.0
-scipy==1.6.1
-scitokens==1.6.2
+scipy==1.11.1
+scitokens==1.7.4
 sentry-sdk==0.7.10
-service_identity==21.1.0
-simplejson==3.15.0
+service_identity==23.1.0
+simplejson==3.19.1
 six==1.16.0
-Sphinx==2.1.0
-sphinx-rtd-theme
+Sphinx==6.2.1
+sphinx-rtd-theme==1.2.2
 twilio==6.10.3
 voevent-parse==1.0.3
 pyparsing==3.0.9
-pytest==6.2.2
-pytest-cov==2.11.1
-pytest-django==4.1.0
-pytz==2021.1
+pytest==7.4.0
+pytest-cov==4.1.0
+pytest-django==4.5.2
+pytz==2023.3
 pyasn1==0.4.8
 pyasn1-modules==0.2.8
 # retry bandaid for efs errors: