diff --git a/docker-compose.yml b/docker-compose.yml
index d683f8568..c52fd4f2a 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,3 +1,4 @@
+name: labca
 services:
   boulder:
     # The `letsencrypt/boulder-tools:latest` tag is automatically built in local
@@ -14,12 +15,14 @@ services:
       # to the IP address where your ACME client's solver is listening. This is
       # pointing at the boulder service's "public" IP, where challtestsrv is.
       FAKE_DNS: 64.112.117.122
-      BOULDER_CONFIG_DIR: test/config
+      BOULDER_CONFIG_DIR: labca/config
       GOCACHE: /boulder/.gocache/go-build
     volumes:
-      - .:/boulder:cached
+      - .:/opt/boulder:cached
+      - /home/labca/boulder_labca:/opt/boulder/labca
+      - /home/labca/nginx_data/static:/var/www/html
       - ./.gocache:/root/.cache/go-build:cached
-      - ./test/certs/.softhsm-tokens/:/var/lib/softhsm/tokens/:cached
+      - /home/labca/boulder_labca/certs/.softhsm-tokens/:/var/lib/softhsm/tokens/
     networks:
       bouldernet:
         ipv4_address: 10.77.77.77
@@ -50,117 +53,137 @@ services:
       - 4001:4001 # ACMEv2
       - 4003:4003 # SFE
     depends_on:
-      - bmariadb
-      - bproxysql
-      - bvitess
-      - bredis_1
-      - bredis_2
+      - bmysql
+      - bredis
       - bconsul
-      - bjaeger
       - bpkimetal
-    entrypoint: test/entrypoint.sh
-    working_dir: &boulder_working_dir /boulder
-
-  bsetup:
-    image: *boulder_tools_image
-    volumes:
-      - .:/boulder:cached
-      - ./.gocache:/root/.cache/go-build:cached
-      - ./test/certs/.softhsm-tokens/:/var/lib/softhsm/tokens/:cached
-    entrypoint: test/certs/generate.sh
-    working_dir: *boulder_working_dir
-    profiles:
-      # Adding a profile to this container means that it won't be started by a
-      # normal "docker compose up/run boulder", only when specifically invoked
-      # with a "docker compose up bsetup".
-      - setup
+      - control
+    entrypoint: labca/entrypoint.sh
+    working_dir: &boulder_working_dir /opt/boulder
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "500k"
+        max-file: "5"
+    restart: always
 
-  bmariadb:
+  bmysql:
     image: mariadb:10.11.13
+    volumes:
+      - dbdata:/var/lib/mysql
     networks:
       bouldernet:
         aliases:
-          - boulder-mariadb
+          - boulder-mysql
     environment:
       MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
-    # Send slow queries to a table so we can check for them in the
-    # integration tests. For now we ignore queries not using indexes,
-    # because that seems to trigger based on the optimizer's choice to not
-    # use an index for certain queries, particularly when tables are still
-    # small.
-    command: mysqld --bind-address=0.0.0.0 --slow-query-log --log-output=TABLE --log-queries-not-using-indexes=ON
+    command: mysqld --bind-address=0.0.0.0 --log-output=TABLE
     logging:
-      driver: none
-
-  bproxysql:
-    image: proxysql/proxysql:2.7.2
-    # The --initial flag force resets the ProxySQL database on startup. By
-    # default, ProxySQL ignores new configuration if the database already
-    # exists. Without this flag, new configuration wouldn't be applied until you
-    # ran `docker compose down`.
-    entrypoint: proxysql -f --idle-threads -c /test/proxysql/proxysql.cnf --initial
-    volumes:
-      - ./test/:/test/:cached
-    depends_on:
-      - bmariadb
-    networks:
-      bouldernet:
-        aliases:
-          - boulder-proxysql
+      driver: "json-file"
+      options:
+        max-size: "500k"
+        max-file: "5"
+    restart: always
 
-  bredis_1:
+  bredis:
     image: redis:7.0.15
     volumes:
       - ./test/:/test/:cached
-    command: redis-server /test/redis-ratelimits.config
+      - /home/labca/boulder_labca:/opt/boulder/labca
+    command: redis-server /opt/boulder/labca/redis-ratelimits.config
     networks:
       bouldernet:
         ipv4_address: 10.77.77.4
+    restart: always
 
-  bredis_2:
-    image: redis:7.0.15
+  bconsul:
+    image: hashicorp/consul:1.19.2
+    depends_on:
+      - control
     volumes:
-      - ./test/:/test/:cached
-    command: redis-server /test/redis-ratelimits.config
+      - /home/labca/boulder_labca:/opt/boulder/labca
     networks:
       bouldernet:
-        ipv4_address: 10.77.77.5
+        ipv4_address: 10.77.77.10
+    command: "consul agent -dev -config-format=hcl -config-file=/opt/boulder/labca/consul/config.hcl"
+    restart: always
 
-  bconsul:
-    image: hashicorp/consul:1.19.1
+  gui:
+    image: *boulder_tools_image
     volumes:
-     - ./test/:/test/:cached
+      - /var/run/docker.sock:/var/run/docker.sock
+      - /home/labca/admin:/go/src/labca
+      - ./.gocache:/root/.cache/go-build
+      - /home/labca/nginx_data/static:/var/www/html
+      - /home/labca/backup:/opt/backup
+      - .:/opt/boulder
+      - /home/labca/boulder_labca:/opt/boulder/labca
+      - /home/labca/boulder_labca/certs/.softhsm-tokens/:/var/lib/softhsm/tokens/
     networks:
-      bouldernet:
-        ipv4_address: 10.77.77.10
-    command: "consul agent -dev -config-format=hcl -config-file=/test/consul/config.hcl"
+      - bouldernet
+    expose:
+      - 3000
+    depends_on:
+      - bmysql
+      - control
+    working_dir: /go/src/labca
+    command: ./setup.sh
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "500k"
+        max-file: "5"
+    restart: always
 
-  bjaeger:
-    image: jaegertracing/all-in-one:1.50
+  nginx:
+    image: nginx:latest
     networks:
       - bouldernet
+    ports:
+      - 80:80
+      - 443:443
+    volumes:
+      - /home/labca/nginx_data/conf.d:/etc/nginx/conf.d
+      - /home/labca/nginx_data/ssl:/etc/nginx/ssl
+      - /home/labca/nginx_data/static:/var/www/html
+    depends_on:
+      - control
+    restart: always
+
+  control:
+    image: *boulder_tools_image
+    networks:
+      - bouldernet
+    volumes:
+      - /var/run/docker.sock:/var/run/docker.sock
+      - /home/labca/admin/data:/opt/labca/data
+      - /home/labca/admin/data:/opt/labca/gui/data
+      - /home/labca/admin/bin:/opt/labca/bin
+      - /home/labca/labca:/opt/labca
+      - /home/labca/backup:/opt/backup
+      - /home/labca/control_logs:/opt/logs
+      - .:/opt/boulder
+      - /home/labca/boulder_labca:/opt/boulder/labca
+      - /home/labca/boulder_labca/certs/.softhsm-tokens/:/var/lib/softhsm/tokens/
+      - /home/labca/nginx_data/conf.d:/etc/nginx/conf.d
+      - /home/labca/nginx_data/ssl:/etc/nginx/ssl
+      - /home/labca/nginx_data/static:/var/www/html
+    expose:
+      - 3030
+    environment:
+      LABCA_FQDN: ${LABCA_FQDN:-notset}
+    working_dir: /opt/labca
+    command: ./control.sh
+    restart: always
 
   bpkimetal:
     image: ghcr.io/pkimetal/pkimetal:v1.20.0
     networks:
       - bouldernet
+    restart: always
 
-  bvitess:
-    # The `letsencrypt/boulder-vtcomboserver:latest` tag is automatically built
-    # in local dev environments. In CI a specific BOULDER_VTCOMBOSERVER_TAG is
-    # passed, and it is pulled with `docker compose pull`.
-    image: letsencrypt/boulder-vtcomboserver:${BOULDER_VTCOMBOSERVER_TAG:-latest}
-    build:
-      context: test/vtcomboserver/
-    environment:
-      # By specifying KEYSPACES vttestserver will create the corresponding
-      # databases on startup.
-      KEYSPACES: boulder_sa_test,boulder_sa_integration,incidents_sa_test,incidents_sa_integration
-      NUM_SHARDS: 1,1,1,1
-    networks:
-      bouldernet:
-        aliases:
-          - boulder-vitess
+volumes:
+  dbdata:
 
 networks:
   # This network represents the data-center internal network. It is used for
