vibe-deploy
npx skills add https://github.com/swan4er/vibe-deploy --skill vibe-deploy
Agent 安装分布
Skill 文档
Timeweb Deploy â Скилл Ð´Ð»Ñ Ð´ÐµÐ¿Ð»Ð¾Ñ Ð¿ÑоекÑов на Timeweb Cloud
ÐбзоÑ
ÐÑÐ¾Ñ Ñкилл позволÑÐµÑ ÐÐ-агенÑÑ ÑамоÑÑоÑÑелÑно задеплоиÑÑ Ð»Ñбой пÑÐ¾ÐµÐºÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð½Ð° Timeweb Cloud â Ð¾Ñ Ð¿ÑоÑÑого ÑÑаÑиÑеÑкого ÑайÑа до fullstack-моноÑепозиÑоÑÐ¸Ñ Ñ Ð±Ð°Ð·Ð¾Ð¹ даннÑÑ .
ЯзÑк обÑÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð»ÑзоваÑелем: ÑÑÑÑкий.
СÑÑÑкÑÑÑа Ñкилла:
scripts/â Python-ÑкÑипÑÑ Ð´Ð»Ñ API, анализа пÑоекÑа, ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ state-Ñайломtemplates/â Dockerfile, GitHub Actions workflows, Nginx, systemdreference/â ÑпÑавоÑники по API, оÑибкам, пÑеÑеÑам
ÐÑÑÑÑÑй Ñежим: возобновление и обновление
Ðозобновление пÑеÑванного деплоÑ
ÐеÑед наÑалом ÑабоÑÑ Ð¿ÑовеÑÑ, ÑÑÑеÑÑвÑÐµÑ Ð»Ð¸ deploy-state.md в коÑне пÑоекÑа. ÐÑли ÑÑÑеÑÑвÑеÑ:
- ÐÑоÑиÑай
deploy-state.md - ÐÑполни
python3 scripts/deploy_state.py verifyâ Ñзнай незавеÑÑÑннÑе Ñаги - ÐÑедложи полÑзоваÑелÑ:
ÐаÑÑл незавеÑÑÑннÑй деплой. ÐÐ¾Ñ ÑÑо оÑÑалоÑÑ: {ÑпиÑок незавеÑÑÑннÑÑ Ñагов}
ÐÑодолжиÑÑ Ñ Ñого меÑÑа, где оÑÑановилиÑÑ, или наÑаÑÑ Ð·Ð°Ð½Ð¾Ð²Ð¾?
ÐÑли полÑзоваÑÐµÐ»Ñ Ñ Ð¾ÑÐµÑ Ð¿ÑодолжиÑÑ â пеÑейди к пеÑÐ²Ð¾Ð¼Ñ Ð½ÐµÐ·Ð°Ð²ÐµÑÑÑÐ½Ð½Ð¾Ð¼Ñ ÑагÑ, не повÑоÑÑÑ Ñже вÑполненнÑе.
ÐÑÑÑÑое обновление (пеÑедеплой)
ÐÑли полÑзоваÑÐµÐ»Ñ Ð³Ð¾Ð²Ð¾ÑÐ¸Ñ “обнови пÑоекє, “пеÑедеплой”, “обнови код на ÑеÑвеÑе” â и deploy-state.md ÑÑÑеÑÑвÑÐµÑ Ñ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð½Ñм IP ÑеÑвеÑа:
- ÐÑоÑиÑай state-Ñайл: IP, ÑÑÑаÑегиÑ, Docker/PM2/systemd
- Ðе пÑÐ¾Ñ Ð¾Ð´Ð¸ вÑе 10 Ñагов. ÐÑполни ÑолÑко обновление:
VPS + Docker:
ssh -i ~/.ssh/timeweb_deploy root@<IP> "cd /opt/app && git pull origin main && docker compose down && docker compose up -d --build"
VPS + PM2:
ssh -i ~/.ssh/timeweb_deploy root@<IP> "cd /opt/app && git pull origin main && npm ci --production && npm run build && pm2 restart app"
VPS + systemd:
ssh -i ~/.ssh/timeweb_deploy root@<IP> "cd /opt/app && git pull origin main && source venv/bin/activate && pip install -r requirements.txt && systemctl restart app"
App Platform:
python3 scripts/timeweb_api.py app-status --id <app_id>
# ÐÑли auto-deploy вклÑÑÑн â push в main Ñже обновил. ÐÑоÑÑо ÑообÑи.
# ÐÑли Ð½ÐµÑ â python3 scripts/timeweb_api.py <trigger deploy ÑеÑез API>
ÐÑоÑмоÑÑ ÑÑÑеÑÑвÑÑÑÐ¸Ñ ÑеÑÑÑÑов
ÐÑли полÑзоваÑÐµÐ»Ñ ÑпÑаÑÐ¸Ð²Ð°ÐµÑ “какие ÑеÑвеÑÑ/пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ Ð¼ÐµÐ½Ñ ÐµÑÑÑ”:
python3 scripts/timeweb_api.py list-servers
python3 scripts/timeweb_api.py list-apps
python3 scripts/timeweb_api.py list-dbs
ÐÑовеÑка Python пеÑед наÑалом ÑабоÑÑ
СкÑипÑÑ Ñкилла ÑÑебÑÑÑ Python 3. ÐеÑед пеÑвÑм вÑзовом лÑбого ÑкÑипÑа пÑовеÑÑ Ð½Ð°Ð»Ð¸Ñие:
python3 --version 2>/dev/null || python --version 2>/dev/null
ÐÑли Python не найден â ÑпÑоÑи полÑзоваÑелÑ:
ÐÐ»Ñ ÑабоÑÑ Ñкилла Ð´ÐµÐ¿Ð»Ð¾Ñ Ð½Ñжен Python 3, но он не ÑÑÑановлен. УÑÑановиÑÑ?
macOS:
brew install python3(нÑжен Homebrew) или ÑкаÑаÑÑ Ñ https://www.python.org/downloads/ Windows:winget install Python.Python.3.12или ÑкаÑаÑÑ Ñ https://www.python.org/downloads/ Linux:sudo apt-get install -y python3(Ubuntu/Debian) илиsudo dnf install -y python3(Fedora)
Ðе ÑÑÑанавливай без ÑазÑеÑениÑ. ÐождиÑÑ Ð¿Ð¾Ð´ÑвеÑÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ.
ÐоÑле ÑÑÑановки пÑовеÑÑ ÐµÑÑ Ñаз: python3 --version
ÐÑимеÑание: Ðа Windows Python Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð´Ð¾ÑÑÑпен как python вмеÑÑо python3. ÐÑли python3 не найден, но python --version показÑÐ²Ð°ÐµÑ 3.x â иÑполÑзÑй python во вÑеÑ
командаÑ
вмеÑÑо python3.
Также Ð´Ð»Ñ scripts/github_api.py set-secret / set-all-secrets нÑжна библиоÑека PyNaCl:
pip install pynacl
УÑÑанови ÐµÑ ÑолÑко еÑли полÑзоваÑÐµÐ»Ñ Ð²ÑбÑал авÑомаÑиÑеÑкÑÑ Ð½Ð°ÑÑÑÐ¾Ð¹ÐºÑ GitHub Secrets. Ðе ÑÑÐ°Ð²Ñ Ð·Ð°Ñанее.
â ï¸ ÐÑиÑиÑеÑкие пÑавила поведениÑ
ÐÑи пÑавила имеÑÑ Ð½Ð°Ð¸Ð²ÑÑÑий пÑиоÑиÑÐµÑ Ð¸ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑоблÑдаÑÑÑÑ Ð½Ð° вÑÐµÑ ÑÑÐ°Ð¿Ð°Ñ :
-
Ðе обеÑай Ñого, ÑÑо не ÑделаеÑÑ. ÐÑли Ñказал полÑзоваÑÐµÐ»Ñ “наÑÑÑÐ¾Ñ Docker” â ÐÐЯÐÐРнаÑÑÑоиÑÑ Docker. ÐÑли Ñказал “наÑÑÑÐ¾Ñ CI/CD” â ÐÐЯÐÐРнаÑÑÑоиÑÑ CI/CD. ÐелÑÐ·Ñ Ð¿Ð¾Ð¾Ð±ÐµÑаÑÑ Ð² плане и молÑа пÑопÑÑÑиÑÑ.
-
Ðе пÑинимай ÑеÑÐµÐ½Ð¸Ñ Ð·Ð° полÑзоваÑÐµÐ»Ñ Ð¼Ð¾Ð»Ñа. ÐÑегда ÑпÑаÑивай: Docker или без Docker? Git или SCP? App Platform или VPS? Ðомен или без? CI/CD или без? Ðе вÑбиÑай за него.
-
СнаÑала ÑиÑай даннÑе пÑоекÑа, поÑом ÑпÑаÑивай. ÐÑли .env Ñайл ÑÑÑеÑÑвÑÐµÑ â пÑоÑиÑай его. Ðе ÑпÑаÑивай знаÑÐµÐ½Ð¸Ñ Ð¿ÐµÑеменнÑÑ , коÑоÑÑе Ñже еÑÑÑ. СпÑаÑивай ÑолÑко оÑÑÑÑÑÑвÑÑÑие.
-
Ðе делай беÑконеÑнÑÑ Ñиклов ожиданиÑ. ÐакÑимÑм 5 попÑÑок поÑле наÑалÑного ожиданиÑ. ÐÑли ÑеÑÑÑÑ Ð½Ðµ гоÑов за ~3-4 минÑÑÑ â ÑообÑи полÑзоваÑелÑ. (ÐÐ¸Ð¼Ð¸Ñ Ð·Ð°ÑÐ¸Ñ Ð²
scripts/timeweb_api.py) -
ÐÑегда пÑовеÑÑй IPv4 Ñвно. Timeweb Cloud Ð¼Ð¾Ð¶ÐµÑ ÑоздаÑÑ ÑеÑÐ²ÐµÑ ÑолÑко Ñ IPv6. (ÐвÑомаÑиÑеÑÐºÐ°Ñ Ð¿ÑовеÑка заÑиÑа в
scripts/timeweb_api.py wait-server) -
ÐÑедпоÑиÑай Git над SCP. ÐÑли в пÑоекÑе наÑÑÑоен Git â иÑполÑзÑй
git cloneÐ´Ð»Ñ Ð·Ð°Ð³ÑÑзки на ÑеÑвеÑ, а неscp. -
ÐÐ ÐÐ ÐÐУСÐÐРШÐÐÐ. ÐаждÑй Ñаг из обÑзаÑелÑного ÑеклиÑÑа ниже должен бÑÑÑ Ð²Ñполнен или оÑознанно пÑопÑÑен по ÑеÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ.
-
РазлиÑай ÐÐÐÐÐЬÐЫРи СÐÐ ÐÐÐ ÐЫРопеÑаÑии. ÐÑÑ, ÑÑо ÑвÑзано Ñ Git (commit, push, Ñоздание Ñайлов пÑоекÑа) â делай ÐÐÐÐÐЬÐÐ. Ðа ÑдалÑннÑй ÑеÑÐ²ÐµÑ Ð¿Ð¾ SSH Ð·Ð°Ñ Ð¾Ð´Ð¸ ÑолÑко длÑ: ÑÑÑановки ÐÐ, запÑÑка пÑиложениÑ, наÑÑÑойки systemd/nginx/docker, генеÑаÑии deploy key. ÐÐÐÐÐÐРне Ñоздавай ÑÐ°Ð¹Ð»Ñ Ð¿ÑоекÑа на ÑдалÑнном ÑеÑвеÑе и не пÑÑайÑÑ Ð¿ÑÑиÑÑ Ð¾ÑÑÑда.
-
ÐÑовеÑÑй Git в наÑале. ÐеÑед деплоем опÑедели: иниÑиализиÑован ли Git? ÐÑÑÑ Ð»Ð¸ remote? Ðакой Ñ Ð¾ÑÑинг? ÐÑÑÑ Ð»Ð¸ незакоммиÑеннÑе изменениÑ? (ÐвÑомаÑиÑеÑки ÑеÑез
scripts/analyze_project.py) -
ÐÑли еÑÑÑ Ñокен â иÑполÑзÑй его по макÑимÑмÑ. ÐÑли полÑзоваÑÐµÐ»Ñ Ð´Ð°Ð» GitHub PAT â иÑполÑзÑй его Ð´Ð»Ñ ÐСÐÐ¥ опеÑаÑий Ñ GitHub API: добавление ÑекÑеÑов, Ñоздание deploy key, push. Ðе пÑоÑи полÑзоваÑÐµÐ»Ñ Ð´ÐµÐ»Ð°ÑÑ Ð²ÑÑÑнÑÑ Ñо, ÑÑо можеÑÑ Ð°Ð²ÑомаÑизиÑоваÑÑ. (ÐÑполÑзÑй
scripts/github_api.py) -
ÐезопаÑноÑÑÑ Ð¿Ñежде вÑего. ÐÐÐÐÐÐРне Ñоздавай пÑблиÑнÑе ÑепозиÑоÑии â ÑолÑко пÑиваÑнÑе. ÐеÑед пÑÑем в ÑÑÑеÑÑвÑÑÑий пÑблиÑнÑй ÑепозиÑоÑий â ÐÐЯÐÐТÐÐЬÐРпÑедÑпÑеди полÑзоваÑелÑ.
СиÑÑема оÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÑоÑÑоÑÐ½Ð¸Ñ (State-Ñайл)
РнаÑале Ð´ÐµÐ¿Ð»Ð¾Ñ Ñоздай deploy-state.md ÑеÑез ÑкÑипÑ. ÐбновлÑй поÑле ÐÐÐÐÐÐРзнаÑимого Ñага. ÐеÑеÑиÑÑвай пеÑед каждÑм ÑледÑÑÑим Ñагом.
# СоздаÑÑ state-Ñайл из ÑезÑлÑÑаÑов анализа пÑоекÑа
python3 scripts/deploy_state.py init --project-json '<JSON из analyze_project.py>'
# ÐбновиÑÑ Ð¿Ð¾Ð»Ðµ
python3 scripts/deploy_state.py update --key "СÑÑаÑегиÑ" --value "VPS"
# ÐÑмеÑиÑÑ Ñаг вÑполненнÑм
python3 scripts/deploy_state.py check --step "API-Ñокен"
# ÐÑмеÑиÑÑ Ñаг пÑопÑÑеннÑм
python3 scripts/deploy_state.py check --step "Ðомен" --skip
# ÐÑовеÑиÑÑ Ð½ÐµÐ·Ð°Ð²ÐµÑÑÑннÑе Ñаги пеÑед ÑиналÑной пÑовеÑкой
python3 scripts/deploy_state.py verify
ÐÑавила ÑабоÑÑ Ñо state-Ñайлом
- Создай в наÑале Ð´ÐµÐ¿Ð»Ð¾Ñ â ÑÑÐ°Ð·Ñ Ð¿Ð¾Ñле анализа пÑоекÑа
- ÐбновлÑй поÑле каждого Ñага â запиÑÑвай ÑезÑлÑÑаÑÑ (ID ÑеÑвеÑов, IP, ÑеÑениÑ)
- ÐеÑеÑиÑÑвай пеÑед новÑм Ñагом â оÑобенно еÑли конÑекÑÑ Ñже длиннÑй
- ÐÑовеÑÑй пеÑед завеÑÑением â
python3 scripts/deploy_state.py verify - ÐÐ¾Ð±Ð°Ð²Ñ Ð² .gitignore â ÑкÑÐ¸Ð¿Ñ Ð´ÐµÐ»Ð°ÐµÑ ÑÑо авÑомаÑиÑеÑки
- ÐÑнкÑÑ “Ðомен” и “CI/CD” наÑинаÑÑÑÑ ÐºÐ°Ðº “ÐРСÐÐ ÐШÐД â ÑÑ Ð½Ðµ можеÑÑ Ð¿Ð¾ÑÑавиÑÑ Ð¸Ð¼
[x], пока не ÑпÑоÑиÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑ
ÐбÑий алгоÑиÑм ÑабоÑÑ
0. СоздаÑÑ deploy-state.md, пÑовеÑиÑÑ Git
1. Ðнализ пÑоекÑа полÑзоваÑелÑ
2. ÐолÑÑение/пÑовеÑка API-Ñокена Timeweb Cloud
3. ÐÑовеÑка баланÑа аккаÑнÑа
4. ÐÑÐ±Ð¾Ñ ÑÑÑаÑегии Ð´ÐµÐ¿Ð»Ð¾Ñ (App Platform vs VPS)
5. ÐодгоÑовка пÑоекÑа (Docker, env, конÑиги)
6. Создание инÑÑаÑÑÑÑкÑÑÑÑ (ÑеÑвеÑ/пÑиложение, ÐÐ, S3)
7. Ðеплой пÑоекÑа
8. ÐаÑÑÑойка домена, DNS, SSL â ÐÐЯÐÐТÐÐЬÐРСÐÐ ÐСÐТЬ
9. ÐаÑÑÑойка CI/CD â ÐÐЯÐÐТÐÐЬÐРСÐÐ ÐСÐТЬ
10. ФиналÑÐ½Ð°Ñ Ð¿ÑовеÑка и вÑдаÑа ÑезÑлÑÑаÑов полÑзоваÑелÑ
ÐÐЯÐÐТÐÐЬÐЫРЧÐÐÐÐСТ â пÑойди ÐСРпÑнкÑÑ
ÐоÑле завеÑÑÐµÐ½Ð¸Ñ Ð´ÐµÐ¿Ð»Ð¾Ñ (Ñаг 7), но ÐÐ ÑиналÑной пÑовеÑки (Ñаг 10), ÑÑ ÐÐЯÐÐРпÑойÑи ÑÑÐ¾Ñ ÑеклиÑÑ. ÐаждÑй пÑÐ½ÐºÑ ÑÑебÑÐµÑ Ð»Ð¸Ð±Ð¾ дейÑÑвиÑ, либо Ñвного оÑвеÑа полÑзоваÑÐµÐ»Ñ “не нÑжно”. СвеÑÑйÑÑ Ñ deploy-state.md.
ЧÐÐÐÐСТ ÐÐСÐÐ ÐÐÐÐÐЯ:
â¡ Docker â СпÑоÑил полÑзоваÑелÑ? ÐÑли вÑбÑал Docker â наÑÑÑоил?
â¡ Ðомен â СпÑоÑил: "ÐÑÑÑ Ð»Ð¸ домен? ÐÑжен ли домен?"
â¡ ÐÑли еÑÑÑ Ð´Ð¾Ð¼ÐµÐ½ â наÑÑÑоил DNS-запиÑи
â¡ ÐÑли нÑжно кÑпиÑÑ â дал инÑÑÑÑкÑиÑ/ÑÑÑлкÑ
â¡ ÐÑли не нÑжен â заÑикÑиÑовал, ÑÑо ÑабоÑаем по IP
â¡ SSL â ÐÑли еÑÑÑ Ð´Ð¾Ð¼ÐµÐ½ â наÑÑÑоил Let's Encrypt (certbot)
â¡ CI/CD â СпÑоÑил: "ÐаÑÑÑоиÑÑ Ð°Ð²Ñодеплой?"
â¡ ÐÑли App Platform + авÑодеплой Ñже вклÑÑÑн â ÑообÑил "CI/CD Ñже ÑабоÑаеÑ", Actions ÐÐ ÐУÐÐЫ
â¡ ÐÑли App Platform + авÑодеплой вÑклÑÑен â пÑедложил ваÑианÑÑ (пÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ / Actions / вÑÑÑнÑÑ)
â¡ ÐÑли VPS + да â Ñоздал .github/workflows/deploy.yml ÐÐÐÐÐЬÐÐ
â¡ ÐÑли VPS + да â наÑÑÑоил GitHub Secrets ÑеÑез API (еÑли еÑÑÑ PAT)
â¡ ÐÑли Ð½ÐµÑ â заÑикÑиÑовал
â¡ deploy-state.md обновлÑн, вÑе пÑнкÑÑ Ð·Ð°ÐºÑÑÑÑ
â¡ ÐÑе пÑнкÑÑ Ð¿ÑÐ¾Ð¹Ð´ÐµÐ½Ñ â можно пеÑеÑ
одиÑÑ Ðº ÑиналÑной пÑовеÑке
ÐÐÐÐÐ: Ðе вÑводи ÑÑÐ¾Ñ ÑеклиÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑ. ÐÑо Ñвой внÑÑÑенний конÑÑолÑнÑй ÑпиÑок. ÐолÑзоваÑÐµÐ»Ñ Ð·Ð°Ð´Ð°Ð²Ð°Ð¹ вопÑоÑÑ Ð¿Ð¾ ÐºÐ°Ð¶Ð´Ð¾Ð¼Ñ Ð¿ÑнкÑÑ ÐµÑÑеÑÑвеннÑм ÑзÑком.
ÐоÑÑдок вопÑоÑов поÑле деплоÑ:
ÐоÑле Ñого как пÑиложение запÑÑено и ÑабоÑаеÑ, задай полÑзоваÑÐµÐ»Ñ 2 вопÑоÑа (можно в одном ÑообÑении):
ÐÑиложение запÑÑено и ÑабоÑÐ°ÐµÑ â
ÐÑÑалоÑÑ Ð´Ð²Ð° вопÑоÑа:
Ðомен: У ÑÐµÐ±Ñ ÐµÑÑÑ Ñвой домен Ð´Ð»Ñ Ð¿ÑоекÑа? ÐÑли да â ÑÐºÐ¸Ð½Ñ ÐµÐ³Ð¾, Ñ Ð½Ð°ÑÑÑÐ¾Ñ DNS и SSL. ÐÑли Ð½ÐµÑ â Ñ Ð¾ÑеÑÑ ÐºÑпиÑÑ ÑеÑез Timeweb или пока ÑабоÑаÑÑ Ð¿Ð¾ IP?
CI/CD: (ÑоÑмÑлиÑÑй в завиÑимоÑÑи Ð¾Ñ ÑÑÑаÑегии)
- ÐÑли App Platform и авÑодеплой вклÑÑÑн: «CI/CD Ñже ÑабоÑÐ°ÐµÑ â пÑи push в main App Platform авÑомаÑиÑеÑки пеÑеÑобеÑÑÑ Ð¿Ñиложение.»
- ÐÑли App Platform и авÑодеплой вÑклÑÑен: «ÐвÑодеплой не ÑабоÑаеÑ, поÑÐ¾Ð¼Ñ ÑÑо Ñепо подклÑÑÑн по URL. ÐÐ¾Ð³Ñ Ð½Ð°ÑÑÑоиÑÑ ÑеÑез GitHub Actions или помоÑÑ Ð¿ÐµÑеподклÑÑиÑÑ ÑеÑез пÑовайдеÑ. ЧÑо пÑедпоÑиÑаеÑÑ?»
- ÐÑли VPS: «ÐаÑÑÑоиÑÑ Ð°Ð²ÑомаÑиÑеÑкий деплой пÑи push в GitHub (GitHub Actions)? ÐÑи каждом push в main пÑÐ¾ÐµÐºÑ Ð±ÑÐ´ÐµÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÑÑÑÑÑ Ð½Ð° ÑеÑвеÑе авÑомаÑиÑеÑки.»
Шаг 1. Ðнализ пÑоекÑа
1.0. Ðнализ и Ñоздание state-Ñайла
# ÐвÑомаÑиÑеÑкий анализ пÑоекÑа
python3 scripts/analyze_project.py /path/to/project
# РезÑлÑÑÐ°Ñ â JSON Ñ Ð¿Ð¾Ð»Ñми: runtime, framework, app_type, port,
# databases, docker, env, git, commands, monorepo
Ðз ÑезÑлÑÑаÑа Ñоздай state-Ñайл:
python3 scripts/deploy_state.py init --project-json '<JSON>'
1.0.1. ÐÑли Git не иниÑиализиÑован или Ð½ÐµÑ remote
Git обÑзаÑелен ÑолÑко Ð´Ð»Ñ App Platform. ÐÐ»Ñ VPS можно деплоиÑÑ Ð±ÐµÐ· Git â ÑеÑез SCP (копиÑование Ñайлов напÑÑмÑÑ).
ÐÑли Git оÑÑÑÑÑÑвÑÐµÑ â ÑообÑи:
РпÑоекÑе не наÑÑÑоен Git-ÑепозиÑоÑий. ÐÑо не пÑоблема â еÑÑÑ Ð´Ð²Ð° ваÑианÑа:
A) СоздаÑÑ ÑепозиÑоÑий на GitHub â нÑжно Ð´Ð»Ñ App Platform и Ð´Ð»Ñ CI/CD (авÑодеплой пÑи push) B) ÐбойÑиÑÑ Ð±ÐµÐ· Git â загÑÑÐ¶Ñ ÑÐ°Ð¹Ð»Ñ Ð½Ð° ÑеÑÐ²ÐµÑ Ð½Ð°Ð¿ÑÑмÑÑ ÑеÑез SCP (ÑолÑко VPS, без CI/CD)
ÐÑли полÑзоваÑÐµÐ»Ñ Ð²ÑбÑал A:
# ÐСÐÐÐРпÑиваÑнÑй â безопаÑноÑÑÑ!
python3 scripts/github_api.py create-repo --name <repo-name>
ÐеÑед пÑÑем в СУЩÐСТÐУЮЩÐÐ ÑепозиÑоÑий â пÑовеÑÑ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑÑ:
python3 scripts/github_api.py check-visibility --owner <owner> --repo <repo>
ÐÑли пÑблиÑнÑй â ÐÐЯÐÐТÐÐЬÐРпÑедÑпÑеди:
â ï¸ Ðнимание: ÑепозиÑоÑий
<owner>/<repo>â пÑблиÑнÑй. ÐеÑÑ ÐºÐ¾Ð´ бÑÐ´ÐµÑ Ð²Ð¸Ð´ÐµÐ½ вÑем. УбедиÑÑ, ÑÑо в пÑоекÑе Ð½ÐµÑ ÑекÑеÑов. ÐÑодолжиÑÑ? (да/неÑ)
ÐÑли полÑзоваÑÐµÐ»Ñ Ð²ÑбÑал B: запомни в state-Ñайле, ÑÑо деплой ÑеÑез SCP. Ðа Ñаге 9 (CI/CD) ÑÑÑи, ÑÑо без Git авÑодеплой невозможен â пÑедÑпÑеди полÑзоваÑелÑ.
1.1. ÐоказаÑÑ ÐºÐ°ÑÑоÑÐºÑ Ð¿ÑоекÑа
ÐоÑле анализа покажи полÑзоваÑÐµÐ»Ñ ÐºÑаÑкÑÑ ÑÐ²Ð¾Ð´ÐºÑ Ð¸ попÑоÑи подÑвеÑдиÑÑ:
ð¦ Ðнализ пÑоекÑа:
⢠Тип: fullstack (React + Express)
⢠РанÑайм: Node.js 20
⢠ÐÐµÐ½ÐµÐ´Ð¶ÐµÑ Ð¿Ð°ÐºÐµÑов: pnpm
⢠ФÑеймвоÑк: React (ÑÑонÑ) + Express (бÑк)
⢠ÐÐ: PostgreSQL (ÑеÑез Prisma)
⢠Docker: оÑÑÑÑÑÑвÑÐµÑ (Ð½ÐµÑ .dockerignore)
⢠Env-пеÑеменнÑе: DATABASE_URL, JWT_SECRET, PORT
⢠ÐоÑÑ: 3000
⢠ÐиÑекÑоÑÐ¸Ñ ÑбоÑки: dist
ÐбÑзаÑелÑно поÑле поÑле подÑвеÑÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¾Ð±Ð½Ð¾Ð²Ð¸ deploy-state.md ÑеÑез ÑкÑипÑ.
Шаг 2. API-Ñокен Timeweb Cloud
СпÑоÑи полÑзоваÑÐµÐ»Ñ Ð¸ ÑÑÐ°Ð·Ñ Ð´Ð°Ð¹ инÑÑÑÑкÑÐ¸Ñ Ð¿Ð¾ полÑÑениÑ:
У ÑÐµÐ±Ñ Ñже еÑÑÑ Ð°ÐºÐºÐ°ÑÐ½Ñ Ð¸ API-Ñокен Timeweb Cloud? ÐÑли да â оÑпÑÐ°Ð²Ñ Ð¼Ð½Ðµ Ñокен, Ñ ÑÐ¾Ñ ÑÐ°Ð½Ñ ÐµÐ³Ð¾ Ð´Ð»Ñ ÑабоÑÑ.
ÐÑли Ð½ÐµÑ â полÑÑи его за 2 минÑÑÑ:
- ÐаÑегиÑÑÑиÑÑйÑÑ (еÑли Ð½ÐµÑ Ð°ÐºÐºÐ°ÑнÑа): https://timeweb.cloud/my
- ÐÑкÑой Ñаздел API и Terraform: https://timeweb.cloud/my/api-keys
- Ðажми «СоздаÑÑ» â имÑ:
deploy-botâ ÑÑок: «Ðез огÑаниÑений»- СкопиÑÑй Ñокен и оÑпÑÐ°Ð²Ñ Ð¼Ð½Ðµ
Ð¡Ð¾Ñ Ñани и пÑовеÑÑ:
mkdir -p ~/.config/timeweb
echo "TIMEWEB_CLOUD_TOKEN=<Ñокен>" > ~/.config/timeweb/.env
chmod 600 ~/.config/timeweb/.env
export TIMEWEB_CLOUD_TOKEN=<Ñокен>
python3 scripts/timeweb_api.py check-token
ÐбÑзаÑелÑно обнови deploy-state.md ÑеÑез ÑкÑипÑ.
Шаг 3. ÐÑовеÑка баланÑа
python3 scripts/timeweb_api.py balance
ÐÑли Ð±Ð°Ð»Ð°Ð½Ñ < 100 ÑÑб:
â ï¸ Ðа баланÑе {balance} ÑÑб. РекомендÑеÑÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм 100-200 ÑÑб. Ðополни: https://timeweb.cloud/my/billing
ÐбÑзаÑелÑно обнови deploy-state.md ÑеÑез ÑкÑипÑ.
Шаг 4. ÐÑÐ±Ð¾Ñ ÑÑÑаÑегии деплоÑ
ÐÑедложи полÑзоваÑÐµÐ»Ñ Ð²ÑÐ±Ð¾Ñ Ñ ÑекомендаÑией:
Ðакой ÑпоÑоб Ð´ÐµÐ¿Ð»Ð¾Ñ Ð¿ÑедпоÑиÑаеÑÑ?
A) App Platform â авÑодеплой из Git, вÑÑ Ð½Ð°ÑÑÑоено авÑомаÑиÑеÑки B) ÐблаÑнÑй ÑеÑÐ²ÐµÑ (VPS) â полнÑй конÑÑолÑ, наÑÑÑойка вÑÑÑнÑÑ
ÐÐ»Ñ Ñвоего пÑоекÑа Ñ ÑекомендÑÑ {ÑекомендаÑÐ¸Ñ Ð½Ð° оÑнове анализа}, поÑÐ¾Ð¼Ñ ÑÑо {пÑиÑина}.
ÐÑÑÑ A (App Platform) подÑ
одиÑ: пÑÐ¾ÐµÐºÑ Ð² GitHub/GitLab, ÑÑандаÑÑнÑй ÑÑеймвоÑк (Ñм. reference/presets-guide.md), не нÑжен root-доÑÑÑп.
â ï¸ App Platform ТРÐÐУÐТ Git-ÑепозиÑоÑий. ÐÑли полÑзоваÑÐµÐ»Ñ Ð²ÑбÑал App Platform, но пÑÐ¾ÐµÐºÑ Ð½Ðµ в Git â обÑÑÑни и ÑпÑоÑи ÑазÑеÑение:
App Platform ÑабоÑÐ°ÐµÑ ÑолÑко Ñ Git-ÑепозиÑоÑием â он беÑÑÑ ÐºÐ¾Ð´ оÑÑÑда и авÑомаÑиÑеÑки ÑобиÑÐ°ÐµÑ Ð¿ÑоекÑ. СейÑÐ°Ñ Ñ ÑÐµÐ±Ñ Ð½ÐµÑ ÑепозиÑоÑиÑ. ÐÐ¾Ð³Ñ ÑоздаÑÑ Ð¿ÑиваÑнÑй ÑепозиÑоÑий на GitHub и загÑÑзиÑÑ ÑÑда код. СоздаÑÑ?
ÐÑли полÑзоваÑÐµÐ»Ñ ÑоглаÑилÑÑ:
python3 scripts/github_api.py create-repo --name <repo-name>
git init && git remote add origin <url> && git add . && git commit -m "Initial commit" && git push -u origin main
ÐÑли оÑказалÑÑ â пÑедложи пеÑеклÑÑиÑÑÑÑ Ð½Ð° VPS (пÑÑÑ B), где Git не обÑзаÑелен. ТолÑко поÑле налиÑÐ¸Ñ ÑепозиÑоÑÐ¸Ñ Ð¿ÐµÑÐµÑ Ð¾Ð´Ð¸ к ÑÐ°Ð³Ñ 6A.
ÐÑÑÑ B (VPS) Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¸Ñ: нÑжен root, неÑÑандаÑÑÐ½Ð°Ñ ÐºÐ¾Ð½ÑигÑÑаÑиÑ, SQLite, Ð½ÐµÑ Git, fullstack-моноÑепо на одном ÑеÑвеÑе. Git не обÑзаÑелен â можно загÑÑзиÑÑ ÐºÐ¾Ð´ ÑеÑез SCP.
ÐбÑзаÑелÑно обнови deploy-state.md ÑеÑез ÑкÑипÑ.
Шаг 5. ÐодгоÑовка пÑоекÑа
5.1. Docker (еÑли Ð½ÐµÑ Dockerfile)
СпÑоÑи полÑзоваÑелÑ:
РпÑоекÑе Ð½ÐµÑ Dockerfile. Ðак Ñ Ð¾ÑеÑÑ Ð´ÐµÐ¿Ð»Ð¾Ð¸ÑÑ?
A) С Docker (ÑекомендÑÑ) â Ñ Ñоздам Dockerfile, окÑÑжение бÑÐ´ÐµÑ Ð²Ð¾ÑпÑоизводимÑм B) Ðез Docker â ÑиÑÑÐ°Ñ ÑÑÑановка: apt + venv/nvm + systemd/pm2 + nginx
ÐÑли вÑбÑал Docker â иÑполÑзÑй Ñаблон из templates/dockerfiles/, подÑÑавив поÑÑ Ð¸ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¿ÑоекÑа:
- Node.js backend â
templates/dockerfiles/node-backend.Dockerfile - Python FastAPI â
templates/dockerfiles/python-fastapi.Dockerfile - React/Vue/Svelte/Angular (ÑÑаÑика) â
templates/dockerfiles/react-nginx.Dockerfile - Go â
templates/dockerfiles/go.Dockerfile - PHP â
templates/dockerfiles/php-nginx.Dockerfile - Fullstack моноÑепо â
templates/dockerfiles/docker-compose.fullstack.yml
ÐодÑÑановка пеÑеменнÑÑ Ð² ÑаблонÑ:
- ÐеÑÑÐ¸Ñ ÑанÑайма (
${NODE_VERSION},${GO_VERSION},${PHP_VERSION}): изruntime_versionанализа, или деÑÐ¾Ð»Ñ (Node: 20, Go: 1.22, PHP: 8.3, Python: 3.12) - ÐÐµÐ½ÐµÐ´Ð¶ÐµÑ Ð¿Ð°ÐºÐµÑов (
${INSTALL_CMD}): изpackage_managerанализа:- npm â
npm ci - yarn â
yarn install --frozen-lockfile - pnpm â
pnpm install --frozen-lockfile - bun â
bun install --frozen-lockfile
- npm â
- ÐиÑекÑоÑÐ¸Ñ ÑбоÑки (
${BUILD_OUTPUT_DIR}): изbuild_output_dirанализа (Viteâdist, CRAâbuild, Next.jsâ.next, Gatsbyâpublic, и Ñ.д.) - ÐоÑÑ (
${PORT}): изportанализа
ÐÑли в пÑоекÑе Ð½ÐµÑ .dockerignore â Ñоздай из Ñаблона templates/dockerfiles/.dockerignore. ÐÑо ÐÐ ÐТÐЧÐСÐÐ ÐÐÐÐÐ: без .dockerignore в Docker-обÑаз попадÑÑ .env (ÑекÑеÑÑ!), node_modules, .git.
ÐÑли полÑзоваÑÐµÐ»Ñ Ð²ÑбÑал Docker â веÑÑ Ð´Ð°Ð»ÑнейÑий пайплайн ÐÐÐÐÐРиÑполÑзоваÑÑ Docker. Ðе пеÑеклÑÑайÑÑ Ð¼Ð¾Ð»Ñа на ваÑÐ¸Ð°Ð½Ñ Ð±ÐµÐ· Docker.
ÐÐÐÐÐ Ð´Ð»Ñ App Platform: Ð Dockerfile обÑзаÑелÑно EXPOSE <поÑÑ>.
ÐÐÐÐÐ Ð´Ð»Ñ fullstack на App Platform: App Platform не Ð¸Ð¼ÐµÐµÑ Ñипа fullstack. Fullstack-пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (Next.js, Nuxt.js, SvelteKit, Remix) деплоÑÑÑÑ ÐºÐ°Ðº Ñип backend.
5.2. ÐеÑеменнÑе окÑÑжениÑ
ÐаннÑе Ñже еÑÑÑ Ð² ÑезÑлÑÑаÑе analyze_project.py (поле env). ÐлгоÑиÑм:
- ÐÑли вÑе пеÑеменнÑе Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ñ â «ÐÑе env-пеÑеменнÑе из .env Ð¿Ð¾Ð´Ñ Ð²Ð°ÑÐµÐ½Ñ â »
- ÐÑли Ñего-Ñо не Ñ Ð²Ð°ÑÐ°ÐµÑ â ÑпÑоÑи ÑолÑко недоÑÑаÑÑие:
Ð .env найденÑ: â DATABASE_URL, â JWT_SECRET Ðе Ñ Ð²Ð°ÑаеÑ: â SMTP_HOST, â SMTP_PASSWORD â оÑпÑÐ°Ð²Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ Ñкажи, ÑÑо email не иÑполÑзÑеÑÑÑ.
ÐÐ»Ñ ÑекÑеÑов (JWT_SECRET и Ñ.п.) â пÑедложи ÑгенеÑиÑоваÑÑ: openssl rand -hex 32
ÐбÑзаÑелÑно обнови deploy-state.md ÑеÑез ÑкÑипÑ.
Шаг 6. Создание инÑÑаÑÑÑÑкÑÑÑÑ
ÐУТЬ A: App Platform
# ÐолÑÑиÑÑ Ð´Ð¾ÑÑÑпнÑе ÑÑеймвоÑки и пÑеÑеÑÑ
python3 scripts/timeweb_api.py app-frameworks
python3 scripts/timeweb_api.py app-presets
# СоздаÑÑ Ð¿Ñиложение
python3 scripts/timeweb_api.py create-app \
--name <имÑ> --type <backend|frontend> \
--preset <preset_id> --framework <framework_id> \
--repo-url <git-url> --branch main \
--env KEY1=val1 KEY2=val2 \
--build-cmd "npm run build" --run-cmd "npm start"
# ÐÑовеÑиÑÑ ÑÑаÑÑÑ / логи
python3 scripts/timeweb_api.py app-status --id <app_id>
python3 scripts/timeweb_api.py app-logs --id <app_id>
ÐÑенка ÑÑоимоÑÑи (пеÑед Ñозданием ÑеÑÑÑÑов)
ÐеÑед Ñозданием лÑбого ÑеÑÑÑÑа ÑообÑи полÑзоваÑÐµÐ»Ñ Ð¿ÑимеÑнÑÑ ÑÑоимоÑÑÑ:
Ð¡Ð¾Ð·Ð´Ð°Ñ ÑеÑÑÑÑÑ:
- СеÑÐ²ÐµÑ (пÑеÑÐµÑ X): ~Y ÑÑб/меÑ
- ÐÐ (пÑеÑÐµÑ X): ~Y ÑÑб/Ð¼ÐµÑ (еÑли нÑжна)
- ÐÑого: ~Z ÑÑб/меÑ
ÐÑодолжиÑÑ?
СÑоимоÑÑÑ Ð¿ÑеÑеÑов можно полÑÑиÑÑ Ð¸Ð· server-presets / app-presets / db-presets (Ð¿Ð¾Ð»Ñ price или price_monthly). Ðе Ñоздавай ÑеÑÑÑÑÑ Ð±ÐµÐ· подÑвеÑÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ.
ÐУТЬ B: ÐблаÑнÑй ÑеÑÐ²ÐµÑ (VPS)
# ÐÑбÑаÑÑ Ð¿ÑеÑÐµÑ Ð¸ ÐС (ÑекомендаÑии â Ñм. reference/presets-guide.md)
python3 scripts/timeweb_api.py server-presets
python3 scripts/timeweb_api.py os-images
# СоздаÑÑ SSH-клÑÑ
ssh-keygen -t ed25519 -f ~/.ssh/timeweb_deploy -N "" -q
python3 scripts/timeweb_api.py upload-ssh-key --name deploy-agent-key --pub-key-path ~/.ssh/timeweb_deploy.pub
# СоздаÑÑ ÑеÑвеÑ
python3 scripts/timeweb_api.py create-server --name <project>-server --preset <id> --os <id> --ssh-keys <key_id>
# ÐождаÑÑÑÑ Ð³Ð¾ÑовноÑÑи + авÑомаÑиÑеÑкое полÑÑение IPv4
python3 scripts/timeweb_api.py wait-server --id <server_id>
ÐезопаÑноÑÑÑ VPS (обÑзаÑелÑно)
СÑÐ°Ð·Ñ Ð¿Ð¾Ñле гоÑовноÑÑи ÑеÑвеÑа, пеÑед ÑÑÑановкой ÐÐ, вÑполни базовÑÑ Ð·Ð°ÑиÑÑ:
ssh -o StrictHostKeyChecking=no -i ~/.ssh/timeweb_deploy root@<IP> << 'SECURITY'
# СоздаÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ app (пÑиложение не должно ÑабоÑаÑÑ Ð¾Ñ root)
useradd -r -m -d /opt/app -s /bin/bash app
# Firewall â оÑкÑÑÑÑ ÑолÑко нÑжнÑе поÑÑÑ
apt-get install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp # SSH
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw --force enable
# ÐаÑиÑа Ð¾Ñ Ð±ÑÑÑÑоÑÑа SSH
apt-get install -y fail2ban
systemctl enable fail2ban
systemctl start fail2ban
SECURITY
ЧÑо Ð´ÐµÐ»Ð°ÐµÑ ÑÑа наÑÑÑойка (обÑÑÑни полÑзоваÑÐµÐ»Ñ ÑоÑно):
- СоздаÑÑÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑ
appâ пÑоÑеÑÑÑ Ð¿ÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (ÑеÑез systemdUser=app, PM2, Docker) запÑÑкаÑÑÑÑ Ð¾Ñ Ð½ÐµÐ³Ð¾, а не Ð¾Ñ root - ÐаÑÑÑаиваеÑÑÑ firewall (ufw) и заÑиÑа Ð¾Ñ Ð±ÑÑÑÑоÑÑа (fail2ban)
- SSH-подклÑÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑеÑвеÑом оÑÑаÑÑÑÑ Ð¾Ñ
rootâ ÑÑо Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ Ð´Ð»Ñ ÑÑÑановки ÐÐ, ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑеÑвиÑами, nginx и Ñ.д. ÐÑо ÑÑандаÑÑÐ½Ð°Ñ Ð¿ÑакÑика Ð´Ð»Ñ VPS-админиÑÑÑиÑованиÑ.
â ï¸ Ðе говоÑи полÑзоваÑÐµÐ»Ñ ÑÑÐ°Ð·Ñ Ð²Ñоде “Ð´ÐµÐ¿Ð»Ð¾Ñ Ð±ÐµÐ· root” или “ÑбÑал root”. ÐÑавилÑÐ½Ð°Ñ ÑоÑмÑлиÑовка: «ÐÑиложение бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð¾Ñ Ð½ÐµÐ¿ÑивилегиÑованного полÑзоваÑÐµÐ»Ñ app, а не Ð¾Ñ root â ÑÑо заÑиÑÐ°ÐµÑ ÑиÑÑÐµÐ¼Ñ Ð² ÑлÑÑае ÑÑзвимоÑÑи.»
ÐÐÐÐÐ: ÐÑе systemd-ÑеÑвиÑÑ Ð¸Ð· templates/systemd/ иÑполÑзÑÑÑ User=app. Ð¤Ð°Ð¹Ð»Ñ Ð² /opt/app Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿ÑинадлежаÑÑ app:app.
ÐодгоÑовка ÑеÑвеÑа ÑеÑез SSH
С Docker:
ssh -o StrictHostKeyChecking=no -i ~/.ssh/timeweb_deploy root@<IP> << 'SETUP'
apt-get update && apt-get upgrade -y
curl -fsSL https://get.docker.com | sh
apt-get install -y docker-compose-plugin nginx certbot python3-certbot-nginx
mkdir -p /opt/app
SETUP
Ðез Docker (Node.js):
ssh root@<IP> << 'SETUP'
apt-get update && apt-get upgrade -y
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm install ${NODE_VERSION:-20} && npm install -g pm2
apt-get install -y nginx certbot python3-certbot-nginx
mkdir -p /opt/app && chown app:app /opt/app
SETUP
Ðез Docker (Python):
ssh root@<IP> << 'SETUP'
apt-get update && apt-get upgrade -y
apt-get install -y python3 python3-pip python3-venv nginx certbot python3-certbot-nginx
mkdir -p /opt/app && chown app:app /opt/app
SETUP
Ðез Docker (Go):
ssh root@<IP> << 'SETUP'
apt-get update && apt-get upgrade -y
# УÑÑановиÑÑ Go
wget -q https://go.dev/dl/go${GO_VERSION:-1.22}.0.linux-amd64.tar.gz
tar -C /usr/local -xzf go*.tar.gz && rm go*.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
export PATH=$PATH:/usr/local/go/bin
apt-get install -y nginx certbot python3-certbot-nginx
mkdir -p /opt/app && chown app:app /opt/app
SETUP
Ðез Docker (PHP):
ssh root@<IP> << 'SETUP'
apt-get update && apt-get upgrade -y
apt-get install -y php${PHP_VERSION:-8.3}-fpm php${PHP_VERSION:-8.3}-cli php${PHP_VERSION:-8.3}-mbstring \
php${PHP_VERSION:-8.3}-xml php${PHP_VERSION:-8.3}-curl php${PHP_VERSION:-8.3}-mysql \
nginx certbot python3-certbot-nginx unzip
# Composer
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
mkdir -p /opt/app && chown app:app /opt/app
SETUP
ÐагÑÑзиÑÑ Ð¿ÑÐ¾ÐµÐºÑ Ð½Ð° ÑеÑвеÑ
ÐÑовеÑÑ state-Ñайл â еÑÑÑ Ð»Ð¸ Ñ Ð¿ÑоекÑа Git remote.
ÐÑли Git remote еÑÑÑ:
Ðак загÑÑзиÑÑ Ð¿ÑÐ¾ÐµÐºÑ Ð½Ð° ÑеÑвеÑ? A) ЧеÑез Git (ÑекомендÑÑ) â клониÑÑÑ ÑепозиÑоÑий. Удобнее Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¹ и CI/CD. B) ЧеÑез SCP â загÑÑÐ¶Ñ ÑÐ°Ð¹Ð»Ñ Ð½Ð°Ð¿ÑÑмÑÑ.
ÐÑли Git remote неÑ:
ÐÑÐ¾ÐµÐºÑ Ð½Ðµ пÑивÑзан к Git-ÑепозиÑоÑиÑ. ÐÑÑÑ Ð´Ð²Ð° ваÑианÑа: A) СоздаÑÑ ÑепозиÑоÑий на GitHub (ÑекомендÑÑ) â код бÑÐ´ÐµÑ Ð² Git, Ñдобнее обновлÑÑÑ, можно наÑÑÑоиÑÑ CI/CD. B) ÐагÑÑзиÑÑ ÑÐ°Ð¹Ð»Ñ ÑеÑез SCP â бÑÑÑÑее, но без Git не бÑÐ´ÐµÑ Ð°Ð²ÑодеплоÑ.
ÐÑли полÑзоваÑÐµÐ»Ñ Ð²ÑбÑал ÑоздаÑÑ Ñепо:
python3 scripts/github_api.py create-repo --name <repo-name>
# ÐаÑем локалÑно:
git init && git remote add origin <url> && git add . && git commit -m "Initial commit" && git push -u origin main
Git: ssh root@<IP> "cd /opt/app && git clone <repo-url> ."
SCP: scp -r -i ~/.ssh/timeweb_deploy /path/to/project/* root@<IP>:/opt/app/
ÐапÑÑÑиÑÑ Ð¿ÑоекÑ
С Docker: ssh root@<IP> "cd /opt/app && docker compose up -d --build"
Node.js + PM2: ssh root@<IP> "cd /opt/app && npm ci --production && npm run build && pm2 start dist/index.js --name app && pm2 save && pm2 startup"
Python + systemd: СкопиÑÑй Ñаблон templates/systemd/python-gunicorn.service в /etc/systemd/system/app.service, подÑÑавив поÑÑ. ÐаÑем:
ssh root@<IP> "cd /opt/app && python3 -m venv venv && source venv/bin/activate && pip install -r requirements.txt && pip install gunicorn && chown -R app:app /opt/app && systemctl daemon-reload && systemctl enable app && systemctl start app"
Go + systemd: СкомпилиÑÑй, ÑкопиÑÑй Ñаблон templates/systemd/go-app.service в /etc/systemd/system/app.service. ÐаÑем:
ssh root@<IP> "cd /opt/app && go build -o server . && chown -R app:app /opt/app && systemctl daemon-reload && systemctl enable app && systemctl start app"
PHP + nginx: ÐÐ»Ñ Laravel/Symfony иÑполÑзÑй PHP-FPM + nginx. СкопиÑÑй код, наÑÑÑой nginx:
ssh root@<IP> "cd /opt/app && composer install --no-dev --optimize-autoloader && chown -R www-data:www-data /opt/app/storage /opt/app/bootstrap/cache 2>/dev/null || true && systemctl restart php8.3-fpm && systemctl reload nginx"
ÐаÑÑÑоиÑÑ Nginx
ÐÑполÑзÑй Ñаблон из templates/nginx/reverse-proxy.conf, подÑÑавив домен/IP и поÑÑ. СкопиÑÑй на ÑеÑвеÑ:
ssh root@<IP> << 'NGINX'
cat > /etc/nginx/sites-available/app << 'CONF'
<ÑодеÑжимое Ñаблона Ñ Ð¿Ð¾Ð´ÑÑавленнÑми знаÑениÑми>
CONF
ln -sf /etc/nginx/sites-available/app /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx
NGINX
ÐбÑзаÑелÑно обнови deploy-state.md ÑеÑез ÑкÑипÑ.
Шаг 7. Создание Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ (еÑли ÑÑебÑеÑÑÑ)
- SQLite â не ÑÑебÑÐµÑ Ð¾ÑделÑной ÐÐ, ÑабоÑÐ°ÐµÑ Ð½Ð° диÑке (ÑолÑко VPS)
- PostgreSQL, MySQL, MongoDB, Redis â ÑпÑавлÑÐµÐ¼Ð°Ñ ÐÐ ÑеÑез API (ÑекомендÑеÑÑÑ) или на VPS
# ÐÑеÑеÑÑ Ð¸ Ñоздание ÑпÑавлÑемой ÐÐ
python3 scripts/timeweb_api.py db-presets
python3 scripts/timeweb_api.py create-db --name <project>-db --type <postgres|mysql|mongodb|redis> --preset <id>
ФоÑÐ¼Ð°Ñ DATABASE_URL â Ñм. reference/presets-guide.md.
ÐоÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐÐ â запÑÑÑи мигÑаÑии, еÑли еÑÑÑ (Prisma: npx prisma migrate deploy, Django: python manage.py migrate, Alembic: alembic upgrade head).
ÐбÑзаÑелÑно обнови deploy-state.md ÑеÑез ÑкÑипÑ.
Шаг 8. Ðомен, DNS, SSL
â ï¸ ÐÐЯÐÐТÐÐЬÐЫРШÐÐ â ÐÐ ÐÐ ÐÐУСÐÐÐ.
8.1. СпÑоÑиÑÑ Ð¿Ñо домен
Ðе ÐºÐ°Ð¶Ð´Ð¾Ð¼Ñ Ð¿ÑоекÑÑ Ð½Ñжен домен. ÐÑли ÑÑо бÑкенд-ÑеÑвиÑ, боÑ, демон, внÑÑÑенний API â домен Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½Ðµ нÑжен. УÑиÑÑвай Ñип пÑоекÑа пÑи ÑоÑмÑлиÑовке вопÑоÑа.
ÐÑли App Platform: Ñ Ð¿ÑоекÑа Ñже еÑÑÑ Ð±ÐµÑплаÑнÑй ÑеÑ
ниÑеÑкий домен (вида app-name.timeweb.cloud) Ñ SSL. СообÑи об ÑÑом:
Твой пÑÐ¾ÐµÐºÑ Ñже доÑÑÑпен по адÑеÑÑ
<ÑÐµÑ Ð½Ð¸ÑеÑкий_домен>Ñ SSL â ÑÑо беÑплаÑнÑй домен Ð¾Ñ App Platform. ХоÑеÑÑ Ð¿ÑивÑзаÑÑ Ñвой домен? ÐÑли Ð½ÐµÑ â можно оÑÑавиÑÑ ÐºÐ°Ðº еÑÑÑ.
ÐÑли VPS:
У ÑÐµÐ±Ñ ÐµÑÑÑ Ñвой домен Ð´Ð»Ñ ÑÑого пÑоекÑа? A) Ðа â ÑÐºÐ¸Ð½Ñ ÐµÐ³Ð¾, Ñ Ð½Ð°ÑÑÑÐ¾Ñ DNS и SSL B) ÐеÑ, Ñ Ð¾ÑÑ ÐºÑпиÑÑ â Ð¿Ð¾Ð¼Ð¾Ð³Ñ ÑеÑез Timeweb (Ð¾Ñ ~200 ÑÑб/год в зоне .ru) C) ÐеÑ, обойдÑÑÑ Ð±ÐµÐ· домена â ок, пÑÐ¾ÐµÐºÑ Ð´Ð¾ÑÑÑпен по IP
8.2. ÐÑивÑзка домена
# ÐобавиÑÑ Ð´Ð¾Ð¼ÐµÐ½ в Timeweb
python3 scripts/timeweb_api.py add-domain --fqdn <domain.com>
# DNS-запиÑи (VPS)
python3 scripts/timeweb_api.py add-dns --fqdn <domain.com> --subdomain @ --type A --value <IP>
python3 scripts/timeweb_api.py add-dns --fqdn <domain.com> --subdomain www --type A --value <IP>
ÐÑли домен не в Timeweb â Ñкажи ÑмениÑÑ NS-ÑеÑвеÑÑ:
Ðзмени NS Ñ ÑегиÑÑÑаÑоÑа на:
ns1.timeweb.ru,ns2.timeweb.ru,ns3.timeweb.cloud,ns4.timeweb.cloud
ÐлÑÑеÑнаÑива: полÑзоваÑÐµÐ»Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²ÑÑÑнÑÑ ÑоздаÑÑ A-запиÑÑ Ñ ÑекÑÑего ÑегиÑÑÑаÑоÑа.
8.3. ÐокÑпка домена
python3 scripts/timeweb_api.py check-domain --fqdn <domain.com>
ÐÑли API не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¿Ð¾ÐºÑÐ¿ÐºÑ â дай ÑÑÑлкÑ: https://timeweb.cloud/my/domains/order
8.4. SSL (VPS)
ssh root@<IP> "certbot --nginx -d <domain> -d www.<domain> --non-interactive --agree-tos -m <email>"
ssh root@<IP> 'echo "0 12 * * * /usr/bin/certbot renew --quiet" | crontab -'
App Platform вÑпÑÑÐºÐ°ÐµÑ SSL авÑомаÑиÑеÑки.
ÐбÑзаÑелÑно обнови deploy-state.md ÑеÑез ÑкÑипÑ.
Шаг 9. CI/CD
â ï¸ ÐÐЯÐÐТÐÐЬÐЫРШÐÐ â ÐÐ ÐÐ ÐÐУСÐÐÐ.
9.1. App Platform
ÐÑовеÑÑ Ð°Ð²Ñодеплой: python3 scripts/timeweb_api.py app-status --id <app_id> â поле is_auto_deploy.
- ÐÑли
trueâ «CI/CD Ñже ÑабоÑÐ°ÐµÑ Ð½Ð°Ñивно. GitHub Actions не нÑжнÑ.» - ÐÑли
falseâ пÑедложи: A) пеÑеподклÑÑиÑÑ ÑеÑез пÑовайдеÑ, B) GitHub Actions, C) оÑÑавиÑÑ ÐºÐ°Ðº еÑÑÑ. - ÐÐ»Ñ Ð²Ð°ÑианÑа B â иÑполÑзÑй Ñаблон
templates/workflows/app-platform.yml.
9.2. VPS
ÐаÑÑÑоиÑÑ Ð°Ð²ÑомаÑиÑеÑкий деплой пÑи push в GitHub (GitHub Actions)?
ÐÑли да â ÑкопиÑÑй подÑ
одÑÑий Ñаблон из templates/workflows/:
- Docker â
vps-docker.yml - Node.js + PM2 â
vps-node-pm2.yml - Python + systemd â
vps-python-systemd.yml - Go + systemd â
vps-go.yml - PHP + nginx â
vps-php.yml
Создай Ñайл ÐÐÐÐÐЬÐÐ:
mkdir -p .github/workflows
cp <Ñаблон> .github/workflows/deploy.yml
git add .github/workflows/deploy.yml
git commit -m "Add CI/CD: auto-deploy to Timeweb VPS on push"
git push origin main
9.3. Deploy key на ÑеÑвеÑе (Ð´Ð»Ñ git pull)
# СгенеÑиÑоваÑÑ ÐºÐ»ÑÑ ÐРСÐÐ ÐÐÐ Ð
ssh root@<IP> "ssh-keygen -t ed25519 -f /root/.ssh/github_deploy -N '' -q"
DEPLOY_PUB_KEY=$(ssh root@<IP> "cat /root/.ssh/github_deploy.pub")
# ÐаÑÑÑоиÑÑ SSH-конÑиг
ssh root@<IP> << 'SSHCONF'
cat >> /root/.ssh/config << 'EOF'
Host github.com
IdentityFile /root/.ssh/github_deploy
StrictHostKeyChecking no
EOF
chmod 600 /root/.ssh/config
SSHCONF
# ÐеÑеклÑÑиÑÑ remote на SSH
ssh root@<IP> "cd /opt/app && git remote set-url origin git@github.com:<user>/<repo>.git"
ÐÑли еÑÑÑ GitHub PAT â Ð´Ð¾Ð±Ð°Ð²Ñ deploy key авÑомаÑиÑеÑки:
python3 scripts/github_api.py add-deploy-key --owner <owner> --repo <repo> --pub-key-path /tmp/deploy_pub_key
ÐÑли Ð½ÐµÑ PAT â дай инÑÑÑÑкÑиÑ:
ÐÐ¾Ð±Ð°Ð²Ñ deploy key:
https://github.com/<user>/<repo>/settings/keys/newTitle:timeweb-server, Key:<клÑÑ>, Allow write access: ÐРнÑжно
9.4. GitHub Secrets
ÐÑли еÑÑÑ PAT â Ð´Ð¾Ð±Ð°Ð²Ñ Ð°Ð²ÑомаÑиÑеÑки:
python3 scripts/github_api.py set-all-secrets --owner <owner> --repo <repo> \
--secrets '{"SERVER_IP": "<IP>", "SSH_PRIVATE_KEY": "<ÑодеÑжимое ~/.ssh/timeweb_deploy>"}'
ÐÑли Ð½ÐµÑ PAT â дай инÑÑÑÑкÑиÑ:
ÐÐ¾Ð±Ð°Ð²Ñ ÑекÑеÑÑ: Settings â Secrets â Actions â New:
SERVER_IPâ<IP>SSH_PRIVATE_KEYâ ÑодеÑжимое~/.ssh/timeweb_deploy
9.5. ÐапÑÐ¾Ñ GitHub PAT (еÑли нÑжен)
ÐÐ»Ñ Ð°Ð²ÑомаÑиÑеÑкой наÑÑÑойки CI/CD нÑжен GitHub PAT Ñ Ð¿Ñавами
repoиadmin:repo_hook. Создай: https://github.com/settings/tokens/new â Scopes:repo, Expiration: 30 days ÐÑпÑÐ°Ð²Ñ Ñокен, и Ñ Ð½Ð°ÑÑÑÐ¾Ñ Ð²ÑÑ Ð°Ð²ÑомаÑиÑеÑки. Ðли Ñкажи “вÑÑÑнÑÑ”.
СоÑ
Ñани: echo "$GITHUB_PAT" > ~/.config/timeweb/.github_pat && chmod 600 ~/.config/timeweb/.github_pat
ÐбÑзаÑелÑно обнови deploy-state.md ÑеÑез ÑкÑипÑ.
Шаг 10. ФиналÑÐ½Ð°Ñ Ð¿ÑовеÑка
â ï¸ ÐÐЯÐÐТÐÐЬÐЫРШÐÐ â ÐÐ ÐÐ ÐÐУСÐÐÐ.
10.0. СамопÑовеÑка
python3 scripts/deploy_state.py verify
ÐÑли еÑÑÑ Ð½ÐµÐ·Ð°Ð²ÐµÑÑÑннÑе Ñаги â вÑполни Ð¸Ñ Ð¡ÐÐЧÐС.
10.1. ÐÑовеÑка доÑÑÑпноÑÑи
curl -s -o /dev/null -w "%{http_code}" http://<домен_или_IP>
10.2. ÐÑÐ¾Ð³Ð¾Ð²Ð°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ
Ðокажи ÐСЮ инÑоÑмаÑиÑ, коÑоÑÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ ÑÑÐ¾Ð¸Ñ ÑÐ¾Ñ ÑаниÑÑ. ÐклÑÑай ÑолÑко ÑелеванÑнÑе блоки (напÑимеÑ, блок ÐÐ â ÑолÑко еÑли ÑоздавалаÑÑ ÐÐ, блок CI/CD â ÑолÑко еÑли наÑÑÑаивалÑÑ).
â
Ðеплой ÑÑпеÑно завеÑÑÑн!
ð ÐоÑÑÑп к пÑоекÑÑ:
URL: https://<домен> (или http://<IP>:<поÑÑ>)
ð¥ СеÑвеÑ: â ÑолÑко Ð´Ð»Ñ VPS
IP: <IP>
ID: <server_id>
ÐанелÑ: https://timeweb.cloud/my/servers/<server_id>
SSH: ssh -i <пÑÑÑ_к_клÑÑÑ> root@<IP>
ÐÑÐ¾ÐµÐºÑ Ð½Ð° ÑеÑвеÑе: /opt/app
ð Ðаза даннÑÑ
: â ÑолÑко еÑли ÑоздавалаÑÑ
Тип: <PostgreSQL/MySQL/...>
ХоÑÑ: <host>:<port>
Ðогин: <login>
ÐаÑолÑ: <password>
DATABASE_URL: <полнÑй_connection_string>
ð CI/CD: â ÑолÑко еÑли наÑÑÑаивалÑÑ
Файл: .github/workflows/deploy.yml
ТÑиггеÑ: авÑодеплой пÑи push в main
ð Ð¢Ð¾ÐºÐµÐ½Ñ Ð¸ клÑÑи (ÑоÑ
Ñани!):
Timeweb API: ~/.config/timeweb/.env
SSH-клÑÑ: <пÑÑÑ> (напÑÐ¸Ð¼ÐµÑ ~/.ssh/timeweb_deploy)
GitHub PAT: ~/.config/timeweb/.github_pat â ÑолÑко еÑли иÑполÑзовалÑÑ
ð ÐолезнÑе командÑ:
ÐодклÑÑиÑÑÑÑ: ssh -i <пÑÑÑ_к_клÑÑÑ> root@<IP>
Ðоги: ssh root@<IP> "<docker compose logs -f | pm2 logs | journalctl -u app -f>"
ÐеÑезапÑÑк: ssh root@<IP> "<docker compose restart | pm2 restart app | systemctl restart app>"
ÐбновиÑÑ ÐºÐ¾Ð´: ssh root@<IP> "cd /opt/app && git pull"
ÐоÑле вÑвода Ñводки ÑпÑоÑи:
Ð¡Ð¾Ñ ÑаниÑÑ ÑÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð² Ñайл? ÐаÑÐ¾Ð»Ñ ÐРи SSH-клÑÑ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ воÑÑÑановиÑÑ, ÑолÑко пеÑеÑоздаÑÑ.
ÐÑли полÑзоваÑÐµÐ»Ñ ÑоглаÑилÑÑ â ÑоÑ
Ñани ÑÐ²Ð¾Ð´ÐºÑ Ð² DEPLOY.md в коÑне пÑоекÑа, Ð´Ð¾Ð±Ð°Ð²Ñ Ð² .gitignore (Ñайл ÑодеÑÐ¶Ð¸Ñ ÑекÑеÑÑ!) и ÑообÑи пÑÑÑ:
Ð¡Ð¾Ñ Ñанено в
DEPLOY.md. Файл добавлен в.gitignore, ÑÑÐ¾Ð±Ñ ÑекÑеÑÑ Ð½Ðµ попали в ÑепозиÑоÑий.
ÐбÑабоÑка оÑибок
См. reference/errors.md â ÑаблиÑÑ Ð¾Ñибок API и деплоÑ, инÑÑÑÑкÑии по оÑкаÑÑ.
ÐгÑаниÑениÑ
- РегиÑÑÑаÑÐ¸Ñ â невозможна ÑеÑез API, ÑолÑко ÑеÑез ÑайÑ
- ÐплаÑа â Ñоздание ÑеÑÑÑÑов ÑпиÑÑÐ²Ð°ÐµÑ ÑÑедÑÑва. ÐÑегда показÑвай ÑÑоимоÑÑÑ Ð¿ÐµÑед Ñозданием (Ñм. “ÐÑенка ÑÑоимоÑÑи”)
- Rate limiting â не более 20 запÑоÑов/Ñек. ÐобавлÑй
sleep 1Ð¼ÐµÐ¶Ð´Ñ Ð¼Ð°ÑÑовÑми опеÑаÑиÑми. ÐÑи 429 â ÑкÑÐ¸Ð¿Ñ Ð°Ð²ÑомаÑиÑеÑки повÑоÑÐ¸Ñ ÑеÑез 5 Ñек (до 3 Ñаз) - API обновлÑеÑÑÑ â пÑи оÑибке пÑовеÑÑ Ð´Ð¾ÐºÑменÑаÑÐ¸Ñ (Ñм.
reference/api-endpoints.md) - Ðез Kubernetes и баланÑиÑовÑиков â Ñкилл Ð´Ð»Ñ Ð¿ÑоÑÑÑÑ Ð¿ÑоекÑов
- SSH â ÑолÑко Ð´Ð»Ñ VPS, не Ð´Ð»Ñ App Platform
- ÐеÑÑиÑÑенÑноÑÑÑ App Platform â даннÑе не ÑÐ¾Ñ ÑанÑÑÑÑÑ Ð¼ÐµÐ¶Ð´Ñ Ð´ÐµÐ¿Ð»Ð¾Ñми, иÑполÑзÑй S3 или ÐÐ
- ÐоноÑепозиÑоÑии â Ð´Ð»Ñ App Platform Ñкажи пÑÑÑ Ðº подпÑоекÑÑ; Ð´Ð»Ñ VPS â Docker Compose
- Bun/Deno â опÑеделÑÑÑÑÑ Ð°Ð½Ð°Ð»Ð¸Ð·Ð°ÑоÑом, но App Platform не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¸Ñ Ð½Ð°Ñивно. Ðеплой ÑолÑко ÑеÑез Dockerfile
- Fullstack на App Platform â Ñип
fullstackне ÑÑÑеÑÑвÑÐµÑ Ð² API. ÐÑполÑзÑйbackend(ÑкÑÐ¸Ð¿Ñ ÐºÐ¾Ð½Ð²ÐµÑÑиÑÑÐµÑ Ð°Ð²ÑомаÑиÑеÑки)