MAATRIX / Блог / Как установить и настроить Invoice Ninja на VPS

Как установить и настроить Invoice Ninja на VPS

MAATRIX

Если вы фрилансер или ведёте небольшую студию, рано или поздно упираетесь в выбор: платить $10-40 в месяц за очередной сервис для счетов или один раз развернуть то же самое на своём сервере. Invoice Ninja — open-source система для выставления счетов, работы с клиентами и приёма платежей, которая закрывает этот вопрос полностью: ваши данные, ваш контроль, никакой абонентки. Ниже — рабочая инструкция по установке через Docker Compose, от чистого VPS до готовой системы со своим доменом и SSL.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Invoice Ninja и кому он подходит

Invoice Ninja — это счета, предложения (quotes), учёт клиентов, задачи с таймтрекингом, повторяющиеся инвойсы (recurring invoices) и приём онлайн-оплат через Stripe, PayPal и ещё пару десятков платёжных шлюзов. Есть бесплатная self-hosted версия с открытым кодом и платная облачная — нас интересует первая.

Кому имеет смысл разворачивать свою инсталляцию:

  • фрилансерам и небольшим студиям, которым нужны красивые PDF-счета с брендингом, но не нужен весь функционал полноценной ERP;
  • бизнесу, который выставляет счета клиентам за рубежом и хочет принимать оплату картой напрямую, без посредников;
  • тем, кто уже пробовал условный QuickBooks Online или FreshBooks и устал от роста цены при добавлении клиентов — в self-hosted версии лимитов на число клиентов и счетов нет.

Честная оговорка: Invoice Ninja — не бухгалтерская программа для сдачи отчётности по российским стандартам, это инструмент именно для выставления счетов и общения с клиентами. Если нужна полноценная ERP с складом и производством, смотрите в сторону ERPNext — это другой класс задач.

Требования к серверу и выбор VPS

Invoice Ninja построен на Laravel и не требует мощного железа — это не Frappe/ERPNext с десятком воркеров. Основная нагрузка — PHP-FPM, MySQL/MariaDB и генерация PDF.

СценарийvCPURAMДиск
Один фрилансер, до 20-30 клиентов1-22 ГБ20-30 ГБ SSD
Небольшая команда, активная работа с recurring-инвойсами и email-рассылкой24 ГБ40 ГБ SSD
Несколько компаний в одной инсталляции (multi-company)2-44-8 ГБ60+ ГБ SSD

На 2 ГБ ОЗУ Docker-стек (приложение + MySQL + опционально Redis) запускается и работает стабильно для одного пользователя, но при первой сборке образов и одновременной генерации нескольких PDF память может подходить к пределу — если тариф минимальный, добавьте swap заранее (см. расчёт размера swap для VPS). Из ОС берите Ubuntu 24.04 LTS — под неё ниже все команды.

Для приёма платежей через Stripe/PayPal и корректной отправки email-уведомлений клиентам важна репутация IP: если сервер будет отправлять счета по почте, лучше выбирать локацию и провайдера без истории в спам-листах.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Установка Docker и подготовка сервера

Работаем не под root, а под пользователем с sudo:

apt update && apt upgrade -y
adduser ninja
usermod -aG sudo ninja
su - ninja

Если своего Docker на сервере ещё нет — разверните его по отдельной инструкции: установка Docker на Ubuntu 24.04 с нуля. Кратко, для тех, кто уже знаком с процессом:

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker

Проверьте, что Docker и Compose-плагин на месте:

docker --version
docker compose version

Заодно закройте лишние порты файрволом — открытыми наружу должны остаться только SSH, 80 и 443 (подробнее — в статье про настройку UFW на VPS):

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Развёртывание Invoice Ninja через Docker Compose

Официальный и самый предсказуемый способ поставить Invoice Ninja — готовый docker-compose от разработчиков. Создайте рабочую директорию и файл окружения:

mkdir -p ~/invoiceninja && cd ~/invoiceninja

Сгенерируйте ключ приложения заранее — он понадобится в .env (32 случайных байта в base64):

openssl rand -base64 32

Создайте .env:

cat > .env <<'EOF'
APP_URL=https://invoice.example.com
APP_KEY=base64:ВСТАВЬТЕ_СГЕНЕРИРОВАННЫЙ_КЛЮЧ
APP_DEBUG=false

DB_HOST=db
DB_DATABASE=ninja
DB_USERNAME=ninja
DB_PASSWORD=замените-на-надежный-пароль
DB_ROOT_PASSWORD=замените-на-другой-надежный-пароль

IN_USER_EMAIL=admin@example.com
IN_PASSWORD=замените-на-надежный-пароль-админа

MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=smtp-user
MAIL_PASSWORD=smtp-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=noreply@example.com
EOF

И docker-compose.yml:

services:
  app:
    image: invoiceninja/invoiceninja:5
    restart: unless-stopped
    env_file: .env
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - ninja_public:/var/www/app/public
      - ninja_storage:/var/www/app/storage
    depends_on:
      - db

  db:
    image: mariadb:11
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_USER: ${DB_USERNAME}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - ninja_db:/var/lib/mysql

volumes:
  ninja_public:
  ninja_storage:
  ninja_db:

Обратите внимание: приложение опубликовано только на 127.0.0.1:8080 — наружу его отдаст обратный прокси с SSL из следующего раздела, напрямую в интернет контейнер не смотрит. Запускайте:

docker compose up -d
docker compose logs -f app

Первый старт занимает пару минут — контейнер накатывает миграции базы и создаёт администратора из IN_USER_EMAIL/IN_PASSWORD. Дождитесь в логах строки о завершении миграций, после чего приложение доступно на http://127.0.0.1:8080 изнутри сервера.

Домен, SSL и обратный прокси

Направьте A-запись домена (например, invoice.example.com) на IP сервера, затем поставьте перед контейнером Caddy — он сам получит и продлит сертификат Let's Encrypt. Если Caddy ещё не установлен, разверните его по инструкции Caddy с авто-SSL на Ubuntu 24.04; дальше достаточно одного блока в Caddyfile:

invoice.example.com {
    reverse_proxy 127.0.0.1:8080
}
sudo systemctl reload caddy

Через 10-30 секунд сертификат выпустится автоматически, и сайт откроется по HTTPS. Если вы используете Nginx вместо Caddy — понадобится классическая связка nginx + certbot, схема та же: прокси на 127.0.0.1:8080, сертификат отдельной командой certbot --nginx.

Проверьте, что приложение реально видит правильный APP_URL — если после смены домена в .env в интерфейсе остаются старые ссылки, перезапустите контейнер:

docker compose down && docker compose up -d

Первая настройка: компания, счета, платежи, крон

Зайдите на https://invoice.example.com, войдите под email/паролем из IN_USER_EMAIL/IN_PASSWORD и сразу смените пароль в настройках профиля — те, что были в .env, лучше не оставлять постоянными.

Дальше стандартный порядок настройки:

  1. Company Settings → Details — название компании, логотип, реквизиты, которые попадут на PDF счетов.
  2. Settings → Invoice Design — выбор шаблона счёта и кастомизация полей (номер, валюта, налоги).
  3. Settings → Online Payments — подключение платёжного шлюза. Из коробки поддерживаются Stripe, PayPal, Mollie, Square и ещё около двадцати провайдеров; для приёма оплаты от иностранных клиентов чаще всего берут Stripe.
  4. Settings → Templates & Reminders — тексты email-уведомлений и автоматические напоминания о просроченной оплате.
  5. Recurring Invoices — если у вас есть клиенты с постоянной абонентской платой, настройте повторяющиеся счета один раз, а не создавайте их вручную каждый месяц.

Recurring-инвойсы, конвертация валют и автонапоминания работают через внутренний планировщик Laravel, которому нужен рабочий cron внутри контейнера — в официальном образе он уже запущен по умолчанию, отдельно ничего не добавляйте. Если решите когда-нибудь вынести обработку очередей на отдельный сервис или добавить свои плановые задачи снаружи — общие принципы разобраны в статье про настройку cron-задач на сервере.

Не забудьте про email: без рабочего SMTP (блок MAIL_* в .env) счета и напоминания клиентам просто не уйдут — проверьте отправку письмом самому себе сразу после настройки, а не в момент, когда счёт уже нужно выставить.

Резервное копирование и обновление

Все данные Invoice Ninja живут в двух местах: база MySQL (ninja_db) и том с загруженными файлами/логотипами (ninja_storage). Бэкапить нужно оба.

Быстрый дамп базы без остановки контейнеров:

docker compose exec db sh -c 'exec mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" ninja' > ninja-$(date +%F).sql

Для регулярных автоматических бэкапов с ротацией и хранением вне сервера удобнее не городить самописный скрипт, а поставить BorgBackup — разбор установки и настройки есть в статье BorgBackup на Ubuntu 24.04; добавьте в список бэкапируемых путей volume ninja_storage (обычно смонтирован в /var/lib/docker/volumes/invoiceninja_ninja_storage/_data) и дамп базы из команды выше.

Обновление до новой версии — замена образа и перезапуск:

docker compose pull
docker compose up -d

Контейнер сам прогонит недостающие миграции при старте. Перед обновлением на минорную/мажорную версию всё же сделайте свежий дамп базы — миграции Laravel редко ломаются, но откатывать их вручную неприятно.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Invoice Ninja бесплатен полностью?

Self-hosted версия (community edition) бесплатна и открыта, ограничений на число клиентов и счетов нет. Платная облачная версия и White Label лицензия — отдельные продукты, для self-hosted они не обязательны.

Можно вести несколько компаний в одной инсталляции?

Да, функция multi-company доступна и в self-hosted версии — добавляется через переключатель компаний в интерфейсе, база при этом общая.

Какая версия PHP и MySQL нужна, если ставить не через Docker?

Официальный образ уже включает нужный стек PHP-FPM и веб-сервер внутри контейнера, поэтому Docker — самый предсказуемый путь; ручная установка на голый сервер (Nginx + PHP-FPM + MariaDB отдельно) тоже возможна, но требует ручного контроля версий PHP-расширений при каждом обновлении.

Как перенести Invoice Ninja на другой сервер?

Перенесите оба volume (ninja_db, ninja_storage) и файл .env с тем же APP_KEY — без совпадающего ключа приложение не расшифрует часть сохранённых данных.

Нужен ли Redis?

Не обязателен для небольшой инсталляции — по умолчанию кеш и очереди работают через файловую систему/базу. Redis имеет смысл добавлять, если счетов и клиентов становится действительно много и генерация PDF начинает подтормаживать.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →