
Self-Hosting Qdrant with Docker on Ubuntu in 2026
Jonas ScholzLooking 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.
Quick Answer
You can self-host Qdrant yourself with Docker on a VPS, but you will own updates, HTTPS, API key handling, storage, backups, monitoring, and recovery.
Use Sliplane if you want to run the same Qdrant container with persistent storage, HTTPS, logs, health checks, and backups without maintaining the server manually.
DIY vs Sliplane
| Route | Cost | Setup time | Maintenance | Best for |
|---|---|---|---|---|
| Raw VPS | €4-€15/month | 1-3 hours | High | Developers who want full control over the vector database host |
| Sliplane | From €9/month | Minutes | Low | Builders who want managed self-hosting for AI apps |
| Qdrant Cloud | Free tier, then usage-based | Minutes | Low | Teams that prefer the official managed Qdrant service |
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:v1.18.2
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
qdrant/qdrant:v1.18.2 was the current stable image when this guide was refreshed in 2026. Before a production deploy, check the Qdrant Docker tags and pin the exact patch version you have tested.
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 (Sliplane Object 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:v1.18.2
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.