{"id":28122761,"url":"https://github.com/chintanboghara/self-hosted-docker-registry","last_synced_at":"2026-02-28T16:30:56.364Z","repository":{"id":291567370,"uuid":"948454523","full_name":"chintanboghara/Self-Hosted-Docker-Registry","owner":"chintanboghara","description":"A turnkey solution for running a private Docker registry on your own infrastructure.","archived":false,"fork":false,"pushed_at":"2025-06-19T04:40:25.000Z","size":36,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-04T10:43:34.972Z","etag":null,"topics":["docker","git","linux","openssl"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chintanboghara.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-14T11:16:04.000Z","updated_at":"2025-06-19T04:49:49.000Z","dependencies_parsed_at":"2025-05-05T12:27:03.862Z","dependency_job_id":"5f504e1d-3e20-4d0d-8054-4fdf82828de9","html_url":"https://github.com/chintanboghara/Self-Hosted-Docker-Registry","commit_stats":null,"previous_names":["chintanboghara/self-hosted-docker-registry"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/chintanboghara/Self-Hosted-Docker-Registry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chintanboghara%2FSelf-Hosted-Docker-Registry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chintanboghara%2FSelf-Hosted-Docker-Registry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chintanboghara%2FSelf-Hosted-Docker-Registry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chintanboghara%2FSelf-Hosted-Docker-Registry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chintanboghara","download_url":"https://codeload.github.com/chintanboghara/Self-Hosted-Docker-Registry/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chintanboghara%2FSelf-Hosted-Docker-Registry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29942775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T13:49:17.081Z","status":"ssl_error","status_checked_at":"2026-02-28T13:48:50.396Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","git","linux","openssl"],"created_at":"2025-05-14T08:14:50.727Z","updated_at":"2026-02-28T16:30:56.324Z","avatar_url":"https://github.com/chintanboghara.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Self‑Hosted Docker Registry\n\nA turnkey solution for running a private Docker registry on your own infrastructure, complete with:\n\n- **HTTPS** (self‑signed TLS or real certificates)  \n- **HTTP Basic Authentication**  \n- **Docker Compose** for easy orchestration  \n- **Idempotent Bash script** (`setup-registry.sh`) to automate setup  \n- **Environment‑driven configuration** via `.env` file  \n\n## Features \u0026 Benefits\n\n1. **Secure by Default**  \n   - TLS encryption for all communications  \n   - Basic auth to restrict access  \n\n2. **Idempotent Automation**  \n   - Re‑run the setup script safely (won’t overwrite existing certs or auth files)  \n   - Clear, user‑friendly help text and error messages  \n\n3. **Modular \u0026 Extensible**  \n   - Docker Compose for multi‑service setups  \n   - Easily swap in Let’s Encrypt or custom CA certs  \n   - Volumes mount into local directories (`data/`, `certs/`, `auth/`)  \n\n4. **Easy Maintenance**  \n   - `.gitignore` excludes sensitive/runtime files  \n   - Well‑documented directory structure  \n   - Suggestions for CI/CD and certificate renewal  \n\n## Repository Layout\n\n```\n\nSelf-Hosted-Docker-Registry/\n│\n├── setup-registry.sh       # Idempotent, documented Bash installer\n├── registry.env            # DOMAIN, USERNAME, PASSWORD\n├── docker-compose.yml      # Compose file for Registry container\n├── auth/                   # HTTP auth data (htpasswd)\n├── certs/                  # TLS certificates\n├── data/                   # Registry storage (images, metadata)\n├── .gitignore              # Exclude auth, certs, data\n└── README.md               # You are here!\n\n````\n\n## Prerequisites\n\n- **Host OS**: Linux (Ubuntu, Debian, CentOS, etc.)  \n- **Docker**: ≥ 20.10 (with `docker compose` plugin)  \n- **OpenSSL**: for self‑signed cert generation  \n- **Git**: to clone this repo  \n- **(Optional)** Certbot \u0026 cron/systemd, for Let’s Encrypt integration  \n\n## Configuration\n\n1. **Clone the repo**  \n   ```bash\n   git clone https://github.com/chintanboghara/Self-Hosted-Docker-Registry.git\n   cd Self-Hosted-Docker-Registry\n   ````\n\n2. **Edit `registry.env`**\n   Rename or copy the template, then set your values:\n\n   ```dotenv\n   # registry.env\n   DOMAIN=registry.example.com       # FQDN for your registry\n   USERNAME=admin                    # Basic auth username\n   PASSWORD=strongpassword123        # Basic auth password\n   ```\n\n3. **Make the script executable**\n\n   ```bash\n   chmod +x setup-registry.sh\n   ```\n\n##  Quick Start\n\nRun the installation script. It will:\n\n* Validate your environment variables\n* Create `certs/`, `auth/`, `data/` directories\n* Generate a self‑signed TLS certificate (if needed)\n* Generate an `htpasswd` file with your credentials (if needed)\n* Launch the registry via Docker Compose\n\n```bash\n./setup-registry.sh\n```\n\n**Success message**:\n\n```\nRegistry running at https://registry.example.com\n```\n\n## How It Works\n\n### 1. `setup-registry.sh`\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n```\n\n* **`usage()`**: Prints help (`--help` flag)\n* **`load_env()`**: Sources `registry.env`, checks for `DOMAIN`, `USERNAME`, `PASSWORD`\n* **`prepare_dirs()`**: Creates `certs/`, `auth/`, `data/` if missing\n* **`generate_cert()`**:\n\n  * If `certs/fullchain.pem` \u0026 `certs/privkey.pem` are absent, calls `openssl req …`\n  * Otherwise: prints “already exists”\n* **`generate_auth()`**:\n\n  * If `auth/htpasswd` is absent, runs `docker run --rm httpd:2.4 htpasswd -Bbn …`\n  * Otherwise: prints “already exists”\n* **`run_compose()`**: Executes `docker compose up -d`\n\n### 2. `docker-compose.yml`\n\n```yaml\nversion: '3.7'\nservices:\n  registry:\n    image: registry:2\n    restart: always\n    ports:\n      - \"443:5000\"\n    environment:\n      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry\n      REGISTRY_HTTP_TLS_CERTIFICATE: /certs/fullchain.pem\n      REGISTRY_HTTP_TLS_KEY: /certs/privkey.pem\n      REGISTRY_AUTH: htpasswd\n      REGISTRY_AUTH_HTPASSWD_REALM: \"Registry Realm\"\n      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd\n    volumes:\n      - ./data:/var/lib/registry\n      - ./certs:/certs:ro\n      - ./auth:/auth:ro\n```\n\n* **Ports**: Exposes `5000` inside container on host’s `443`\n* **Volumes**:\n\n  * `./data` → persistent image storage\n  * `./certs` → TLS (read‑only)\n  * `./auth` → htpasswd (read‑only)\n* **Env vars**: Configure storage path, TLS files, and basic auth\n\n## Usage Examples\n\n1. **Login**\n\n   ```bash\n   docker login https://$DOMAIN\n   # Username: admin\n   # Password: \u003cyour password\u003e\n   ```\n\n2. **Push an image**\n\n   ```bash\n   docker pull alpine\n   docker tag alpine $DOMAIN/my-alpine:latest\n   docker push $DOMAIN/my-alpine:latest\n   ```\n\n3. **Pull an image**\n\n   ```bash\n   docker pull $DOMAIN/my-alpine:latest\n   ```\n\n## Certificate Renewal (Let’s Encrypt)\n\n\u003e *Optional*: replace the self‑signed step with real certs from Let’s Encrypt.\n\n1. Install Certbot on your host.\n2. In `setup-registry.sh`, replace `generate_cert()` with:\n\n   ```bash\n   certbot certonly --standalone -d \"$DOMAIN\" --non-interactive --agree-tos -m you@example.com\n   ln -sf /etc/letsencrypt/live/$DOMAIN/fullchain.pem certs/fullchain.pem\n   ln -sf /etc/letsencrypt/live/$DOMAIN/privkey.pem certs/privkey.pem\n   ```\n3. Set up a cron or `systemd` timer:\n\n   ```cron\n   0 3 * * * certbot renew --deploy-hook \"/path/to/repo/setup-registry.sh\"\n   ```\n\n   This renews certs daily at 03:00 and restarts the registry if they’ve changed.\n\n## Troubleshooting\n\n* **Port conflict**:\n  If port 443 is in use, edit `docker-compose.yml` to map host `8443:5000` and login via `https://$DOMAIN:8443`.\n\n* **Certificate errors**:\n\n  * For self‑signed certs, add `--insecure-registry $DOMAIN` to Docker daemon or import the cert into your OS trust store.\n  * For Let’s Encrypt, check `/var/log/letsencrypt/letsencrypt.log`.\n\n* **Permission denied**:\n  Ensure your user is in the `docker` group or run with `sudo`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchintanboghara%2Fself-hosted-docker-registry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchintanboghara%2Fself-hosted-docker-registry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchintanboghara%2Fself-hosted-docker-registry/lists"}