-
Verify cloud-init — run cloud-init status. If not done, retry every 10 seconds for up to 120 seconds. If still not done at the end of the wait, report the current status and stop — do not proceed.
-
Locate and mount data volume:
a. Run lsblk to identify the data volume device. On Cyso/OpenStack, Cinder volumes appear as /dev/sdb (virtio-scsi), not /dev/vdb (virtio-blk).
b. Check for an existing filesystem: sudo blkid <device>. If no filesystem is reported, format: sudo mkfs.ext4 <device>. If a filesystem already exists, skip formatting.
c. Create the mount point and mount:
sudo mkdir -p /data
sudo mount <device> /data
d. Register in fstab using UUID (not device path):
echo "UUID=$(sudo blkid -s UUID -o value <device>) /data ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab
e. Verify: mount | grep /data
-
Fix app directory ownership — cloud-init creates __APP_DIR__ as root; always correct this:
sudo chown -R ubuntu:ubuntu __APP_DIR__
If __APP_DIR__ does not exist, create it first: sudo mkdir -p __APP_DIR__ && sudo chown ubuntu:ubuntu __APP_DIR__
-
Create .env file (only if the stack needs runtime environment variables — skip if the
project has no such requirement):
a. Write the minimum required values to __APP_DIR__/.env, e.g.:
NODE_ENV=production
PORT=<app-port>
DB_PATH=/data/<project-slug>.db
b. Set permissions: chmod 600 __APP_DIR__/.env
c. Do NOT write ANTHROPIC_API_KEY to this file now. Populate it manually via SSH after deployment is complete — never write its value to any file tracked in version control or stored in Terraform state.
-
Add ubuntu to docker group:
sudo usermod -aG docker ubuntu
newgrp docker
usermod does not take effect in the current SSH session. newgrp docker activates the group for the current session. CI/CD pipelines use a fresh SSH session and inherit the updated group automatically.
-
Remove the stock default nginx site:
bash scripts/remove-default-nginx-site.sh
The distro's default site and this project's own site both declaring default_server fails
nginx -t with "duplicate default server", leaving the previous config silently active after a
reload. Idempotent — safe to re-run on every bootstrap/deploy, including when a second,
co-hosted site is added later.
-
Smoke test — run docker ps. Expected result: empty container list with no permission error.