name: deploy-server
description: Use this skill to provision or update a Welley server on a supported cloud (currently DigitalOcean) when the user asks to deploy a new instance or run a server update. Covers single-instance deployments and SSH-based updates, including interactive collection of missing credentials, SSH keys, domain, region, and sizing.
Розгортання сервера
Огляд
Ця навичка розгортає на DigitalOcean стек Welley з одним інстансом і може запускати оновлення через SSH. Вона підказує агенту, як зібрати відсутні дані, отримати доступні характеристики інстансів із визначеного джерела, створити віртуальну машину, налаштувати хост, розгорнути Welley командою wlycli deployment create і перевірити результат.
Назви команд мають збігатися з CLI:
wlycli deployment createwlycli deployment updatewlycli deployment delete
Типові значення (DigitalOcean)
- Регіон:
nyc3 - Образ:
latest LTS available via API(визначається черезimages?type=distribution) - Назва дроплета: випадково згенерована у форматі
wlsly-<adjective>-<surname>(наприклад,wlsly-bright-hopper). Скористайтеся фрагментом генератора назв ізreferences/digitalocean.md. Якщо створюється керована база даних, використайте ту саму назву. - Цільовий тариф: Basic / Regular (Shared CPU)
- Цільовий розмір: 2 vCPU / 4 GB RAM / 80 GB SSD / 4 TB трафіку (~$24/міс)
Правило зміни типових значень
Якщо користувач указує будь-яке з типових значень (регіон, образ, назва дроплета, проєкт, розмір), агент повинен:
- Дослівно повторити змінене значення.
- Попросити підтвердження, перш ніж продовжувати.
Шаблон інтерактивного введення
Запитуйте лише про те, чого бракує. Використовуйте саме ці формулювання, щоб уникнути двозначності. Запитуйте по колах. Коло 1: не більше 2 запитань за раз. У колі 2 можна запропонувати єдиний варіант «прийняти всі типові значення». Якщо середовище виконання підтримує вибір, пропонуйте 2 або 3 варіанти на запитання (A/B/C). Уникайте вільної форми, якщо вона не потрібна.
Запитання кола 1 (акаунт і доступ):
- «Чи є у вас токен DigitalOcean API, або мені зачекати, поки ви його надасте?»
- «Який домен має використовувати цей сервер (наприклад,
super-puper.example.com)? Чи керуєте ви його DNS?» - «Чи є у вас публічний SSH-ключ, який можна використати, або мені створити й завантажити новий?»
- «Чи хочете ви додати цей дроплет до наявного проєкту DigitalOcean? Якщо так, вкажіть назву або ID проєкту.»
- «Вимога до DNS: потрібно створити записи A/AAAA для
<domain>іstorage.<domain>(якщо немає CDN). Чи можете ви зробити це до запуску certbot?» - «Вимога до DNS для пошти: для домену з
--smtp-fromпотрібні записи SPF, DMARC і DKIM, інакше листи із запрошеннями та підтвердженнями для нових одержувачів можуть мовчки відкидатися. Вони вже налаштовані, чи показати вам записи, які потрібні вашому SMTP-провайдеру?» - Якщо користувач питає, де взяти токен DO, дайте це посилання:
https://cloud.digitalocean.com/account/api/tokens
Запитання кола 2 (розмір, розташування та параметри розгортання):
- «Вам підійде типовий регіон
nyc3чи потрібен інший?» - «Вам підійде типовий розмір (2 vCPU / 2 GB) чи потрібні інші параметри CPU/RAM?»
- «Використати останню LTS-версію Ubuntu, доступну в API, чи якусь конкретну версію Ubuntu?»
- «Якого користувача SSH використовувати після початкового налаштування (типово:
wlsly)? Можна залишити типового.» - «Вам потрібна керована база Postgres чи використати Postgres із комплектного контейнера?»
- Якщо обрано керований Postgres: «Який регіон і розмір бази використати? Можу типово взяти
nyc3і 1 vCPU / 2 GB.» - Якщо обрано керований Postgres: «Чи продовжувати створення за місячною ціною, яку вказує провайдер?»
- «Вкажіть обов'язкові налаштування SMTP (host, user, password, from). OTEL необов'язковий, указуйте його лише за потреби.»
- «Для створення потрібна електронна адреса адміністратора. Вкажіть її зараз (прапорець:
--email/-e). Якщо ви її не вкажете, я попрошу ввести її двічі для підтвердження.»
Запропонуйте в колі 2 варіант «прийняти всі типові значення», щоб пришвидшити збір даних.
Якщо якоїсь відповіді бракує, поставте цільове уточнювальне запитання (одне або два).
Порядок дій (DigitalOcean, один інстанс)
- Зберіть потрібні дані (запитайте, якщо чогось бракує).
- Токен DigitalOcean API
- Назва або ID проєкту (необов'язково; якщо не вказано або не знайдено, використайте типовий проєкт)
- Регіон
- Цільовий розмір інстансу (наприклад, 4 vCPU / 16 GB RAM)
- Доменне ім'я
- Публічний SSH-ключ (або згода створити й зареєструвати його)
- Електронна адреса адміністратора для першого входу та відновлення пароля (обов'язкова для створення;
--email/-e). Якщо її немає, попросіть ввести двічі й переконайтеся, що вони збігаються. - Необов'язково: власні TLS-сертифікати чи certbot
- Підтвердження доступу до DNS (потрібно мати змогу створити записи A/AAAA для
<domain>і, якщо використовується, дляstorage.<domain>)
- Отримайте типи інстансів і виберіть розмір.
- Використайте фрагмент для розмірів із
references/digitalocean.md, щоб отримати список і відфільтрувати його за CPU/RAM. - Якщо збігів кілька, уточніть у користувача.
2b. Визначте slug образу Ubuntu.
- Викличте
GET /v2/images?type=distribution&per_page=200і відфільтруйте Ubuntu. - Якщо користувач просив конкретну версію, переконайтеся, що її slug існує, і підтвердіть вибір.
- Інакше виберіть зі списку slug останньої LTS-версії та підтвердьте його з користувачем перед створенням.
- Створіть дроплет.
- Використовуйте DigitalOcean API напряму (doctl необов'язковий).
- Образ: віддавайте перевагу вказаному користувачем; інакше виберіть останню LTS зі списку API.
- Додайте відбиток SSH-ключа або створіть і завантажте ключ.
- Увімкніть моніторинг.
- Якщо назву або ID проєкту вказано, але не знайдено, створіть дроплет без проєкту (у типовому проєкті).
- Примітка: керовану базу даних можна створювати паралельно зі створенням дроплета.
Паралельне виконання
Агент має поєднувати незалежні завдання, щоб скоротити загальний час виконання:
- Поки збираєте дані від користувача (коло 2), починайте створювати дроплет, якщо токен, регіон, розмір, образ і SSH-ключ уже підтверджені.
- Поки дроплет розгортається, починайте створювати керований Postgres (якщо його просили).
- Поки дроплет запускається, продовжуйте збирати решту даних (SMTP, OTEL, електронна адреса адміністратора).
- Якщо для кроку бракує важливих даних, призупиніть цей крок і продовжуйте інші завдання, які можна виконувати паралельно.
- Якщо DNS керується в DigitalOcean, створіть або оновіть записи A/AAAA, щойно стане відома IP-адреса дроплета (не чекайте кроку повного розгортання).
- DNS і домен.
- Запитайте, чи створювати або оновлювати DNS у DigitalOcean, чи залишити зовнішній DNS.
- Якщо використовується DNS DigitalOcean, створіть записи A/AAAA з IP-адресою дроплета.
- Налаштуйте хост через SSH.
- Створіть користувача без прав root (наприклад,
wlsly), надайте йому sudo і скопіюйте авторизовані SSH-ключі. - Вийдіть із root і знову увійдіть як цей користувач, перш ніж продовжувати.
- Встановіть Docker і docker compose.
- Завантажте бінарний файл Welley CLI з AppStore і зробіть його виконуваним:
- Базова URL-адреса:
https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?develop=stable&platform=<os>/<arch> - Виберіть правильне значення
platformза ОС і архітектурою:- Linux x86_64:
linux/amd64 - Linux arm64:
linux/arm64 - macOS x86_64:
darwin/amd64 - macOS arm64:
darwin/arm64 - Windows x86_64:
windows/amd64
- Linux x86_64:
- Приклад (Linux x86_64):
curl -fL 'https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?develop=stable&platform=linux/amd64' -o wlycli chmod +x wlycli - Очікувані заголовки відповіді містять:
x-artifact-display-name: Welley CLIx-artifact-full-name: social.wellesley.wlyclix-artifact-kind: clix-artifact-platform: <os>/<arch>, наприкладlinux/amd64x-artifact-sha256: <sha256>x-artifact-version: <version>x-channel: develop
- Перш ніж встановлювати, краще перевірити заголовки запитом HEAD і переконатися, що назва артефакту, тип, платформа та канал збігаються із запитаним бінарним файлом.
- Базова URL-адреса:
- Перевірте бінарний файл CLI: виконайте
wlycli -vіwlycli deployment --help, щоб переконатися, що збірка очікувана.
- Розгорніть Welley.
- Виконайте
wlycli deployment createз потрібними параметрами. - Використовуйте типові налаштування для одного інстансу (без зовнішнього Postgres, якщо користувач не просить).
- Якщо потрібен керований Postgres, спершу створіть його (база DigitalOcean), а потім використайте повернені host/port/db/user/password у прапорцях
--postgres-*. - Якщо API чи інтерфейс не повертає пароль користувача бази, скиньте автентифікацію користувача бази, щоб отримати нові облікові дані, перш ніж запускати
wlycli. - Неінтерактивні запуски мають передавати
--email/-e, інакше команда завершиться помилкою. --base-dirуказує на батьківський каталог; CLI сам створює підкаталог проєкту.- CLI відмовляється працювати, якщо каталог проєкту або контейнери вже існують; перед повторною спробою потрібне очищення.
- Сертифікати (обов'язково).
- Типово: використовуйте Certbot у режимі standalone (неінтерактивно).
- Користувач має спрямувати записи DNS A/AAAA для домену (і для
storage.<domain>, якщо він використовується) на IP дроплета до запуску certbot. - CLI підтримує
--public-ip(перевизначити виявлену IP-адресу) і--skip-dns-preflight, якщо потрібно обійти перевірку. - Ніколи не вважайте, що DNS налаштовано. Запитайте й дочекайтеся явного підтвердження.
- Ніколи не використовуйте
--skip-dns-preflight, якщо користувач прямо цього не просить. - Якщо CDN не налаштовано, запит сертифіката certbot має містити
storage.<domain>. - Використовуйте самопідписані сертифікати, лише якщо користувач прямо про це просить, і передайте
--self-signed-certs(генерує самопідписані сертифікати на Go). - Надайте користувачу інструкції з налаштування DNS і дочекайтеся підтвердження:
- «Створіть записи A/AAAA, щоб
<domain>вказував на IP дроплета.» - «Якщо використовується
storage.<domain>, створіть запис A/AAAA і для нього.» - «Коли DNS оновиться, повідомте мені, і я продовжу. Я не бачу, чи поширився DNS, поки ви не попросите мене перевірити розв'язання імені.»
- Агент може сам перевірити поширення DNS командою
ping -c 1 <domain>і порівняти IP з IP дроплета. Якщо вони збігаються, продовжуйте.
7b. DNS для пошти (SPF / DMARC / DKIM).
- Лист із домену без SPF і DMARC часто відкидають Gmail та Outlook для нових одержувачів, навіть якщо SMTP-провайдер повідомляє, що його доставлено.
deployment createвиводитьWarning:, якщо для домену з--smtp-fromнемає запису SPF або немає запису DMARC у_dmarc.<domain>чи в батьківському домені. Це не блокує розгортання. Ніколи не ігноруйте попередження: покажіть його користувачу й дайте записи, які треба додати:<mail-domain>TXTv=spf1 include:<provider> ~all(точне значення include надає SMTP-провайдер; додайте його до наявного запису SPF, ніколи не створюйте другий)_dmarc.<mail-domain>TXTv=DMARC1; p=none; rua=mailto:dmarc@<mail-domain>- DKIM: записи
<selector>._domainkey.<mail-domain>, які SMTP-провайдер генерує під час перевірки домену
- Перевірте командами
dig +short TXT <mail-domain>іdig +short TXT _dmarc.<mail-domain>. - CLI не може перевірити DKIM (селектор залежить від провайдера). Завжди просіть користувача підтвердити, що DKIM перевірено в SMTP-провайдера, навіть якщо
createне вивів попередження. В Amazon SES та подібних провайдерів SPF перевіряється для власного домену конверта провайдера, тож пройти DMARC допоможе лише DKIM. В SES: розділ Verified identities, далі<mail-domain>, далі DKIM. Там має бути статус Successful.
- Перевірте й повідомте про результат.
- Перевірте
docker psі кінцеві точки стану сервісів. - Надайте остаточні дані для підключення та наступні кроки.
Оновлення через SSH
Коли користувач просить «оновити сервер»:
- Запитайте адресу чи IP цільового хоста, а також користувача й ключ SSH.
- Виконайте
wlycli deployment update --domain <domain> [--force-restart]. - Перевірте стан контейнерів і Nginx.
Ресурси
- Фрагменти та приклади DigitalOcean API:
references/digitalocean.md.
Секрети й прапорці
Використовуйте ці назви прапорців для секретів:
- Хост SMTP:
--smtp-host - Користувач SMTP:
--smtp-user - Пароль SMTP:
--smtp-password - Адреса відправника SMTP:
--smtp-from - Кінцева точка OTEL:
--otel-endpoint - Заголовки OTEL:
--otel-headers
Мінімальна команда створення
Обов'язкові прапорці:
--domain--email--smtp-host--smtp-user--smtp-password--smtp-from
Мінімальний приклад:
wlycli deployment create \
--domain example.com \
--email admin@example.com \
--smtp-host smtp.example.com \
--smtp-user user \
--smtp-password pass \
--smtp-from noreply@example.com
Типові значення керованого Postgres (DigitalOcean і CLI)
Якщо ви використовуєте керований Postgres від DigitalOcean, не покладайтеся на типові значення CLI. Явно задайте всі прапорці --postgres-*:
- Типові значення DO:
- Порт:
25060 - База даних:
defaultdb - Користувач:
doadmin
- Порт:
- Типові значення CLI (якщо пропустити прапорці):
- Порт:
5432 - База даних:
wlsly - Користувач:
wlsly
- Порт:
Нотатки щодо використання CLI
- Перевірка версії:
wlycli -vабоwlycli --version(прапорець). Підкомандиversionнемає. - Використовуйте
--base-dirлише якщо потрібне нетипове розташування (типово~/.welley). CLI створить каталог, якщо матиме дозвіл. - Неінтерактивні запуски через SSH мають містити
--emailі всі потрібні прапорці, щоб уникнути запитів. - Якщо користувач надає бінарний файл CLI на сервері (наприклад,
~/wcli), використовуйте його напряму. Не переміщуйте його, якщо не просять. - Копіюйте фрагменти дослівно із
references/digitalocean.mdдля всіх викликів DO API. Не переписуйте, не адаптуйте й не імпровізуйте розбір у Python: навіть невеликі зміни (наприклад, екранування чи лапки) можуть ламатися в різних оболонках. - Віддалені скрипти SSH: завжди використовуйте
ssh host 'bash -s' << 'EOF'(heredoc у лапках). Ніколи не використовуйтеssh host "..."з подвійними лапками: zsh розкриває$(...)і[...]локально, до надсилання на віддалений хост.
Відновлення після збою
Якщо deployment create завершується помилкою і потрібна повторна спроба:
- Скористайтеся
wlycli deployment delete --domain <domain> --yes-please-delete-all-the-data, щоб очистити залишки. - Команда delete спробує очистити файли, що належать root, через контейнер. Якщо це все одно не вдасться, видаліть каталог проєкту в
--base-dirз підвищеними правами й запустіть команду знову.
Попередня перевірка порту 80 (необов'язково)
Якщо certbot завершується помилкою, перед повторним запуском перевірте доступність порту 80:
docker run --rm -d -p 80:80 --name test-http nginx:alpine
curl -s http://<domain>:80
docker rm -f test-http