Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Manifest

The manifest defines service identity, metadata, and build configuration. It lives in startos/manifest/ as two files:

  • index.ts – the setupManifest() call
  • i18n.ts – translated strings for description and alerts

manifest/i18n.ts

Locale objects for user-facing manifest strings. Each is a record of locale to string:

export const short = {
  en_US: 'Brief description (one line)',
  es_ES: 'Descripcion breve (una linea)',
  de_DE: 'Kurze Beschreibung (eine Zeile)',
  pl_PL: 'Krotki opis (jedna linia)',
  fr_FR: 'Description breve (une ligne)',
}

export const long = {
  en_US:
    'Longer description explaining what the service does and its key features.',
  es_ES:
    'Descripcion mas larga que explica que hace el servicio y sus caracteristicas principales.',
  de_DE:
    'Langere Beschreibung, die erklart, was der Dienst tut und seine wichtigsten Funktionen.',
  pl_PL:
    'Dluzszy opis wyjasniajacy, co robi usluga i jej kluczowe funkcje.',
  fr_FR:
    'Description plus longue expliquant ce que fait le service et ses fonctionnalites principales.',
}

// Export alertInstall, alertUpdate, etc. as needed (or null for no alert)

manifest/index.ts

import { setupManifest } from '@start9labs/start-sdk'
import { short, long } from './i18n'

export const manifest = setupManifest({
  id: 'my-service',
  title: 'My Service',
  license: 'MIT',
  packageRepo: 'https://github.com/Start9Labs/my-service-startos',
  upstreamRepo: 'https://github.com/original/my-service',
  marketingUrl: 'https://example.com/',
  donationUrl: null,
  docsUrls: ['https://docs.example.com/guides'],
  description: { short, long },
  volumes: ['main'],
  images: {
    /* see Images Configuration below */
  },
  alerts: {
    install: null,
    update: null,
    uninstall: null,
    restore: null,
    start: null,
    stop: null,
  },
  dependencies: {},
})

Required Fields

FieldDescription
idUnique identifier (lowercase, hyphens allowed)
titleDisplay name shown in UI
licenseSPDX identifier (MIT, Apache-2.0, GPL-3.0, etc.)
packageRepoURL to the StartOS package repository
upstreamRepoURL to the original project repository
marketingUrlURL for the project’s main website
donationUrlDonation URL or null
docsUrlsArray of URLs to upstream documentation
description.shortLocale object (see manifest/i18n.ts)
description.longLocale object (see manifest/i18n.ts)
volumesStorage volumes (usually ['main'])
imagesDocker image configuration (including arch)
alertsUser notifications for lifecycle events (locale objects or null)
dependenciesService dependencies

License

Check the upstream project’s LICENSE file and use the correct SPDX identifier (e.g., MIT, Apache-2.0, GPL-3.0). If you have a git submodule, symlink to its license. Otherwise, copy the license text directly from the upstream repository:

# With submodule
ln -sf upstream-project/LICENSE LICENSE

# Without submodule -- copy from upstream repo

Icon

Symlink from upstream if available (svg, png, jpg, or webp, max 40 KiB):

ln -sf upstream-project/logo.svg icon.svg

Images Configuration

Each image can include an arch field specifying supported architectures. It defaults to ['x86_64', 'aarch64', 'riscv64'] if omitted, but it is good practice to list architectures explicitly for transparency. The arch field must align with the ARCHES variable in the Makefile.

Pre-built Docker Tag

Use when an image exists on Docker Hub or another registry:

images: {
  main: {
    source: {
      dockerTag: 'nginx:1.25',
    },
    arch: ['x86_64', 'aarch64'],
  },
},

Local Docker Build

Use when building from a Dockerfile in the project:

// Dockerfile in project root
images: {
  main: {
    source: {
      dockerBuild: {},
    },
    arch: ['x86_64', 'aarch64'],
  },
},

If upstream has a working Dockerfile: Set workdir to the upstream directory. If the Dockerfile is named Dockerfile, you can omit the dockerfile field:

images: {
  main: {
    source: {
      dockerBuild: {
        workdir: './upstream-project',
      },
    },
    arch: ['x86_64', 'aarch64'],
  },
},

For a non-standard Dockerfile name, specify dockerfile relative to project root:

images: {
  main: {
    source: {
      dockerBuild: {
        workdir: './upstream-project',
        dockerfile: './upstream-project/sync-server.Dockerfile',
      },
    },
    arch: ['x86_64', 'aarch64'],
  },
},

If you need a custom Dockerfile: Create one in your project root:

COPY upstream-project/ .

Architecture Support

The arch field accepts these values:

ValueArchitecture
x86_64Intel/AMD 64-bit
aarch64ARM 64-bit
riscv64RISC-V 64-bit

Most services support ['x86_64', 'aarch64']. Only add riscv64 if the upstream image actually supports it. The ARCHES variable in the Makefile must align (see Makefile).

GPU/Hardware Acceleration

For services requiring GPU access:

images: {
  main: {
    source: {
      dockerTag: 'ollama/ollama:0.13.5',
    },
    arch: ['x86_64', 'aarch64'],
    nvidiaContainer: true,  // Enable NVIDIA GPU support
  },
},
hardwareAcceleration: true,  // Top-level flag

Multiple Images

Services can define multiple images. Each image needs its own arch field:

images: {
  app: {
    source: { dockerTag: 'myapp:latest' },
    arch: ['x86_64', 'aarch64'],
  },
  db: {
    source: { dockerTag: 'postgres:15' },
    arch: ['x86_64', 'aarch64'],
  },
},

Alerts

Display messages to users during lifecycle events. Use locale objects for translated alerts, or null for no alert:

// In manifest/i18n.ts
export const alertInstall = {
  en_US: 'After installation, run the "Get Admin Credentials" action to retrieve your password.',
  es_ES: 'Despues de la instalacion, ejecute la accion "Obtener credenciales de administrador" para recuperar su contrasena.',
  de_DE: 'Fuhren Sie nach der Installation die Aktion "Admin-Zugangsdaten abrufen" aus, um Ihr Passwort abzurufen.',
  pl_PL: 'Po instalacji uruchom akcje "Pobierz dane administratora", aby uzyskac haslo.',
  fr_FR: "Apres l'installation, executez l'action 'Obtenir les identifiants admin' pour recuperer votre mot de passe.",
}

// In manifest/index.ts
import { short, long, alertInstall } from './i18n'

alerts: {
  install: alertInstall,
  update: null,
  uninstall: null,
  restore: null,
  start: null,
  stop: null,
},

Volumes

Storage volumes for persistent data. When possible, prefer matching the upstream project’s volume naming convention for clarity:

// If upstream docker-compose uses a volume named "mcaptcha-data"
volumes: ['mcaptcha-data'],

// Simple services can use 'main'
volumes: ['main'],

For services needing separate storage areas:

volumes: ['main', 'db', 'config'],

Reference these in main.ts mounts by the volume ID you chose.

Dependencies

Declare dependencies on other StartOS services. Note that dependency description is a plain string, not a locale object:

dependencies: {
  // Required dependency
  bitcoin: {
    description: 'Required for blockchain data',
    optional: false,
  },

  // Optional dependency with metadata
  'c-lightning': {
    description: 'Needed for Lightning payments',
    optional: true,
    metadata: {
      title: 'Core Lightning',
      icon: 'https://raw.githubusercontent.com/Start9Labs/cln-startos/refs/heads/master/icon.png',
    },
  },
},