├── .gitignore ├── README.md ├── auth └── htpasswd ├── certs └── .keep ├── docker-compose.yml ├── index.html ├── nginx.conf └── temp └── .keep /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore bundler config. 2 | /.bundle 3 | 4 | # Ignore all logfiles and tempfiles. 5 | /log/* 6 | /tmp/* 7 | !/log/.keep 8 | !/tmp/.keep 9 | 10 | # Ignore Byebug command history file. 11 | .byebug_history 12 | 13 | /cache 14 | /cache/* 15 | /tmp 16 | /tmp/* 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | Devteds [Episode #2](https://devteds.com/episodes/2-setup-private-docker-registry-secure-with-ssl-password) 4 | 5 | Learn how to setup a private secure docker registry in the cloud. 6 | 7 | [Episode video link](https://youtu.be/KMldBtbJ4qI) 8 | 9 | [![Episode Video Link](https://i.ytimg.com/vi/KMldBtbJ4qI/hqdefault.jpg)](https://youtu.be/KMldBtbJ4qI) 10 | 11 | Visit https://devteds.com to watch all the episodes 12 | 13 | ## Tested on 14 | 15 | * Mac OSX - 10.10.5 16 | * Docker - 1.12.1 17 | * Docker compose - 1.8.0 18 | * Docker Machine - 0.8.1 19 | * Ubuntu 16.x (Droplet on Digitalocean) 20 | 21 | ## Instructions / commands 22 | 23 | Login to digitalocean.com, sign up for an account if you don't have one already, generate ACCESS_TOKEN and save 24 | 25 | ### Create VM / Droplet on DigitalOcean 26 | ``` 27 | mkdir ~/projects/private-registry 28 | cd ~/projects/private-registry 29 | 30 | docker-machine create -d digitalocean --digitalocean-access-token= my-private-registry 31 | 32 | # Get the SERVER IP ADDRESS using, 33 | docker-machine ip my-private-registry 34 | ``` 35 | 36 | If you don’t have a DigitalOcean account, [Register now](https://m.do.co/c/a9b9aef156d6) and get some credit and that should get you running a VM of about 2 months (promo as of 10/30/16) - https://m.do.co/c/a9b9aef156d6 37 | 38 | ### Configure & Run Services 39 | 40 | ``` 41 | # create nginx root 42 | docker-machine ssh my-private-registry mkdir /root/nginx-root 43 | 44 | # create/copy basic nginx.conf, 45 | docker-machine scp nginx.conf my-private-registry:/root/nginx-root/ 46 | 47 | # create/copy an index.html file, 48 | docker-machine scp index.html my-private-registry:/root/nginx-root/ 49 | 50 | # create docker-compose.yml for nginx service. and, 51 | eval $(docker-machine env my-private-registry) 52 | env | grep DOCKER 53 | # verify the docker host which should be pointing to the public IP Address of the my-private-registry 54 | docker-compose start 55 | 56 | # Verify nginx on http:/// and that should work 57 | 58 | # Pick a domain name - free ones, buy one, sub domain off of an existing one or if you have a spare 59 | # Set the A record pointing to the SERVER IP ADDRESS 60 | 61 | # Verify nginx using http:/// and that should work 62 | 63 | # Add registry service to docker-compose.yml 64 | # Update nginx to define upstream for registry service 65 | docker-compose stop 66 | docker-machine scp nginx.conf my-private-registry:/root/ 67 | docker-compose start 68 | 69 | # Verify registry http:///v2/_catalog and that should work 70 | 71 | docker-compose stop 72 | 73 | mkdir certs 74 | # Get SSL certificate from sslforfree.com (certificate.crt, ca_bundle.crt & private.key) 75 | # Unzip the files into certs folder create server.crt using, 76 | cat certs/certificate.crt certs/ca_bundle.crt > certs/server.crt 77 | 78 | docker-machine ssh my-private-registry mkdir /root/certs 79 | docker-machine scp certs/private.key my-private-registry:/root/certs/ 80 | docker-machine scp certs/server.crt my-private-registry:/root/certs/ 81 | 82 | # Update nginx to add virtual server for 443 with SSL ON 83 | docker-machine scp nginx.conf my-private-registry:/root/ 84 | docker-compose start 85 | # or docker-compose up -d 86 | 87 | # Verify SSL https:/// 88 | 89 | docker-compose stop 90 | # Update nginx to redirect all HTTP to HTTPS 91 | docker-machine scp nginx.conf my-private-registry:/root/ 92 | docker-compose start 93 | # Verify the redirects 94 | 95 | docker-compose stop 96 | # Generate htpasswd on the server 97 | # Update nginx for basic_auth 98 | docker-machine scp nginx.conf my-private-registry:/root/ 99 | docker-compose start 100 | # Verify basic auth is working 101 | 102 | ``` 103 | 104 | 105 | ## Create a dev machine 106 | 107 | Switch to a separate terminal window to create a separate docker machine to test the registry 108 | 109 | ``` 110 | docker-machine create -d virtualbox dev1 111 | docker-machine ssh dev1 112 | docker pull busybox 113 | docker login 114 | # Provide login details 115 | docker tag busybox /busybox 116 | docker push /busybox 117 | 118 | # Verify on http:///v2/_catalog 119 | ``` 120 | -------------------------------------------------------------------------------- /auth/htpasswd: -------------------------------------------------------------------------------- 1 | admin:$apr1$zCm.j9vz$SMFTmZxs5YfW7kZhrvpsL1 2 | -------------------------------------------------------------------------------- /certs/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devteds/e2-setup-private-docker-registry/09f2150f5f9af7237a984637f8f3c9d0776aae81/certs/.keep -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | revp: 4 | image: nginx:latest 5 | volumes: 6 | - "/root/nginx-root:/usr/share/nginx/html:ro" 7 | - "/root/nginx.conf:/etc/nginx/nginx.conf:ro" 8 | - "/root/certs:/usr/share/certs:ro" 9 | - "/root/auth/htpasswd:/etc/nginx/.htpasswd:ro" 10 | ports: 11 | - "80:80" 12 | - "443:443" 13 | depends_on: 14 | - reg 15 | links: 16 | - reg 17 | reg: 18 | image: registry 19 | expose: 20 | - 5000 21 | volumes: 22 | - "/root/reg-data:/var/lib/registry:rw" -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | Looks good! -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | user root; 2 | 3 | events { 4 | worker_connections 1024; 5 | } 6 | 7 | http { 8 | include mime.types; 9 | default_type application/octet-stream; 10 | sendfile on; 11 | tcp_nopush on; 12 | keepalive_timeout 65; 13 | gzip on; 14 | gzip_types text/plain text/css text/javascript 15 | application/javascript application/json 16 | application/xml; 17 | index index.html index.htm; 18 | 19 | upstream docker_reg { 20 | server reg:5000; 21 | } 22 | 23 | server { 24 | listen 80 default_server; 25 | listen [::]:80 default_server; 26 | server_name _; 27 | return 301 https://$host$request_uri; 28 | } 29 | 30 | server { 31 | listen 443; 32 | 33 | root /usr/share/nginx/html; 34 | 35 | ssl on; 36 | ssl_certificate /usr/share/certs/server.crt; 37 | ssl_certificate_key /usr/share/certs/private.key; 38 | 39 | chunked_transfer_encoding on; 40 | 41 | location / { 42 | auth_basic "Registry realm"; 43 | auth_basic_user_file /etc/nginx/.htpasswd; 44 | root /usr/share/nginx/html; 45 | } 46 | 47 | location /v2/ { 48 | auth_basic "Registry realm"; 49 | auth_basic_user_file /etc/nginx/.htpasswd; 50 | add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always; 51 | proxy_read_timeout 900; 52 | proxy_pass http://docker_reg; 53 | } 54 | 55 | error_page 500 502 503 504 /500.html; 56 | client_max_body_size 4G; 57 | keepalive_timeout 10; 58 | } 59 | } -------------------------------------------------------------------------------- /temp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devteds/e2-setup-private-docker-registry/09f2150f5f9af7237a984637f8f3c9d0776aae81/temp/.keep --------------------------------------------------------------------------------