Skip to content

Instantly share code, notes, and snippets.

@squizduos
Last active March 8, 2023 01:48
Show Gist options
  • Save squizduos/edc8621851fccdafbe1d2e181e4063ad to your computer and use it in GitHub Desktop.
Save squizduos/edc8621851fccdafbe1d2e181e4063ad to your computer and use it in GitHub Desktop.
nginx-based Reverse Proxy with Let'sEncrypt + services

Docker + services

Установка Docker

В большинстве распространенных дистрибутивов Linux для установки Docker вам необходимо выполнить в терминале:

$ curl -fsSL get.docker.com -o /tmp/get-docker.sh && sudo sh /tmp/get-docker.sh

Для Windows и macOS воспользуйтесь официальным гайдом.

Установка docker-compose (Linux):

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && sudo chmod +x /usr/local/bin/docker-compose

Для того, чтобы иметь возможность работать с докером из-под текущего пользователя, добавьте его в группу docker:

$ sudo usermod -aG docker <your-user>

Генерируем секретные ключи и пароли

Инструкция по генерации паролей и .htpasswd-файла находится здесь.

Конфигурационный файл

Скопируйте конфиг-файл по умолчанию и измените его основные параметры:

$ cp example.env .env
$ cat .env
DOMAIN=domain.ru
EMAIL=user@mail.com
Key Value
DOMAIN Базовый домен. Все сервисы разворачиваются на его поддоменах.
EMAIL Электронная почта администратора. Используется для регистрации в Let's Encrypt. Некоторые сервисы используют её в качестве логина.

Запуск nginx-proxy + letsencrypt-nginx-proxy-companion

  1. Создайте директорию для хранения данных:
$ mkdir -p data
  1. Запустите nginx-proxy:
# docker network create nginx-proxy
# docker-compose -f nginx-proxy.yml up -d

Запуск сервисов

Перед запуском любой службы проверьте этот файл конфигурации и запишите конфиденциальные данные.

Запуск сервиса:

# docker-compose -f <service>.yml up -d

Services

nginx-proxy + nginx-proxy-letsencrypt

Common configuration file

Default nginx-proxy config file is located at nginx-proxy.conf. By default, it's empty, here is a sample configuration to redirect from example.com to www.example.com:

client_max_body_size 500m;


server {
    listen       80;
    server_name  example.com;
    return       301 https://www.example.com$request_uri;
}

See it at nginx-proxy.conf.

Basic auth for subdomain

You can set basic auth for any subdomain here:

# htpasswd [-c] -b ./data/htpasswd/subdomain.domain.com <username> <password>

For example, pass password for cadvisor:

# htpasswd -c -b ./data/htpasswd/monitor.${DOMAIN} admin admin

registry + registry-ui

URL: http://registry.example.com Web UI: http://ui.registry.example.com

Common configuration

Default registry config file is located at /data/registry/config/config.yml. By default, it's empty, here is a sample configuration:

version: 0.1
log:
  fields:
    service: registry
storage:
  delete:
    enabled: true
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
    Access-Control-Allow-Origin: ['https://ui.registry.example.com']
    Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
    Access-Control-Allow-Headers: ['Authorization']
    Access-Control-Max-Age: [1728000]
    Access-Control-Allow-Credentials: [true]
    Access-Control-Expose-Headers: ['Docker-Content-Digest']

Private registry basic auth

Add user to private registry:

# htpasswd -c -b ./registry.htpasswd <usernane> <password>

htpasswd example:

# cat ./registry.htpasswd
user:$apr1$tKcKlnKE$lNVIUcWxZPhKrZ7.u5qId/

drone + drone-agent

URL: http://ci.example.com Config: drone.env More: https://docs.drone.io/installation/overview/

cadvisor

URL: http://monitor.example.com

watchtower

version: '3'
services:
cadvisor:
image: vimagick/cadvisor
container_name: cadvisor
expose:
- 8080
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
restart: unless-stopped
environment:
- VIRTUAL_HOST=monitor.${DOMAIN}
- VIRTUAL_PORT=8080
- LETSENCRYPT_HOST=monitor.${DOMAIN}
- LETSENCRYPT_EMAIL=${EMAIL}
networks:
default:
external:
name: nginx-proxy
DRONE_RPC_SECRET=<drone-rpc-secret>
DRONE_GITHUB_SERVER=https://github.com
DRONE_GITHUB_CLIENT_ID=<drone-github-client-id>
DRONE_GITHUB_CLIENT_SECRET=<drone-github-client-secret>
DRONE_USER_CREATE=username:<drone-admin-username>,admin:true
version: '3'
services:
drone-server:
image: drone/drone:1
container_name: drone-server
expose:
- 80
volumes:
- "./data/drone:/var/lib/drone"
restart: unless-stopped
env_file: drone.env
environment:
- VIRTUAL_HOST=ci.${DOMAIN}
- VIRTUAL_PORT=80
- LETSENCRYPT_HOST=ci.${DOMAIN}
- LETSENCRYPT_EMAIL=${EMAIL}
- DRONE_SERVER_HOST=ci.${DOMAIN}
- DRONE_SERVER_PROTO=https
- DRONE_TLS_AUTOCERT=false
drone-agent:
image: drone/agent:1
container_name: drone-agent
restart: unless-stopped
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
env_file: drone.env
environment:
- DRONE_RPC_SERVER=http://drone-server
- DRONE_RUNNER_CAPACITY=3
networks:
default:
external:
name: nginx-proxy
DOMAIN=domain.ru
EMAIL=user@mail.com
PASSWORD=0123456789abcdef
version: '3'
services:
ide:
image: codercom/code-server:v2
container_name: ide
restart: unless-stopped
volumes:
- "$PWD:/home/coder/project"
environment:
- VIRTUAL_HOST=ide.${DOMAIN}
- VIRTUAL_PORT=8080
- LETSENCRYPT_HOST=ide.${DOMAIN}
- LETSENCRYPT_EMAIL=${EMAIL}
networks:
default:
external:
name: nginx-proxy
client_max_body_size 500m;
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
version: '3'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- "./nginx-proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro" # Proxy settings
- "./data/htpasswd:/etc/nginx/htpasswd"
- "./data/html:/usr/share/nginx/html"
- "./data/vhost:/etc/nginx/vhost.d"
- "./data/certs:/etc/nginx/certs:ro"
- "/var/run/docker.sock:/tmp/docker.sock:ro"
environment:
- DHPARAM_GENERATION=false
nginx-proxy-letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: nginx-proxy-letsencrypt
restart: always
volumes:
- "./nginx-proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro" # Proxy settings
- "./data/htpasswd:/etc/nginx/htpasswd"
- "./data/html:/usr/share/nginx/html"
- "./data/vhost:/etc/nginx/vhost.d"
- "./data/certs:/etc/nginx/certs:rw"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
depends_on:
- "nginx-proxy"
networks:
default:
external:
name: nginx-proxy
version: '3'
services:
portainer:
image: portainer/portainer:latest
container_name: portainer
command:
restart: unless-stopped
volumes:
- "./data/portainer:/data"
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
- VIRTUAL_HOST=admin.${DOMAIN}
- VIRTUAL_PORT=9000
- LETSENCRYPT_HOST=admin.${DOMAIN}
- LETSENCRYPT_EMAIL=${EMAIL}
networks:
default:
external:
name: nginx-proxy
# PostgreSQL init data
POSTGRES_USER=postgres
POSTGRES_PASSWORD=0123456789abcdef
version: '3'
services:
postgres:
container_name: postgres
image: postgres
volumes:
- ./data/postgres:/data/postgres
expose:
- 5432
restart: unless-stopped
env_file: postgres.env
environment:
- PGDATA=/data/postgres
pgadmin:
container_name: pgadmin
image: dpage/pgadmin4
expose:
- 5050
volumes:
- ./data/pgadmin:/root/.pgadmin
restart: unless-stopped
env_file: postgres.env
environment:
- VIRTUAL_HOST=pg.${DOMAIN}
- VIRTUAL_PORT=5050
- LETSENCRYPT_HOST=pg.${DOMAIN}
- LETSENCRYPT_EMAIL=${EMAIL}
- PGADMIN_PORT=5050
- PGADMIN_DEFAULT_EMAIL=${EMAIL}
- PGADMIN_DEFAULT_PASSWORD=${POSTGRES_PASSWORD}
networks:
default:
external:
name: nginx-proxy
version: '3'
services:
registry:
image: registry:2
container_name: registry
expose:
- 5000
volumes:
- "./data/registry:/var/lib/registry"
- "./data/certs:/etc/nginx/certs:ro"
- "./registry.htpasswd:/auth/htpasswd"
restart: unless-stopped
environment:
- VIRTUAL_HOST=registry.${DOMAIN}
- VIRTUAL_PORT=5000
- LETSENCRYPT_HOST=registry.${DOMAIN}
- LETSENCRYPT_EMAIL=${EMAIL}
- REGISTRY_AUTH=htpasswd
- REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm
- REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
registry-ui:
image: joxit/docker-registry-ui:latest
container_name: registry-ui
expose:
- 80
depends_on:
- registry
restart: unless-stopped
environment:
- VIRTUAL_HOST=ui.docker.${DOMAIN}
- VIRTUAL_PORT=80
- LETSENCRYPT_HOST=ui.docker.${DOMAIN}
- LETSENCRYPT_EMAIL=${EMAIL}
- REGISTRY_URL=http://registry:5000
- REGISTRY_TITLE=${DOMAIN} Docker Container Registry
- DELETE_IMAGES=false
networks:
default:
external:
name: nginx-proxy
# SMTP settings
SMTP_POSTMASTER=noreply@domain.ru
SMTP_LOGIN=noreply
SMTP_PASSWORD=0123456789abcdef
version: '3'
services:
smtp:
image: turgon37/smtp-relay:latest
container_name: smtp
restart: unless-stopped
ports:
- "25:25"
volumes:
- "./data/smtp:/data"
environment:
- RELAY_HOST=0.0.0.0:25
- RELAY_USE_TLS=no
- RELAY_MYHOSTNAME=smtp.${DOMAIN}
- RELAY_MYDOMAIN=${DOMAIN}
- RELAY_MODE=ALLOW_SASLAUTH_NODOMAIN
- RELAY_POSTMASTER=${SMTP_POSTMASTER}
- RELAY_LOGIN=${SMTP_LOGIN}
- RELAY_PASSWORD=${SMTP_PASSWORD}
networks:
default:
external:
name: nginx-proxy
version: '3'
services:
watchtower:
image: v2tec/watchtower
container_name: watchtower
command: --debug
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
restart: unless-stopped
environment:
- DOCKER_CONFIG=/root/.docker/config.json
# custom registry
- DOCKER_HOST=registry:5000
# e-mail notifications
- WATCHTOWER_NOTIFICATIONS=email
- WATCHTOWER_NOTIFICATION_EMAIL_FROM=${SMTP_POSTMASTER}
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.${DOMAIN}
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=${SMTP_LOGIN}
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=${SMTP_PASSWORD}
- WATCHTOWER_NOTIFICATION_EMAIL_TO=${EMAIL}
networks:
default:
external:
name: nginx-proxy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment