Piku — минималистичная платформа, превращающая git push в деплой на своём сервере. Проект под лицензией MIT, не требует Docker и работает на слабых машинах: автор начинал с Raspberry Pi. Внутри — Python, nginx и uWSGI: знакомый стек. Для небольшого VPS это типичный сценарий. Ниже — установка, деплой, домен, диагностика и откат.
Как работает piku
Вы добавляете Git-remote на сервер и отправляете ветку. Piku принимает push по SSH, раскладывает код в каталог приложения и запускает процесс. Сборки образа и реестра нет: зависимости ставятся на месте, а изоляция ограничена каталогом и системным пользователем.
Piku определяет runtime по файлам проекта: для Python создаётся virtualenv, для Node ставится node_modules, для Go задаётся GOPATH, для Java используются Maven или Gradle. Затем читается Procfile: типы wsgi, web, worker, static, cron, release и preflight описывают запуск. Супервизор — uWSGI, nginx проксирует запросы на сокет или порт.
Настройки хранятся в ENV и в переменных, которые меняются через CLI. Домены, HTTPS и статические пути тоже описаны переменными, поэтому конфигурация версионируется.
Подготовка сервера
Подойдёт чистый Debian или Ubuntu LTS. Нужны Python 3.10+, nginx, uWSGI и SSH. Установщик запускайте от root после чтения скрипта: он добавит пакеты и создаст piku.
curl -fsSL https://piku.github.io/get -o /tmp/piku-get.sh
less /tmp/piku-get.sh
sudo sh /tmp/piku-get.sh
sudo ufw allow 22,80,443/tcp
Доступ закройте ключом. Создайте пару, скопируйте публичную часть на сервер и добавьте её через setup:ssh:
ssh-keygen -t ed25519 -C "deploy@laptop"
scp ~/.ssh/id_ed25519.pub root@203.0.113.10:/tmp/
ssh root@203.0.113.10
sudo su - piku -c "python3 piku.py setup:ssh /tmp/id_ed25519.pub"
Если SSH работает, добавьте A-запись домена на IP. Сертификат Let’s Encrypt выпускается после того, как имя начнёт резолвиться.
Первый деплой
Создадим минимальное WSGI-приложение: функцию application, которую uWSGI вызовет при старте. Procfile свяжет тип wsgi с модулем и точкой входа.
mkdir hello-piku && cd hello-piku
git init
git branch -M main
cat > app.py <<'PY'
def application(environ, start_response):
body = b"Hello from piku\n"
start_response("200 OK", [("Content-Type", "text/plain")])
return [body]
PY
printf 'wsgi: app:application\n' > Procfile
git add . && git commit -m "first deploy"
git remote add piku piku@203.0.113.10:hello
git push piku main
Во время push появится лог установки зависимостей и запуска. Если всё прошло успешно, приложение доступно по IP. Имя репозитория в remote — это имя приложения; оно же нужно в командах.
Procfile и ENV
Проект может содержать несколько процессов. Фоновый обработчик, задача по расписанию и миграции описываются отдельными строками. release выполняется после установки зависимостей, preflight — до неё.
wsgi: app:application
worker: python worker.py
cron: 0 3 * * * python cleanup.py
release: python migrate.py
Переменные задаются в ENV. Для WSGI порт не нужен, но процесс web обязан слушать $PORT. Домен, HTTPS и число процессов uWSGI — там же.
NGINX_SERVER_NAME=hello.example.com
NGINX_HTTPS_ONLY=1
UWSGI_PROCESSES=4
BIND_ADDRESS=127.0.0.1
PORT=9080
Часть значений удобно менять без коммита. Helper piku ставится в /usr/local/bin и сам находит remote в текущем каталоге:
sudo curl -fsSL https://raw.githubusercontent.com/piku/piku/master/piku -o /usr/local/bin/piku
sudo chmod 755 /usr/local/bin/piku
piku config:set DEBUG=0
piku config:set UWSGI_PROCESSES=2
piku logs
piku deploy
ENV попадает в Git, поэтому секреты передавайте через config:set.
Домены и TLS
После установки NGINX_SERVER_NAME и повторного деплоя piku создаёт виртуальный хост и пытается получить сертификат. Проверьте DNS, редирект и срок действия.
dig +short hello.example.com
curl -I http://hello.example.com
curl -I https://hello.example.com
echo | openssl s_client -connect hello.example.com:443 \
-servername hello.example.com 2>/dev/null | \
openssl x509 -noout -dates
Если сертификат не выпустился, проверьте DNS, 80-й порт и NGINX_SERVER_NAME. После переезда сервера продление легко потерять.
Логи и диагностика
Основной инструмент — piku logs. Фильтр по имени отделяет рабочего от веб-сервера. Для отладки откройте shell в каталоге приложения.
piku logs
piku logs worker
piku -t run bash
ss -ltnp | grep -E ':(80|443|9080)'
sudo nginx -t
sudo journalctl -u nginx --since "30 min ago"
Типичная последовательность проверки выглядит так:
- приложение слушает порт из
ENVи отвечает черезcurl; - в логах uWSGI нет ошибок импорта;
- nginx видит upstream и не отдаёт 502;
- домен резолвится, порты 80 и 443 открыты;
- в
Procfileнет опечатки в имени модуля.
Обновления и откат
Новый деплой — обычный push. Piku перезапускает процессы, если не отключён PIKU_AUTO_RESTART. Для отката сделайте обратный коммит: так останется след о причине изменения.
git log --oneline -5
git revert --no-edit HEAD
git push piku main
piku logs
Миграции требуют внимания. Схема должна быть совместима с предыдущей версией кода, иначе откат приложения станет откатом данных. Перед релизом сделайте дамп.
Ограничения и безопасность
Piku — не контейнерная платформа. Пользователь piku по замыслу выполняет произвольные команды через CLI, поэтому доступ к нему равен доступу к shell. Не выдавайте аккаунт посторонним и не размещайте приложения разных владельцев на одном пользователе. Для изоляции нужны отдельные пользователи, ВМ или контейнеры.
Включите вход по ключам, отключите пароли в sshd_config, обновляйте nginx и uWSGI. Резервируйте ~/.piku/apps, ENV, конфигурацию nginx и базы: git хранит код, но не состояние.
Итог
Piku — быстрый способ получить Heroku-подобный деплой без Kubernetes и Docker. Он подходит для pet-проектов и небольших команд, которым важны простые логи. Начните с одного приложения, затем добавьте домен.
- установите piku на чистый Debian или Ubuntu LTS;
- закройте SSH ключами и оставьте открытыми только 22, 80 и 443;
- опишите процессы в
Procfile, а настройки — вENV; - проверьте порт, логи uWSGI и конфигурацию nginx;
- откатывайтесь через
git revert, а не через force-push; - резервируйте каталог приложений и базы.