Docker
Learn how to self-host Shelve using Docker
Self-Hosting with Docker
Shelve provides official Docker images and a Docker Compose configuration for easy self-hosting. This guide will walk you through the process of deploying Shelve using Docker.
Docker Images
Official Shelve images are available on GitHub Container Registry. You can pull the latest version or a specific one:
# Pull latest version
docker pull ghcr.io/hugorcd/shelve:latest
# Pull specific version
docker pull ghcr.io/hugorcd/shelve:v2.0.0.beta-11
If you opt for the image setup, you will have to provide the necessary services (PostgreSQL, Redis) and connect them manually by setting the required environment variables:
DATABASE_URL
NUXT_PRIVATE_REDIS_URL
Docker Compose
The recommended way to deploy Shelve is using Docker Compose, which will handle all the required services (PostgreSQL, Redis) and their configuration. Check the Docker Compose file for the community version or app-compose.coolify.yml for the Coolify version.
To deploy Shelve using Docker Compose, follow these steps:
Copy the Docker Compose file.
Create the .env
file with the required environment variables. You can find the list of required variables in the Docker Compose file.
Run the following command to start the services:
docker-compose -f app-compose.community.yml up -d
Access the application by navigating to http://localhost:3000
.
That's it! You have successfully self-hosted the Shelve application using Docker Compose.
services:
shelve_app:
image: ghcr.io/hugorcd/shelve:latest
container_name: shelve_app
restart: always
environment:
- DATABASE_URL=${DATABASE_URL:-postgres://postgres:postgres@shelve_db:5432/postgres}
- NUXT_PRIVATE_REDIS_URL=${NUXT_PRIVATE_REDIS_URL:-redis://shelve_redis:6379}
- NUXT_PRIVATE_ENCRYPTION_KEY=${NUXT_PRIVATE_ENCRYPTION_KEY}
- NUXT_SESSION_PASSWORD=${NUXT_SESSION_PASSWORD}
# OAuth configuration
- NUXT_OAUTH_GITHUB_CLIENT_ID=${NUXT_OAUTH_GITHUB_CLIENT_ID}
- NUXT_OAUTH_GITHUB_CLIENT_SECRET=${NUXT_OAUTH_GITHUB_CLIENT_SECRET}
- NUXT_OAUTH_GOOGLE_CLIENT_ID=${NUXT_OAUTH_GOOGLE_CLIENT_ID}
- NUXT_OAUTH_GOOGLE_CLIENT_SECRET=${NUXT_OAUTH_GOOGLE_CLIENT_SECRET}
# Optional
- NUXT_PRIVATE_RESEND_API_KEY=${NUXT_PRIVATE_RESEND_API_KEY}
- NUXT_PRIVATE_ADMIN_EMAILS=${NUXT_PRIVATE_ADMIN_EMAILS}
depends_on:
shelve_redis:
condition: service_healthy
shelve_db:
condition: service_healthy
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:3000/api/hello" ]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
deploy:
resources:
limits:
cpus: '1'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
networks:
- shelve-network
shelve_db:
container_name: shelve_db
image: postgres:17-alpine
restart: always
volumes:
- postgres:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
POSTGRES_DB: ${POSTGRES_DB:-postgres}
healthcheck:
test: [ "CMD", "pg_isready", "-U", "postgres" ]
interval: 30s
timeout: 10s
retries: 3
networks:
- shelve-network
shelve_redis:
container_name: shelve_redis
image: redis:7.4-alpine
restart: always
volumes:
- redis:/data
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 30s
timeout: 10s
retries: 3
networks:
- shelve-network
networks:
shelve-network:
driver: bridge
volumes:
postgres:
redis:
Health Checks
The Docker Compose configuration includes health checks for all services:
- Shelve application: Checks the API endpoint every 30 seconds
- PostgreSQL: Verifies database connectivity
- Redis: Ensures Redis is responding
Resource Management
The configuration includes resource limits to ensure stable operation:
- CPU: 1 core limit, 0.5 core reserved
- Memory: 1GB limit, 512MB reserved
Data Persistence
Data is persisted using Docker volumes:
- postgres: PostgreSQL data
- redis: Redis data These volumes ensure your data survives container restarts.
Troubleshooting
If you encounter issues, check the container logs:
# All services
docker compose logs
# Specific service
docker compose logs <service-name>
For more detailed logs, you can find them in the JSON log files (limited to 10MB per file, 3 files maximum).
Upgrading
To upgrade Shelve, pull the latest image and restart the services:
Pull the latest image:
docker compose pull
Restart the services:
docker compose down
docker compose up -d
Security Considerations
- Always use strong, unique values for sensitive environment variables
- Consider using a reverse proxy with SSL termination
- Regularly update to the latest version for security patches
- Restrict network access as needed