Add initial setup for pgAdmin 4 with Docker and Nginx Proxy Manager
- Created .env.example for environment variable configuration. - Added .gitignore to exclude sensitive files. - Introduced config_local.py for pgAdmin settings. - Added docker-compose.portainer.yml for service orchestration. - Created Dockerfile for custom image building. - Added README.md with setup instructions and usage guidelines. - Included servers.json as a template for PostgreSQL server connections.
This commit is contained in:
14
.env.example
Normal file
14
.env.example
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
TZ=Europe/Moscow
|
||||||
|
|
||||||
|
PGADMIN_DEFAULT_EMAIL=admin@example.com
|
||||||
|
PGADMIN_DEFAULT_PASSWORD=change-this-password
|
||||||
|
PGADMIN_PUBLISHED_PORT=5050
|
||||||
|
PGADMIN_VOLUME_NAME=pgadmin_data
|
||||||
|
|
||||||
|
PGADMIN_CONFIG_SERVER_MODE=True
|
||||||
|
PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED=True
|
||||||
|
PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION=True
|
||||||
|
PGADMIN_CONFIG_UPGRADE_CHECK_ENABLED=False
|
||||||
|
|
||||||
|
NPM_NETWORK=npm_proxy
|
||||||
|
PGADMIN_DOMAIN=pgadmin.example.com
|
||||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.DS_Store
|
||||||
4
Dockerfile
Normal file
4
Dockerfile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
FROM dpage/pgadmin4:latest
|
||||||
|
|
||||||
|
COPY config_local.py /pgadmin4/config_local.py
|
||||||
|
COPY servers.json /pgadmin4/servers.json
|
||||||
201
README.md
Normal file
201
README.md
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
# pgAdmin 4 for Portainer + Nginx Proxy Manager
|
||||||
|
|
||||||
|
Этот репозиторий подготовлен для развертывания `pgAdmin 4` как отдельного веб-сервиса:
|
||||||
|
|
||||||
|
- через `Portainer` как stack;
|
||||||
|
- через `Nginx Proxy Manager` как reverse proxy;
|
||||||
|
- с постоянным хранением данных в Docker volume;
|
||||||
|
- с отдельным файлом `servers.json` для преднастройки подключений к PostgreSQL.
|
||||||
|
|
||||||
|
## Что лежит в репозитории
|
||||||
|
|
||||||
|
- `docker-compose.portainer.yml` - основной stack-файл для Portainer;
|
||||||
|
- `Dockerfile` - опциональный Dockerfile, если позже захочешь собирать свой образ;
|
||||||
|
- `.env.example` - шаблон переменных окружения;
|
||||||
|
- `config_local.py` - настройки pgAdmin для корректной работы за reverse proxy;
|
||||||
|
- `servers.json` - список преднастроенных серверов PostgreSQL;
|
||||||
|
- `.gitignore` - чтобы случайно не закоммитить секреты из `.env`.
|
||||||
|
|
||||||
|
## 1. Подготовка
|
||||||
|
|
||||||
|
Файл `.env.example` используй как шаблон значений.
|
||||||
|
|
||||||
|
Есть два способа:
|
||||||
|
|
||||||
|
- локально скопировать `.env.example` в `.env`;
|
||||||
|
- или ввести эти же значения вручную в переменные stack'а в `Portainer`.
|
||||||
|
|
||||||
|
Минимально нужно поменять:
|
||||||
|
|
||||||
|
- `PGADMIN_DEFAULT_EMAIL`
|
||||||
|
- `PGADMIN_DEFAULT_PASSWORD`
|
||||||
|
- `PGADMIN_DOMAIN`
|
||||||
|
- `NPM_NETWORK`
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
```env
|
||||||
|
TZ=Europe/Moscow
|
||||||
|
PGADMIN_DEFAULT_EMAIL=admin@your-domain.com
|
||||||
|
PGADMIN_DEFAULT_PASSWORD=super-strong-password
|
||||||
|
PGADMIN_PUBLISHED_PORT=5050
|
||||||
|
PGADMIN_VOLUME_NAME=pgadmin_data
|
||||||
|
PGADMIN_CONFIG_SERVER_MODE=True
|
||||||
|
PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED=True
|
||||||
|
PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION=True
|
||||||
|
PGADMIN_CONFIG_UPGRADE_CHECK_ENABLED=False
|
||||||
|
NPM_NETWORK=npm_proxy
|
||||||
|
PGADMIN_DOMAIN=pgadmin.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Подготовка сети для Nginx Proxy Manager
|
||||||
|
|
||||||
|
Очень важно, чтобы контейнер с `pgAdmin` и контейнер `Nginx Proxy Manager` находились в одной Docker-сети.
|
||||||
|
|
||||||
|
Этот вариант настройки предполагает, что `Portainer`, `pgAdmin` и `Nginx Proxy Manager` работают на одном Docker host.
|
||||||
|
|
||||||
|
Если у тебя у NPM уже есть внешняя сеть, используй ее имя в `.env` через `NPM_NETWORK`.
|
||||||
|
|
||||||
|
Если такой сети еще нет, создай ее на Docker host:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker network create npm_proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
Если Nginx Proxy Manager уже работает, проверь имя его сети и подставь именно его.
|
||||||
|
|
||||||
|
Также убедись, что сам контейнер `Nginx Proxy Manager` подключен к этой же внешней сети.
|
||||||
|
|
||||||
|
## 3. Настройка списка БД в `servers.json`
|
||||||
|
|
||||||
|
По умолчанию файл пустой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Servers": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Если хочешь, чтобы после первого входа серверы уже были добавлены в интерфейс `pgAdmin`, заполни `servers.json`.
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Servers": {
|
||||||
|
"1": {
|
||||||
|
"Name": "Production",
|
||||||
|
"Group": "Servers",
|
||||||
|
"Host": "postgres-prod",
|
||||||
|
"Port": 5432,
|
||||||
|
"MaintenanceDB": "postgres",
|
||||||
|
"Username": "postgres",
|
||||||
|
"SSLMode": "prefer"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"Name": "Staging",
|
||||||
|
"Group": "Servers",
|
||||||
|
"Host": "postgres-stage",
|
||||||
|
"Port": 5432,
|
||||||
|
"MaintenanceDB": "postgres",
|
||||||
|
"Username": "postgres",
|
||||||
|
"SSLMode": "prefer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Важно:
|
||||||
|
|
||||||
|
- `Host` должен быть доступен из контейнера `pgAdmin`;
|
||||||
|
- если PostgreSQL-контейнеры живут в Docker, они тоже должны быть в общей сети или быть доступны по IP/DNS;
|
||||||
|
- пароли подключений лучше не хранить в репозитории.
|
||||||
|
|
||||||
|
## 4. Деплой через Portainer
|
||||||
|
|
||||||
|
Есть два нормальных варианта.
|
||||||
|
|
||||||
|
### Вариант A. Через Git-репозиторий
|
||||||
|
|
||||||
|
1. Закоммить файлы этого репозитория в свой Git.
|
||||||
|
2. В `Portainer` открой `Stacks`.
|
||||||
|
3. Нажми `Add stack`.
|
||||||
|
4. Выбери `Repository`.
|
||||||
|
5. Укажи URL репозитория.
|
||||||
|
6. В поле compose file path укажи `docker-compose.portainer.yml`.
|
||||||
|
7. Добавь stack environment variables по значениям из `.env.example`.
|
||||||
|
8. Нажми `Deploy the stack`.
|
||||||
|
|
||||||
|
### Вариант B. Через Web editor
|
||||||
|
|
||||||
|
1. Открой `Stacks`.
|
||||||
|
2. Нажми `Add stack`.
|
||||||
|
3. Вставь содержимое `docker-compose.portainer.yml`.
|
||||||
|
4. Ниже заполни stack environment variables из `.env.example`.
|
||||||
|
5. Нажми `Deploy the stack`.
|
||||||
|
|
||||||
|
## 5. Проверка после старта
|
||||||
|
|
||||||
|
После развертывания проверь:
|
||||||
|
|
||||||
|
- контейнер `pgadmin` в статусе `running`;
|
||||||
|
- healthcheck стал `healthy`;
|
||||||
|
- локально сервис открывается по `http://IP_СЕРВЕРА:5050`, если ты оставил `PGADMIN_PUBLISHED_PORT=5050`.
|
||||||
|
|
||||||
|
Если страница не открывается:
|
||||||
|
|
||||||
|
- посмотри логи контейнера в Portainer;
|
||||||
|
- проверь, что внешний volume создался;
|
||||||
|
- проверь, что сеть `NPM_NETWORK` существует;
|
||||||
|
- проверь, что пароль и email заданы.
|
||||||
|
|
||||||
|
## 6. Настройка в Nginx Proxy Manager
|
||||||
|
|
||||||
|
Когда контейнер уже поднят:
|
||||||
|
|
||||||
|
Перед этим проверь, что DNS-запись домена из `PGADMIN_DOMAIN` указывает на сервер, где работает `Nginx Proxy Manager`.
|
||||||
|
|
||||||
|
1. Открой `Nginx Proxy Manager`.
|
||||||
|
2. Перейди в `Proxy Hosts`.
|
||||||
|
3. Нажми `Add Proxy Host`.
|
||||||
|
4. В `Domain Names` укажи значение из `PGADMIN_DOMAIN`.
|
||||||
|
5. `Scheme`: `http`.
|
||||||
|
6. `Forward Hostname / IP`: `pgadmin`.
|
||||||
|
7. `Forward Port`: `80`.
|
||||||
|
8. Включи `Websockets Support`.
|
||||||
|
9. Во вкладке `SSL` выпусти `Let's Encrypt` сертификат.
|
||||||
|
10. Включи `Force SSL`.
|
||||||
|
|
||||||
|
Если NPM не видит хост `pgadmin`, почти всегда проблема в том, что контейнеры не находятся в одной внешней Docker-сети.
|
||||||
|
|
||||||
|
Если `Nginx Proxy Manager` у тебя находится на другом сервере, не используй `pgadmin` как upstream. В этом случае:
|
||||||
|
|
||||||
|
- оставь опубликованный порт `PGADMIN_PUBLISHED_PORT`;
|
||||||
|
- в NPM укажи IP Docker host;
|
||||||
|
- `Forward Port` поставь равным `PGADMIN_PUBLISHED_PORT`.
|
||||||
|
|
||||||
|
## 7. Первый вход в pgAdmin
|
||||||
|
|
||||||
|
После настройки proxy:
|
||||||
|
|
||||||
|
1. Открой `https://PGADMIN_DOMAIN`.
|
||||||
|
2. Войди под `PGADMIN_DEFAULT_EMAIL`.
|
||||||
|
3. Используй `PGADMIN_DEFAULT_PASSWORD`.
|
||||||
|
4. Если в `servers.json` были добавлены серверы, они появятся автоматически.
|
||||||
|
5. Если их нет, добавь подключения вручную через интерфейс.
|
||||||
|
|
||||||
|
## 8. Как обновлять
|
||||||
|
|
||||||
|
Если используешь `image: dpage/pgadmin4:latest`, обновление простое:
|
||||||
|
|
||||||
|
1. В `Portainer` открой stack.
|
||||||
|
2. Нажми `Pull and redeploy`.
|
||||||
|
|
||||||
|
Если позже захочешь перейти на собственную сборку, можно использовать `Dockerfile`, но для первого запуска через Portainer обычно стабильнее и проще использовать официальный образ, как в текущем `docker-compose.portainer.yml`.
|
||||||
|
|
||||||
|
## 9. Полезные замечания
|
||||||
|
|
||||||
|
- `pgAdmin` хранит пользовательские настройки и сохраненные серверы в volume `pgadmin_data`.
|
||||||
|
- Если удалить volume, настройки и сохраненные подключения будут потеряны.
|
||||||
|
- `servers.json` импортируется как исходная преднастройка, но дальше рабочее состояние живет уже в данных `pgAdmin`.
|
||||||
|
- Если меняешь `servers.json` после первого запуска, иногда проще удалить volume и развернуть заново, чем ждать повторного импорта.
|
||||||
12
config_local.py
Normal file
12
config_local.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
PROXY_X_FOR_COUNT = 1
|
||||||
|
PROXY_X_PROTO_COUNT = 1
|
||||||
|
PROXY_X_HOST_COUNT = 1
|
||||||
|
PROXY_X_PORT_COUNT = 1
|
||||||
|
PROXY_X_PREFIX_COUNT = 0
|
||||||
|
|
||||||
|
UPGRADE_CHECK_ENABLED = False
|
||||||
|
CHECK_SUPPORTED_BROWSER = False
|
||||||
|
ENHANCED_COOKIE_PROTECTION = True
|
||||||
|
|
||||||
|
SESSION_EXPIRATION_TIME = 12 * 60 * 60
|
||||||
|
MAX_SESSION_IDLE_TIME = 60 * 60
|
||||||
38
docker-compose.portainer.yml
Normal file
38
docker-compose.portainer.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
services:
|
||||||
|
pgadmin:
|
||||||
|
image: dpage/pgadmin4:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ:-UTC}
|
||||||
|
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
|
||||||
|
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
|
||||||
|
PGADMIN_LISTEN_PORT: 80
|
||||||
|
PGADMIN_CONFIG_SERVER_MODE: ${PGADMIN_CONFIG_SERVER_MODE:-True}
|
||||||
|
PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: ${PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED:-True}
|
||||||
|
PGADMIN_CONFIG_UPGRADE_CHECK_ENABLED: ${PGADMIN_CONFIG_UPGRADE_CHECK_ENABLED:-False}
|
||||||
|
PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION: ${PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION:-True}
|
||||||
|
volumes:
|
||||||
|
- pgadmin_data:/var/lib/pgadmin
|
||||||
|
- ./config_local.py:/pgadmin4/config_local.py:ro
|
||||||
|
- ./servers.json:/pgadmin4/servers.json:ro
|
||||||
|
expose:
|
||||||
|
- "${PGADMIN_PUBLISHED_PORT:-5050}:80"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://127.0.0.1:80/misc/ping').read()\""]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
start_period: 40s
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
driver: bridge
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgadmin_data:
|
||||||
|
name: ${PGADMIN_VOLUME_NAME:-pgadmin_data}
|
||||||
3
servers.json
Normal file
3
servers.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Servers": {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user