
Self-hosting Qdrant with Docker on an Ubuntu Server

Looking to power AI apps with vector search but want full control over your infrastructure? By self-hosting Qdrant on a Linux Ubuntu server, you can avoid usage-based pricing and ensure your data stays where you want it.
This comprehensive guide will walk you through deploying a production-ready Qdrant instance using Docker and Caddy for automatic HTTPS. You'll learn about security, monitoring, backups, and performance optimization.
Why Self-Host Qdrant?
- Cost Control: Avoid per-vector pricing and usage-based fees
- Data Privacy: Keep your vectors and metadata on your own infrastructure
- Full Control: Configure exactly what you need without platform limitations
- No Vendor Lock-in: Migrate your data anytime without restrictions
- Custom Networking: Set up VPNs, custom domains, and advanced firewall rules
Prerequisites
Before we begin, ensure you have:
- A running Ubuntu Linux server (20.04 LTS or newer recommended)
- At least 2GB RAM and 2 CPU cores (4GB+ recommended for production)
- 20GB+ available disk space
- A domain name pointing to your server (optional but recommended)
- Basic SSH and command line skills
Want to self-host Qdrant without managing your own server? Deploy it on Sliplane in 45 seconds with built-in HTTPS and volume persistence.
Step 1: Update Your Server
SSH into your Ubuntu server and apply updates:
sudo apt-get update
sudo apt-get upgrade -y
This ensures your server has the latest security patches and packages.
Step 2: Configure Firewall
Since Docker bypasses traditional Linux firewalls like UFW, use your cloud provider's firewall:
- Hetzner: Cloud Firewall
- DigitalOcean: Firewall rules in control panel
- AWS: Security Groups
- Google Cloud: VPC firewall rules
- Azure: Network Security Groups
Configure these inbound rules:
- Port 22 (SSH) - Your IP only
- Port 80 (HTTP) - Public
- Port 443 (HTTPS) - Public
Cloud provider firewalls work at the network level before traffic reaches your server, providing better security than host-based firewalls.
Step 3: Docker Installation
Install Docker and dependencies:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
Add Docker's official repo:
echo \
"deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo $VERSION_CODENAME) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Install Docker Engine and plugins:
sudo apt-get install docker-ce docker-ce-cli \
containerd.io docker-buildx-plugin docker-compose-plugin -y
Verify Docker works:
sudo docker run hello-world
Step 4: Installing Caddy for Automatic HTTPS
Caddy will reverse proxy to Qdrant and handle Let's Encrypt certificates.
Install Caddy:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy -y
Edit the Caddyfile config:
sudo nano /etc/caddy/Caddyfile
Use your domain:
yourdomain.com {
reverse_proxy localhost:6333
}
Or temporarily for local IP testing:
:80 {
reverse_proxy localhost:6333
}
Restart Caddy:
sudo systemctl restart caddy
Step 5: Running Qdrant with Docker Compose
Create a directory for Qdrant and go into it:
mkdir ~/qdrant
cd ~/qdrant
Create docker-compose.yml
:
services:
qdrant:
image: qdrant/qdrant:latest
container_name: qdrant
restart: unless-stopped
ports:
- "6333:6333" # REST API
- "6334:6334" # gRPC API (optional)
volumes:
- qdrant_data:/qdrant/storage
- ./config:/qdrant/config
environment:
- QDRANT__SERVICE__API_KEY=your-secret-key-here
- QDRANT__LOG_LEVEL=INFO
- QDRANT__SERVICE__HTTP_PORT=6333
- QDRANT__SERVICE__GRPC_PORT=6334
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:6333/healthz"]
interval: 30s
timeout: 10s
retries: 3
networks:
- qdrant-network
networks:
qdrant-network:
driver: bridge
volumes:
qdrant_data:
driver: local
Important: Replace your-secret-key-here
with a strong, randomly generated API key. Generate one with:
openssl rand -hex 32
If you remove the API key environment variable, Qdrant will run without authentication (not recommended for production).
Create a config directory and optional configuration file:
mkdir config
Create config/production.yaml
(optional, for advanced configuration):
service:
http_port: 6333
grpc_port: 6334
enable_cors: true
storage:
performance:
max_search_threads: 0 # Use all available CPU cores
max_optimization_threads: 0
log_level: "INFO"
Start Qdrant:
sudo docker compose up -d
Check that it's running:
sudo docker compose ps
sudo docker compose logs qdrant
Qdrant is now running and accessible on port 6333.
Step 6: Accessing Your Self-Hosted Qdrant Instance
Open your domain in a browser. You should see the Qdrant dashboard at:
https://yourdomain.com/dashboard
Test the API with curl:
# Health check
curl https://yourdomain.com/healthz
# List collections (requires API key)
curl -X GET 'https://yourdomain.com/collections' \
-H 'api-key: your-secret-key-here'
# Create a test collection
curl -X PUT 'https://yourdomain.com/collections/test' \
-H 'Content-Type: application/json' \
-H 'api-key: your-secret-key-here' \
-d '{
"vectors": {
"size": 4,
"distance": "Cosine"
}
}'
Security Hardening
Essential Security Measures
1. Strong API Keys
# Generate a secure 32-byte API key
openssl rand -hex 32
2. Regular Security Updates
# Set up automatic security updates
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades
3. Fail2ban Protection
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
4. SSH Key Authentication
# Disable password authentication in /etc/ssh/sshd_config
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart ssh
5. IP Allowlisting
For IP-based access control, configure your cloud provider's firewall to only allow specific IP ranges on ports 80/443. This is more reliable than application-level restrictions.
Monitoring and Maintenance
Health Monitoring
Create a simple health check script:
nano ~/health-check.sh
#!/bin/bash
API_KEY="your-secret-key-here"
QDRANT_URL="https://yourdomain.com"
response=$(curl -s -w "%{http_code}" -X GET "${QDRANT_URL}/healthz" -H "api-key: ${API_KEY}")
http_code="${response: -3}"
if [ "$http_code" = "200" ]; then
echo "$(date): Qdrant is healthy"
else
echo "$(date): Qdrant health check failed (HTTP $http_code)"
# Optional: send alert email or notification
fi
Make it executable and add to cron:
chmod +x ~/health-check.sh
crontab -e
# Add: */5 * * * * /home/ubuntu/health-check.sh >> /var/log/qdrant-health.log
Backup Strategy
For production deployments, we recommend using your cloud provider's built-in backup solutions:
Option 1: Cloud Provider Block Storage Snapshots (Recommended)
Most cloud providers offer automated volume snapshots:
- Hetzner: Use Cloud Volume snapshots via the console or API
- DigitalOcean: Enable automated Droplet backups or Volume snapshots
- AWS: Use EBS snapshots with lifecycle policies
- Google Cloud: Use persistent disk snapshots
These snapshots are incremental, crash-consistent, and can be automated with retention policies.
Option 2: Restic + S3 for Cross-Cloud Backups
For a cloud-agnostic backup solution, use Restic with S3-compatible storage:
# Install Restic
sudo apt update
sudo apt install restic -y
# Initialize repository (one time)
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
restic -r s3:s3.amazonaws.com/your-bucket/qdrant-backups init
# Create backup script
nano ~/backup-qdrant.sh
#!/bin/bash
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
RESTIC_REPOSITORY="s3:s3.amazonaws.com/your-bucket/qdrant-backups"
# Stop Qdrant for consistency (optional but recommended)
docker compose stop qdrant
# Backup the Docker volume
restic -r $RESTIC_REPOSITORY backup /var/lib/docker/volumes/qdrant_qdrant_data/_data \
--tag qdrant \
--cleanup-cache
# Start Qdrant again
docker compose start qdrant
# Prune old backups (keep last 7 daily, 4 weekly, 12 monthly)
restic -r $RESTIC_REPOSITORY forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
Schedule automated backups:
chmod +x ~/backup-qdrant.sh
crontab -e
# Add: 0 2 * * * /home/ubuntu/backup-qdrant.sh >> /var/log/qdrant-backup.log 2>&1
Restic provides deduplication, encryption, and works with any S3-compatible storage (AWS S3, Backblaze B2, Wasabi, MinIO).
Updating Your Qdrant Installation
To upgrade to the latest version:
cd ~/qdrant
sudo docker compose pull
sudo docker compose up -d
Your data persists across updates thanks to Docker volumes.
Cost Comparison with Other Providers
Self-hosting Qdrant can save significant money:
Provider | vCPU | RAM | Storage | Monthly Cost | Setup Complexity |
---|---|---|---|---|---|
Pinecone | N/A | N/A | N/A | $30–300+ | ⭐ Easy |
Qdrant Cloud | 2 | 2 GB | 10 GB | $30–49 | ⭐ Easy |
Weaviate Cloud | 2 | 2 GB | 20 GB | $25–40 | ⭐ Easy |
Sliplane | 2 | 2 GB | 40 GB | €9 | ⭐ Easy |
Hetzner (self-hosted) | 2 | 4 GB | 40 GB | €5–8 | ⭐⭐⭐ Advanced |
DigitalOcean (self-hosted) | 2 | 2 GB | 50 GB | $12–18 | ⭐⭐⭐ Advanced |
Self-hosting avoids per-vector or usage-based pricing, but requires basic system admin skills.
Performance Optimization
System-Level Tuning
Optimize your Ubuntu server for Qdrant:
# Increase file descriptor limits
echo "* soft nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "* hard nofile 65536" | sudo tee -a /etc/security/limits.conf
# Optimize kernel parameters for vector workloads
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
echo "net.core.rmem_max=134217728" | sudo tee -a /etc/sysctl.conf
echo "net.core.wmem_max=134217728" | sudo tee -a /etc/sysctl.conf
# Apply changes
sudo sysctl -p
Docker Resource Management
Monitor your Qdrant container resources:
# Check current resource usage
docker stats qdrant
# View container details
docker inspect qdrant
If you need to limit resources, you can restart the container with limits:
sudo docker compose down
sudo docker run -d \
--name qdrant \
--memory="2g" \
--cpus="1.0" \
--restart unless-stopped \
-p 6333:6333 \
-v qdrant_data:/qdrant/storage \
-e QDRANT__SERVICE__API_KEY=your-secret-key-here \
qdrant/qdrant:latest
Troubleshooting Common Issues
Port Conflicts
# Check what's using port 6333
sudo netstat -tlnp | grep :6333
sudo ss -tulpn | grep :6333
Memory Issues
# Monitor Docker container resources
docker stats qdrant
# Check system memory
free -h
htop
Permission Errors
# Fix Docker volume permissions
sudo docker exec qdrant chown -R qdrant:qdrant /qdrant/storage
Log Analysis
# View real-time logs
sudo docker compose logs -f qdrant
# Check last 100 lines
sudo docker compose logs --tail=100 qdrant
# Filter for errors
sudo docker compose logs qdrant | grep -i error
Scaling Considerations
Vertical Scaling
- Upgrade to a server with more RAM and CPU cores
- Increase Docker resource limits accordingly
- Optimize Qdrant configuration for larger datasets
Horizontal Scaling
- Set up Qdrant cluster with multiple nodes
- Use a load balancer (HAProxy, Nginx) for request distribution
- Implement data sharding strategies
What's Included vs. Qdrant Cloud
Self-hosted Qdrant includes:
- Full vector search capabilities
- Advanced filtering and hybrid search
- Web dashboard and REST/gRPC APIs
- Clustering and replication
- Snapshots and backups
Qdrant Cloud additional features:
- Managed backups and monitoring
- Automatic scaling and updates
- 24/7 support and SLA guarantees
- Multi-region deployment
For most use cases, self-hosting provides everything you need. Check the official Qdrant documentation for detailed feature comparisons.
Conclusion
You now have a production-ready Qdrant vector database running on your Ubuntu server! This setup gives you:
- Complete control over your vector search infrastructure
- Significant cost savings compared to managed services
- Data privacy with your vectors staying on your own servers
- Scalability to handle growing AI workloads
Remember to maintain regular backups, security updates, and monitoring to keep your instance running smoothly.
Want the power of self-hosted Qdrant without managing your own server? Deploy it on Sliplane in 45 seconds with built-in HTTPS and volume persistence.