Хочете швидкий і безпечний роздавач програм у своїй локалці? Приватний Flatpak-репозиторій вирішує одразу кілька задач: контроль оновлень, економію зовнішнього трафіку й стабільні версії для робочих місць. Нижче — покроково: як створити репо, підписати GPG-ключем, опублікувати на вашому сервері Linux і налаштувати автооновлення клієнтів. 🔒

Підготовка сервера

Крок 1. Встановити інструменти

Працюємо в терміналі на сервері Linux. Підійде будь-який дистрибутив; приклад для Debian/Ubuntu:

sudo apt update
sudo apt install -y flatpak ostree gpg nginx

Flatpak опирається на OSTree. Ми зберемо локальне сховище й віддамо його через Nginx. Це класика для snap та flatpak-сценаріїв у LAN.

Крок 2. Згенерувати GPG-ключ для підписання

GPG-підпис захищає цілісність репо. Створюємо ключ і запам’ятовуємо його ID:

gpg --quick-generate-key "LAN Flatpak Repo <repo@lan>" rsa4096 sign 0
KEYID=$(gpg --list-keys --with-colons | awk -F: '/^pub/ {print $5; exit}')
echo "$KEYID" | sudo tee /srv/GPG_KEYID >/dev/null

Експортуємо публічний ключ, щоб клієнти могли довіряти репозиторію:

sudo install -d -m 755 /srv/flatpak-repo
sudo gpg --armor --export "$KEYID" | sudo tee /srv/flatpak-repo/pubkey.gpg >/dev/null

Крок 3. Ініціалізація Flatpak/OSTree-репозиторію

sudo ostree --repo=/srv/flatpak-repo init --mode=archive-z2
sudo chown -R www-data:www-data /srv/flatpak-repo

Режим archive-z2 — оптимальний для віддачі через HTTP.

Крок 4. Наповнити репо пакетами (дзеркало вибраних з Flathub)

Найпростіше — дзеркалити потрібні референси (app/runtime) із Flathub. Cкладаємо список і тягнемо його:

# Приклади референсів (налаштуйте під свої потреби)
echo "app/org.gimp.GIMP/x86_64/stable" | sudo tee -a /srv/flatpak-repo/refs.txt
echo "runtime/org.gnome.Platform/x86_64/45" | sudo tee -a /srv/flatpak-repo/refs.txt

# Додаємо віддалений репозиторій Flathub в локальний OSTree-конфіг
töree=/srv/flatpak-repo
sudo ostree remote add --repo="$toree" --if-not-exists flathub https://dl.flathub.org/repo/

# Тягнемо вибрані референси
while read -r ref; do
  sudo ostree pull --mirror --repo="$toree" flathub "$ref"
done < /srv/flatpak-repo/refs.txt

# Генеруємо summary та підписуємо його нашим ключем (критично!)
KEYID=$(cat /srv/GPG_KEYID)
sudo flatpak build-update-repo --generate-static-deltas --gpg-sign="$KEYID" /srv/flatpak-repo

Якщо з часом додасте нові референси — повторіть pull і build-update-repo.

Крок 5. Віддати репо через Nginx

Налаштуємо простий віртуальний хост для /srv/flatpak-repo. Приклад:

sudo tee /etc/nginx/sites-available/flatpak >/dev/null <<'NGX'
server {
  listen 80;
  server_name lan-flatpak;  # або IP сервера

  location /flatpak/ {
    alias /srv/flatpak-repo/;
    autoindex on;
  }
}
NGX

sudo ln -s /etc/nginx/sites-available/flatpak /etc/nginx/sites-enabled/flatpak
sudo nginx -t && sudo systemctl reload nginx

Тепер ключ буде доступний за URL типу http://<ip-сервера>/flatpak/pubkey.gpg, а сам репозиторій — у тій же директорії.

Налаштування клієнтів

На клієнтах імпортуємо ключ і додаємо віддалений репозиторій. Усі дії — через термінал Linux:

# Завантажити публічний ключ
wget -O pubkey.gpg http://<ip-сервера>/flatpak/pubkey.gpg

# Додати LAN-репозиторій (system-wide)
sudo flatpak remote-add --if-not-exists --gpg-import=pubkey.gpg lan http://<ip-сервера>/flatpak/

# Перевірити наявні додатки/рантайми
flatpak remote-ls lan | head

# Встановити застосунок із LAN-репо
sudo flatpak install -y lan org.gimp.GIMP

Готово! Клієнти довіряють саме вашому GPG-підпису на summary, а обновлення приходитимуть із локальної мережі 🚀

Автооновлення клієнтів через systemd timers

Щоб не бігати по машинах руками, створіть systemd-сервіс і таймер, які оновлюватимуть Flatpak-пакети автоматично.

# Сервіс автооновлення
sudo tee /etc/systemd/system/flatpak-autoupdate.service >/dev/null <<'UNIT'
[Unit]
Description=Flatpak auto-update from LAN remote

[Service]
Type=oneshot
ExecStart=/usr/bin/flatpak update -y --noninteractive
UNIT

# Таймер (щодоби о 03:00)
sudo tee /etc/systemd/system/flatpak-autoupdate.timer >/dev/null <<'UNIT'
[Unit]
Description=Run Flatpak auto-update daily

[Timer]
OnCalendar=03:00
Persistent=true

[Install]
WantedBy=timers.target
UNIT

sudo systemctl daemon-reload
sudo systemctl enable --now flatpak-autoupdate.timer

Це саме той випадок, де "cron та systemd timers" виграють зручністю: нічого зайвого, працює стабільно.

Альтернативні способи

  • Apache або простий тестовий HTTP: на етапі відладки можна тимчасово віддати репо так: python3 -m http.server у каталозі /srv/flatpak-repo (але для бойового використання лишайте Nginx).
  • Автосинхронізація репо на сервері: оформіть bash скрипти, що тягнуть нові версії з Flathub і перевипускають summary.
# /usr/local/bin/flatpak-repo-sync.sh
#!/usr/bin/env bash
set -euo pipefail
REPO=/srv/flatpak-repo
KEYID=$(cat /srv/GPG_KEYID)

sudo ostree remote add --repo="$REPO" --if-not-exists flathub https://dl.flathub.org/repo/
while read -r ref; do
  [[ -z "$ref" ]] && continue
  sudo ostree pull --mirror --repo="$REPO" flathub "$ref"
done < "$REPO/refs.txt"

sudo flatpak build-update-repo --generate-static-deltas --gpg-sign="$KEYID" "$REPO"
# systemd-юніти для сервера
sudo tee /etc/systemd/system/flatpak-repo-sync.service >/dev/null <<'UNIT'
[Unit]
Description=Sync local Flatpak repo from Flathub

[Service]
Type=oneshot
ExecStart=/usr/local/bin/flatpak-repo-sync.sh
UNIT

sudo tee /etc/systemd/system/flatpak-repo-sync.timer >/dev/null <<'UNIT'
[Unit]
Description=Run Flatpak repo sync daily

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target
UNIT

sudo systemctl daemon-reload
sudo systemctl enable --now flatpak-repo-sync.timer

GUI-спосіб для клієнтів

Якщо ви на GNOME/KDE, зручно додати репозиторій через файл .flatpakrepo. Створіть його на сервері й дайте посилання користувачам:

sudo tee /srv/flatpak-repo/lan.flatpakrepo >/dev/null <<'RPO'
[Flatpak Repo]
Title=LAN Flatpak Repo
Url=http://<ip-сервера>/flatpak/
GPGKey=-----BEGIN PGP PUBLIC KEY BLOCK-----\n...ваш публічний ключ з pubkey.gpg (armor)...\n-----END PGP PUBLIC KEY BLOCK-----
RPO

Користувач завантажує цей файл і відкриває його в центрі програм (GNOME Software/Discover), після чого з’являється нове джерело застосунків.

FAQ

Чому клієнт не бачить додаток (No such ref)?

Швидше за все, дзеркалили лише app, але забули відповідний runtime. Додайте потрібний runtime до refs.txt, виконайте pull і build-update-repo.

"GPG failed to verify" при додаванні remote

Клієнт не довіряє ключу або summary не підписано. Переконайтеся, що імпортовано той самий pubkey.gpg і ви виконали flatpak build-update-repo --gpg-sign=KEYID.

403/404 від Nginx

Перевірте права доступу до каталогу: chown -R www-data:www-data /srv/flatpak-repo, а також правильність шляху в alias.

Автооновлення не спрацьовує

Перевірте таймер: systemctl status flatpak-autoupdate.timer. Також дивіться логи сервісу: journalctl -u flatpak-autoupdate.service.

Потрібні пакунки іншої архітектури (arm64)?

Додавайте референси з відповідним суфіксом архітектури (наприклад, aarch64) і оновлюйте summary.

Чи можна повністю відключити інтернет-каталоги на клієнті?

Так. Видаліть або вимкніть інші remotes: flatpak remote-delete flathub або --no-use-for-deps в окремих сценаріях.

Порада від Kernelka

Бережіть приватний GPG-ключ: робіть резервну копію в надійному місці, задайте strong-пароль і обмежте доступ до сервера файрволом. Для LAN-сценарію цього достатньо, а от зовнішню публікацію краще робити з окремим ключем і піддоменом. І не забувайте про автоматизацію: менше рутини — менше помилок 😉

Підсумок

  • Створили й підписали приватний Flatpak-репозиторій у локальній мережі.
  • Опублікували його через Nginx на вашому сервері Linux.
  • Налаштували клієнти на довіру до GPG-ключа й отримання пакетів з LAN.
  • Увімкнули автооновлення на клієнтах через systemd timers.
  • За бажанням — автоматизували синхронізацію репо за допомогою bash скрипти на сервері.