Created
September 14, 2022 05:00
-
-
Save wezzels/1e981589c1852a143be2106be4486533 to your computer and use it in GitHub Desktop.
Docker registry and letsencrypt auto reconfigure.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Basic setup for my container registry, minio, and openVPN. Keep and SSL updates | |
DOMAIN_NAME=example.com | |
USER=myuser | |
sudo mkdir -p /opt/registry/data | |
sudo mkdir -p /opt/registry/web | |
sudo mkdir -p /opt/registry/web/certbot/conf | |
sudo mkdir -p /opt/registry/web/certbot/www | |
sudo mkdir -p /opt/registry/setup | |
sudo mkdir -p /opt/registry/auth | |
sudo mkdir -p /opt/registry/cert | |
sudo chown -R $USER:$USER /opt/registry | |
sudo apt -y install apache2-utils | |
#curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh | |
#chmod +x init-letsencrypt.sh | |
#sudo ./init-letsencrypt.sh | |
#htpasswd -Bc /opt/registry/registry.password testuser | |
cat <<EOF > /opt/registry/auth/docker-compose.yml | |
version: '3' | |
services: | |
registry: | |
image: registry:2 | |
ports: | |
- "5000:5000" | |
environment: | |
REGISTRY_HTTP_ADDR: 0.0.0.0:5000 | |
REGISTRY_HTTP_TLS_CERTIFICATE: /etc/letsencrypt/live/$DOMAIN_NAME/fullchain.pem | |
REGISTRY_HTTP_TLS_KEY: /etc/letsencrypt/live/$DOMAIN_NAME/privkey.pem | |
REGISTRY_AUTH: htpasswd | |
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm | |
REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password | |
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data | |
restart: always | |
volumes: | |
- /opt/registry/web/certbot/conf:/etc/letsencrypt | |
- /opt/registry/auth:/auth | |
- /opt/registry/cert:/cert | |
- /opt/registry/data:/data | |
#dummy password and user are:testuser:passwordtester | |
nginx: | |
image: nginx:1.15-alpine | |
ports: | |
- "80:80" | |
- "8443:8443" | |
command: "/bin/sh -c 'while :; do sleep 6h & wait 303468{!}; nginx -s reload; done & nginx -g \"daemon off;\"'" | |
volumes: | |
- /opt/registry/app:/data/www | |
- /opt/registry/web:/etc/nginx/conf.d | |
- /opt/registry/web/certbot/conf:/etc/letsencrypt | |
- /opt/registry/web/certbot/www:/var/www/certbot | |
certbot: | |
image: certbot/certbot | |
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait 303468{!}; done;'" | |
volumes: | |
- /opt/registry/web/certbot/conf:/etc/letsencrypt | |
- /opt/registry/web/certbot/www:/var/www/certbot | |
EOF | |
cat <<EOF > /opt/registry/web/app.conf | |
server { | |
listen 80; | |
server_name $DOMAIN_NAME; | |
location / { | |
return 301 https://$host$request_uri; | |
} | |
location /.well-known/acme-challenge/ { | |
root /var/www/certbot; | |
} | |
} | |
server { | |
listen 8443 ssl; | |
server_name $DOMAIN_NAME; | |
include /etc/letsencrypt/options-ssl-nginx.conf; | |
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; | |
ssl_certificate /etc/letsencrypt/live/$DOMAIN_NAME/fullchain.pem; | |
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN_NAME/privkey.pem; | |
location / { | |
proxy_pass http://$DOMAIN_NAME; #for demo purposes | |
} | |
} | |
EOF | |
cat <<EOF > /opt/registry/init-letsencrypt.sh | |
#!/bin/bash | |
if ! [ -x "$(command -v docker-compose)" ]; then | |
echo 'Error: docker-compose is not installed.' >&2 | |
exit 1 | |
fi | |
domains=($DOMAIN_NAME) | |
rsa_key_size=4096 | |
data_path="/opt/registry/web/certbot/" | |
email="wlrobbi@sandia.gov" # Adding a valid address is strongly recommended | |
staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits | |
if [ -d "$data_path" ]; then | |
read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision | |
if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then | |
exit | |
fi | |
fi | |
if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then | |
echo "### Downloading recommended TLS parameters ..." | |
mkdir -p "$data_path/conf" | |
curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf" | |
curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem" | |
echo | |
fi | |
echo "### Creating dummy certificate for $domains ..." | |
path="/etc/letsencrypt/live/$domains" | |
mkdir -p "$data_path/conf/live/$domains" | |
docker-compose run --rm --entrypoint "\ | |
openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\ | |
-keyout '$path/privkey.pem' \ | |
-out '$path/fullchain.pem' \ | |
-subj '/CN=localhost'" certbot | |
echo | |
echo "### Starting nginx ..." | |
docker-compose up --force-recreate -d nginx | |
echo | |
echo "### Deleting dummy certificate for $domains ..." | |
docker-compose run --rm --entrypoint "\ | |
rm -Rf /etc/letsencrypt/live/$domains && \ | |
rm -Rf /etc/letsencrypt/archive/$domains && \ | |
rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot | |
echo | |
echo "### Requesting Let's Encrypt certificate for $domains ..." | |
#Join $domains to -d args | |
domain_args="" | |
for domain in "${domains[@]}"; do | |
domain_args="$domain_args -d $domain" | |
done | |
# Select appropriate email arg | |
case "$email" in | |
"") email_arg="--register-unsafely-without-email" ;; | |
*) email_arg="--email $email" ;; | |
esac | |
# Enable staging mode if needed | |
if [ $staging != "0" ]; then staging_arg="--staging"; fi | |
docker-compose run --rm --entrypoint "\ | |
certbot certonly --webroot -w /var/www/certbot \ | |
$staging_arg \ | |
$email_arg \ | |
$domain_args \ | |
--rsa-key-size $rsa_key_size \ | |
--agree-tos \ | |
--force-renewal" certbot | |
echo | |
echo "### Reloading nginx ..." | |
docker-compose exec nginx nginx -s reload | |
EOF | |
sudo sh ./init-letsencrypt.sh | |
cd /opt/registry | |
docker-compose up -d |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DOMAIN_NAME=example.com | |
sudo mkdir -p /opt/minio/data1-1 | |
sudo mkdir -p /opt/minio/data1-2 | |
sudo mkdir -p /opt/minio/data2-1 | |
sudo mkdir -p /opt/minio/data2-2 | |
sudo mkdir -p /opt/minio/data3-1 | |
sudo mkdir -p /opt/minio/data3-2 | |
sudo mkdir -p /opt/minio/data4-1 | |
sudo mkdir -p /opt/minio/data4-2 | |
cat <<EOF > /opt/minio/docker-compose.yml | |
version: '3.7' | |
# Settings and configurations that are common for all containers | |
x-minio-common: &minio-common | |
image: quay.io/minio/minio:RELEASE.2022-09-07T22-25-02Z | |
command: server --console-address ":9001" http://minio{1...4}/data{1...2} | |
# command: server --certs-dir /root/.minio/certs --skipcertcheck --console-address ":9001" https://minio{1...4}/data{1...2} | |
expose: | |
- "9000" | |
- "9001" | |
environment: | |
MINIO_ROOT_USER: adminUser | |
MINIO_ROOT_PASSWORD: adminPssword | |
healthcheck: | |
test: ["CMD", "curl", "-f", "https://localhost:9000/minio/health/live"] | |
interval: 30s | |
timeout: 20s | |
retries: 3 | |
# starts 4 docker containers running minio server instances. | |
# using nginx reverse proxy, load balancing, you can access | |
# it through port 9000. | |
services: | |
minio1: | |
<<: *minio-common | |
hostname: minio1 | |
volumes: | |
- /opt/minio/data1-1:/data1 | |
- /opt/minio/data1-2:/data2 | |
# - /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/fullchain.pem:/root/.minio/certs/public.crt | |
# - /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/privkey.pem:/root/.minio/certs/private.key | |
minio2: | |
<<: *minio-common | |
hostname: minio2 | |
volumes: | |
- /opt/minio/data2-1:/data1 | |
- /opt/minio/data2-2:/data2 | |
# - /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/fullchain.pem:/root/.minio/certs/public.crt | |
# - /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/privkey.pem:/root/.minio/certs/private.key | |
minio3: | |
<<: *minio-common | |
hostname: minio3 | |
volumes: | |
- /opt/minio/data3-1:/data1 | |
- /opt/minio/data3-2:/data2 | |
# - /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/fullchain.pem:/root/.minio/certs/public.crt | |
# - /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/privkey.pem:/root/.minio/certs/private.key | |
minio4: | |
<<: *minio-common | |
hostname: minio4 | |
volumes: | |
- /opt/minio/data4-1:/data1 | |
- /opt/minio/data4-2:/data2 | |
# - /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/fullchain.pem:/root/.minio/certs/public.crt | |
# - /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/privkey.pem:/root/.minio/certs/private.key | |
nginx: | |
image: nginx:1.19.2-alpine | |
hostname: nginx | |
volumes: | |
- ./nginx.conf:/etc/nginx/nginx.conf:ro | |
- /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/fullchain.pem:/etc/nginx/certs/public.crt | |
- /opt/registry/web/certbot/conf/live/$DOMAIN_NAME/privkey.pem:/etc/nginx/certs/private.key | |
ports: | |
- "9000:9000" | |
- "9001:9001" | |
depends_on: | |
- minio1 | |
- minio2 | |
- minio3 | |
- minio4 | |
EOF | |
cat <<EOF > /opt/minio/nginx.conf | |
user nginx; | |
worker_processes auto; | |
error_log /var/log/nginx/error.log warn; | |
pid /var/run/nginx.pid; | |
events { | |
worker_connections 4096; | |
} | |
http { | |
include /etc/nginx/mime.types; | |
default_type application/octet-stream; | |
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" ' | |
'\$status \$body_bytes_sent "\$http_referer" ' | |
'"\$http_user_agent" "\$http_x_forwarded_for"'; | |
access_log /var/log/nginx/access.log main; | |
sendfile on; | |
keepalive_timeout 65; | |
# include /etc/nginx/conf.d/*.conf; | |
upstream minio { | |
server minio1:9000; | |
server minio2:9000; | |
server minio3:9000; | |
server minio4:9000; | |
} | |
upstream console { | |
ip_hash; | |
server minio1:9001; | |
server minio2:9001; | |
server minio3:9001; | |
server minio4:9001; | |
} | |
server { | |
listen 9000 ssl http2 default_server; | |
server_name $DOMAIN_NAME; | |
ssl_certificate /etc/nginx/certs/public.crt; | |
ssl_certificate_key /etc/nginx/certs/private.key; | |
# To allow special characters in headers | |
ignore_invalid_headers off; | |
# Allow any size file to be uploaded. | |
# Set to a value such as 1000m; to restrict file size to a specific value | |
client_max_body_size 0; | |
# To disable buffering | |
proxy_buffering off; | |
proxy_request_buffering off; | |
location / { | |
proxy_set_header Host \$http_host; | |
proxy_set_header X-Real-IP \$remote_addr; | |
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; | |
proxy_set_header X-Forwarded-Proto \$scheme; | |
proxy_connect_timeout 300; | |
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1 | |
proxy_http_version 1.1; | |
proxy_set_header Connection ""; | |
chunked_transfer_encoding off; | |
proxy_pass http://minio; | |
} | |
} | |
server { | |
listen 9001 ssl http2 default_server; | |
server_name $DOMAIN_NAME; | |
ssl_certificate /etc/nginx/certs/public.crt; | |
ssl_certificate_key /etc/nginx/certs/private.key; | |
# To allow special characters in headers | |
ignore_invalid_headers off; | |
# Allow any size file to be uploaded. | |
# Set to a value such as 1000m; to restrict file size to a specific value | |
client_max_body_size 0; | |
# To disable buffering | |
proxy_buffering off; | |
proxy_request_buffering off; | |
location / { | |
proxy_set_header Host \$http_host; | |
proxy_set_header X-Real-IP \$remote_addr; | |
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; | |
proxy_set_header X-Forwarded-Proto \$scheme; | |
proxy_set_header X-NginX-Proxy true; | |
# This is necessary to pass the correct IP to be hashed | |
real_ip_header X-Real-IP; | |
proxy_connect_timeout 300; | |
# To support websocket | |
proxy_http_version 1.1; | |
proxy_set_header Upgrade \$http_upgrade; | |
proxy_set_header Connection "upgrade"; | |
chunked_transfer_encoding off; | |
proxy_pass http://console; | |
} | |
} | |
} | |
EOF | |
cd /opt/minio | |
docker-compose up -d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment