From 690d8f8f6e10c10cca0632f5c267826da7552ed5 Mon Sep 17 00:00:00 2001 From: Anton Kaspiarovich Date: Mon, 19 Sep 2016 16:06:11 +0300 Subject: [PATCH] Added local Docker Registry and Certbot script to support generation of SSL certificates --- README.md | 2 +- cmd/certbot | 295 ++++++++++++++++++++++++++++ docker-compose.yml | 14 +- etc/logging/syslog/default.yml | 6 + etc/volumes/local/default.yml | 5 + etc/volumes/nfs/default.yml | 6 + quickstart.sh | 7 + site/_data/docs.yml | 5 + site/_docs/quickstart.md | 2 +- site/_docs/reference/cli/certbot.md | 115 +++++++++++ site/_docs/reference/cli/index.md | 3 +- site/_docs/tools/docker-registry.md | 112 +++++++++++ 12 files changed, 568 insertions(+), 4 deletions(-) create mode 100644 cmd/certbot create mode 100644 site/_docs/reference/cli/certbot.md create mode 100644 site/_docs/tools/docker-registry.md diff --git a/README.md b/README.md index 168cd4fa8..5877fd62a 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ NB. the instructions will also work in anywhere supported by [Docker Machine](ht / ``` -1. Update the docker-machine security group in the AWS console to permit inbound http traffic on port 80 (from the machine(s) from which you want to have access only), also UDP on 25826 and 12201 from 127.0.0.1/32. +1. Update the docker-machine security group in the AWS console to permit inbound http traffic on ports 80 and 443 (from the machine(s) from which you want to have access only), also UDP on 25826 and 12201 from 127.0.0.1/32. # General Getting Started Instructions diff --git a/cmd/certbot b/cmd/certbot new file mode 100644 index 000000000..6f51af570 --- /dev/null +++ b/cmd/certbot @@ -0,0 +1,295 @@ +#!/bin/bash -e + +SUB_CMD_NAME="certbot" + +cmd_desc() { + echo "For running Certbot (Self-Signed and Let’s Encrypt SSL) related commands" +} + +cmd_usage() { + echo "usage: ${CMD_NAME} ${SUB_CMD_NAME} " +} + +help() { + cmd_usage + echo + echo "Available subcommands are:" + printf " %-22s %s\n" "gen-export-certs" "Generate and Export Self-Signed SSL certificates for Nginx SSL support." + printf " %-22s %s\n" "gen-letsencrypt-certs" "Generate SSL certificates issued by Let's Encrypt for Nginx SSL support." + printf " %-22s %s\n" "export-letsencrypt-certs" "Export new SSL certificates issued by Let's Encrypt to the ADOP NGINX Proxy container." + printf " %-22s %s\n" "help" "Prints this help information" + echo +} + +gen_export_help() { + echo "usage: ${CMD_NAME} ${SUB_CMD_NAME} gen-export-certs []" + printf " %-2s %s\n" "" "Options:" + printf " %-3s %s\n" "" " : This is the domain name which will be secured by Let’s Encrypt SSL. (Required)" + printf " %-3s %s\n" "" " : Service name will be used for copying fullchain.pem and privkey.pem SSL files from auto generated domain name folder to static one: /certs/. (Optional)" + printf " %-3s %s\n" "" "-h : Prints this help." + + echo + echo "Examples of usage:" + printf " %-30s %s\n ${CMD_NAME} ${SUB_CMD_NAME} gen-export-certs example.com" + printf " %-30s %s\n ${CMD_NAME} ${SUB_CMD_NAME} gen-export-certs registry.example.com registry" + echo +} + +gen_letsencrypt_help() { + echo "usage: ${CMD_NAME} ${SUB_CMD_NAME} gen-letsencrypt-certs []" + printf " %-2s %s\n" "" "Options:" + printf " %-3s %s\n" "" " : This is the domain name which will be secured by Let’s Encrypt SSL. (Required)" + printf " %-3s %s\n" "" " : Service name will be used for copying fullchain.pem and privkey.pem SSL files from auto generated domain name folder to static one: /certs/. (Optional)" + printf " %-3s %s\n" "" "-h : Prints this help." + + echo + echo "Examples of usage:" + printf " %-30s %s\n ${CMD_NAME} ${SUB_CMD_NAME} gen-letsencrypt-certs example.com" + printf " %-30s %s\n ${CMD_NAME} ${SUB_CMD_NAME} gen-letsencrypt-certs registry.example.com registry" + echo +} + +export_letsencrypt_help() { + echo "usage: ${CMD_NAME} ${SUB_CMD_NAME} export-letsencrypt-certs []" + printf " %-2s %s\n" "" "Options:" + printf " %-3s %s\n" "" " : This is the domain name for which we will export certificate files. (Required)" + printf " %-3s %s\n" "" " : Service name will be used for specific NGINX virtual host configuration, you have to upload in ADOP NGINX container virtual host configuration file as /etc/nginx/sites-available/.conf." + printf " %-3s %s\n" "" " We will also use as a prefix for SSL keys for your service, for instance '/etc/nginx/ssl/_fullchain.pem' (Optional)" + printf " %-3s %s\n" "" "-h : Prints this help." + + echo + echo "Examples of usage:" + printf " %-30s %s\n ${CMD_NAME} ${SUB_CMD_NAME} export-letsencrypt-certs example.com" + printf " %-30s %s\n ${CMD_NAME} ${SUB_CMD_NAME} export-letsencrypt-certs registry.example.com registry" + echo +} + +gen_export_certs() { + # Set Parameters Values + export DOMAIN_NAME=$1 + export SERVICE_NAME=$2 + + local OPTIND + + while getopts "h" opt; do + case $opt in + h) + gen_export_help + exit 1 + ;; + esac + done + + if [ -z ${DOMAIN_NAME} ]; then + gen_export_help + exit 1 + fi + + #### + # Windows Git bash terminal identifies + # /CN=${DOMAIN_NAME} as a path and appends the absolute path + # of parent directory to it + #### + HOST_OS=$(uname) + CLIENT_SUBJ="/CN=${DOMAIN_NAME}" + if echo "${HOST_OS}" | grep -E "MINGW*" >/dev/null + then + CLIENT_SUBJ="//CN=${DOMAIN_NAME}" + fi + + export GEN_CERTS_LOG="CERTBOT_GEN_EXPORT_CERTS_`date '+%y%m%d-%H%M%S'`.log" + export TEMP_CERT_PATH=$(mktemp -d tmp_certbot.XXXXXXXXXX) || { echo "Failed to create temp folder"; exit 1; } + export PATH_PRIVATE_KEY_FILE_NAME=privkey.pem + export PATH_CERTIFICATE_FILE_NAME=fullchain.pem + + # Change certificates file names with the SERVICE_NAME as prefix + if [ -n "${SERVICE_NAME}" ]; then + export PATH_PRIVATE_KEY_FILE_NAME="${SERVICE_NAME}_${PATH_PRIVATE_KEY_FILE_NAME}" + export PATH_CERTIFICATE_FILE_NAME="${SERVICE_NAME}_${PATH_CERTIFICATE_FILE_NAME}" + fi + + echo "Generate new private key and self-signed certificate..." + openssl req -subj "${CLIENT_SUBJ}" \ + -newkey rsa:4096 -nodes -sha256 -keyout ${TEMP_CERT_PATH}/${PATH_PRIVATE_KEY_FILE_NAME} \ + -x509 -days 365 -out ${TEMP_CERT_PATH}/${PATH_CERTIFICATE_FILE_NAME} >> ${GEN_CERTS_LOG} 2>&1 || { echo "Error generating certificates. Please see " ${GEN_CERTS_LOG} " for more info"; exit 1; } + + if [ -n "${SERVICE_NAME}" ] && [ "${SERVICE_NAME}" == "registry" ]; then + # Copy private key and self-signed certificate to the Docker Registry volume + echo "Copying certificates to the registry_certs volume..." + export CONTAINER_ID=$(docker run -v registry_certs:/certs busybox //bin/sh -c "mkdir -p //certs/registry" && docker ps -l -q) + if [ -n "${CONTAINER_ID}" ]; then + docker cp ${TEMP_CERT_PATH}/${PATH_CERTIFICATE_FILE_NAME} ${CONTAINER_ID}:/certs/registry/fullchain.pem + docker cp ${TEMP_CERT_PATH}/${PATH_PRIVATE_KEY_FILE_NAME} ${CONTAINER_ID}:/certs/registry/privkey.pem + docker rm -f ${CONTAINER_ID} + fi + fi + + # Copy private key and self-signed certificate to the ADOP NGINX (proxy) container SSL folder + echo "Copying certificates to the ADOP Proxy container..." + docker cp ${TEMP_CERT_PATH}/${PATH_CERTIFICATE_FILE_NAME} proxy:/etc/nginx/ssl/ + docker cp ${TEMP_CERT_PATH}/${PATH_PRIVATE_KEY_FILE_NAME} proxy:/etc/nginx/ssl/ + + # Some versions of Docker also require you to trust the certificate at the OS level + echo "Copying self-signed certificate to the trusted location /etc/docker/certs.d/..." + + if [ "${MACHINE_TYPE}" == "aws" ] && [ -n "${MACHINE_NAME}" ]; then + echo "Copying via docker-machine to the ${MACHINE_NAME}..." + docker-machine scp ${TEMP_CERT_PATH}/${PATH_CERTIFICATE_FILE_NAME} ${MACHINE_NAME}:/tmp + docker-machine ssh ${MACHINE_NAME} "sudo mkdir -p /etc/docker/certs.d/${DOMAIN_NAME}" + docker-machine ssh ${MACHINE_NAME} "sudo cp /tmp/${PATH_CERTIFICATE_FILE_NAME} /etc/docker/certs.d/${DOMAIN_NAME}/ca.crt" + else + mkdir -p /etc/docker/certs.d/${DOMAIN_NAME} + cp ${TEMP_CERT_PATH}/${PATH_CERTIFICATE_FILE_NAME} /etc/docker/certs.d/${DOMAIN_NAME}/ca.crt + fi + + # Enable service NGINX configuration by making symlink from "available" folder + if [ -n "${SERVICE_NAME}" ]; then + echo "Enable ${SERVICE_NAME} NGINX configuration..." + docker exec proxy ln -sf //etc/nginx/sites-available/${SERVICE_NAME}.conf //etc/nginx/sites-enabled/${SERVICE_NAME}.conf + fi + + # Restart Docker Registry to make sure we started it again with TLS enabled + echo "Restart Docker Registry container with applied certificates..." + docker restart registry > /dev/null 2>&1 + + # Reload NGINX configuration + echo "Restart ADOP Proxy container with updated certificates..." + docker exec proxy nginx -s reload + + # Cleaning up all temporary folders and files + rm -f temp.seq + rm -rf ${TEMP_CERT_PATH} + rm -f ${GEN_CERTS_LOG} + + echo "Self-Signed certificates has been generated successfully..." +} + +gen_letsencrypt_certs() { + # Set Parameters Values + export DOMAIN_NAME=$1 + export SERVICE_NAME=$2 + + local OPTIND + + while getopts "h" opt; do + case $opt in + h) + gen_letsencrypt_help + exit 1 + ;; + esac + done + + if [ -z ${DOMAIN_NAME} ]; then + gen_letsencrypt_help + exit 1 + fi + + echo "INFO: Let's Encrypt SSL certificates will be issued for ${DOMAIN_NAME}." + + export PROXY_CONTAINER_ID=$(docker ps --filter="name=proxy" -q | xargs) + export PROXY_CONTAINER_RESTART=false + if [ ! -z ${PROXY_CONTAINER_ID} ]; then + read -r -p "We found running Proxy (NGINX) container. To issue new SSL certificate we have to stop & start Proxy container, which will be cause of ADOP short outage. Please, confirm restart of Proxy (NGINX) container? [y/n] " response + case $response in + [yY][eE][sS]|[yY]) + PROXY_CONTAINER_RESTART=true + printf "Stopping Proxy (NGINX) container..." + docker stop proxy + ;; + *) + printf "SSL certificate issuing aborted by user." + exit 1 + ;; + esac + fi + + docker run --rm -i \ + -p 80:80 \ + -p 443:443 \ + -v registry_certs:/etc/letsencrypt \ + accenture/certbot:0.0.1 \ + certonly --standalone -d ${DOMAIN_NAME} --text --non-interactive --register-unsafely-without-email --agree-tos + + if [ -n "${SERVICE_NAME}" ]; then + export SERVICE_FOLDER="/certs/${SERVICE_NAME}" + docker run -i --rm -v registry_certs:/certs busybox sh -c "mkdir -p ${SERVICE_FOLDER} && cp -RL /certs/live/${DOMAIN_NAME}/fullchain.pem /certs/live/${DOMAIN_NAME}/privkey.pem ${SERVICE_FOLDER}" + fi + + if [ ${PROXY_CONTAINER_RESTART} = true ]; then + printf "Starting Proxy (NGINX) container..." + docker start proxy + fi +} + +export_letsencrypt_certs() { + # Set Parameters Values + export DOMAIN_NAME=$1 + export SERVICE_NAME=$2 + + local OPTIND + + while getopts "h" opt; do + case $opt in + h) + export_letsencrypt_help + exit 1 + ;; + esac + done + + if [ -z ${DOMAIN_NAME} ]; then + export_letsencrypt_help + exit 1 + fi + + export DEST_CHAIN_FILE_NAME=fullchain.pem + export DEST_PRIVATE_KEY_FILE_NAME=privkey.pem + + if [ -n "${SERVICE_NAME}" ]; then + export DEST_CHAIN_FILE_NAME="${SERVICE_NAME}_fullchain.pem" + export DEST_PRIVATE_KEY_FILE_NAME="${SERVICE_NAME}_privkey.pem" + docker exec proxy ln -sf //etc/nginx/sites-available/${SERVICE_NAME}.conf //etc/nginx/sites-enabled/${SERVICE_NAME}.conf + fi + + export CONTAINER_ID=$(docker run -v registry_certs:/certs busybox //bin/sh -c "mkdir -p //tmp/certs; cp -L //certs/live/${DOMAIN_NAME}/fullchain.pem //tmp/certs/fullchain.pem; cp -L //certs/live/${DOMAIN_NAME}/privkey.pem //tmp/certs/privkey.pem" && docker ps -l -q) + if [ -n "${CONTAINER_ID}" ]; then + docker cp ${CONTAINER_ID}:/tmp/certs/fullchain.pem ${DEST_CHAIN_FILE_NAME} + docker cp ${CONTAINER_ID}:/tmp/certs/privkey.pem ${DEST_PRIVATE_KEY_FILE_NAME} + docker cp ${DEST_CHAIN_FILE_NAME} proxy:/etc/nginx/ssl/ + docker cp ${DEST_PRIVATE_KEY_FILE_NAME} proxy:/etc/nginx/ssl/ + + rm ${DEST_CHAIN_FILE_NAME} ${DEST_PRIVATE_KEY_FILE_NAME} + docker rm -f ${CONTAINER_ID} + + docker exec proxy nginx -s reload + fi +} + +shift $(($OPTIND -1)) +SUBCOMMAND_OPT="${1:-help}" + +# Only shift if there are other parameters +if [ $# -ge 1 ]; then + shift +fi + +case ${SUBCOMMAND_OPT} in + "cmd_desc"|"help") + ${SUBCOMMAND_OPT} "$@" + ;; + "gen-export-certs") + gen_export_certs "$@" + ;; + "gen-letsencrypt-certs") + gen_letsencrypt_certs "$@" + ;; + "export-letsencrypt-certs") + export_letsencrypt_certs "$@" + ;; + *) + echo "Invalid parameter(s) or option(s)." + help + exit 1 + ;; +esac diff --git a/docker-compose.yml b/docker-compose.yml index 4567e945d..284866e0f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ proxy: container_name: proxy restart: always - image: accenture/adop-nginx:0.2.0 + image: accenture/adop-nginx:0.3.0 #build: ../images/docker-nginx/ net: ${CUSTOM_NETWORK_NAME} ports: @@ -341,3 +341,15 @@ ldap-phpadmin: LDAP_SERVER_PORT: "389" LDAP_SERVER_BIND_ID: "${LDAP_ADMIN},${LDAP_FULL_DOMAIN}" LDAP_SERVER_BASE_DN: "${LDAP_FULL_DOMAIN}" + +registry: + container_name: registry + restart: always + image: registry:2.5.1 + net: ${CUSTOM_NETWORK_NAME} + expose: + - "5000" + environment: + REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data + REGISTRY_HTTP_TLS_CERTIFICATE: /certs/registry/fullchain.pem + REGISTRY_HTTP_TLS_KEY: /certs/registry/privkey.pem diff --git a/etc/logging/syslog/default.yml b/etc/logging/syslog/default.yml index 93ccb4139..24cb87fab 100644 --- a/etc/logging/syslog/default.yml +++ b/etc/logging/syslog/default.yml @@ -107,3 +107,9 @@ nexus: log_opt: syslog-address: "udp://${LOGSTASH_HOST}:25826" tag: "nexus" + +registry: + log_driver: "syslog" + log_opt: + syslog-address: "udp://${LOGSTASH_HOST}:25826" + tag: "registry" diff --git a/etc/volumes/local/default.yml b/etc/volumes/local/default.yml index 0eb1731d4..01d42fe0a 100644 --- a/etc/volumes/local/default.yml +++ b/etc/volumes/local/default.yml @@ -62,3 +62,8 @@ jenkins: nexus: volumes: - nexus_sonatype_work:/sonatype-work + +registry: + volumes: + - registry_certs:/certs + - registry_data:/data diff --git a/etc/volumes/nfs/default.yml b/etc/volumes/nfs/default.yml index 24926e542..e543ee147 100644 --- a/etc/volumes/nfs/default.yml +++ b/etc/volumes/nfs/default.yml @@ -79,3 +79,9 @@ nexus: volume_driver: nfs volumes: - ${NFS_HOST}/nfs/nexus_sonatype_work:/sonatype-work + +registry: + volume_driver: nfs + volumes: + - ${NFS_HOST}/nfs/registry_certs:/certs + - ${NFS_HOST}/nfs/registry_data:/data diff --git a/quickstart.sh b/quickstart.sh index 926b6214e..0ce5517ea 100755 --- a/quickstart.sh +++ b/quickstart.sh @@ -226,4 +226,11 @@ case ${MACHINE_TYPE} in esac # Use the ADOP CLI +eval $(docker-machine env ${MACHINE_NAME}) + ./adop compose -m "${MACHINE_NAME}" ${CLI_COMPOSE_OPTS} init + +# Generate and export Self-Signed SSL certificate for Docker Registry, applicable only for AWS type +if [ ${MACHINE_TYPE} == "aws" ]; then + ./adop certbot gen-export-certs "registry.$(docker-machine ip ${MACHINE_NAME}).nip.io" registry +fi diff --git a/site/_data/docs.yml b/site/_data/docs.yml index e708610a8..d77c88150 100644 --- a/site/_data/docs.yml +++ b/site/_data/docs.yml @@ -27,6 +27,11 @@ - operating/projects - operating/cartridges +- title: Tools + docs: + - tools + - tools/docker-registry + - title: Developing docs: - developing diff --git a/site/_docs/quickstart.md b/site/_docs/quickstart.md index 2110e3325..5a7bd6284 100644 --- a/site/_docs/quickstart.md +++ b/site/_docs/quickstart.md @@ -53,4 +53,4 @@ NB. the instructions will also work in anywhere supported by [Docker Machine](ht 1. Log in using the username and password you specified in the quickstart script. - These can also be found in your "platform.secrets.sh" file -1. Update the docker-machine security group in the AWS console to permit inbound http traffic on port 80 (from the machine(s) from which you want to have access only), also UDP on 25826 and 12201 from 127.0.0.1/32. +1. Update the docker-machine security group in the AWS console to permit inbound http traffic on ports 80 and 443 (from the machine(s) from which you want to have access only), also UDP on 25826 and 12201 from 127.0.0.1/32. diff --git a/site/_docs/reference/cli/certbot.md b/site/_docs/reference/cli/certbot.md new file mode 100644 index 000000000..0ce229365 --- /dev/null +++ b/site/_docs/reference/cli/certbot.md @@ -0,0 +1,115 @@ +--- +layout: docs +chapter: Reference - CLI +title: certbot +permalink: /docs/reference/cli/certbot/ +--- + +[Back to CLI Commands](/adop-docker-compose/docs/reference/cli/) + +## Command + +`./adop certbot []` + +Used for running ADOP Certbot related commands. + +*Originally, this script was developed in order to support Docker Registry, but while we developing it, we realized, that it's actually can be more abstract and used for entire stack, so that you can have SSL-enabled secure stack.* + +## Subcommands + +### gen-export-certs + + + + + + + + + + + + + + + + + + + + + + +
Subcommand
gen-export-certs [<options>]Generates self-signed certificates and export them to the ADOP Proxy (NGINX)
Option
<domain-name>Sets the Domain Name for which self-signed certificates will be issued (required).
<service-name>Sets the Service Name, where <SERVICE-NAME> is the reference name for which you want to generate certificates (optional). In case of "registry" service-name specifically, script will also export certificates to the ADOP Docker Registry certs volume.
+ +### gen-letsencrypt-certs + + + + + + + + + + + + + + + + + + + + + + +
Subcommand
gen-letsencrypt-certs [<options>]Request (generate) SSL certificates issued by Let's Encrypt.
Option
<domain-name>Sets the Domain Name for which certificates by Let's Encrypt will be issued (required).
<service-name>Sets the Service Name, where <SERVICE-NAME> is the reference name for which you want to generate certificates (optional).
+ +### export-letsencrypt-certs + + + + + + + + + + + + + + + + + + + + + + +
Subcommand
export-letsencrypt-certs [<options>]Export SSL certificates issued by Let's Encrypt to the ADOP Proxy (NGINX) container.
Option
<domain-name>Sets the Domain Name for which, certificates issued by Let's Encrypt before (by gen-letsencrypt-certs), will be exported to the Docker volumes (required).
<service-name>Sets the Service Name, where <SERVICE-NAME> is the reference name for which you want to enable NGINX configuration from sites-available to sites-enabled (optional)
+ +## Examples + +Generate and export self-signed certificates + +``` +./adop certbot gen-export-certs registry..nip.io registry +``` + +Request (generate) issued by Let's Encrypt certificates + +``` +./adop certbot gen-letsencrypt-certs registry..nip.io registry +./adop certbot gen-letsencrypt-certs .nip.io +``` + +Export issued by Let's Encrypt certificates to the ADOP Proxy volume and Enable NGINX link configuration from sites-available to sites-enabled + +``` +./adop certbot export-letsencrypt-certs registry..nip.io registry +./adop certbot export-letsencrypt-certs .nip.io +``` diff --git a/site/_docs/reference/cli/index.md b/site/_docs/reference/cli/index.md index 0d71aecb9..06fedb716 100644 --- a/site/_docs/reference/cli/index.md +++ b/site/_docs/reference/cli/index.md @@ -1,7 +1,7 @@ --- layout: docs chapter: Reference -title: Command Line Interface +title: Command Line Interface permalink: /docs/reference/cli/ --- A quick reference to ADOP CLI commands. @@ -11,3 +11,4 @@ A quick reference to ADOP CLI commands. * [./adop project](/adop-docker-compose/docs/reference/cli/project/) * [./adop target](/adop-docker-compose/docs/reference/cli/target/) * [./adop workspace](/adop-docker-compose/docs/reference/cli/workspace/) +* [./adop certbot](/adop-docker-compose/docs/reference/cli/certbot/) diff --git a/site/_docs/tools/docker-registry.md b/site/_docs/tools/docker-registry.md new file mode 100644 index 000000000..c806c131c --- /dev/null +++ b/site/_docs/tools/docker-registry.md @@ -0,0 +1,112 @@ +--- +layout: docs +chapter: Tools +title: Docker Registry +permalink: /docs/tools/docker-registry/ +--- + +* [About Docker Registry](#about-docker-registry) + * [Insecure Registry](#insecure-registry) +* [Configuration](#configuration) + * [Self-Signed Certificate](#self-signed-certificate) + * [Make Self-Signed certificate trusted](#make-self-signed-certificate-trusted) + * [Let's Encrypt](#lets-encrypt) +* [Example of usage](#example-of-usage) + +## About Docker Registry +With the Docker Registry integrated into ADOP, you can build and store your own Docker images privately inside the stack. +You can read more about Docker Registry at [https://docs.docker.com/registry/introduction/](https://docs.docker.com/registry/introduction/) + +### Insecure Registry +Docker Registry is designed to use SSL by default and what most importantly, certificate which's issued by a known CA. +You can read more about [Insecure Registry](https://docs.docker.com/registry/insecure/). + +It's important to understand, as if you're using QuickStart.sh, **by default this script will deploy [Insecure Registry](https://docs.docker.com/registry/insecure/)** and this way of usage have downsides i.e. requires trusted certificate on each workstation including your own laptop. +But we also have [Let's Encrypt](#lets-encrypt) scripts which would help you to generate real certificates, issued by Let's Encrypt, but we can not implement this way of usage by default (automatically), as Let's Encrypt have strict limits and because of limits, unfortunately we can't guarantee working Docker Registry. You can read more about - [Let's Encrypt Rate Limits](https://letsencrypt.org/docs/rate-limits/). + +## Configuration +We've added generation of self-signed certificate for Docker Registry by default in QuickStart.sh script via [Certbot CLI](/adop-docker-compose/docs/reference/cli/certbot/), +which means, whenever you would initialize ADOP via QuickStart.sh, out-of-the-box you will have **Insecure Docker Registry**. + +Example of usage (actual lines from QuickStart.sh): + +``` +# quickstart.sh + +./adop compose -m "${MACHINE_NAME}" ${CLI_COMPOSE_OPTS} init + +if [ ${MACHINE_TYPE} == "aws" ]; then + ./adop certbot gen-export-certs "registry.$(docker-machine ip ${MACHINE_NAME}).nip.io" registry +fi +``` + +This "./adop certbot gen-export-certs" one command, will: + +* Generate Self-Signed certificates +* Copy certificates to the ADOP Docker Registry volume +* Copy certificates to the ADOP Proxy volume +* Copy certificates to the trusted location on a host machine - /etc/docker/certs.d/ +* Enable ADOP Proxy, NGINX configuration for ADOP Docker Registry +* Restart ADOP Docker Registry +* Reload ADOP Proxy, NGINX configuration + +By the end of all these steps, we'll have successfully deployed Insecure Docker Registry on "registry.<>.nip.io" domain name with [authentication via NGINX](https://docs.docker.com/registry/recipes/nginx/) and LDAP. + +It's important to understand, that by default, you would able to operate with Insecure Docker Registry **ONLY INSIDE THE STACK**, for example from ADOP Jenkins or even host-machine (where you'd deployed ADOP), as by Certbot it's already made self-signed certificates trusted. + +If you will try to authenticate or pull some Docker image from Insecure Docker Registry, most probably you will get the following: + +``` +Error response from daemon: Get https://registry..nip.io/v1/users/: x509: certificate signed by unknown authority +``` + +It means, that you have to [Make Self-Signed certificate trusted](#make-self-signed-certificate-trusted) on any workstation, from which you're trying to executing those commands, even your own laptop. But, you could also avoid this by using [Let's Encrypt](#lets-encrypt). + +### Self-Signed Certificate +Docker Engine support several ways how you can use/trust Insecure Docker Registry. + +1. Built-in process via /etc/docker/certs.d/${DOMAIN_NAME}, please, read about this method at [https://docs.docker.com/engine/security/certificates/#/understanding-the-configuration](https://docs.docker.com/engine/security/certificates/#/understanding-the-configuration) +2. Trust certificate on the OS level - [Make Self-Signed certificate trusted](#make-self-signed-certificate-trusted) +3. Additional options via DOCKER_OPTS such as "---insecure-registry" [https://docs.docker.com/registry/insecure/#/deploying-a-plain-http-registry](https://docs.docker.com/registry/insecure/#/deploying-a-plain-http-registry) - marked as **VERY insecure solution** + +#### Make Self-Signed certificate trusted +For each platform the process might be different, please check documentation per platform: + +* [Docker for Windows](https://github.com/docker/docker/issues/21189) +* [Docker for Linux](https://docs.docker.com/engine/security/certificates/#/understanding-the-configuration) +* [Docker for Mac](https://docs.docker.com/docker-for-mac/faqs/#how-do-i-add-custom-ca-certificates) + +### Let's Encrypt +This way of usage is more preferable, as Let's Encrypt issuing real/valid SSL certificates by known CA **absolutely for free**. + +Let's play the scenario, when you want to deploy ADOP via ADOP CLI i.e. without QuickStart.sh, but with Let's Encrypt for Docker Registry, to avoid the situation where you'll have to trust self-signed certificates. + +Previously, most probably, you had only one step to initialize ADOP: +``` +./adop compose init +``` + +But now, we would need to add few more steps, one before initialization and one after: + +``` +./adop certbot gen-letsencrypt-certs registry..nip.io registry +./adop compose init +./adop certbot export-letsencrypt-certs registry..nip.io registry +``` + +The reason why we've to add more steps, is because Let's Encrypt have builtin domain validation process, please read more about this at [https://letsencrypt.org/how-it-works/#domain-validation](https://letsencrypt.org/how-it-works/#domain-validation). All the process of copying certificates etc. will remains the same, as it was described above. What's most important here is that in this way, you'll have "production-ready" Docker Registry, not evaluation-mode as it was with Insecure Docker Registry. + +## Example of usage + +Authentication: + +``` +docker login -u -p registry..nip.io +``` + +Docker image Pull or Push: + +``` +docker push registry..nip.io/imagename:0.0.1 +docker pull registry..nip.io/imagename:0.0.1 +```