diff --git a/.tugboat/config.yml b/.tugboat/config.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c6c8bcd6d3224ffe1d3a73d0fcd994b027fde187
--- /dev/null
+++ b/.tugboat/config.yml
@@ -0,0 +1,85 @@
+services:
+  php:
+    # Specify the version of Drupal you wish to use for Tugboat below.
+    image: tugboatqa/drupal:11
+    default: true
+    http: false
+    depends: mysql
+    commands:
+      update:
+        # Run various commands from the drupal/recommended-project root.
+        - |
+          set -eux
+
+          # This is an environment variable we added in the Dockerfile that
+          # provides the path to Drupal composer root (not the web root).
+          cd $DRUPAL_COMPOSER_ROOT
+
+          # Configure composer to require this module as a symlink.
+          composer config minimum-stability dev
+          composer config repositories.tugboat path $TUGBOAT_ROOT
+          composer require \
+            drupal/civictheme \
+            drupal/default_content \
+            drupal/experience_builder \
+            drupal/components
+
+          # Install Drupal on the site.
+          rm -f $DRUPAL_DOCROOT/sites/default/settings.php
+          php -d memory_limit=-1 \
+            vendor/bin/drush.php \
+            --yes \
+            --db-url=mysql://tugboat:tugboat@mysql:3306/tugboat \
+            --site-name="Live preview for ${TUGBOAT_PREVIEW_NAME}" \
+            --account-pass=admin \
+            site:install standard
+
+          # Require settings.local.php increase CLI memory limit, add trusted
+          # host patterns, and allow for enabling hidden xb_dev_standard module.
+          echo "require_once '$TUGBOAT_ROOT/.tugboat/settings.local.php';" >> $DOCROOT/sites/default/settings.php
+
+          # Set up the files directory permissions.
+          mkdir -p $DRUPAL_DOCROOT/sites/default/files
+          chgrp -R www-data $DRUPAL_DOCROOT/sites/default/files
+          chmod 2775 $DRUPAL_DOCROOT/sites/default/files
+          chmod -R g+w $DRUPAL_DOCROOT/sites/default/files
+
+          # Enable the module.
+          vendor/bin/drush --yes pm:install \
+            components \
+            default_content \
+            experience_builder \
+            media_library \
+            xb_dev_standard
+
+          # Enable starshot_demo theme.
+          vendor/bin/drush --yes theme:enable starshot_demo
+          vendor/bin/drush --yes config:set system.theme default starshot_demo
+
+          # Create node/1
+          vendor/bin/drush scr $TUGBOAT_ROOT/.tugboat/create-article-node.php
+
+      build:
+        # Update Drupal core composer packages and run any Drupal updates.
+        - |
+          set -eux
+          cd $DRUPAL_COMPOSER_ROOT
+          composer install --optimize-autoloader
+          # Update packages and dependencies.
+          composer update --with-all-dependencies \
+            drupal/civictheme \
+            drupal/default_content \
+            drupal/components \
+            drupal/experience_builder
+          # Run Drupal updates
+          vendor/bin/drush --yes updb
+          vendor/bin/drush cache:rebuild
+
+        # Ensure web user can access theme files.
+        - chgrp -R www-data .
+
+        # Warm Drupal caches
+        - 'curl --silent --header "Host: $TUGBOAT_DEFAULT_SERVICE_URL_HOST" http://localhost > /dev/null'
+
+  mysql:
+    image: tugboatqa/mariadb
diff --git a/.tugboat/create-article-node.php b/.tugboat/create-article-node.php
new file mode 100644
index 0000000000000000000000000000000000000000..aaf16e441e13e32d601fcb8cbc1fe6d4521888b2
--- /dev/null
+++ b/.tugboat/create-article-node.php
@@ -0,0 +1,14 @@
+<?php
+
+declare(strict_types=1);
+
+// We assume the "Standard" profile is installed at this point, along with the
+// Experience Builder modules.
+
+use Drupal\node\Entity\Node;
+
+$node = Node::create([
+  'type' => 'article',
+  'title' => 'Test article node for XB+SDDS (go to /xb/node/1 to test)',
+]);
+$node->save();
diff --git a/.tugboat/settings.local.php b/.tugboat/settings.local.php
new file mode 100644
index 0000000000000000000000000000000000000000..21981c3b95aa2b894503cb99262c74ca3c574bc4
--- /dev/null
+++ b/.tugboat/settings.local.php
@@ -0,0 +1,13 @@
+<?php
+// phpcs:ignoreFile
+
+// Add tugboat URLs to the Drupal trusted host patterns.
+$settings['trusted_host_patterns'] = ['\.tugboatqa\.com$'];
+
+// Set memory_limit to unlimited for CLI operations.
+if (PHP_SAPI === 'cli') {
+  ini_set('memory_limit', '-1');
+}
+
+// Allow the `xb_dev_standard` hidden module to be installed.
+$settings['extension_discovery_scan_tests'] = TRUE;