diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..9456410 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,64 @@ +name: deploy-portainer + +# Ручной запуск: вкладка Actions → Run workflow. +# Создаёт или обновляет стек photo-editor на Portainer +# (https://ptr.byte-mate.ru) из deploy/docker-compose.yml. +on: + workflow_dispatch: + +concurrency: + group: deploy + cancel-in-progress: true + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Deploy stack to Portainer + env: + PORTAINER_URL: https://ptr.byte-mate.ru + PORTAINER_API_KEY: ${{ secrets.PORTAINER_API_KEY }} + STACK_NAME: photo-editor + # Если не задано — берётся первый endpoint из /api/endpoints + ENDPOINT_ID: ${{ vars.PORTAINER_ENDPOINT_ID }} + run: | + set -euo pipefail + + if [ -z "${PORTAINER_API_KEY:-}" ]; then + echo "::error::Секрет PORTAINER_API_KEY не задан" + echo "::error::Создайте API-ключ в Portainer (Account → API keys) и добавьте его в секреты репозитория." + exit 1 + fi + + AUTH="Authorization: Bearer ${PORTAINER_API_KEY}" + + # Определяем endpoint (окружение Docker), если не задан вручную + if [ -z "${ENDPOINT_ID:-}" ]; then + ENDPOINT_ID=$(curl -fsSk -H "$AUTH" "$PORTAINER_URL/api/endpoints" | jq -r '.[0].Id') + echo "Endpoint id автоопределён: ${ENDPOINT_ID}" + fi + echo "Endpoint id: ${ENDPOINT_ID}" + + # Ищем существующий стек + STACK_ID=$(curl -fsSk -H "$AUTH" \ + "$PORTAINER_URL/api/stacks?filters=%7B%22EndpointId%22%3A${ENDPOINT_ID}%7D" \ + | jq -r ".[] | select(.Name==\"${STACK_NAME}\") | .Id" | head -1 || true) + + if [ -n "${STACK_ID}" ]; then + echo "Обновляю стек ${STACK_NAME} (id=${STACK_ID})" + curl -fsSk -X PUT -H "$AUTH" \ + -F "StackFileContent=@deploy/docker-compose.yml" \ + "$PORTAINER_URL/api/stacks/${STACK_ID}?endpointId=${ENDPOINT_ID}" >/dev/null + else + echo "Создаю стек ${STACK_NAME}" + curl -fsSk -X POST -H "$AUTH" \ + -F "Name=${STACK_NAME}" \ + -F "EndpointId=${ENDPOINT_ID}" \ + -F "StackFileContent=@deploy/docker-compose.yml" \ + "$PORTAINER_URL/api/stacks/create/standalone" >/dev/null + fi + + echo "✅ Стек ${STACK_NAME} развёрнут на ${PORTAINER_URL}" diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 0000000..6acb69b --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,23 @@ +# Файл развёртывания на хосте Portainer. +# Используется workflow .gitea/workflows/deploy.yml (публикует образ, +# уже собранный workflow build-container). +services: + photo-editor: + image: git.byte-mate.ru/coder/photo-editor:latest + pull_policy: always + container_name: kadr-photo-editor + ports: + - "3000:3000" + volumes: + # История версий — именованный том, переживает обновление стека + - kadr-history:/app/history + # Аутентификация и конфиг Codex с хоста Portainer. + # Альтернатива — переменная OPENAI_API_KEY ниже. + - /root/.codex:/root/.codex + environment: + - COMFY_URL=http://192.168.31.240:8188 + # - OPENAI_API_KEY=${OPENAI_API_KEY} + restart: unless-stopped + +volumes: + kadr-history: