migrate from cc
This commit is contained in:
parent
677d93af69
commit
d2dac031c4
8
.example.env
Normal file
8
.example.env
Normal file
@ -0,0 +1,8 @@
|
||||
# --- Infrastructure
|
||||
DOMAIN=
|
||||
|
||||
REG=git.sys.smsynergy.ru
|
||||
REG_USER=
|
||||
REG_PASS=
|
||||
|
||||
# --- Databases
|
||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.vscode
|
||||
.env
|
||||
temp
|
||||
202
dev/docker-compose.yml
Normal file
202
dev/docker-compose.yml
Normal file
@ -0,0 +1,202 @@
|
||||
services:
|
||||
# --- Infrastructure services ---
|
||||
traefik:
|
||||
image: traefik:v2.9
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./traefik/acme:/acme
|
||||
command:
|
||||
- --api.dashboard=true
|
||||
- --providers.docker=true
|
||||
- --providers.docker.defaultRule=Host(`app.${DOMAIN}`) && PathPrefix(`/{{ index .Labels "com.docker.compose.service" }}/`)
|
||||
- --entrypoints.web.address=:80
|
||||
# Применяем middleware auth автоматически ко всем сервисам через entrypoint
|
||||
- --entrypoints.web.http.middlewares=auth@docker,error-401@docker
|
||||
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --entrypoints.websecure.http.tls=true
|
||||
- --entrypoints.websecure.http.tls.certresolver=le
|
||||
|
||||
- --certificatesresolvers.le.acme.email=admin@mail.${DOMAIN}
|
||||
- --certificatesresolvers.le.acme.storage=/acme/acme.json
|
||||
# - --certificatesresolvers.le.acme.tlschallenge=true
|
||||
- --certificatesresolvers.le.acme.httpchallenge=true
|
||||
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)"
|
||||
- "traefik.http.routers.traefik.entrypoints=web"
|
||||
- "traefik.http.routers.traefik.service=api@internal"
|
||||
|
||||
# Forward auth middleware
|
||||
- "traefik.http.middlewares.auth.forwardauth.address=http://sah/api/forward/check"
|
||||
- "traefik.http.middlewares.auth.forwardauth.trustForwardHeader=true"
|
||||
- "traefik.http.middlewares.auth.forwardauth.authResponseHeaders=Authorization,Cookie"
|
||||
|
||||
# Error handler для перехвата 401 ошибок от сервисов
|
||||
- "traefik.http.middlewares.error-401.errors.status=401-401"
|
||||
- "traefik.http.middlewares.error-401.errors.service=sah"
|
||||
- "traefik.http.middlewares.error-401.errors.query=/api/forward/handle-401"
|
||||
|
||||
# Middleware для stripprefix
|
||||
- "traefik.http.middlewares.global-stripprefix.replacepathregex.regex=^/([^/]+)/(.*)"
|
||||
- "traefik.http.middlewares.global-stripprefix.replacepathregex.replacement=/$$2"
|
||||
- traefik.http.middlewares.global-stripprefix2.replacepathregex.regex=^/([^/]+)/[^/]+/(.*)
|
||||
- traefik.http.middlewares.global-stripprefix2.replacepathregex.replacement=/$$2
|
||||
|
||||
sah:
|
||||
image: ${REG}/cc/sah:latest
|
||||
volumes:
|
||||
- ./sah/data:/data
|
||||
environment:
|
||||
- COOKIE_DOMAIN=${DOMAIN}
|
||||
- SAH_DOMAIN=sah.${DOMAIN}
|
||||
labels:
|
||||
- "traefik.http.routers.sah.rule=Host(`sah.${DOMAIN}`)"
|
||||
- "traefik.http.services.sah.loadbalancer.server.port=80"
|
||||
|
||||
portainer:
|
||||
image: portainer/portainer-ce:latest
|
||||
environment:
|
||||
- PORTAINER_HTTP_ENABLED=true
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
labels:
|
||||
- "traefik.http.routers.portainer.rule=Host(`portainer.${DOMAIN}`)"
|
||||
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
|
||||
|
||||
watchtower:
|
||||
image: containrrr/watchtower
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /root/.docker/config.json:/config.json
|
||||
environment:
|
||||
- WATCHTOWER_CLEANUP=true
|
||||
- WATCHTOWER_DEBUG=true
|
||||
- WATCHTOWER_LABEL_ENABLE=true
|
||||
- WATCHTOWER_POLL_INTERVAL=30
|
||||
- WATCHTOWER_SSL_VERIFY=false
|
||||
labels:
|
||||
- traefik.enable=false
|
||||
|
||||
portagent:
|
||||
image: portainer/agent:2.19.1
|
||||
restart: always
|
||||
ports:
|
||||
- 9001:9001
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /var/lib/docker/volumes:/var/lib/docker/volumes
|
||||
labels:
|
||||
- traefik.enable=false
|
||||
|
||||
api:
|
||||
image: tecnativa/tcp-proxy
|
||||
restart: unless-stopped
|
||||
tty: true
|
||||
environment:
|
||||
- LISTEN=:80 :443
|
||||
- TALK=traefik:80 traefik:443
|
||||
- TIMEOUT_TUNNEL=360s
|
||||
labels:
|
||||
- traefik.http.routers.api.middlewares=global-stripprefix
|
||||
- traefik.http.services.api.loadbalancer.server.port=80
|
||||
|
||||
# --- Database services ---
|
||||
|
||||
mongo:
|
||||
image: mongo:4.0.9
|
||||
ports:
|
||||
- "27017:27017/tcp"
|
||||
restart: "always"
|
||||
volumes:
|
||||
- ./db/mongo:/data/db
|
||||
- ./dump/mongo:/dump
|
||||
labels:
|
||||
- traefik.enable=false
|
||||
|
||||
mongoadmin:
|
||||
image: mongo-express:1.0-20-alpine3.19
|
||||
environment:
|
||||
- ME_CONFIG_MONGODB_ENABLE_ADMIN=true
|
||||
- ME_CONFIG_MONGODB_URL=mongodb://mongo:27017/
|
||||
- ME_CONFIG_BASICAUTH=false # Отключает базовую аутентификацию
|
||||
labels:
|
||||
- traefik.http.routers.mongoadmin.rule=Host(`mongoadmin.${DOMAIN}`)
|
||||
- traefik.http.services.mongoadmin.loadbalancer.server.port=8081
|
||||
|
||||
# --- Application services ---
|
||||
|
||||
app:
|
||||
image: ${REG}/cc/front3:latest
|
||||
restart: "always"
|
||||
labels:
|
||||
- "traefik.http.routers.app.rule=Host(`app.${DOMAIN}`) && PathPrefix(`/`)"
|
||||
- "traefik.http.services.app.loadbalancer.server.port=80"
|
||||
|
||||
ma:
|
||||
image: ${REG}/cc/cc_ma
|
||||
environment:
|
||||
- "DB_BIG=big"
|
||||
- "DB_HOST=mongo"
|
||||
- "MA_PREFIX=p1"
|
||||
- "DB_NAME=master"
|
||||
- "MA_NO_SYNC=master"
|
||||
- "DB="
|
||||
- "PROCESSES=4"
|
||||
- "MA_SEARCH_LIMIT=500"
|
||||
restart: "always"
|
||||
labels:
|
||||
- com.centurylinklabs.watchtower.enable=true
|
||||
# - traefik.http.routers.ma.middlewares=global-stripprefix
|
||||
|
||||
# --- Plugins services ---
|
||||
|
||||
metabase:
|
||||
image: metabase/metabase:latest
|
||||
restart: always
|
||||
environment:
|
||||
- MB_JETTY_PORT=3000
|
||||
- MB_DB_TYPE=h2 # Используем встроенную H2 БД (не для продакшена!)
|
||||
- MB_DB_FILE=/metabase-data/metabase.db
|
||||
- MB_SITE_NAME=SMSynergy Analytics
|
||||
volumes:
|
||||
- ./metabase:/metabase-data # Сохраняем данные между перезапусками
|
||||
labels:
|
||||
- "traefik.http.routers.metabase.rule=Host(`metabase.${DOMAIN}`)"
|
||||
- "traefik.http.services.metabase.loadbalancer.server.port=3000"
|
||||
|
||||
n8n:
|
||||
image: n8nio/n8n:1.121.2
|
||||
container_name: n8n
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- N8N_PORT=5678
|
||||
- N8N_SECURE_COOKIE=false
|
||||
- DB_TYPE=sqlite
|
||||
- DB_SQLITE_POOL_SIZE=64
|
||||
- N8N_RUNNERS_ENABLED=true
|
||||
- N8N_GIT_NODE_DISABLE_BARE_REPOS=true
|
||||
- N8N_BLOCK_ENV_ACCESS_IN_NODE=false
|
||||
- N8N_DIAGNOSTICS_ENABLED=false
|
||||
- N8N_PERSONALIZATION_ENABLED=false
|
||||
labels:
|
||||
- "traefik.http.routers.n8n.rule=Host(`n8n.${DOMAIN}`)"
|
||||
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
|
||||
|
||||
jupyter:
|
||||
image: jupyter/datascience-notebook:latest
|
||||
command: >
|
||||
start-notebook.sh
|
||||
--NotebookApp.token=''
|
||||
--NotebookApp.password=''
|
||||
--ServerApp.disable_check_xsrf=True
|
||||
volumes:
|
||||
- ./jupyter_data:/home/jovyan/work
|
||||
labels:
|
||||
- "traefik.http.routers.jupyter.rule=Host(`jupyter.${DOMAIN}`)"
|
||||
- "traefik.http.services.jupyter.loadbalancer.server.port=8888"
|
||||
2
dev/login.sh
Normal file
2
dev/login.sh
Normal file
@ -0,0 +1,2 @@
|
||||
. ./.env
|
||||
docker login $REG -u $REG_USER -p $REG_PASS
|
||||
233
setup-alpine.sh
Normal file
233
setup-alpine.sh
Normal file
@ -0,0 +1,233 @@
|
||||
#!/bin/sh
|
||||
|
||||
REG=git.sys.smsynergy.ru
|
||||
VERSION=v0.0.1
|
||||
|
||||
. ./.env
|
||||
|
||||
echo $DOMAIN
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo " Установка системы Panorama Analytics"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Проверка наличия необходимых утилит
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "Установка Docker..."
|
||||
apk add --no-cache docker docker-compose
|
||||
rc-update add docker boot
|
||||
service docker start
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# Запрос DOMAIN
|
||||
if [ -z "$DOMAIN" ]; then
|
||||
echo -n "Введите домен для запуска системы Panorama Analytics (например: example.com): "
|
||||
read DOMAIN
|
||||
|
||||
if [ -z "$DOMAIN" ]; then
|
||||
echo "Ошибка: DOMAIN обязателен для продолжения"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "DOMAIN: $DOMAIN"
|
||||
fi
|
||||
|
||||
# Запрос токена (для доступа к git registry)
|
||||
if [ -z "$REG_USER" ]; then
|
||||
echo -n "Введите логинт для доступа к git registry: "
|
||||
read REG_USER
|
||||
|
||||
if [ -z "$REG_USER" ]; then
|
||||
echo "Ошибка: логин обязателен для продолжения"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$REG_PASS" ]; then
|
||||
echo -n "Введите пароль для доступа к git registry: "
|
||||
read REG_PASS
|
||||
|
||||
if [ -z "$REG_PASS" ]; then
|
||||
echo "Ошибка: пароль обязателен для продолжения"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Настройка окружения..."
|
||||
|
||||
# Создаем .env файл
|
||||
cat > .env <<EOF
|
||||
# --- Infrastructure
|
||||
DOMAIN=${DOMAIN}
|
||||
|
||||
REG=git.sys.smsynergy.ru
|
||||
REG_USER=${REG_USER}
|
||||
REG_PASS=${REG_PASS}
|
||||
|
||||
# --- Databases
|
||||
EOF
|
||||
|
||||
echo ".env файл создан"
|
||||
|
||||
# Логин в Docker registry
|
||||
echo ""
|
||||
echo "Авторизация в Docker registry..."
|
||||
echo "$REG_PASS" | docker login $REG -u $REG_USER --password-stdin
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Ошибка: не удалось авторизоваться в Docker registry"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Авторизация успешна"
|
||||
|
||||
# Скачивание docker-compose.yml
|
||||
echo ""
|
||||
echo "Скачивание docker-compose.yml версии ${VERSION}..."
|
||||
|
||||
# Пробуем скачать из git репозитория
|
||||
# Пробуем разные варианты URL
|
||||
DOWNLOADED=0
|
||||
|
||||
# Создаем базовую HTTP аутентификацию (Base64)
|
||||
AUTH_BASE64=$(printf "%s:%s" "${REG_USER}" "${REG_PASS}" | base64 -w 0 2>/dev/null || printf "%s:%s" "${REG_USER}" "${REG_PASS}" | base64)
|
||||
|
||||
for COMPOSE_URL in \
|
||||
"https://${REG}/cc/deploy/raw/tag/${VERSION}/dev/docker-compose.yml" \
|
||||
"https://${REG}/cc/deploy/src/tag/${VERSION}/dev/docker-compose.yml" \
|
||||
"https://${REG}/cc/deploy/-/raw/${VERSION}/dev/docker-compose.yml" \
|
||||
"https://${REG}/cc/deploy/-/blob/${VERSION}/dev/docker-compose.yml?format=raw"; do
|
||||
echo "Попытка скачать: ${COMPOSE_URL}"
|
||||
|
||||
# Пробуем с базовой HTTP аутентификацией через заголовок (для BusyBox wget)
|
||||
echo "Попытка с Basic Auth..."
|
||||
if wget --header="Authorization: Basic ${AUTH_BASE64}" -O docker-compose.yml "${COMPOSE_URL}" 2>&1 | tee /tmp/wget_output.log; then
|
||||
if [ -f "docker-compose.yml" ] && [ -s "docker-compose.yml" ]; then
|
||||
# Проверяем, что это не HTML страница с ошибкой
|
||||
if head -1 docker-compose.yml | grep -q "services:"; then
|
||||
echo "docker-compose.yml успешно скачан с URL: ${COMPOSE_URL}"
|
||||
DOWNLOADED=1
|
||||
break
|
||||
else
|
||||
echo "Предупреждение: скачанный файл не похож на docker-compose.yml"
|
||||
cat docker-compose.yml | head -5
|
||||
rm -f docker-compose.yml
|
||||
fi
|
||||
fi
|
||||
else
|
||||
HTTP_CODE=$(grep -o "HTTP/[0-9.]* [0-9]*" /tmp/wget_output.log 2>/dev/null | tail -1 | awk '{print $2}' || echo "unknown")
|
||||
if [ "$HTTP_CODE" != "unknown" ]; then
|
||||
echo "HTTP код: ${HTTP_CODE}"
|
||||
fi
|
||||
if [ -f /tmp/wget_output.log ]; then
|
||||
echo "Вывод wget:"
|
||||
cat /tmp/wget_output.log | tail -3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Пробуем с токеном в заголовке
|
||||
echo "Попытка с токеном в заголовке..."
|
||||
if wget --header="Authorization: token ${REG_PASS}" -O docker-compose.yml "${COMPOSE_URL}" 2>&1 | tee /tmp/wget_output.log; then
|
||||
if [ -f "docker-compose.yml" ] && [ -s "docker-compose.yml" ]; then
|
||||
if head -1 docker-compose.yml | grep -q "services:"; then
|
||||
echo "docker-compose.yml успешно скачан с токеном: ${COMPOSE_URL}"
|
||||
DOWNLOADED=1
|
||||
break
|
||||
else
|
||||
rm -f docker-compose.yml
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Пробуем с Bearer токеном
|
||||
echo "Попытка с Bearer токеном..."
|
||||
if wget --header="Authorization: Bearer ${REG_PASS}" -O docker-compose.yml "${COMPOSE_URL}" 2>&1 | tee /tmp/wget_output.log; then
|
||||
if [ -f "docker-compose.yml" ] && [ -s "docker-compose.yml" ]; then
|
||||
if head -1 docker-compose.yml | grep -q "services:"; then
|
||||
echo "docker-compose.yml успешно скачан с Bearer токеном: ${COMPOSE_URL}"
|
||||
DOWNLOADED=1
|
||||
break
|
||||
else
|
||||
rm -f docker-compose.yml
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Пробуем с URL содержащим credentials (для некоторых систем)
|
||||
COMPOSE_URL_WITH_AUTH="https://${REG_USER}:${REG_PASS}@${REG}/cc/deploy/raw/tag/${VERSION}/dev/docker-compose.yml"
|
||||
if [ "$COMPOSE_URL" = "https://${REG}/cc/deploy/raw/tag/${VERSION}/dev/docker-compose.yml" ]; then
|
||||
echo "Попытка с credentials в URL..."
|
||||
if wget -O docker-compose.yml "${COMPOSE_URL_WITH_AUTH}" 2>&1 | tee /tmp/wget_output.log; then
|
||||
if [ -f "docker-compose.yml" ] && [ -s "docker-compose.yml" ]; then
|
||||
if head -1 docker-compose.yml | grep -q "services:"; then
|
||||
echo "docker-compose.yml успешно скачан с credentials в URL"
|
||||
DOWNLOADED=1
|
||||
break
|
||||
else
|
||||
rm -f docker-compose.yml
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
if [ $DOWNLOADED -eq 0 ]; then
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "ОШИБКА: не удалось скачать docker-compose.yml"
|
||||
echo "=========================================="
|
||||
echo "Проверьте:"
|
||||
echo "1. Правильность версии: ${VERSION}"
|
||||
echo "2. Доступность репозитория: ${REG}/cc/deploy"
|
||||
echo "3. Правильность логина и пароля"
|
||||
echo "4. Существование файла: dev/docker-compose.yml в указанной версии"
|
||||
echo ""
|
||||
echo "Попробуйте вручную:"
|
||||
AUTH_B64=$(printf "%s:%s" "${REG_USER}" "${REG_PASS}" | base64 -w 0 2>/dev/null || printf "%s:%s" "${REG_USER}" "${REG_PASS}" | base64)
|
||||
echo "wget --header=\"Authorization: Basic ${AUTH_B64}\" -O docker-compose.yml \"https://${REG}/cc/deploy/raw/tag/${VERSION}/dev/docker-compose.yml\""
|
||||
echo "или:"
|
||||
echo "wget -O docker-compose.yml \"https://${REG_USER}:${REG_PASS}@${REG}/cc/deploy/raw/tag/${VERSION}/dev/docker-compose.yml\""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Проверка наличия docker-compose.yml
|
||||
if [ ! -f "docker-compose.yml" ]; then
|
||||
echo "Ошибка: docker-compose.yml не найден"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Запуск docker-compose
|
||||
echo ""
|
||||
echo "Запуск контейнеров..."
|
||||
docker-compose up -d
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Ошибка: не удалось запустить контейнеры"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ожидание запуска сервисов
|
||||
echo ""
|
||||
echo "Ожидание запуска сервисов..."
|
||||
sleep 5
|
||||
|
||||
# Проверка статуса
|
||||
echo ""
|
||||
echo "Статус контейнеров:"
|
||||
docker-compose ps
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " Установка завершена!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Зайдите на http://sah.${DOMAIN} для продолжения"
|
||||
echo ""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user