- Gereksinimler
- Kurulum
- Adım 1: Let's Encrypt ile Domain Sertifikalarının Oluşturulması
- Adım 2: Portus Auth Service RSA Sertifikalarının Oluşturulması
- Adım 3: Registry Init Dosyasının Oluşturulması
- Adım 4: Portus Nginx Konfigürasyonu
- Adım 5: Registry Nginx Konfigürasyonu
- Adım 6: Registry Config.yml
- Adım 7: .env Dosyası
- Adım 8: Docker Compose Dosyasını Oluşturma
- Adım 9: Projeyi Başlatma
- Yol Haritası
- Docker ve Docker Compose yüklü olmalıdır.
- Let's Encrypt tarafından sağlanan domain sertifikaları (örneğin, fullchain.pem ve privkey.pem).
Let's Encrypt ile domain sertifikalarını oluşturmak için certbot kullanabilirsiniz. Aşağıdaki komutlar, portus.mydomain.com
ve registry.mydomain.com
domainleri için sertifika oluşturur:
docker run -it --rm --name certbot -p 80:80 -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/certbot certonly --test-cert --standalone -d portus.mydomain.com --email [email protected] --agree-tos
docker run -it --rm --name certbot -p 80:80 -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/certbot certonly --test-cert --standalone -d registry.mydomain.com --email [email protected] --agree-tos
Sertifikalar başarıyla oluşturulduktan sonra, sertifika ve anahtar dosyaları şu dizinde bulunacaktır:
/etc/letsencrypt/live/portus.mydomain.com/
/etc/letsencrypt/live/registry.mydomain.com/
RSA anahtar çifti ve sertifika oluşturmak için aşağıdaki komutları kullanın:
# Özel anahtarı oluşturma
openssl genrsa -out secrets/auth_service_private.key 2048
# Public key dosyasını oluşturma
openssl rsa -in secrets/auth_service_private.key -pubout -out secrets/auth_service_public.pem
# Public key dosyasını bir sertifika olarak kaydedin
openssl req -new -x509 -key secrets/auth_service_private.key -out secrets/auth_service_public.crt -days 365
Dosya yapınız şu şekilde olmalıdır:
secrets/
├── auth_service_private.key
├── auth_service_public.pem
└── auth_service_public.crt
Docker Registry'nin başlatılması sırasında kullanılacak init script'i oluşturun:
registry/init:
#!/bin/sh
set -x
# Public key dosyasını CA sertifikaları dizinine kopyalama
cp /secrets/auth_service_public.crt /usr/local/share/ca-certificates/auth_service_public.crt
# CA sertifikalarını güncelleme
update-ca-certificates
# Docker Registry'yi başlatma
registry serve /etc/docker/registry/config.yml
Bu dosyanın çalıştırılabilir olduğundan emin olun:
chmod +x registry/init
Nginx konfigürasyon dosyasını oluşturun:
nginx/conf.d/portus.conf:
upstream portus {
least_conn;
server portus:3000 max_fails=3 fail_timeout=15s;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name portus.mydomain.com;
root /srv/Portus/public;
# Added By AI
http2 on;
# SSL
ssl_certificate /etc/letsencrypt/live/portus.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/portus.mydomain.com/privkey.pem;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.2;
# Ciphers chosen for forward secrecy and compatibility.
#
# http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
# Added By AI
ssl_session_timeout 10m;
# OCSP Stapling - Added By AI
#ssl_stapling on;
#ssl_stapling_verify on;
#ssl_trusted_certificate /etc/letsencrypt/live/portus.mydomain.com/fullchain.pem;
# HSTS - Added By AI
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Don't allow the browser to render the page inside a frame or iframe
# and avoid Clickjacking. More in the following link:
#
# https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options
add_header X-Frame-Options DENY;
# Disable content-type sniffing on some browsers.
add_header X-Content-Type-Options nosniff;
# This header enables the Cross-site scripting (XSS) filter built into
# most recent web browsers. It's usually enabled by default anyway, so the
# role of this header is to re-enable the filter for this particular
# website if it was disabled by the user.
add_header X-XSS-Protection "1; mode=block";
# Add header for IE in compatibility mode.
add_header X-UA-Compatible "IE=edge";
# Portus needs to handle /v2/token for authentication
location = /v2/token {
proxy_pass https://portus;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
proxy_buffering on;
}
# Portus needs to handle /v2/webhooks/events for notifications
location = /v2/webhooks/events {
proxy_pass https://portus;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
proxy_buffering on;
}
# Assets are mapped inside of /srv/Portus/public from a shared volume.
location ~ ^/(assets)/ {
access_log off;
gzip_static on;
expires max;
add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "";
break;
}
# Portus handles everything else for the UI
location / {
try_files $uri/index.html $uri.html $uri @portus;
}
location @portus {
proxy_pass https://portus;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
proxy_buffering on;
}
}
Nginx konfigürasyon dosyasını oluşturun:
nginx/conf.d/registry.conf:
# See https://distribution.github.io/distribution/recipes/nginx/
upstream registry {
least_conn;
server registry:5000 max_fails=3 fail_timeout=15s;
}
## Set a variable to help us decide if we need to add the
## 'Docker-Distribution-Api-Version' header.
## The registry always sets this header.
## In the case of nginx performing auth, the header is unset
## since nginx is auth-ing before proxying.
map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
'' 'registry/2.0';
}
log_format registry '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name registry.mydomain.com;
# Added By AI
http2 on;
# SSL
ssl_certificate /etc/letsencrypt/live/registry.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/registry.mydomain.com/privkey.pem;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.2 TLSv1.3;
# Ciphers chosen for forward secrecy and compatibility.
#
# http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
# Added By AI
ssl_session_timeout 10m;
# OCSP Stapling - Added By AI
#ssl_stapling on;
#ssl_stapling_verify on;
#ssl_trusted_certificate /etc/letsencrypt/live/registry.mydomain.com/fullchain.pem;
# HSTS - Added By AI
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Don't allow the browser to render the page inside a frame or iframe
# and avoid Clickjacking. More in the following link:
#
# https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options
add_header X-Frame-Options DENY;
# Disable content-type sniffing on some browsers.
add_header X-Content-Type-Options nosniff;
# This header enables the Cross-site scripting (XSS) filter built into
# most recent web browsers. It's usually enabled by default anyway, so the
# role of this header is to re-enable the filter for this particular
# website if it was disabled by the user.
add_header X-XSS-Protection "1; mode=block";
# Add header for IE in compatibility mode.
add_header X-UA-Compatible "IE=edge";
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486)
chunked_transfer_encoding on;
location /v2/ {
# Do not allow connections from docker 1.5 and earlier
# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}
## If $docker_distribution_api_version is empty, the header is not added.
## See the map directive above where this variable is defined.
add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;
proxy_pass https://registry;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
proxy_buffering on;
# These headers are required for Docker to trust the registry
# certificate and enable client-side certificate validation
#proxy_ssl_verify on;
#proxy_ssl_trusted_certificate /etc/letsencrypt/live/registry.mydomain.com/fullchain.pem;
#proxy_ssl_session_reuse off;
access_log /var/log/nginx/registry.access.log registry;
error_log /var/log/nginx/registry.error.log;
}
}
Docker Registry için konfigürasyon dosyasını oluşturun:
registry/config.yml:
version: 0.1
storage:
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: true
http:
addr: 0.0.0.0:5000
debug:
addr: 0.0.0.0:5001
redis:
addr: redis:6379
pool:
maxidle: 16
maxactive: 64
dialtimeout: 200ms
readtimeout: 200ms
writetimeout: 200ms
auth:
token:
realm: https://${PORTUS_FQDN}/v2/token
service: ${REGISTRY_FQDN}
issuer: ${PORTUS_FQDN}
rootcertbundle: /secrets/auth_service_public.crt
notifications:
endpoints:
- name: portus
url: https://${PORTUS_FQDN}/v2/webhooks/events
timeout: 2000ms
threshold: 5
backoff: 1s
Ortam değişkenlerini tanımlamak için .env dosyasını oluşturun:
.env:
REGISTRY_FQDN=registry.mydomain.com
REGISTRY_SECRET=zyLUImiMWrKIeoyuYUBRl22b3UG3jeFIIZktYubTlITxciXcU9ed4jBUoDrq7zMkg9w7D8moWGPK2Xjgsfdsfd3HxE68d6dDC45HGyOB9rBdP4kAWoixCKbRyp8RvX63aWmHH9dq0RJblQEQOJQZEzqEjwxESlS0OqtUW7obe2McjXesTUYbWhiK1KonSI5vsNBrCcJ2byYBj8TtJRen7Xzmdfsfi3YBfSRFOGRa6g0nFLUgKZhXSuoWmn
DATABASE_NAME=portus
DATABASE_PASSWORD=example
PORTUS_PASSWORD=12345678
PORTUS_FQDN=portus.mydomain.com
docker-compose.yml dosyasını aşağıdaki gibi oluşturun:
docker-compose.yml:
version: '3.8'
services:
redis:
image: redis:latest
container_name: redis
ports:
- "6379:6379"
registry:
image: registry:2.8.3
command: [ "/bin/sh", "/etc/docker/registry/init" ]
environment:
REGISTRY_HTTP_SECRET: ${REGISTRY_SECRET}
REGISTRY_AUTH_TOKEN_REALM: https://${PORTUS_FQDN}/v2/token
REGISTRY_AUTH_TOKEN_SERVICE: ${REGISTRY_FQDN}
REGISTRY_AUTH_TOKEN_ISSUER: ${PORTUS_FQDN}
REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE: /secrets/auth_service_public.crt
# SSL
REGISTRY_HTTP_TLS_CERTIFICATE: /etc/letsencrypt/live/registry.mydomain.com/fullchain.pem
REGISTRY_HTTP_TLS_KEY: /etc/letsencrypt/live/registry.mydomain.com/privkey.pem
# REDIS
REGISTRY_REDIS_ADDR: redis:6379
# Portus endpoint
REGISTRY_NOTIFICATIONS_ENDPOINTS: >
- name: portus
url: https://${PORTUS_FQDN}/v2/webhooks/events
timeout: 2000ms
threshold: 5
backoff: 1s
volumes:
- ./registry/config.yml:/etc/docker/registry/config.yml:ro
- ./registry/init:/etc/docker/registry/init:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
- ./secrets:/secrets:ro
ports:
- "5000:5000"
- "5001:5001" # required to access debug service
links:
- redis:redis
- portus:portus
portus:
image: opensuse/portus:2.4.3
platform: linux/amd64
environment:
- PORTUS_MACHINE_FQDN_VALUE=${PORTUS_FQDN}
- PORTUS_DB_HOST=db
- PORTUS_DB_DATABASE=${DATABASE_NAME}
- PORTUS_DB_PASSWORD=${DATABASE_PASSWORD}
- PORTUS_DB_POOL=5
- PORTUS_SECRET_KEY_BASE=${REGISTRY_SECRET}
- PORTUS_KEY_PATH=/secrets/auth_service_private.key
- PORTUS_PASSWORD=${PORTUS_PASSWORD}
- PORTUS_PUMA_TLS_KEY=/etc/letsencrypt/live/portus.mydomain.com/privkey.pem
- PORTUS_PUMA_TLS_CERT=/etc/letsencrypt/live/portus.mydomain.com/fullchain.pem
ports:
- "3000:3000"
links:
- db
volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro
- ./secrets:/secrets:ro
- static:/srv/Portus/public
background:
image: opensuse/portus:2.4.3
platform: linux/amd64
depends_on:
- portus
- db
environment:
- PORTUS_MACHINE_FQDN_VALUE=${PORTUS_FQDN}
- CCONFIG_PREFIX=PORTUS
- PORTUS_DB_HOST=db
- PORTUS_DB_DATABASE=${DATABASE_NAME}
- PORTUS_DB_PASSWORD=${DATABASE_PASSWORD}
- PORTUS_DB_POOL=5
- PORTUS_SECRET_KEY_BASE=${REGISTRY_SECRET}
- PORTUS_KEY_PATH=/secrets/auth_service_private.key
- PORTUS_PASSWORD=${PORTUS_PASSWORD}
- PORTUS_BACKGROUND=true
links:
- db
volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro
- ./secrets:/secrets:ro
db:
image: mariadb
command: ["--character-set-server=utf8", "--collation-server=utf8_unicode_ci"]
environment:
- MARIADB_DATABASE=${DATABASE_NAME}
- MARIADB_ROOT_PASSWORD=${DATABASE_PASSWORD}
- MARIADB_CHARSET=utf8
- MARIADB_COLLATION=utf8_unicode_ci
ports:
- "3306:3306"
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
links:
- registry:registry
- portus:portus
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- /etc/letsencrypt:/etc/letsencrypt
- ./logs/nginx:/var/log/nginx
- static:/srv/Portus/public:ro
volumes:
static:
driver: local
docker-compose up
Production ortamında Docker Registry'yi kurarken aşağıdaki adımları takip etmek önemlidir:
- SSL/TLS kullanarak güvenlik sağlama.
- Kimlik doğrulama ve yetkilendirme yapılandırma.
- Depolama sürücüsünü uygun şekilde yapılandırma.
- Performansı artırmak için cache ve yük dengeleme kullanma.
- Loglama ve izleme sistemleri kurma.
- Düzenli yedekleme ve geri yükleme stratejileri oluşturma.
- Yüksek erişilebilirlik sağlama.