# yaml-language-server: $schema=https://schema.zeabur.app/template.json
apiVersion: zeabur.com/v1
kind: Template
metadata:
    name: Garage
spec:
    description: Garage is a lightweight self-hosted S3-compatible object storage service for small-to-medium deployments.
    icon: https://garagehq.deuxfleurs.fr/img/logo.svg
    variables:
        - key: GARAGE_PUBLIC_DOMAIN
          type: DOMAIN
          name: Garage S3 API Domain
          description: Public domain for the Garage S3 API endpoint.
    tags:
        - Tool
        - Storage
    readme: |-
        # Garage

        Garage is a lightweight, self-hosted, S3-compatible object storage service.

        Project website: https://garagehq.deuxfleurs.fr/
        Source repository: https://git.deuxfleurs.fr/Deuxfleurs/garage

        This Zeabur template deploys a single-node Garage instance for development, staging, and migration validation. It is not a high-availability production cluster.

        ## What Gets Deployed

        - Garage `dxflrs/garage:v2.3.0`
        - Persistent metadata directory at `/var/lib/garage/meta`
        - Persistent object data directory at `/var/lib/garage/data`
        - S3 API on port `3900`
        - Web endpoint on port `3902`
        - Admin API listening inside the container on port `3903`

        The service starts with `garage server --single-node --default-bucket`, so Garage initializes a single-node layout and creates the default bucket and access key from environment variables.

        ## Required Input

        Only the public S3 API domain is required. Credentials, bucket name, internal endpoint, and service tokens are generated automatically by the template.

        ## Default Bucket

        The template creates a default bucket named `vmemo-media`.

        Use the deployment instructions panel to copy the S3 endpoint, region, bucket, access key ID, and secret access key.

        ## Production Note

        This template uses a fixed internal RPC secret because the official Garage image does not include a shell for deriving a hex secret from Zeabur's generated password variable. The RPC port is not exposed as a public Zeabur port.

        For production object storage, prefer a separate multi-node Garage cluster with at least three nodes, a generated `rpc_secret`, and `replication_factor = 3`.
    services:
        - name: garage
          icon: https://garagehq.deuxfleurs.fr/img/logo.svg
          template: PREBUILT_V2
          spec:
            id: garage
            source:
                image: dxflrs/garage:v2.3.0
                command:
                    - /garage
                    - server
                    - --single-node
                    - --default-bucket
            ports:
                - id: web
                  port: 3900
                  type: HTTP
                - id: s3web
                  port: 3902
                  type: HTTP
            volumes:
                - id: metadata
                  dir: /var/lib/garage/meta
                - id: data
                  dir: /var/lib/garage/data
            instructions:
                - title: Garage S3 API Endpoint
                  content: ${ZEABUR_WEB_URL}
                - title: Garage Internal S3 Endpoint
                  content: ${GARAGE_S3_ENDPOINT}
                - title: Garage Region
                  content: ${GARAGE_S3_REGION}
                - title: Garage Bucket
                  content: ${GARAGE_S3_BUCKET}
                - title: Garage Access Key ID
                  content: ${GARAGE_S3_ACCESS_KEY_ID}
                - title: Garage Secret Access Key
                  content: ${GARAGE_S3_SECRET_ACCESS_KEY}
                - title: Garage Admin Token
                  content: ${GARAGE_ADMIN_TOKEN}
            env:
                GARAGE_ADMIN_TOKEN:
                    default: ${PASSWORD}
                    expose: false
                GARAGE_CONFIG_FILE:
                    default: /etc/garage.toml
                    expose: false
                GARAGE_DEFAULT_ACCESS_KEY:
                    default: GK00000000000000000000000000000000
                    expose: false
                GARAGE_DEFAULT_BUCKET:
                    default: vmemo-media
                    expose: false
                GARAGE_DEFAULT_SECRET_KEY:
                    default: ${PASSWORD}
                    expose: false
                GARAGE_METRICS_TOKEN:
                    default: ${PASSWORD}
                    expose: false
                GARAGE_RPC_SECRET:
                    default: "0000000000000000000000000000000000000000000000000000000000000000"
                    expose: false
                GARAGE_S3_ACCESS_KEY_ID:
                    default: ${GARAGE_DEFAULT_ACCESS_KEY}
                    expose: true
                GARAGE_S3_BUCKET:
                    default: ${GARAGE_DEFAULT_BUCKET}
                    expose: true
                GARAGE_S3_ENDPOINT:
                    default: http://${CONTAINER_HOSTNAME}:3900
                    expose: true
                GARAGE_S3_FORCE_PATH_STYLE:
                    default: "true"
                    expose: true
                GARAGE_S3_PUBLIC_ENDPOINT:
                    default: ${ZEABUR_WEB_URL}
                    expose: true
                GARAGE_S3_REGION:
                    default: garage
                    expose: true
                GARAGE_S3_SECRET_ACCESS_KEY:
                    default: ${GARAGE_DEFAULT_SECRET_KEY}
                    expose: true
            configs:
                - path: /etc/garage.toml
                  template: |
                    metadata_dir = "/var/lib/garage/meta"
                    data_dir = "/var/lib/garage/data"
                    db_engine = "sqlite"
                    metadata_auto_snapshot_interval = "6h"

                    replication_factor = 1
                    compression_level = 2

                    rpc_bind_addr = "[::]:3901"
                    rpc_public_addr = "127.0.0.1:3901"

                    [s3_api]
                    s3_region = "garage"
                    api_bind_addr = "[::]:3900"
                    root_domain = ".${ZEABUR_WEB_DOMAIN}"

                    [s3_web]
                    bind_addr = "[::]:3902"
                    root_domain = ".${ZEABUR_S3WEB_DOMAIN}"
                    index = "index.html"

                    [admin]
                    api_bind_addr = "[::]:3903"
                    admin_token = "${GARAGE_ADMIN_TOKEN}"
                    metrics_token = "${GARAGE_METRICS_TOKEN}"
                  permission: 420
                  envsubst: true
          domainKey: GARAGE_PUBLIC_DOMAIN
