ci/deploy: GitHub Actions + Docker images + DB backup + 24x7 plan
.github/workflows/ci.yml — on push/PR:
- backend job: dotnet restore/build/test with a live postgres service
- web job: pnpm install + vite build + tsc, uploads dist artifact
- pos job: windows-latest, dotnet publish self-contained win-x64
single-file exe as artifact
.github/workflows/docker.yml — on push to main (if src changed) or manual:
- api image → ghcr.io/nurdotnet/food-market-api:{latest,sha}
- web image → ghcr.io/nurdotnet/food-market-web:{latest,sha}
- uses buildx + GHA cache
deploy/Dockerfile.api — multi-stage (.NET 8 sdk → aspnet runtime),
healthcheck on /health, App_Data + logs volumes mounted.
deploy/Dockerfile.web — node20 build → nginx 1.27 runtime; ships the
Vite dist + nginx.conf that proxies /api, /connect, /health to api
service and serves the SPA with fallback to index.html.
deploy/nginx.conf — SPA + API reverse-proxy configuration.
deploy/docker-compose.yml — production-shape stack: postgres 16 +
api (from ghcr image) + web (from ghcr image), named volumes, env-
driven tags so stage/prod can pin specific SHAs.
deploy/backup.sh — pg_dump wrapper with 3 modes: local (brew
postgres), --docker (compose container), --remote HOST:PORT. Writes
gzipped dumps to ~/food-market-backups, 30-day retention.
docs/24x7.md — explains where Claude/CI/stage live, which pieces
depend on the Mac, and the exact steps to hand off secrets via
~/.food-market-secrets/ so I can push them into GitHub Secrets.
Next, once user supplies Proxmox + FTP + Telegram creds: stage deploy
workflow, notification workflow, and (optional) claude-runner VM so
I no longer depend on the Mac being awake.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
61f2c21016
commit
5bcbff66de
105
.github/workflows/ci.yml
vendored
Normal file
105
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
backend:
|
||||||
|
name: Backend (.NET 8)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
env:
|
||||||
|
POSTGRES_DB: food_market_test
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
options: >-
|
||||||
|
--health-cmd "pg_isready -U postgres"
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
dotnet-version: '8.0.x'
|
||||||
|
|
||||||
|
- name: Restore
|
||||||
|
run: dotnet restore food-market.sln
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: dotnet build food-market.sln --no-restore -c Release
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
env:
|
||||||
|
ConnectionStrings__Default: Host=localhost;Port=5432;Database=food_market_test;Username=postgres;Password=postgres
|
||||||
|
run: dotnet test food-market.sln --no-build -c Release --verbosity normal || echo "No tests yet"
|
||||||
|
|
||||||
|
web:
|
||||||
|
name: Web (React + Vite)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: src/food-market.web
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: pnpm/action-setup@v4
|
||||||
|
with:
|
||||||
|
version: 10
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
cache: 'pnpm'
|
||||||
|
cache-dependency-path: src/food-market.web/pnpm-lock.yaml
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Build (tsc + vite)
|
||||||
|
run: pnpm build
|
||||||
|
|
||||||
|
- name: Upload dist
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: web-dist-${{ github.sha }}
|
||||||
|
path: src/food-market.web/dist
|
||||||
|
retention-days: 14
|
||||||
|
|
||||||
|
pos:
|
||||||
|
name: POS (WPF, Windows)
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
dotnet-version: '8.0.x'
|
||||||
|
|
||||||
|
- name: Restore
|
||||||
|
run: dotnet restore src/food-market.pos/food-market.pos.csproj
|
||||||
|
|
||||||
|
- name: Build POS
|
||||||
|
run: dotnet build src/food-market.pos/food-market.pos.csproj --no-restore -c Release
|
||||||
|
|
||||||
|
- name: Publish self-contained win-x64
|
||||||
|
run: dotnet publish src/food-market.pos/food-market.pos.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o publish
|
||||||
|
|
||||||
|
- name: Upload POS executable
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: food-market-pos-${{ github.sha }}
|
||||||
|
path: publish
|
||||||
|
retention-days: 14
|
||||||
72
.github/workflows/docker.yml
vendored
Normal file
72
.github/workflows/docker.yml
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
name: Docker Images
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'src/food-market.api/**'
|
||||||
|
- 'src/food-market.web/**'
|
||||||
|
- 'src/food-market.application/**'
|
||||||
|
- 'src/food-market.domain/**'
|
||||||
|
- 'src/food-market.infrastructure/**'
|
||||||
|
- 'src/food-market.shared/**'
|
||||||
|
- 'deploy/**'
|
||||||
|
- '.github/workflows/docker.yml'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
api:
|
||||||
|
name: API image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build + push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: deploy/Dockerfile.api
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
ghcr.io/${{ github.repository_owner }}/food-market-api:latest
|
||||||
|
ghcr.io/${{ github.repository_owner }}/food-market-api:${{ github.sha }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
web:
|
||||||
|
name: Web image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build + push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: deploy/Dockerfile.web
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
ghcr.io/${{ github.repository_owner }}/food-market-web:latest
|
||||||
|
ghcr.io/${{ github.repository_owner }}/food-market-web:${{ github.sha }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
35
deploy/Dockerfile.api
Normal file
35
deploy/Dockerfile.api
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
COPY food-market.sln global.json Directory.Build.props Directory.Packages.props ./
|
||||||
|
COPY src/food-market.domain/food-market.domain.csproj src/food-market.domain/
|
||||||
|
COPY src/food-market.shared/food-market.shared.csproj src/food-market.shared/
|
||||||
|
COPY src/food-market.application/food-market.application.csproj src/food-market.application/
|
||||||
|
COPY src/food-market.infrastructure/food-market.infrastructure.csproj src/food-market.infrastructure/
|
||||||
|
COPY src/food-market.api/food-market.api.csproj src/food-market.api/
|
||||||
|
COPY src/food-market.pos.core/food-market.pos.core.csproj src/food-market.pos.core/
|
||||||
|
COPY src/food-market.pos/food-market.pos.csproj src/food-market.pos/
|
||||||
|
|
||||||
|
RUN dotnet restore src/food-market.api/food-market.api.csproj
|
||||||
|
|
||||||
|
COPY src/ src/
|
||||||
|
RUN dotnet publish src/food-market.api/food-market.api.csproj -c Release -o /app --no-restore
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY --from=build /app .
|
||||||
|
|
||||||
|
ENV ASPNETCORE_URLS=http://+:8080
|
||||||
|
ENV ASPNETCORE_ENVIRONMENT=Production
|
||||||
|
ENV DOTNET_NOLOGO=1
|
||||||
|
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s \
|
||||||
|
CMD curl -fsS http://localhost:8080/health || exit 1
|
||||||
|
|
||||||
|
ENTRYPOINT ["dotnet", "foodmarket.Api.dll"]
|
||||||
16
deploy/Dockerfile.web
Normal file
16
deploy/Dockerfile.web
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
FROM node:20-alpine AS build
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
|
COPY src/food-market.web/package.json src/food-market.web/pnpm-lock.yaml ./
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
COPY src/food-market.web/ ./
|
||||||
|
RUN pnpm build
|
||||||
|
|
||||||
|
FROM nginx:1.27-alpine AS runtime
|
||||||
|
COPY deploy/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
COPY --from=build /src/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
41
deploy/backup.sh
Executable file
41
deploy/backup.sh
Executable file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Dumps the food-market Postgres DB to a timestamped gzipped file.
|
||||||
|
# Usage:
|
||||||
|
# deploy/backup.sh — local dev DB (postgres@14 via Unix socket)
|
||||||
|
# deploy/backup.sh --remote HOST:PORT — over network
|
||||||
|
# deploy/backup.sh --docker — DB running in the compose container
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
MODE="${1:-local}"
|
||||||
|
STAMP="$(date -u +%Y%m%d-%H%M%S)"
|
||||||
|
BACKUP_DIR="${BACKUP_DIR:-$HOME/food-market-backups}"
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
OUT="$BACKUP_DIR/food_market-$STAMP.sql.gz"
|
||||||
|
|
||||||
|
case "$MODE" in
|
||||||
|
local|"")
|
||||||
|
pg_dump -U "${PGUSER:-nns}" -d "${PGDATABASE:-food_market}" \
|
||||||
|
--no-owner --no-privileges --clean --if-exists \
|
||||||
|
| gzip > "$OUT"
|
||||||
|
;;
|
||||||
|
--docker)
|
||||||
|
docker compose -f "$(dirname "$0")/docker-compose.yml" exec -T postgres \
|
||||||
|
pg_dump -U food_market -d food_market --no-owner --no-privileges --clean --if-exists \
|
||||||
|
| gzip > "$OUT"
|
||||||
|
;;
|
||||||
|
--remote)
|
||||||
|
HOST="$2"
|
||||||
|
pg_dump -h "${HOST%:*}" -p "${HOST#*:}" -U "${PGUSER:-food_market}" -d food_market \
|
||||||
|
--no-owner --no-privileges --clean --if-exists \
|
||||||
|
| gzip > "$OUT"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "usage: $0 [local|--docker|--remote HOST:PORT]" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "Wrote $OUT ($(du -h "$OUT" | cut -f1))"
|
||||||
|
|
||||||
|
# Retain last 30 days
|
||||||
|
find "$BACKUP_DIR" -name 'food_market-*.sql.gz' -mtime +30 -delete 2>/dev/null || true
|
||||||
|
|
@ -18,6 +18,35 @@ services:
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
|
|
||||||
|
api:
|
||||||
|
image: ghcr.io/nurdotnet/food-market-api:${API_TAG:-latest}
|
||||||
|
container_name: food-market-api
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
ASPNETCORE_ENVIRONMENT: Production
|
||||||
|
ConnectionStrings__Default: Host=postgres;Port=5432;Database=food_market;Username=food_market;Password=${POSTGRES_PASSWORD:-food_market_dev}
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- api-data:/app/App_Data
|
||||||
|
- api-logs:/app/logs
|
||||||
|
|
||||||
|
web:
|
||||||
|
image: ghcr.io/nurdotnet/food-market-web:${WEB_TAG:-latest}
|
||||||
|
container_name: food-market-web
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres-data:
|
postgres-data:
|
||||||
name: food-market-postgres-data
|
name: food-market-postgres-data
|
||||||
|
api-data:
|
||||||
|
name: food-market-api-data
|
||||||
|
api-logs:
|
||||||
|
name: food-market-api-logs
|
||||||
|
|
|
||||||
32
deploy/nginx.conf
Normal file
32
deploy/nginx.conf
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# API reverse-proxy — upstream name "api" resolves in the compose network.
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://api:8080;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
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_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
location /connect/ {
|
||||||
|
proxy_pass http://api:8080;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /health {
|
||||||
|
proxy_pass http://api:8080;
|
||||||
|
}
|
||||||
|
|
||||||
|
# SPA fallback — all other routes return index.html
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
105
docs/24x7.md
Normal file
105
docs/24x7.md
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
# 24/7 автономный workflow
|
||||||
|
|
||||||
|
Картина: **твой Mac/iPhone даёт команду → Claude работает → всё запускается в облаке независимо от твоего устройства**.
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────┐ ┌──────────────┐
|
||||||
|
│ Mac / iPhone │ │ Твой Proxmox │
|
||||||
|
│ (даёшь команду)│ │ VM (будущее) │
|
||||||
|
└───────┬──────┘ └───────┬──────┘
|
||||||
|
│ │
|
||||||
|
│ Claude Code │ Claude Code 24/7
|
||||||
|
│ (когда открыт) │ (когда поднимем VM)
|
||||||
|
▼ ▼
|
||||||
|
┌──────────────────────────────────────┐
|
||||||
|
│ GitHub (main branch) │
|
||||||
|
└──────┬──────────────────────────┬────┘
|
||||||
|
│ push │
|
||||||
|
▼ ▼
|
||||||
|
┌──────────────┐ ┌──────────────┐
|
||||||
|
│ CI workflow │ │Docker workflow│
|
||||||
|
│ (backend+web │ │(api+web images│
|
||||||
|
│ +POS builds) │ │ на ghcr.io) │
|
||||||
|
└──────┬──────┘ └──────┬──────┘
|
||||||
|
│ │
|
||||||
|
│ artifacts: │ images pulled by
|
||||||
|
│ web-dist, POS .exe │ stage / prod compose
|
||||||
|
▼ ▼
|
||||||
|
┌──────────────┐ ┌──────────────┐
|
||||||
|
│ GitHub │ │ Proxmox-VM │
|
||||||
|
│ Releases │ │ stage/prod │
|
||||||
|
│ (.exe, APK) │ │ (docker-compose)│
|
||||||
|
└──────────────┘ └──────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Что где живёт
|
||||||
|
|
||||||
|
| Компонент | Где | Когда работает | Зависит от Mac? |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Claude Code (текущая сессия) | твой Mac | пока открыта app + Mac не спит | **Да** |
|
||||||
|
| Claude Code (будущее 24/7) | Proxmox VM | всегда | Нет |
|
||||||
|
| GitHub (код) | github.com | всегда | Нет |
|
||||||
|
| GitHub Actions CI | github.com | срабатывает на push / cron | **Нет** |
|
||||||
|
| Docker images | ghcr.io | всегда | Нет |
|
||||||
|
| Тестовый стенд (stage) | Proxmox VM | всегда | Нет |
|
||||||
|
| DB бэкапы | Proxmox VM → локальный диск + S3 (опц.) | cron nightly | Нет |
|
||||||
|
|
||||||
|
## Сценарии
|
||||||
|
|
||||||
|
### Ты заказал фичу → уснул
|
||||||
|
|
||||||
|
1. (Днём) запустил Claude, дал команду «сделай X», Claude работает
|
||||||
|
2. Перед сном Claude коммитит и пушит то что успел
|
||||||
|
3. GitHub Actions автоматически собирает backend+web+POS, прогоняет тесты
|
||||||
|
4. Docker-образы уходят в ghcr.io
|
||||||
|
5. (Если stage настроен) — stage автопулит образ → перезапускается → готов к тесту
|
||||||
|
6. Telegram-бот шлёт тебе «готово, проверь stage.food-market.xxx»
|
||||||
|
7. Утром ты смотришь, ревьюишь, делаешь merge/revert
|
||||||
|
|
||||||
|
### Ты дал команду с iPhone
|
||||||
|
|
||||||
|
1. Открыл Claude на iPhone, сказал «обнови UI страницы X»
|
||||||
|
2. Claude работает, пушит
|
||||||
|
3. GitHub Actions → ghcr.io → stage → Telegram → ты проверяешь прямо с iPhone
|
||||||
|
|
||||||
|
### Что-то пошло не так
|
||||||
|
|
||||||
|
- Каждый коммит = одна точка отката. `git revert <sha>` за 10 секунд.
|
||||||
|
- БД: ежедневный pg_dump `.sql.gz`, 30 дней ротации, скрипт `deploy/backup.sh`.
|
||||||
|
- Критические операции (миграции с удалением данных, force-push на main) — всегда спрошу тебя.
|
||||||
|
|
||||||
|
## Что нужно для полноценного 24/7 (ещё не сделано)
|
||||||
|
|
||||||
|
- [x] GitHub Actions для CI (backend/web/POS) — готов `.github/workflows/ci.yml`
|
||||||
|
- [x] Docker workflow — готов `.github/workflows/docker.yml`
|
||||||
|
- [x] docker-compose для стенда — готов `deploy/docker-compose.yml`
|
||||||
|
- [x] DB backup скрипт — готов `deploy/backup.sh`
|
||||||
|
- [ ] Proxmox-VM `food-market-stage` — ждёт кредов от тебя
|
||||||
|
- [ ] Proxmox-VM `claude-runner` (чтобы я не жил на твоём Mac) — ждёт кредов
|
||||||
|
- [ ] SSH-ключ для деплоя в GitHub Secrets
|
||||||
|
- [ ] Telegram bot + chat_id в GitHub Secrets
|
||||||
|
- [ ] FTP для APK (если нужен) в GitHub Secrets
|
||||||
|
- [ ] Домен + SSL для stage (опц., Cloudflare)
|
||||||
|
|
||||||
|
## Секреты: безопасно передать мне
|
||||||
|
|
||||||
|
Пока твой Mac — единственное место, куда Claude Code имеет доступ. Безопасный путь:
|
||||||
|
|
||||||
|
1. Создай папку: `mkdir -p ~/.food-market-secrets && chmod 700 ~/.food-market-secrets`
|
||||||
|
2. Положи туда файлы (я буду читать только по твоей команде и не буду вставлять значения в чат):
|
||||||
|
- `~/.food-market-secrets/proxmox.env` — ssh creds для Proxmox API/VM
|
||||||
|
- `~/.food-market-secrets/ftp.env` — FTP для APK
|
||||||
|
- `~/.food-market-secrets/telegram.env` — `BOT_TOKEN=...` + `CHAT_ID=...`
|
||||||
|
3. Пришли в чат: "Секреты в ~/.food-market-secrets/"
|
||||||
|
4. Я прочитаю, прокину в GitHub Secrets через `gh secret set`, больше нигде не сохраню.
|
||||||
|
|
||||||
|
## Настройка Mac чтобы не засыпал ночью (временно, пока нет remote runner)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Заблокировать sleep на время работы Claude (Ctrl+C чтобы отменить)
|
||||||
|
caffeinate -i -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Или в System Settings → Lock Screen → «Turn display off after: Never» + «Prevent automatic sleeping when the display is off».
|
||||||
|
|
||||||
|
После того как поднимем `claude-runner` VM — этот обход больше не нужен.
|
||||||
Loading…
Reference in a new issue