Skip to main content

Vývoj aplikací Docker

Přehled

Aplikace Docker běží v kontejnerech spravovaných Docker Engine v TOS 7.

Předpoklad: Docker Engine není v TOS 7 předinstalovaný. Je poskytován jako aplikace v TOS App Center a uživatel jej musí nainstalovat a povolit. Když uživatelé instalují aplikaci založenou na Dockeru, platforma automaticky zkontroluje Docker Engine a vyzve k instalaci, pokud chybí nebo je zakázán — od vývojáře není vyžadována žádná další akce.

Základní požadavky:

  • Musí být poskytnut docker-compose.yml kompatibilní s Compose Spec 3.8+
  • Data musí být ukládána do adresářů přístupných NAS prostřednictvím připojení svazků
  • Privilegovaný režim je přísně zakázán
  • Systémové základní porty (22, 80, 443, 8181, 5050) nesmějí být obsazeny

Struktura balíčku (archiv .tar.gz)

Aplikace Docker se podává jako archiv .tar.gz. Archiv musí obsahovat přesně následující soubory na kořenové úrovni:

<appid>.tar.gz
├── config.ini
├── <appid>.lang
├── <appid>.svg
└── docker-compose.yml

Popisy souborů:

SouborVyžadovánoPopis
config.ini✅ AnoKonfigurace metadat aplikace
<appid>.lang✅ AnoVícejazyčný soubor (14 jazyků)
<appid>.svg✅ AnoIkona aplikace (formát SVG)
docker-compose.yml✅ AnoKonfigurace orchestrace kontejnerů

Důležité poznámky:

  • Pole config.ini.icon musí ukazovat na /images/icons/<appid>.svg. Platforma se o mapování postará během instalace.
  • Název balíčku se řídí formátem definovaným v Kapitole 3: <appid>.tar.gz
  • U aplikací Docker s UI musí docker-compose.yml obsahovat sekci x-app-meta (viz oddíl 9.3).
  • U aplikací Docker bez UI sekce x-app-meta není vyžadována.

Specifikace docker-compose.yml

version: "3.8"
services:
<appid>:
image: <registry>/<image>:<tag> # Images limited to Docker Hub only
container_name: <appid>
restart: unless-stopped
Volumes:
- /Volume*/DockerAppData/<appid>/config:/config
- /Volume*/DockerAppData/<appid>/data:/data
ports:
- "<host_port>:<container_port>"
environment:
- TZ=Asia/Shanghai
user: "1000:1000"

x-app-meta:
web:
port: <host_port>
protocol: http

Poznámka: * v /Volume*/ představuje číslo svazku (např. Volume1, Volume2) zvolené uživatelem při instalaci.

Pravidla:

  1. Verze: Musí být kompatibilní s Compose Spec 3.8 nebo vyšší
  2. x-app-meta: U aplikací Docker s UI musí být tag x-app-meta připojen na konec souboru docker-compose.yml (za blok services) a obsahovat web.port (číslo portu Web UI) a web.protocol (protokol požadavků, obvykle http).
    x-app-meta:
    web:
    port: 8080
    protocol: http
  3. Perzistence dat: Všechny datové adresáře musí být připojeny k hostitelským cestám. Data uložená pouze uvnitř kontejneru budou při odstranění kontejneru ztracena.
  4. Mapování portů:
    • Zakázané porty: 22, 80, 443, 8181, 5050 (systémové služby)
    • Doporučený rozsah: 8000-19999
    • Před podáním ověřte, že vybraný port není na TNAS používán
  5. Privilegovaný režim: Přísně zakázán. Pro určení UID/GID musí být použito pole user.
  6. Časové pásmo: Výchozí konfigurace TZ=Asia/Shanghai. Uživatelé ji mohou podle potřeby upravit.
  7. Název kontejneru: Musí odpovídat id aplikace
  8. Zásada restartu: Pro běžné služby použijte unless-stopped
  9. Síťový režim: network_mode: host je přísně zakázán, s výjimkou síťových nástrojů na úrovni systému. Síťové nástroje na úrovni systému musí při podání jasně uvést odůvodnění a mohou jej používat pouze po schválení. Pro běžné aplikace je přísně zakázán. Použití hostitelského síťového režimu narušuje izolaci kontejneru a představuje bezpečnostní rizika. Místo toho použijte mapování portů:
    ports:
    - "8080:8080"
  10. Časové pásmo: Časové pásmo kontejneru musí být explicitně nakonfigurováno:
environment:
- TZ=Asia/Shanghai
- TZ=${TZ:-Asia/Shanghai} # Allow user override

Nenechávejte časové pásmo prázdné — nekonzistentní časová razítka mohou u aplikací citlivých na čas způsobit poškození dat.

Požadavky na obraz a zabezpečení

  1. Zdroj obrazu (pouze Docker Hub): Všechny obrazy Docker musí pocházet z Docker Hub. Obrazy mimo Docker Hub budou rovnou zamítnuty. Obrazy musí být hostovány na Docker Hub (hub.docker.com). Jiné registry obrazů (jako ghcr.io, quay.io, vlastní soukromé registry atd.) nejsou podporovány.

    PrioritaZdrojPříklad
    1 (Preferovaný)Oficiální projektové obrazy Docker Hubnginx, postgres
    2Ověření vydavatelé na Docker HubObrazy Docker Hub s odznakem Verified
    3Známé komunitní obrazy Docker Hublinuxserver/jellyfin (100M+ stažení, aktivně udržované)
    ❌ ZamítnutoObrazy ze zdrojů mimo Docker HubSoukromé registry, ghcr.io, quay.io atd.
    ❌ ZamítnutoNeověřené osobní obrazy na Docker HubObrazy Docker Hub s nízkým počtem stažení, bez dokumentace

    Povinný požadavek: Obrazy musí být hostovány na Docker Hub. Zdroj obrazu bude ověřen během kontroly. Použití obrazů mimo Docker Hub povede k okamžitému zamítnutí.

    Obrazy ze zdrojů mimo Docker Hub nebo neověřené obrazy Docker Hub budou zamítnuty během bezpečnostní kontroly.

  2. Velikost obrazu: Ke zmenšení velikosti používejte vícefázová sestavení nebo základní obrazy Alpine.

  3. Citlivé informace: Hardcodování hesel, tokenů nebo tajemství v obrazech či souborech compose je zakázáno. Používejte proměnné prostředí nebo soubory .env.

  4. Bezpečnostní skenování: Před podáním spusťte docker scan nebo trivy ke kontrole známých zranitelností.

  5. Oprávnění uživatele: Spouštění jako root je přísně zakázáno a režim --privileged je přísně zakázán. Prostřednictvím pole user musí být určen nerootový uživatel.

Kompletní příklad

Přehled aplikace:

  • ID: myapp-docker
  • Typ: aplikace Docker
  • Obraz: linuxserver/myapp:latest
  • Port: 8080
  • Závislost: DockerEngine

config.ini

{
"id": "myapp-docker",
"icon": "/images/icons/myapp-docker.svg",
"publisher": "Developer Name",
"path": "http://${ip}:8080",
"exec": true,
"open_path": true,
"resize": true,
"maxmin": true,
"width": 0,
"height": 0,
"help": "https://github.com/example/myapp/wiki",
"version": "1.0.0",
"recommend": false,
"beta": false,
"low_version": "TOS7.0",
"category": ["Utilities"],
"depend": ["DockerEngine"],
"relation": ["docker", "DockerEngine"],
"platform": "x86_64",
"official": "https://example.com",
"application_type": "docker",
"system_id": "",
"package": "",
"compose_project": "myapp-docker",
"user": "myapp",
"all_user_display": true,
"allow_open_in_mobile": false
}

docker-compose.yml

version: "3.8"
services:
myapp-docker:
image: linuxserver/myapp:1.0.0
container_name: myapp-docker
restart: unless-stopped
Volumes:
- /Volume*/DockerAppData/myapp-docker/config:/config
- /Volume*/DockerAppData/myapp-docker/data:/data
ports:
- "8080:8080"
environment:
- TZ=Asia/Shanghai
- PUID=1000
- PGID=1000

x-app-meta:
web:
port: 8080
protocol: http

Poznámka: * v /Volume*/ představuje číslo svazku (např. Volume1, Volume2) zvolené uživatelem při instalaci. Tato aplikace otevírá své WebUI externě, takže path používá formát http://${ip}:<port>.

Pořadí spouštění vícekontejnerových služeb: Pro aplikace s více službami (např. Web + Databáze):

services:
app-db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
app-web:
image: myapp:1.0.0
depends_on:
app-db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
  • Ke správnému pořadí spouštění použijte depends_on s condition: service_healthy
  • Pro každou službu musí být definovány kontroly stavu
  • Validace platformy: všechny služby musí být zdravé, než se aplikace zobrazí jako "Running"

Zpracování selhání kontroly stavu:

  • Po 3 po sobě jdoucích selháních kontroly stavu je kontejner označen jako "unhealthy"
  • App Center zobrazí aplikaci jako "Abnormal"
  • Zásada restartu Dockeru (unless-stopped) se pokusí restartovat nezdravé kontejnery
  • Pokud kontejner vstoupí do smyčky restartování, platforma označí aplikaci jako vyžadující pozornost vývojáře

Zálohování, migrace a reset dat

OperaceMetodaPoznámky
ZálohováníZkopírujte celý adresář /Volume*/DockerAppData/<appid>/ na záložní místoDoporučuje se zazálohovat konfigurační a datové adresáře před upgradem
MigraceZkopírujte datový adresář na nový svazek a aktualizujte cesty připojení svazků v docker-compose.ymlMigrace mezi svazky je podporována; před zahájením zajistěte zastavení kontejneru
ResetOdstraňte adresáře /Volume*/DockerAppData/<appid>/data/ a /Volume*/DockerAppData/<appid>/config/Obnoví počáteční stav; uživatelská data ve sdílených složkách nejsou ovlivněna

Poznámka: Konfigurace a data jsou uloženy samostatně, což podporuje nezávislé zálohování a obnovu. Hlavní upgrady vyžadují zazálohování obou adresářů.