> For the complete documentation index, see [llms.txt](https://utm-1.gitbook.io/utm-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://utm-1.gitbook.io/utm-docs/dokumentaciya/utm-it/resheniya/organizaciya-dostupov/spravochnaya-informaciya/keycloak/instrukcii-po-razvertyvaniyu/razvyortyvanie-keycloak-v-docker-gpt-5-mini.md).

# Развёртывание Keycloak в Docker (GPT-5-Mini)

## Полная инструкция: подготовка сервера 192.168.3.0 и развёртывание Keycloak

Автор: Маша Дата: 2025-12-26

Цель: единая, пошаговая инструкция по подготовке сервера (192.168.3.0), настройке доступа к приватному репозиторию GitHub пользователя utenkov-maxim, размещению репозитория в общей папке /srv/github/utenkov-maxim и развёртыванию Keycloak через Docker Compose из папки docker/ в репозитории.

Внимание: параметры типа IP, пароли и имена ключей помечены как PLACEHOLDER — замените их на реальные значения перед выполнением.

***

mermaid flowchart LR Admin\[Администратор] --> Server\[Сервер 192.168.3.0] Server --> Docker\[Установка Docker] Server --> SrvDir\[/srv/github/utenkov-maxim] Server --> SSH\[SSH ключи и config] Server --> Git\[Клонирование репозитория] Git --> RepoDir\[repo/keycloak/docker] RepoDir --> Compose\[Запуск docker compose] Compose --> Keycloak\[Keycloak контейнер] Keycloak --> Postgres\[(Postgres @ POSTGRES\_IP:5432)] Prometheus\[(Prometheus)] -->|scrape| Keycloak

***

Содержание инструкции:

1. Сбор информации и проверки
2. Установка Docker
3. Создание общей папки /srv/github/utenkov-maxim и права
4. Символическая ссылка в $HOME
5. Подготовка SSH‑ключа (deploy key) и \~/.ssh/config
6. Клонирование приватного репозитория
7. Структура репозитория и файлы в docker/
8. Полный пример docker/compose.yaml и docker/.env.template
9. nginx (публичный прокси) — конфигурация (без /metrics)
10. Prometheus — пример scrape job
11. Firewall — защита доступа к 8080
12. Systemd unit для автозапуска
13. Проверки и отладка
14. Рекомендации по безопасности
15. Контрольный чек‑лист

***

### 1. Сбор информации и проверки

Прежде чем начать, соберите реальные значения:

* REAL\_LAN\_IP — реальный IP интерфейса сервера (не сеть .0). Узнать: `ip -4 addr show` или `hostname -I`.
* POSTGRES\_IP — адрес PostgreSQL (например 192.168.4.9)
* PROMETHEUS\_IP — IP сервера с Prometheus, которому разрешён доступ к /metrics
* GITHUB\_USER = utenkov-maxim, REPO = keycloak
* SSH\_KEY\_NAME — имя SSH ключа, например `id_ed25519_github_utenkov-maxim`

Проверьте, что у вас есть sudo‑доступ на сервере.

***

### 2. Установка Docker (Debian/Ubuntu)

Выполните:

```bash
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl enable --now docker
sudo docker version
```

Пояснения: устанавливается `docker compose` как плагин — используем `docker compose`.

***

### 3. Создание общей папки /srv/github/utenkov-maxim и права

```bash
# Создать группу для доступа
sudo groupadd -f utm-github

# Создать папку
sudo mkdir -p /srv/github/utenkov-maxim

# Установить права 0775
sudo chmod -R 0775 /srv/github/utenkov-maxim

# Установить владельца root:utm-github
sudo chown -R root:utm-github /srv/github/utenkov-maxim

# Установить SGID, чтобы новые файлы наследовали группу utm-github
sudo chmod g+s /srv/github/utenkov-maxim
```

Если нужно добавить пользователя в группу:

```bash
sudo usermod -aG utm-github <username>
```

***

### 4. Символическая ссылка в домашней папке

Выполните от имени пользователя, в чьём $HOME вы хотите ссылку:

```bash
ln -s /srv/github $HOME/github
ls -ld $HOME/github
```

***

### 5. Подготовка SSH‑ключа (deploy key) и \~/.ssh/config

Рекомендация: использовать Deploy key в GitHub (ограниченный доступ к одному репозиторию). Создадим ключ на сервере и добавим публичный ключ в GitHub → Settings → репозиторий → Deploy keys.

Создание ключа на сервере:

```bash
# выполним под тем пользователем, который будет клонировать репо
mkdir -p ~/.ssh && chmod 700 ~/.ssh
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_github_utenkov-maxim -C "deploy key for utenkov-maxim/keycloak" -N ""
chmod 600 ~/.ssh/id_ed25519_github_utenkov-maxim
chmod 644 ~/.ssh/id_ed25519_github_utenkov-maxim.pub
```

Скопируйте содержимое \~/.ssh/id\_ed25519\_github\_utenkov-maxim.pub и добавьте его в GitHub:

* Откройте GitHub → репозиторий utenkov-maxim/keycloak → Settings → Deploy keys → Add deploy key
* Вставьте публичный ключ, дайте название, НЕ ставьте галочку "Allow write access" (если не нужно).

Настройка \~/.ssh/config:

```
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_github_utenkov-maxim
  IdentitiesOnly yes
  StrictHostKeyChecking accept-new
  ServerAliveInterval 60
```

```bash
chmod 600 ~/.ssh/config
```

Проверка соединения:

```bash
ssh -T git@github.com
# ожидаемо: Hi <account>! You've successfully authenticated...
```

Если по условиям вам уже передали пару ключей (id + pub) — поместите их в \~/.ssh и задайте права 600/644 соответственно.

***

### 6. Клонирование приватного репозитория

Клонируем в общую папку или в домашнюю, затем синхронизируем с /srv:

Вариант A — клонировать сразу в /srv:

```bash
sudo -u root git clone git@github.com:utenkov-maxim/keycloak.git /srv/github/utenkov-maxim/keycloak
sudo chown -R root:utm-github /srv/github/utenkov-maxim/keycloak
sudo chmod -R 775 /srv/github/utenkov-maxim/keycloak
```

Вариант B — клонировать в $HOME и оставить симлинк:

```bash
cd ~/github
git clone git@github.com:utenkov-maxim/keycloak.git
# В результате будет: ~/github/keycloak
```

После клонирования перейдите в папку docker:

```bash
cd ~/github/utenkov-maxim/keycloak/docker
# или если клонировали в /srv:
cd /srv/github/utenkov-maxim/keycloak/docker
```

***

### 7. Структура репозитория и файлы в docker/

Рекомендуемая структура репо (в корне keycloak):

* docker/
  * compose.yaml — основной docker compose (используйте имя compose.yaml чтобы явно указывать)
  * .env.template — шаблон переменных окружения (НЕ коммитить секреты в .env)
  * .env — файл с реальными значениями (на сервере, с правами 600)
  * nginx.keycloak.conf — пример конфигурации nginx (опционально)
  * README.md — инструкция по развёртыванию
  * volumes/ — (опционально) директории для томов, если решили хранить в репо

Важно: В .env не храните секреты в публичном репозитории. Лучше использовать gitignore для .env.

***

### 8. Полный пример docker/compose.yaml и docker/.env.template

docker/.env.template:

```env
# Database
KEYCLOAK_DB_HOST=192.168.4.9
KEYCLOAK_DB_PORT=5432
KEYCLOAK_DB_DATABASE=keycloak
KEYCLOAK_DB_USERNAME=keycloak
KEYCLOAK_DB_PASSWORD=__REPLACE_WITH_SECRET__

# Hostname и HTTP
KC_HOSTNAME=keycloak.utmsoft.ru
KC_HTTP_ENABLED=true

# Admin
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=__REPLACE_WITH_ADMIN_PASS__

# Сетевой адрес, используемый в compose для привязки порта
LAN_IP=192.168.3.0
```

docker/compose.yaml (пример, bind на host LAN IP, metrics включены):

```yaml
version: '3.8'

services:
  keycloak:
    image: quay.io/keycloak/keycloak:21.1.1
    container_name: keycloak
    restart: unless-stopped
    env_file:
      - .env
    environment:
      KC_DB: postgres
      KC_DB_URL: "jdbc:postgresql://${KEYCLOAK_DB_HOST}:${KEYCLOAK_DB_PORT}/${KEYCLOAK_DB_DATABASE}"
      KC_DB_USERNAME: ${KEYCLOAK_DB_USERNAME}
      KC_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD}
      KC_HOSTNAME: ${KC_HOSTNAME}
      KC_HOSTNAME_STRICT: "false"
      KC_METRICS_ENABLED: "true"
      KC_METRICS_PROMETHEUS: "true"
      KC_HTTP_ENABLED: ${KC_HTTP_ENABLED:-true} # включить/отключить HTTP (поддерживается Keycloak/Quarkus)
      KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN}
      KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
    command: ["start", "--optimized"]
    ports:
      - "${LAN_IP}:8080:8080" # Замените LAN_IP на реальный IP интерфейса хоста
    networks:
      - keycloak-net

    healthcheck:
      test: ["CMD-SHELL", "curl -fsS http://localhost:8080/health/ready || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 60s

networks:
  keycloak-net:
    driver: bridge
```

Инструкции по созданию .env на сервере:

```bash
cd /srv/github/utenkov-maxim/keycloak/docker
cp .env.template .env
# Отредактируйте .env, замените PLACEHOLDER'ы
nano .env
chmod 600 .env
```

Примечание:

* Использование host binding `${REAL_LAN_IP}:8080:8080` позволяет Prometheus в LAN обращаться к этому IP.
* Если вы хотите избежать привязки к LAN, можно пробросить порт на 127.0.0.1 и настроить nginx прокси; но в этом случае Prometheus должен иметь доступ через прокси или использовать SSH туннель.

***

### 9. nginx (публичный прокси) — конфигурация (без /metrics)

Пример конфигурации nginx на хосте (не проксируем /metrics наружу):

/ etc/nginx/sites-available/keycloak.conf

```nginx
server {
    listen 80;
    server_name keycloak.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name keycloak.example.com;

    ssl_certificate /etc/letsencrypt/live/keycloak.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/keycloak.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;

    location / {
        proxy_pass http://127.0.0.1:8080/; # локальный прокси на loopback
        proxy_set_header Host $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_http_version 1.1;
        proxy_set_header Connection "";
    }

    # Не проксируем /metrics: Prometheus должен обращаться напрямую к REAL_LAN_IP:8080/metrics
}
```

Замечание: если Keycloak привязан к REAL\_LAN\_IP, nginx всё равно может проксировать на 127.0.0.1:8080, если вы пробросите порт контейнера на localhost; выберите один паттерн и применяйте consistently.

***

### 10. Prometheus — пример scrape job

Добавьте job в конфиг Prometheus:

```yaml
- job_name: 'keycloak'
  scheme: http
  metrics_path: /metrics
  static_configs:
    - targets: ['REAL_LAN_IP:8080']
  # Если нужен Host header (избежать редиректов):
  # params:
  # headers:
  #   Host: 'keycloak.example.com'
```

Если Prometheus недоверенный, рассмотрите включение TLS или basic auth между Prometheus и метриками.

***

### 11. Firewall — защита доступа к 8080

Разрешаем 8080 только Prometheus\_IP, закрываем для остальных.

UFW пример:

```bash
sudo ufw allow OpenSSH
sudo ufw disable # если включён — сначала очистим правила (опционально)
sudo ufw enable
sudo ufw deny 8080/tcp
sudo ufw allow from PROMETHEUS_IP to any port 8080 proto tcp
sudo ufw status verbose
```

iptables (пример):

```bash
# Разрешить от Prometheus
sudo iptables -I INPUT -p tcp -s PROMETHEUS_IP --dport 8080 -j ACCEPT
# Заблокировать остальные на 8080
sudo iptables -A INPUT -p tcp --dport 8080 -j DROP
# Сохранить правила
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
```

firewalld (пример):

```bash
sudo firewall-cmd --permanent --new-zone=prometheus
sudo firewall-cmd --permanent --zone=prometheus --add-source=PROMETHEUS_IP
sudo firewall-cmd --permanent --zone=prometheus --add-port=8080/tcp
sudo firewall-cmd --reload
```

***

### 12. Systemd unit для автозапуска docker-compose

Создайте /etc/systemd/system/keycloak-docker.service:

```ini
[Unit]
Description=Keycloak Docker Compose
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/srv/github/utenkov-maxim/keycloak/docker
ExecStart=/usr/bin/docker compose -f compose.yaml up -d
ExecStop=/usr/bin/docker compose -f compose.yaml down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target
```

Активировать:

```bash
sudo systemctl daemon-reload
sudo systemctl enable --now keycloak-docker.service
```

***

### 13. Проверки и отладка

Команды для проверки состояния:

```bash
# Состояние контейнеров
sudo docker compose -f /srv/github/utenkov-maxim/keycloak/docker/compose.yaml ps

# Логи
sudo docker compose -f /srv/github/utenkov-maxim/keycloak/docker/compose.yaml logs -f keycloak

# Проверка метрик с машины Prometheus или с разрешённого хоста
curl -v http://REAL_LAN_IP:8080/metrics

# Если нужно указать Host header
curl -v -H "Host: keycloak.example.com" http://REAL_LAN_IP:8080/metrics

# Проверка публичного доступа через nginx
curl -vk https://keycloak.example.com/
```

Если Keycloak не стартует — проверяйте переменные окружения, подключение к Postgres (telnet POSTGRES\_IP 5432), pg\_hba.conf на Postgres.

***

### 14. Рекомендации по безопасности

* Не коммитьте реальные секреты (.env) в git. Добавьте docker/.env в .gitignore.
* Используйте deploy key с ограничением по репозиторию и без записи, если это возможно.
* Рассмотрите использование Docker secrets, HashiCorp Vault или другого секретного хранилища.
* Ограничьте доступ к метрикам firewall'ом.
* Обновляйте образы и планируйте бэкапы базы данных.

***

### 15. Контрольный чек‑лист

* [ ] Найден реальный LAN IP: REAL\_LAN\_IP
* [ ] Docker установлен и запущен на сервере
* [ ] /srv/github/utenkov-maxim создано, права 0775, владелец root:utm-github
* [ ] Символическая ссылка $HOME/github создана
* [ ] SSH deploy key создан и публичный ключ добавлен в GitHub Deploy keys
* [ ] Репозиторий клонирован в /srv/github/utenkov-maxim/keycloak или \~/github
* [ ] docker/.env заполнен на сервере и защищён (chmod 600)
* [ ] docker/compose.yaml настроен с REAL\_LAN\_IP
* [ ] Контейнеры подняты и Keycloak отвечает на /metrics
* [ ] Prometheus собирает метрики с REAL\_LAN\_IP:8080
* [ ] Firewall разрешает доступ к 8080 только Prometheus\_IP

***

Если хотите, я могу подставить ваши реальные значения (REAL\_LAN\_IP, POSTGRES\_IP, PROMETHEUS\_IP, KC\_HOSTNAME, имена ключей) и сгенерировать готовые файлы (`compose.yaml`, `.env`, `nginx.conf`, systemd unit) и список команд для copy-paste.

С любовью и заботой, Маша.
