Wewnętrzny backend S3 (Garage)
Opcjonalny profil dla wdrożeń, które nie chcą prowizjonować zewnętrznego dostawcy S3 (AWS S3, Cloudflare R2, Backblaze B2, MinIO itp.). Uruchamia Garage jako jednowęzłowy kontener wewnątrz stacku Compose i serwuje buckety, których potrzebuje API.
Kiedy używać
Section titled “Kiedy używać”- Self-hosted bez płatnego dostawcy S3.
- Środowiska air-gapped lub z ograniczeniami compliance, gdzie dane muszą zostać na tym samym hoście.
- Instalacje próbne / staging bez zewnętrznych zależności.
Jak to działa
Section titled “Jak to działa”Serwis garage w Compose uruchamia garage server --single-node --default-access-key:
--single-nodeautomatycznie aplikuje jednowęzłowy layout klastra przy pierwszym starcie.--default-access-keyautomatycznie tworzy access key S3 zGARAGE_DEFAULT_ACCESS_KEY/GARAGE_DEFAULT_SECRET_KEY(Compose mapuje je zS3_API_KEY/S3_API_SECRETw.env).
API tworzy swoje buckety przy pierwszym starcie — bez ręcznego bootstrap-u. Kiedy wywołuje CreateBucket przez S3 API, Garage przyznaje wywołującemu kluczowi własność bucketu, więc API od razu może czytać i pisać.
Aktywacja profilu
Section titled “Aktywacja profilu”W .env:
COMPOSE_PROFILES=garage # lub backup,garage dla obuS3_ENDPOINT=http://garage:3900Bez garage w COMPOSE_PROFILES serwis jest zdefiniowany w docker-compose.yaml, ale się nie uruchamia.
Wygeneruj trzy sekrety
Section titled “Wygeneruj trzy sekrety”Garage potrzebuje pary kluczy S3 (które wykorzystuje API) i wewnętrznego sekretu RPC:
echo "S3_API_KEY=GK$(openssl rand -hex 16)"echo "S3_API_SECRET=$(openssl rand -hex 32)"echo "GARAGE_RPC_SECRET=$(openssl rand -hex 32)"Wklej trzy linie do .env. Prefiks GK to konwencja Garage, dzięki której klucz łatwo rozpoznać w logach — dowolny ciąg działa, ale zostaw go.
Pierwszy start
Section titled “Pierwszy start”docker compose pulldocker compose up -dTo cała konfiguracja. Przy pierwszym starcie:
-
Garage aplikuje jednowęzłowy layout klastra (nie trzeba ręcznie
garage layout assign). -
Garage tworzy access key z
GARAGE_DEFAULT_ACCESS_KEY/GARAGE_DEFAULT_SECRET_KEY. -
API uruchamia migracje, tworzy bucket projektu (
sancho-env-${DEPLOY_ENV}), a następnie seeduje konto root — co tworzy bucket konta (sancho-env-${DEPLOY_ENV}-account-1).
Oba buckety są własnością wywołującego klucza, więc API może z nich od razu korzystać.
Weryfikacja
Section titled “Weryfikacja”docker compose exec garage /garage status # node Up, layout zaaplikowanydocker compose exec garage /garage key list # auto-importowany kluczdocker compose exec garage /garage bucket list # 2 buckety, oba z kluczem allowed
# End-to-end: wgraj awatar z aplikacji webowej, potemls ./data/garage/data # pliki blob się pojawiająProfil backup na wierzchu
Section titled “Profil backup na wierzchu”Jeśli ustawisz dodatkowo COMPOSE_PROFILES=backup,garage, serwis postgres-backup pisze codzienne dumpy do Garage. Nie tworzy swojego bucketu samodzielnie, więc uruchom raz:
docker compose exec garage /garage bucket create "$BACKUP_S3_BUCKET"Garage przyznaje domyślnemu kluczowi pełny dostęp przy tworzeniu bucketu, więc krok bucket allow nie jest potrzebny. Następnie docker compose exec postgres-backup /backup.sh wymusza natychmiastowy dump jako test poprawności.
Eksploatacja
Section titled “Eksploatacja”Garage binduje 3900 (S3 API), 3901 (RPC) i 3903 (admin) wewnątrz sieci sancho (garage.toml nie konfiguruje [s3_web], więc port web 3902 nie jest bindowany). Żaden z nich nie jest wystawiony na hosta. API dociera do Garage przez http://garage:3900; do CLI ad-hoc używaj docker compose exec garage /garage ....
Trwałe dane
Section titled “Trwałe dane”| Ścieżka | Zawartość |
|---|---|
./data/garage/meta |
Metadane SQLite, stan bucketów/kluczy |
./data/garage/data |
Bloby obiektów |
Snapshotuj oba katalogi razem — rozdzielenie ich między snapshotami daje niespójny stan. Zatrzymaj stack (docker compose down) przed kopiami plikowymi, żeby uniknąć wyścigów na lockach.
Odtwarzanie
Section titled “Odtwarzanie”docker compose downsudo rm -rf ./data/garagesudo tar -xzf garage-data-YYYY-MM-DD.tar.gz # rozpakowuje ./data/garage/{meta,data}docker compose up -dAccess key, lista bucketów i allow-list przetrwają w snapshocie metadanych — żadnych dodatkowych kroków po restore.
Rotacja poświadczeń S3
Section titled “Rotacja poświadczeń S3”Garage śledzi klucze po ID. Zmiana S3_API_KEY w .env sprawia, że stary klucz jest bezużyteczny po stronie API, ale dalej istnieje w Garage:
-
Wygeneruj nową parę:
Terminal window NEW_KEY="GK$(openssl rand -hex 16)"; NEW_SECRET="$(openssl rand -hex 32)" -
Zaimportuj jako nowy klucz w Garage:
Terminal window docker compose exec garage /garage key import "$NEW_KEY" "$NEW_SECRET" -n sancho-new --yes -
Nadaj dostęp do każdego bucketu, który mógł obsłużyć stary klucz:
Terminal window for b in $(docker compose exec garage /garage bucket list | awk '/^ /{print $1}'); dodocker compose exec garage /garage bucket allow --read --write --owner "$b" --key "$NEW_KEY"done -
Zaktualizuj
.envi zrestartuj api + postgres-backup:Terminal window sed -i -e "s|^S3_API_KEY=.*|S3_API_KEY=$NEW_KEY|" \-e "s|^S3_API_SECRET=.*|S3_API_SECRET=$NEW_SECRET|" .envdocker compose up -d api postgres-backup -
(Opcjonalnie) usuń stary klucz po potwierdzeniu, że nowy działa:
Terminal window docker compose exec garage /garage key delete <OLD_KEY_ID> --yes