Self-hosting a container registry

#!/usr/bin/env sh

USERNAME=username
PASSWORD=password
HOST=127.0.0.1
PORT=5000
NAME=registry
DIRECTORY=~/.var/ow-image-registry

usage()
{
    echo <<EOF
Launches a docker container of the official Docker `registry` image.
Tries to use sane defaults and be idempotent. Running this script
after the first time will simply run the container.

-U, --username Username to login to registry.
-P, --password Password to login to registry.
-h, --host Interface to bind.
-p, --port  Port to expose on host.
-n, --name  Name of container.
-d, --directory Data directory.
EOF

    exit 2
}

PARSED_ARGUMENTS=$(getopt -a -n registry.sh -o U:P:h:p:n:d: --long username:,password:,host:,port:,name:,directory: -- "$@")
VALID_ARGUMENTS=$?
if [ "$VALID_ARGUMENTS" != "0" ]; then
  usage
fi

eval set -- "$PARSED_ARGUMENTS"

while :
do
  case "$1" in
    -U | --username)  USERNAME=${2}     ; shift 2 ;;
    -P | --password)  PASSWORD=${2}     ; shift 2 ;;
    -h | --host)      HOST=${2}         ; shift 2 ;;
    -p | --port)      PORT=${2}         ; shift 2 ;;
    -n | --name)      NAME=${2}         ; shift 2 ;;
    -d | --directory) DIRECTORY=${2}    ; shift 2 ;;
    # -- means the end of the arguments; drop this, and break out of the while loop
    --) shift; break ;;
    # If invalid options were passed, then getopt should have reported an error,
    # which we checked as VALID_ARGUMENTS when getopt was called...
    *) echo "Unexpected option: $1 - this should not happen."
       usage ;;
  esac
done

if ! command -v htpasswd &> /dev/null
then
    echo "Requires `htpasswd` to bcrypt credentials. Try `yay -Sy apache-tools` on Arch Linux."
    exit
fi

mkdir -p ${DIRECTORY}/data
mkdir -p ${DIRECTORY}/security

if ! [ -e ${DIRECTORY}/security/htpasswd ]
then
    touch ${DIRECTORY}/security/htpasswd
    echo "password" | htpasswd -iB ${DIRECTORY}/security/htpasswd username
fi

if ! [ -e ${DIRECTORY}/security/registry.crt ]
then
    echo "Generating self-signed certificate."
    openssl req -newkey rsa:4096 \
        -x509 \
        -sha256 \
        -days 365 \
        -nodes \
        -subj "/C=US/ST=California/O=Owoga/CN=owoga.com" \
        -out ${DIRECTORY}/security/registry.crt \
        -keyout ${DIRECTORY}/security/registry.key
fi

CONTAINER_EXISTS=$(docker ps -a | grep ${NAME} &> /dev/null)
if ! [ $? -eq 0 ]
then
    docker \
        run  \
        -p ${HOST}:${PORT}:5000 \
        --name ${NAME} \
        -v ${DIRECTORY}/data:/var/lib/registry \
        -v ${DIRECTORY}/security:/etc/security \
        -e REGISTRY_HTTP_TLS_CERTIFICATE=/etc/security/registry.crt \
        -e REGISTRY_HTTP_TLS_KEY=/etc/security/registry.key \
        -e REGISTRY_AUTH=htpasswd \
        -e REGISTRY_AUTH_HTPASSWD_PATH=/etc/security/htpasswd \
        -e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
        registry:2
else
    docker start ${NAME}
fi

Show Comments