├── README.md ├── docker-compose.yml └── pull_tag_and_push.sh /README.md: -------------------------------------------------------------------------------- 1 | This guide shows you how to set up a Docker Private Registry on a local network with full HTTPS support, which will work straight out of the box with all Docker Engines. Perfect for demos and workshops with poor internet connectivity and lots of bandwidth hungry Docker users. 2 | 3 | Thanks to [@winggundamth](https://twitter.com/winggundamth) for the idea! 4 | 5 | ## Set up temporary server 6 | 7 | Get a hold of a server somewhere with a public IP. Make sure that the server has port ``443`` open to the internet. 8 | 9 | ## Set DNS 10 | 11 | Create an ``A`` record for ``registry.yourdomain.com`` to point to the public IP of the temporary server. 12 | 13 | ## Run letsencrypt 14 | 15 | Run letsencrypt on the temporary server. 16 | 17 | git clone https://github.com/letsencrypt/letsencrypt 18 | cd letsencrypt 19 | ./letsencrypt-auto certonly 20 | 21 | The certificate files and key (4 files total) are placed here: 22 | 23 | $ ls /etc/letsencrypt/archive/registry.yourdomain.com/ 24 | cert1.pem 25 | chain1.pem 26 | fullchain1.pem 27 | privkey1.pem 28 | 29 | ## Download certificates 30 | 31 | Copy all certificate files and the private key to ``.ssl/registry/`` in your home folder on your local machine. 32 | 33 | ## Run registry 34 | 35 | ### Linux 36 | 37 | Edit the path to the certs folder under ``volumes:`` in ``docker-compose.yml``, then do 38 | 39 | docker-compose up -d 40 | 41 | ### Mac 42 | 43 | On a Mac you need to do a bit more. First, install [Docker Toolbox](https://www.docker.com/products/docker-toolbox) to get the latest versions of Docker Machine. Make sure your Docker Machine VM is up and running: 44 | 45 | $ docker-machine ls 46 | NAME ACTIVE DRIVER STATE URL SWARM ERRORS 47 | default - virtualbox Running tcp://192.168.99.100:2376 48 | 49 | #### Put certs in place 50 | 51 | Ensure that the certificates and key are in your home folder, for example: 52 | 53 | /Users/johndoe/.ssl/registry/ 54 | 55 | 56 | #### Start the registry 57 | 58 | docker-compose up -d 59 | 60 | Ensure that you can reach the registry: 61 | 62 | $ curl https://$(docker-machine ip)/ 63 | curl: (60) SSL certificate problem: Invalid certificate chain 64 | More details... 65 | 66 | You should get a certificate error, since you're not using the right DNS name. 67 | 68 | #### Forward port 69 | 70 | You now want to forward a port on your machine onto the VM's port 443. The problem is that to get access to port 443 on your machine, VirtualBox needs to run as root (bad idea). A better workaround is to use SSH port forwarding. 71 | 72 | This is what it will look like: 73 | 74 | 443 on host --> 8080 on host --> 443 on docker-machine VM 75 | 76 | ##### Forward port in VirtualBox 77 | 78 | Open Virtualbox and select the Docker Machine VM. Click ``Settings -> Network ->``, and on the NAT interface add a rule to forward TCP on host port ``8080`` to guest port ``443``. 79 | 80 | ##### Disable Password authentication 81 | 82 | Before we enable remote access, you don't want to risk people guessing your Mac password, so turn off password auth for SSH. 83 | 84 | In ``/private/etc/ssh/sshd_config`` (edit as root), ensure this line exists: 85 | 86 | PasswordAuthentication no 87 | 88 | ##### Enable Remote access 89 | 90 | Go to ``System Preferences -> Sharing`` and tick ``Remote Login``. 91 | 92 | Add yourself to authorized keys: 93 | 94 | cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys 95 | 96 | ##### Forward port with SSH 97 | 98 | $ sudo su - 99 | # ssh -i /Users/johndoe/.ssh/id_rsa johndoe@localhost -L \*:443::8080 100 | 101 | Try it out: 102 | 103 | $ curl https://localhost/ 104 | curl: (60) SSL certificate problem: Invalid certificate chain 105 | More details... 106 | 107 | ## Update the DNS record 108 | 109 | Get your current IP on the network where your users are, for example ``192.168.111.123``, and update your DNS record to point to that IP. 110 | 111 | ## Test 112 | 113 | $ curl https://registry.yourdomain.com/v2/ 114 | {}% 115 | 116 | ## Push images to local registry 117 | 118 | Pull down an image from the official hub, re-tag it to the local registry and push it up. 119 | 120 | docker pull redis 121 | docker tag redis registry.yourdomain.com/redis 122 | docker push registry.yourdomain.com/redis 123 | 124 | This script pulls, tags and pushes a list of images: 125 | 126 | ./pull_tag_and_push.sh registry.yourdomain.com redis python:2.7 127 | 128 | ## That's it! 129 | 130 | Your LAN users can now use your private registry to pull the image: 131 | 132 | docker pull registry.yourdomain.com/redis 133 | 134 | Or in a Compose file: 135 | 136 | redis: 137 | image: registry.yourdomain.com/redis 138 | 139 | Or in a Dockerfile: 140 | 141 | FROM registry.yourdomain.com/redis 142 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | registry: 2 | restart: always 3 | image: registry:2 4 | ports: 5 | - 443:5000 6 | environment: 7 | REGISTRY_HTTP_TLS_CERTIFICATE: /certs/fullchain1.pem 8 | REGISTRY_HTTP_TLS_KEY: /certs/privkey1.pem 9 | volumes: 10 | - "${HOME}/.ssl/registry:/certs" 11 | - "${HOME}/data:/var/lib/registry" 12 | -------------------------------------------------------------------------------- /pull_tag_and_push.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | function usage() { 3 | echo "usage: $0 [registry fqdn] [images]" && exit 1 4 | } 5 | [ "${1}" == "" ] && usage 6 | REGISTRY="${1}" 7 | # Define images 8 | shift 9 | HUB_IMAGES="${@}" 10 | echo ${HUB_IMAGES} 11 | # Pull all images from Docker Hub 12 | echo ${HUB_IMAGES} | xargs -I% -n1 docker pull % 13 | [ $? -ne 0 ] && echo "failed to fetch all images" && exit 1 14 | # Tag all images with local private registry 15 | echo ${HUB_IMAGES} | xargs -I% -n1 docker tag % ${REGISTRY}/% 16 | [ $? -ne 0 ] && echo "failed to tag all images" && exit 1 17 | # Push images to private registry 18 | echo ${HUB_IMAGES} | xargs -I% -n1 docker push ${REGISTRY}/% 19 | [ $? -ne 0 ] && echo "failed to push all images" && exit 1 20 | exit 0 21 | --------------------------------------------------------------------------------