• Home
  • Cloud VPS
    • Hong Kong VPS
    • US VPS
  • Dedicated Servers
    • Hong Kong Servers
    • US Servers
    • Singapore Servers
    • Japan Servers
  • Company
    • Contact Us
    • Blog
logo logo
  • Home
  • Cloud VPS
    • Hong Kong VPS
    • US VPS
  • Dedicated Servers
    • Hong Kong Servers
    • US Servers
    • Singapore Servers
    • Japan Servers
  • Company
    • Contact Us
    • Blog
ENEN
  • 简体简体
  • 繁體繁體
Client Area

Self-Hosted Docker Registry on Hong Kong VPS: Private Container Images (2026)

August 23, 2026

Docker Hub’s free tier imposes rate limits (100 pulls per 6 hours for unauthenticated users) and stores your container images on US servers. A private Docker registry on your Hong Kong VPS eliminates rate limits entirely, keeps proprietary application images on your infrastructure, and — critically for Asia-Pacific teams — makes docker pull operations dramatically faster for servers and CI/CD runners in the region via CN2 GIA routing.


Registry Options Compared

OptionFeaturesComplexityBest For
Docker Registry v2 (official)Basic push/pull, no UISimpleCI/CD automation, teams comfortable with CLI
HarborWeb UI, RBAC, vulnerability scanning, replicationMediumEnterprise teams, security-conscious deployments
Gitea Container RegistryIntegrated with Gitea, basic UISimple (if using Gitea)Teams already using Gitea for Git

Option A: Docker Registry v2 (Simple and Fast)

Step 1: Deploy Registry

<code">apt update && apt upgrade -y
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
apt install -y nginx certbot python3-certbot-nginx apache2-utils

mkdir -p /opt/registry/{data,auth}

# Generate htpasswd authentication
htpasswd -Bbn registry_user StrongRegistryPassword! > /opt/registry/auth/htpasswd

docker run -d \
  --name registry \
  --restart unless-stopped \
  -p 127.0.0.1:5000:5000 \
  -v /opt/registry/data:/var/lib/registry \
  -v /opt/registry/auth:/auth \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM="Registry" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  -e REGISTRY_STORAGE_DELETE_ENABLED=true \
  registry:2

docker ps | grep registry

Step 2: Nginx with SSL

<code">cat > /etc/nginx/sites-available/registry << 'EOF'
server {
    listen 443 ssl http2;
    server_name registry.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/registry.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/registry.yourdomain.com/privkey.pem;

    # Large image layers need big client body
    client_max_body_size 5G;
    client_body_timeout 300s;

    # Disable request buffering — stream directly to registry
    proxy_request_buffering off;
    proxy_buffering off;

    location /v2/ {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 900s;
        proxy_connect_timeout 30s;
        proxy_send_timeout 900s;
    }
}
EOF

ln -s /etc/nginx/sites-available/registry /etc/nginx/sites-enabled/
certbot --nginx -d registry.yourdomain.com
nginx -t && systemctl reload nginx

Step 3: Push and Pull Images

<code"># Log in from any Docker client
docker login registry.yourdomain.com
# Username: registry_user
# Password: StrongRegistryPassword!

# Tag your image
docker tag myapp:latest registry.yourdomain.com/myorg/myapp:latest
docker tag myapp:latest registry.yourdomain.com/myorg/myapp:v1.2.0

# Push
docker push registry.yourdomain.com/myorg/myapp:latest

# Pull from any server (authenticated)
docker pull registry.yourdomain.com/myorg/myapp:latest

# List repositories
curl -u registry_user:StrongRegistryPassword! \
  https://registry.yourdomain.com/v2/_catalog

# List tags for an image
curl -u registry_user:StrongRegistryPassword! \
  https://registry.yourdomain.com/v2/myorg/myapp/tags/list

Option B: Harbor (Enterprise Registry with Web UI)

Install Harbor

<code"># Harbor requires Docker Compose
HARBOR_VERSION="v2.11.0"
wget https://github.com/goharbor/harbor/releases/download/${HARBOR_VERSION}/harbor-online-installer-${HARBOR_VERSION}.tgz
tar xzf harbor-online-installer-${HARBOR_VERSION}.tgz
cd harbor

# Configure
cp harbor.yml.tmpl harbor.yml
nano harbor.yml
<code"># Key settings in harbor.yml:
hostname: harbor.yourdomain.com
https:
  port: 443
  certificate: /etc/letsencrypt/live/harbor.yourdomain.com/fullchain.pem
  private_key: /etc/letsencrypt/live/harbor.yourdomain.com/privkey.pem
harbor_admin_password: StrongHarborAdminPass!
database:
  password: StrongDBPass!
<code"># Issue SSL first, then install Harbor
certbot certonly --standalone -d harbor.yourdomain.com

./prepare
./install.sh

# Harbor starts on ports 80 and 443
docker compose ps

Harbor Key Features

  • Web UI — browse repositories, manage tags, view image metadata
  • RBAC — project-level permissions: admin, developer, guest roles per registry project
  • Vulnerability scanning — Trivy integration scans images for CVEs before they are deployed
  • Replication — mirror images to Docker Hub, Amazon ECR, or other Harbor instances
  • Content trust — Notary-based image signing

Option C: Gitea Container Registry

If you already run Gitea (see article #78), it includes a built-in container registry compatible with the Docker registry protocol:

<code"># Enable in Gitea app.ini
[packages]
ENABLED = true

# Push images to Gitea registry:
docker login git.yourdomain.com
docker tag myapp:latest git.yourdomain.com/youruser/myapp:latest
docker push git.yourdomain.com/youruser/myapp:latest

# Images appear in Gitea under: Packages → Container

Registry Integration with CI/CD

GitHub Actions → HK Registry → HK VPS Deploy

<code"># .github/workflows/deploy.yml
name: Build, Push, Deploy

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Log in to private registry
        uses: docker/login-action@v3
        with:
          registry: registry.yourdomain.com
          username: ${{ secrets.REGISTRY_USER }}
          password: ${{ secrets.REGISTRY_PASSWORD }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            registry.yourdomain.com/myorg/myapp:latest
            registry.yourdomain.com/myorg/myapp:${{ github.sha }}
          cache-from: type=registry,ref=registry.yourdomain.com/myorg/myapp:latest
          cache-to: type=inline

      - name: Deploy to VPS
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            docker login registry.yourdomain.com \
              -u ${{ secrets.REGISTRY_USER }} \
              -p ${{ secrets.REGISTRY_PASSWORD }}
            docker pull registry.yourdomain.com/myorg/myapp:latest
            docker compose -f /opt/myapp/docker-compose.yml up -d --no-deps app
            docker image prune -f

Docker Compose Using Private Registry

<code"># docker-compose.yml — reference private registry images
version: '3.8'
services:
  app:
    image: registry.yourdomain.com/myorg/myapp:latest
    restart: unless-stopped
    # ...

  worker:
    image: registry.yourdomain.com/myorg/myapp-worker:latest
    restart: unless-stopped
    # ...

Registry Maintenance

<code"># Delete old image tags to reclaim storage
# Using Docker registry API:
REGISTRY="https://registry.yourdomain.com"
CREDS="registry_user:StrongRegistryPassword!"
IMAGE="myorg/myapp"

# Get manifest digest for a tag
DIGEST=$(curl -su $CREDS -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  -I "${REGISTRY}/v2/${IMAGE}/manifests/v1.0.0" \
  | grep -i Docker-Content-Digest | awk '{print $2}' | tr -d '\r')

# Delete the manifest (removes the tag)
curl -su $CREDS -X DELETE \
  "${REGISTRY}/v2/${IMAGE}/manifests/${DIGEST}"

# Run garbage collection to reclaim disk space
docker exec registry /bin/registry garbage-collect /etc/docker/registry/config.yml
<code"># Automated cleanup: delete images older than 30 days
cat > /opt/registry-cleanup.sh << 'EOF'
#!/bin/bash
# Uses registry-cli: pip install registry-cli
# registry -l "registry_user:StrongPassword!" \
#   -r https://registry.yourdomain.com \
#   --delete --num 5  # Keep last 5 tags per image
echo "Registry cleanup: $(date)"
EOF

Backup the Registry Data

<code"># Backup registry storage volume
crontab -l | { cat; echo "0 3 * * * tar czf /opt/backups/registry_\$(date +%Y%m%d).tar.gz /opt/registry/data/ && find /opt/backups -name 'registry_*' -mtime +7 -delete"; } | crontab -

Performance: Pull Speed from Asia

Pulling a 500 MB Docker image from your Hong Kong registry versus Docker Hub:

SourceShanghai server pull time (500 MB)
Docker Hub (US servers)5–20 minutes (congested, throttled)
Your HK Registry (CN2 GIA)30–90 seconds
GitHub Container Registry (US)3–15 minutes

The CN2 GIA speed difference makes a meaningful impact on deployment pipelines — a 10-minute Docker pull delays every deployment for mainland China-based CI runners or production servers. The HK registry turns this into under 2 minutes.


Conclusion

A private Docker registry on a Hong Kong VPS eliminates Docker Hub rate limits, keeps proprietary images on your infrastructure, and makes docker pull operations 5–10× faster for Asia-Pacific servers via CN2 GIA routing. Docker Registry v2 serves most teams with minimal overhead; Harbor adds enterprise features (RBAC, vulnerability scanning, replication) for security-conscious deployments. Both integrate seamlessly with GitHub Actions CI/CD pipelines.

Host your images: Browse Server.HK Hong Kong VPS plans — add a 40–200 GB NVMe volume for image storage and deploy Docker Registry v2 alongside your existing applications.

Recent Posts

  • Self-Hosted Private Search Engine on Hong Kong VPS: SearXNG (2026)
  • WireGuard Site-to-Site VPN with Hong Kong VPS: Connect Your Offices (2026)
  • Deploy Elixir Phoenix on Hong Kong VPS: Real-Time Apps for Asia (2026)
  • GPU Dedicated Server in Hong Kong: AI Model Training and Inference (2026)
  • Vector Database on Hong Kong VPS: Build a RAG System with pgvector (2026)

Recent Comments

  1. Hong Kong VPS Uptime and SLA: What 99.9% Uptime Really Means for Your Business (2026) - Server.HK on How to Monitor Your Hong Kong VPS: Uptime, Performance, and Alert Setup Guide (2026)
  2. Best Hong Kong VPS Providers in 2026: Compared by Speed, Routing, and Value - Server.HK on How to Migrate Your Website to a Hong Kong VPS: Zero-Downtime Transfer Guide (2026)
  3. vibramycin injection on How to Choose the Right Hong Kong VPS Plan: A Buyer’s Guide for 2026
  4. allopurinol for gout on CN2 GIA vs BGP vs CN2 GT: What’s the Real Difference for China Connectivity?
  5. antibiotics online purchase on How to Set Up a WordPress Site on a Hong Kong VPS with aaPanel (Step-by-Step 2026)

Knowledge Base

Access detailed guides, tutorials, and resources.

Live Chat

Get instant help 24/7 from our support team.

Send Ticket

Our team typically responds within 10 minutes.

logo
Alipay Cc-paypal Cc-stripe Cc-visa Cc-mastercard Bitcoin
Cloud VPS
  • Hong Kong VPS
  • US VPS
Dedicated Servers
  • Hong Kong Servers
  • US Servers
  • Singapore Servers
  • Japan Servers
More
  • Contact Us
  • Blog
  • Legal
© 2026 Server.HK | Hosting Limited, Hong Kong | Company Registration No. 77008912
Telegram
Telegram @ServerHKBot