Blog

Tutorial: Deploy the d0a1 stack in 30 minutes (step by step)

Deploying the d0a1 stack takes about 30 minutes if you follow this guide to the letter. We assume a clean VPS with Ubuntu 24.04 and a domain pointed at it.

1. Prerequisites

  • VPS Ubuntu 24.04 — minimum 2 vCPU, 8 GB RAM. Recommended: 4 vCPU, 16 GB RAM to run 14B models without swap.
  • Domain pointed to the VPS with A and AAAA (IPv6) records.
  • SSH access with a public key (not password).
  • Docker + Docker Compose installed (we install them if missing).

2. Prepare the VPS

# Connect to the VPS
ssh user@your-domain.com

# Update
sudo apt update && sudo apt upgrade -y

# Install Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in for the group to apply

# Install Docker Compose (comes with docker-compose-plugin)
sudo apt install -y docker-compose-plugin
docker compose version

3. Clone the workspace

git clone https://git.d0a1.es/d0a1/workspace.git
cd workspace
ls -la

You will find:

  • docker-compose.yml — orchestration for 15+ services.
  • .env.example — environment variable template.
  • manage.sh — control script (start / stop / logs / backup).
  • README.md — extended documentation.

4. Configure environment variables

cp .env.example .env
nano .env

Key variables you need to fill in:

# Main domain
DOMAIN=d0a1.es
ADMIN_EMAIL=hello@d0a1.es

# Database (change the passwords)
DB_PASSWORD=change-me-now
DB_ROOT_PASSWORD=change-me-too

# Ollama (default model)
OLLAMA_DEFAULT_MODEL=llama3.1:8b

# SMTP (for outgoing email, if you have it)
SMTP_HOST=smtp.your-provider.com
SMTP_PORT=587
SMTP_USER=hello@d0a1.es
SMTP_PASSWORD=your-password

# Qdrant (vector store)
QDRANT_API_KEY=$(openssl rand -hex 32)

# Custom SSH port (recommended for security)
SSH_PORT=2222

5. Bring up the stack

./manage.sh start

This brings up, in order:

  1. Project internal network
  2. PostgreSQL (structured data)
  3. Redis (cache + object cache + sessions)
  4. Qdrant (vector store)
  5. Ollama (local LLM — downloads the default model)
  6. WordPress + php-fpm + WP-CLI
  7. n8n (automations)
  8. Open WebUI (chat interface for Ollama)
  9. Traefik (reverse proxy + automatic HTTPS with Let’s Encrypt)
  10. Watchtower (auto-update for images)

The first boot takes 5-10 minutes (image + LLM model downloads). Subsequent boots are seconds.

6. Verify everything works

./manage.sh status
# Verifies all containers are "healthy"

curl -I https://$DOMAIN
# Should return 200 OK with HTTPS

# Test Ollama
curl http://localhost:11434/api/tags
# Lists downloaded models

# Test Qdrant
curl http://localhost:6333/collections
# Lists existing collections

7. WordPress post-install

# Enter the WordPress container
docker compose exec wordpress bash

# Install WP-CLI if not present
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp

# Create admin user (replace values)
wp user create admin admin@d0a1.es --role=administrator --user_pass="StrongPass123!"

# Activate base plugins
wp plugin activate polylang redis-cache code-snippets wp-mail-smtp

# Install the d0a1-binary theme
wp theme install d0a1-binary --activate

# Create a child theme (optional but recommended)
wp scaffold child-theme d0a1-custom --parent_theme=d0a1-binary
wp theme activate d0a1-custom

8. First automations

With the stack running, activate extensions and workflows as needed:

# Extension: automatic backups
docker compose exec wordpress wp plugin activate scheduled-backup
# Configure rclone pointing at your B2 bucket
docker compose exec wordpress rclone config

# Skill: SEO operator
docker compose exec wordpress wp plugin activate seo-content-operator

# Workflow: auto-publish
# Activate via the n8n UI at https://$DOMAIN:5678

9. Basic hardening

  • Change the SSH port (already done in .env).
  • Disable password login: sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config && sudo systemctl restart sshd
  • Set up fail2ban for SSH and WordPress login.
  • Enable UFW: sudo ufw allow 80/tcp && sudo ufw allow 443/tcp && sudo ufw allow 2222/tcp && sudo ufw enable.
  • Rotate the API keys in .env every 90 days.

10. Periodic maintenance

# Update the whole stack
./manage.sh update

# Full backup (DB + uploads)
./manage.sh backup

# View logs from all services
./manage.sh logs

# View resource usage
./manage.sh stats

That’s it. In less than an hour you have WordPress + Ollama + n8n + Qdrant + 15 more services running under HTTPS, with automated backups and a unified control panel.

If you get stuck, open an issue at git.d0a1.es/d0a1/workspace or ask in the support channel.