Harbor Container Registry
Enterprise-class container registry with vulnerability scanning, image signing, and replication.
Overview
Harbor Container Registry is an open-source, enterprise-grade container registry that extends Docker Distribution with security-focused features including vulnerability scanning, content signing, and role-based access control. Originally created by VMware and now a CNCF graduated project, Harbor addresses the security and governance gaps in basic container registries by providing comprehensive image lifecycle management with built-in security scanning via Trivy, multi-tenancy support, and replication capabilities for distributed deployments.
This Harbor deployment stack combines the Harbor core services with PostgreSQL for metadata storage, Redis for caching and session management, Trivy for vulnerability scanning, and NGINX as a reverse proxy. The architecture separates concerns across multiple specialized containers: harbor-core handles API operations and authentication, harbor-portal provides the web interface, jobservice manages background tasks like garbage collection and replication, while registryctl manages the underlying Docker registry storage. This multi-service approach enables horizontal scaling and independent updates of components.
This configuration is ideal for organizations requiring private container registries with enterprise security features, development teams needing vulnerability scanning integrated into their CI/CD pipelines, and compliance-driven environments where image provenance and security scanning are mandatory. The stack provides a self-hosted alternative to managed registry services while offering more advanced security and governance features than basic Docker Registry deployments, making it particularly valuable for air-gapped environments, multi-tenant scenarios, and organizations with strict data sovereignty requirements.
Key Features
- Trivy-powered vulnerability scanning with CVE database integration and severity-based policy enforcement
- Content signing and trust verification using Docker Content Trust and Notary integration
- Role-based access control with project-level permissions and LDAP/OIDC authentication support
- Multi-registry replication for disaster recovery and geographically distributed deployments
- Webhook notifications for image push/pull events and vulnerability scan results
- Project quotas and resource management with storage usage tracking and limits
- Comprehensive audit logging for compliance with detailed user activity tracking
- Garbage collection automation for efficient storage management and cleanup policies
Common Use Cases
- 1Enterprise container registry with security scanning for large development teams requiring vulnerability assessment
- 2Air-gapped environments needing private registry with offline vulnerability database updates
- 3Multi-tenant SaaS platforms requiring project isolation and granular access controls per customer
- 4Compliance-driven organizations needing audit trails and image signing for regulatory requirements
- 5Hybrid cloud deployments requiring image replication between on-premises and cloud registries
- 6DevSecOps pipelines integrating vulnerability scanning gates before production deployments
- 7Container supply chain security implementations requiring image provenance and trust verification
Prerequisites
- Minimum 4GB RAM and 2 CPU cores for Harbor core services plus database and cache components
- 50GB+ available storage for container images, vulnerability database, and PostgreSQL data
- Ports 80 and 443 available for HTTP/HTTPS access through NGINX reverse proxy
- SSL certificates configured for production HTTPS access and Docker client trust
- Understanding of container registry concepts, Docker authentication, and certificate management
- Network connectivity for Trivy vulnerability database updates and image replication if required
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 log: 3 image: goharbor/harbor-log:latest4 volumes: 5 - harbor_log:/var/log/docker/:z6 - ./config/log/logrotate.conf:/etc/logrotate.d/logrotate.conf:z7 networks: 8 - harbor-net9 restart: unless-stopped1011 registry: 12 image: goharbor/registry-photon:latest13 volumes: 14 - registry_data:/storage:z15 - ./config/registry/config.yml:/etc/registry/config.yml:z16 networks: 17 - harbor-net18 depends_on: 19 - log20 restart: unless-stopped2122 registryctl: 23 image: goharbor/harbor-registryctl:latest24 volumes: 25 - registry_data:/storage:z26 - ./config/registry/config.yml:/etc/registry/config.yml:z27 - ./config/registryctl/config.yml:/etc/registryctl/config.yml:z28 networks: 29 - harbor-net30 restart: unless-stopped3132 postgresql: 33 image: goharbor/harbor-db:latest34 environment: 35 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}36 volumes: 37 - database:/var/lib/postgresql/data:z38 networks: 39 - harbor-net40 restart: unless-stopped4142 core: 43 image: goharbor/harbor-core:latest44 environment: 45 CORE_KEY: ${CORE_KEY}46 _REDIS_URL_CORE: redis://redis:6379/047 SYNC_REGISTRY: "false"48 CHART_CACHE_DRIVER: redis49 _REDIS_URL_REG: redis://redis:6379/150 PORTAL_URL: http://portal:808051 REGISTRY_URL: http://registry:500052 TOKEN_SERVICE_URL: http://core:8080/service/token53 HARBOR_ADMIN_PASSWORD: ${HARBOR_ADMIN_PASSWORD}54 DATABASE_TYPE: postgresql55 volumes: 56 - core_data:/data:z57 - ./config/core/app.conf:/etc/core/app.conf:z58 networks: 59 - harbor-net60 depends_on: 61 - log62 - registry63 - postgresql64 - redis65 restart: unless-stopped6667 portal: 68 image: goharbor/harbor-portal:latest69 networks: 70 - harbor-net71 depends_on: 72 - log73 - core74 restart: unless-stopped7576 jobservice: 77 image: goharbor/harbor-jobservice:latest78 volumes: 79 - job_logs:/var/log/jobs:z80 - ./config/jobservice/config.yml:/etc/jobservice/config.yml:z81 networks: 82 - harbor-net83 depends_on: 84 - core85 restart: unless-stopped8687 redis: 88 image: goharbor/redis-photon:latest89 volumes: 90 - redis_data:/var/lib/redis91 networks: 92 - harbor-net93 restart: unless-stopped9495 trivy-adapter: 96 image: goharbor/trivy-adapter-photon:latest97 environment: 98 SCANNER_TRIVY_CACHE_DIR: /home/scanner/.cache/trivy99 SCANNER_TRIVY_REPORTS_DIR: /home/scanner/.cache/reports100 volumes: 101 - trivy_cache:/home/scanner/.cache102 networks: 103 - harbor-net104 restart: unless-stopped105106 proxy: 107 image: goharbor/nginx-photon:latest108 ports: 109 - "80:8080"110 - "443:8443"111 volumes: 112 - ./config/nginx:/etc/nginx:z113 networks: 114 - harbor-net115 depends_on: 116 - registry117 - core118 - portal119 restart: unless-stopped120121volumes: 122 harbor_log: 123 registry_data: 124 database: 125 core_data: 126 job_logs: 127 redis_data: 128 trivy_cache: 129130networks: 131 harbor-net: 132 driver: bridge.env Template
.env
1# Harbor Admin Password2HARBOR_ADMIN_PASSWORD=Harbor1234534# PostgreSQL5POSTGRES_PASSWORD=secure_postgres_password67# Core Secret Key8CORE_KEY=your_32_char_secret_key_hereUsage Notes
- 1Harbor UI at https://localhost
- 2Default login: admin / Harbor12345
- 3Includes Trivy vulnerability scanning
- 4Use harbor installer for full setup
Individual Services(10 services)
Copy individual services to mix and match with your existing compose files.
log
log:
image: goharbor/harbor-log:latest
volumes:
- harbor_log:/var/log/docker/:z
- ./config/log/logrotate.conf:/etc/logrotate.d/logrotate.conf:z
networks:
- harbor-net
restart: unless-stopped
registry
registry:
image: goharbor/registry-photon:latest
volumes:
- registry_data:/storage:z
- ./config/registry/config.yml:/etc/registry/config.yml:z
networks:
- harbor-net
depends_on:
- log
restart: unless-stopped
registryctl
registryctl:
image: goharbor/harbor-registryctl:latest
volumes:
- registry_data:/storage:z
- ./config/registry/config.yml:/etc/registry/config.yml:z
- ./config/registryctl/config.yml:/etc/registryctl/config.yml:z
networks:
- harbor-net
restart: unless-stopped
postgresql
postgresql:
image: goharbor/harbor-db:latest
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- database:/var/lib/postgresql/data:z
networks:
- harbor-net
restart: unless-stopped
core
core:
image: goharbor/harbor-core:latest
environment:
CORE_KEY: ${CORE_KEY}
_REDIS_URL_CORE: redis://redis:6379/0
SYNC_REGISTRY: "false"
CHART_CACHE_DRIVER: redis
_REDIS_URL_REG: redis://redis:6379/1
PORTAL_URL: http://portal:8080
REGISTRY_URL: http://registry:5000
TOKEN_SERVICE_URL: http://core:8080/service/token
HARBOR_ADMIN_PASSWORD: ${HARBOR_ADMIN_PASSWORD}
DATABASE_TYPE: postgresql
volumes:
- core_data:/data:z
- ./config/core/app.conf:/etc/core/app.conf:z
networks:
- harbor-net
depends_on:
- log
- registry
- postgresql
- redis
restart: unless-stopped
portal
portal:
image: goharbor/harbor-portal:latest
networks:
- harbor-net
depends_on:
- log
- core
restart: unless-stopped
jobservice
jobservice:
image: goharbor/harbor-jobservice:latest
volumes:
- job_logs:/var/log/jobs:z
- ./config/jobservice/config.yml:/etc/jobservice/config.yml:z
networks:
- harbor-net
depends_on:
- core
restart: unless-stopped
redis
redis:
image: goharbor/redis-photon:latest
volumes:
- redis_data:/var/lib/redis
networks:
- harbor-net
restart: unless-stopped
trivy-adapter
trivy-adapter:
image: goharbor/trivy-adapter-photon:latest
environment:
SCANNER_TRIVY_CACHE_DIR: /home/scanner/.cache/trivy
SCANNER_TRIVY_REPORTS_DIR: /home/scanner/.cache/reports
volumes:
- trivy_cache:/home/scanner/.cache
networks:
- harbor-net
restart: unless-stopped
proxy
proxy:
image: goharbor/nginx-photon:latest
ports:
- "80:8080"
- "443:8443"
volumes:
- ./config/nginx:/etc/nginx:z
networks:
- harbor-net
depends_on:
- registry
- core
- portal
restart: unless-stopped
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 log:5 image: goharbor/harbor-log:latest6 volumes:7 - harbor_log:/var/log/docker/:z8 - ./config/log/logrotate.conf:/etc/logrotate.d/logrotate.conf:z9 networks:10 - harbor-net11 restart: unless-stopped1213 registry:14 image: goharbor/registry-photon:latest15 volumes:16 - registry_data:/storage:z17 - ./config/registry/config.yml:/etc/registry/config.yml:z18 networks:19 - harbor-net20 depends_on:21 - log22 restart: unless-stopped2324 registryctl:25 image: goharbor/harbor-registryctl:latest26 volumes:27 - registry_data:/storage:z28 - ./config/registry/config.yml:/etc/registry/config.yml:z29 - ./config/registryctl/config.yml:/etc/registryctl/config.yml:z30 networks:31 - harbor-net32 restart: unless-stopped3334 postgresql:35 image: goharbor/harbor-db:latest36 environment:37 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}38 volumes:39 - database:/var/lib/postgresql/data:z40 networks:41 - harbor-net42 restart: unless-stopped4344 core:45 image: goharbor/harbor-core:latest46 environment:47 CORE_KEY: ${CORE_KEY}48 _REDIS_URL_CORE: redis://redis:6379/049 SYNC_REGISTRY: "false"50 CHART_CACHE_DRIVER: redis51 _REDIS_URL_REG: redis://redis:6379/152 PORTAL_URL: http://portal:808053 REGISTRY_URL: http://registry:500054 TOKEN_SERVICE_URL: http://core:8080/service/token55 HARBOR_ADMIN_PASSWORD: ${HARBOR_ADMIN_PASSWORD}56 DATABASE_TYPE: postgresql57 volumes:58 - core_data:/data:z59 - ./config/core/app.conf:/etc/core/app.conf:z60 networks:61 - harbor-net62 depends_on:63 - log64 - registry65 - postgresql66 - redis67 restart: unless-stopped6869 portal:70 image: goharbor/harbor-portal:latest71 networks:72 - harbor-net73 depends_on:74 - log75 - core76 restart: unless-stopped7778 jobservice:79 image: goharbor/harbor-jobservice:latest80 volumes:81 - job_logs:/var/log/jobs:z82 - ./config/jobservice/config.yml:/etc/jobservice/config.yml:z83 networks:84 - harbor-net85 depends_on:86 - core87 restart: unless-stopped8889 redis:90 image: goharbor/redis-photon:latest91 volumes:92 - redis_data:/var/lib/redis93 networks:94 - harbor-net95 restart: unless-stopped9697 trivy-adapter:98 image: goharbor/trivy-adapter-photon:latest99 environment:100 SCANNER_TRIVY_CACHE_DIR: /home/scanner/.cache/trivy101 SCANNER_TRIVY_REPORTS_DIR: /home/scanner/.cache/reports102 volumes:103 - trivy_cache:/home/scanner/.cache104 networks:105 - harbor-net106 restart: unless-stopped107108 proxy:109 image: goharbor/nginx-photon:latest110 ports:111 - "80:8080"112 - "443:8443"113 volumes:114 - ./config/nginx:/etc/nginx:z115 networks:116 - harbor-net117 depends_on:118 - registry119 - core120 - portal121 restart: unless-stopped122123volumes:124 harbor_log:125 registry_data:126 database:127 core_data:128 job_logs:129 redis_data:130 trivy_cache:131132networks:133 harbor-net:134 driver: bridge135EOF136137# 2. Create the .env file138cat > .env << 'EOF'139# Harbor Admin Password140HARBOR_ADMIN_PASSWORD=Harbor12345141142# PostgreSQL143POSTGRES_PASSWORD=secure_postgres_password144145# Core Secret Key146CORE_KEY=your_32_char_secret_key_here147EOF148149# 3. Start the services150docker compose up -d151152# 4. View logs153docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/harbor-registry-stack/run | bashTroubleshooting
- Harbor UI shows 'Internal Server Error': Check PostgreSQL connectivity and ensure database initialization completed successfully in logs
- Docker login fails with certificate errors: Verify SSL certificates are properly configured in NGINX and trusted by Docker daemon
- Trivy scanner shows outdated vulnerability database: Check internet connectivity and restart trivy-adapter container to force database update
- Job service fails with Redis connection errors: Verify Redis container is healthy and check Redis URL configuration in core service environment
- Registry push fails with 'insufficient storage': Check available disk space and configure garbage collection policies to free unused image layers
- LDAP authentication not working: Verify LDAP server connectivity and check Harbor core logs for authentication binding errors
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
harbor-coreharbor-portaltrivypostgresqlredisnginx
Tags
#harbor#registry#docker#security#enterprise
Category
DevOps & CI/CDAd Space
Shortcuts: C CopyF FavoriteD Download