1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-28 06:31:58 +00:00

feat: docker compose builder

This commit is contained in:
Jason Rasmussen 2024-12-17 13:25:53 -05:00
parent fd34a914a6
commit c191f9cc5b
No known key found for this signature in database
GPG key ID: 75AD31BF84C94773
12 changed files with 3795 additions and 1 deletions

10
docker/.gitignore vendored
View file

@ -1 +1,9 @@
.env .DS_Store
node_modules
/build
/.svelte-kit
/dist
/package
.env
.env.*
!.env.example

1
docker/.npmrc Normal file
View file

@ -0,0 +1 @@
engine-strict=true

1
docker/.nvmrc Normal file
View file

@ -0,0 +1 @@
22.11.0

14
docker/.prettierignore Normal file
View file

@ -0,0 +1,14 @@
.DS_Store
node_modules
/build
/package
/coverage
.env
.env.*
!.env.example
*.md
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

9
docker/.prettierrc Normal file
View file

@ -0,0 +1,9 @@
{
"jsonRecursiveSort": true,
"organizeImportsSkipDestructiveCodeActions": true,
"plugins": ["prettier-plugin-organize-imports", "prettier-plugin-sort-json"],
"printWidth": 120,
"semi": true,
"singleQuote": true,
"trailingComma": "all"
}

87
docker/eslint.config.mjs Normal file
View file

@ -0,0 +1,87 @@
import { FlatCompat } from '@eslint/eslintrc';
import js from '@eslint/js';
import typescriptEslint from '@typescript-eslint/eslint-plugin';
import tsParser from '@typescript-eslint/parser';
import globals from 'globals';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
export default [
{
ignores: [
'**/.DS_Store',
'**/node_modules',
'build',
'package',
'**/.env',
'**/.env.*',
'!**/.env.example',
'**/pnpm-lock.yaml',
'**/package-lock.json',
'**/yarn.lock',
'eslint.config.mjs',
'coverage',
],
},
...compat.extends(
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:unicorn/recommended',
),
{
plugins: {
'@typescript-eslint': typescriptEslint,
},
languageOptions: {
globals: {
...globals.browser,
...globals.node,
NodeJS: true,
},
parser: tsParser,
ecmaVersion: 2022,
sourceType: 'module',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
},
rules: {
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_$',
varsIgnorePattern: '^_$',
},
],
curly: 2,
'unicorn/no-useless-undefined': 'off',
'unicorn/prefer-spread': 'off',
'unicorn/no-null': 'off',
'unicorn/prevent-abbreviations': 'off',
'unicorn/no-nested-ternary': 'off',
'unicorn/consistent-function-scoping': 'off',
'unicorn/prefer-top-level-await': 'off',
'unicorn/import-style': 'off',
'svelte/button-has-type': 'error',
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/require-await': 'error',
'object-shorthand': ['error', 'always'],
},
},
];

2470
docker/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

30
docker/package.json Normal file
View file

@ -0,0 +1,30 @@
{
"name": "immich-docker",
"version": "0.0.0",
"description": "A docker-compose generator for Immich",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "vite build",
"generate": "npm run build && node dist/immich-docker.js > docker-compose.gen.yaml"
},
"type": "module",
"author": "",
"private": true,
"license": "GNU Affero General Public License version 3",
"dependencies": {
"js-yaml": "^4.1.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^9.16.0",
"@types/js-yaml": "^4.0.9",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"globals": "^15.13.0",
"json-schema-to-ts": "^3.1.1",
"prettier-plugin-organize-imports": "^4.1.0",
"prettier-plugin-sort-json": "^4.0.0",
"vite": "^6.0.3"
}
}

206
docker/src/index.ts Normal file
View file

@ -0,0 +1,206 @@
import { dump as dumpYaml } from 'js-yaml';
import { ComposeSpecification, PropertiesServices } from './types';
const RELEASE_VERSION = 'v1.122.0';
type Options = BaseOptions & DatabaseOptions & FolderOptions;
type BaseOptions = {
releaseVersion: string;
healthchecks: boolean;
};
type FolderOptions = {
baseLocation: string;
encodedVideoLocation?: string;
libraryLocation?: string;
uploadLocation?: string;
profileLocation?: string;
thumbnailsLocation?: string;
backupsLocation?: string;
};
type DatabaseOptions =
| {
externalDatabaseUrl: string;
databaseVectorExtension?: VectorExtension;
}
| {
databaseUser: string;
databasePassword: string;
databaseName: string;
databaseLocation: string;
};
type VectorExtension = 'pgvector' | 'pgvecto.rs';
type HardwareAccelerationPlatform = 'nvenc' | 'quicksync' | 'rkmpp' | 'vappi' | 'vaapi-wsl';
const getDatabaseUri = (options: Options): { url: string; extension?: VectorExtension } => {
if ('externalDatabaseUrl' in options) {
return {
url: options.externalDatabaseUrl,
extension: options.databaseVectorExtension,
};
}
const { databaseUser, databasePassword, databaseName } = options;
return {
url: `postgres://${databaseUser}:${databasePassword}@database:5432/${databaseName}`,
};
};
const makeHealthcheck = (enabled: boolean, healthcheck?: string) => {
if (!enabled) {
return { disabled: true };
}
if (healthcheck) {
return { test: healthcheck };
}
return;
};
const build = (options: Options): ComposeSpecification => {
const {
healthchecks,
baseLocation,
encodedVideoLocation,
uploadLocation,
backupsLocation,
profileLocation,
libraryLocation,
thumbnailsLocation,
} = options;
const database = getDatabaseUri(options);
const serverDependsOn = ['redis'];
const internalBaseLocation = '/usr/src/app/upload';
const serverVolumes = [
`${baseLocation}:${internalBaseLocation}`,
encodedVideoLocation && `${encodedVideoLocation}:${internalBaseLocation}/encoded-video`,
libraryLocation && `${libraryLocation}:${internalBaseLocation}/library`,
uploadLocation && `${uploadLocation}:${internalBaseLocation}/upload`,
profileLocation && `${profileLocation}:${internalBaseLocation}/profile`,
thumbnailsLocation && `${thumbnailsLocation}:${internalBaseLocation}/thumbs`,
backupsLocation && `${backupsLocation}:${internalBaseLocation}/backups`,
`/etc/localtime:/etc/localtime:ro`,
].filter((value): value is string => !!value);
const spec: ComposeSpecification = {
name: 'immich',
services: {
'immich-server': {
image: `ghcr.io/immich-app/immich-server:${RELEASE_VERSION}`,
environment: {
DB_URL: database.url,
DB_VECTOR_EXTENSION: database.extension,
},
volumes: serverVolumes,
ports: ['2283:2283'],
depends_on: serverDependsOn,
restart: 'always',
healthcheck: makeHealthcheck(healthchecks),
},
'immich-machine-learning': {
image: `ghcr.io/immich-app/immich-machine-learning:${RELEASE_VERSION}-cuda`,
volumes: ['model-cache:/cache'],
restart: 'always',
healthcheck: makeHealthcheck(healthchecks),
},
redis: {
image: 'docker.io/redis:6.2-alpine',
restart: 'always',
healthcheck: makeHealthcheck(healthchecks, 'redis-cli ping || exit 1'),
},
},
volumes: {
'model-cache': {},
},
};
if ('externalDatabaseUrl' in options === false) {
const { databaseUser, databasePassword, databaseName, databaseLocation } = options;
(spec.services as PropertiesServices).database = {
image: 'docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0',
restart: 'always',
environment: {
POSTGRES_PASSWORD: databasePassword,
POSTGRES_USER: databaseUser,
POSTGRES_DB: databaseName,
POSTGRES_INITDB_ARGS: '--data-checksums',
},
volumes: [`${databaseLocation}:/var/lib/postgresql/data`],
healthcheck: makeHealthcheck(
healthchecks,
[
'pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;',
`Chksum="$$(psql --dbname="$\${POSTGRES_DB}" --username="$\${POSTGRES_USER}" --tuples-only --no-align`,
`--command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";`,
'echo "checksum failure count is $$Chksum";',
`[ "$$Chksum" = '0' ] || exit 1\n`,
].join(' '),
),
command: [
`postgres`,
`-c shared_preload_libraries=vectors.so`,
`-c 'search_path="$$user", public, vectors'`,
`-c logging_collector=on`,
`-c max_wal_size=2GB`,
`-c shared_buffers=512MB`,
`-c wal_compression=on`,
].join(' '),
};
serverDependsOn.push('database');
}
return spec;
};
const withNewLines = (yaml: string) =>
yaml.replaceAll(/(?<leading>[^:]\n)(?<key>[ ]{0,2}\S+:)$/gm, '$<leading>\n$<key>');
const main = () => {
const commonOptions = {
baseLocation: '/home/immich',
releaseVersion: 'v1.122.0',
healthchecks: true,
// hardwareAcceleration: 'nvenc',
};
const defaultOptions: Options = {
...commonOptions,
databaseName: 'immich',
databaseUser: 'postgres',
databasePassword: 'postgres',
databaseLocation: '/home/immich/database',
};
const splitStorageOptions: Options = {
...defaultOptions,
thumbnailsLocation: '/home/fast/thumbs',
};
const externalOptions: Options = {
...commonOptions,
externalDatabaseUrl: 'postgres://immich:immich@localhost:5432/immich',
databaseVectorExtension: 'pgvector',
};
const spec = build(externalOptions);
const yaml = dumpYaml(spec, { indent: 2, lineWidth: 140 });
let output = withNewLines(yaml);
console.log(output);
};
main();
// get.immich.app/install?hardware-acceleration=nvenc&api-port=2283&vector-extension=pgvector&data=/data&thumbs=/thumbs&release-version=1.122.0&database-user=admin&database-password=admin&database-name=immich&no-healthchecks

937
docker/src/types.ts Normal file
View file

@ -0,0 +1,937 @@
export type DefinitionsInclude =
| string
| {
path?: StringOrList;
env_file?: StringOrList;
project_directory?: string;
};
export type StringOrList = string | ListOfStrings;
export type ListOfStrings = string[];
export type DefinitionsDevelopment = {
watch?: {
ignore?: string[];
path: string;
action: 'rebuild' | 'sync' | 'sync+restart';
target?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}[];
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
} & Development;
export type Development = {
watch?: {
ignore?: string[];
path: string;
action: 'rebuild' | 'sync' | 'sync+restart';
target?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}[];
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
} | null;
export type DefinitionsDeployment = {
mode?: string;
endpoint_mode?: string;
replicas?: number | string;
labels?: ListOrDict;
rollback_config?: {
parallelism?: number | string;
delay?: string;
failure_action?: string;
monitor?: string;
max_failure_ratio?: number | string;
order?: 'start-first' | 'stop-first';
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
update_config?: {
parallelism?: number | string;
delay?: string;
failure_action?: string;
monitor?: string;
max_failure_ratio?: number | string;
order?: 'start-first' | 'stop-first';
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
resources?: {
limits?: {
cpus?: number | string;
memory?: string;
pids?: number | string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
reservations?: {
cpus?: number | string;
memory?: string;
generic_resources?: DefinitionsGenericResources;
devices?: DefinitionsDevices;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
restart_policy?: {
condition?: string;
delay?: string;
max_attempts?: number | string;
window?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
placement?: {
constraints?: string[];
preferences?: {
spread?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}[];
max_replicas_per_node?: number | string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
} & Deployment;
export type ListOrDict =
| {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` ".+".
*/
[k: string]: undefined | string | number | boolean | null;
}
| string[];
export type DefinitionsGenericResources = {
discrete_resource_spec?: {
kind?: string;
value?: number | string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}[];
export type DefinitionsDevices = {
capabilities: ListOfStrings;
count?: string | number;
device_ids?: ListOfStrings;
driver?: string;
options?: ListOrDict;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}[];
export type Deployment = {
mode?: string;
endpoint_mode?: string;
replicas?: number | string;
labels?: ListOrDict;
rollback_config?: {
parallelism?: number | string;
delay?: string;
failure_action?: string;
monitor?: string;
max_failure_ratio?: number | string;
order?: 'start-first' | 'stop-first';
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
update_config?: {
parallelism?: number | string;
delay?: string;
failure_action?: string;
monitor?: string;
max_failure_ratio?: number | string;
order?: 'start-first' | 'stop-first';
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
resources?: {
limits?: {
cpus?: number | string;
memory?: string;
pids?: number | string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
reservations?: {
cpus?: number | string;
memory?: string;
generic_resources?: DefinitionsGenericResources;
devices?: DefinitionsDevices;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
restart_policy?: {
condition?: string;
delay?: string;
max_attempts?: number | string;
window?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
placement?: {
constraints?: string[];
preferences?: {
spread?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}[];
max_replicas_per_node?: number | string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
} | null;
export type ExtraHosts = {} | string[];
export type ServiceConfigOrSecret = (
| string
| {
source?: string;
target?: string;
uid?: string;
gid?: string;
mode?: number | string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}
)[];
export type Command = null | string | string[];
export type EnvFile =
| string
| (
| string
| {
path: string;
format?: string;
required?: boolean | string;
}
)[];
/**
* This interface was referenced by `PropertiesNetworks`'s JSON-Schema definition
* via the `patternProperty` "^[a-zA-Z0-9._-]+$".
*/
export type DefinitionsNetwork = {
name?: string;
driver?: string;
driver_opts?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string | number;
};
ipam?: {
driver?: string;
config?: {
subnet?: string;
ip_range?: string;
gateway?: string;
aux_addresses?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}[];
options?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
external?:
| boolean
| string
| {
name?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
internal?: boolean | string;
enable_ipv6?: boolean | string;
attachable?: boolean | string;
labels?: ListOrDict;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
} & Network;
export type Network = {
name?: string;
driver?: string;
driver_opts?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string | number;
};
ipam?: {
driver?: string;
config?: {
subnet?: string;
ip_range?: string;
gateway?: string;
aux_addresses?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}[];
options?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
external?:
| boolean
| string
| {
name?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
internal?: boolean | string;
enable_ipv6?: boolean | string;
attachable?: boolean | string;
labels?: ListOrDict;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
} | null;
/**
* This interface was referenced by `PropertiesVolumes`'s JSON-Schema definition
* via the `patternProperty` "^[a-zA-Z0-9._-]+$".
*/
export type DefinitionsVolume = {
name?: string;
driver?: string;
driver_opts?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string | number;
};
external?:
| boolean
| string
| {
name?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
labels?: ListOrDict;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
} & Volume;
export type Volume = {
name?: string;
driver?: string;
driver_opts?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string | number;
};
external?:
| boolean
| string
| {
name?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
labels?: ListOrDict;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
} | null;
/**
* The Compose file is a YAML file defining a multi-containers based application.
*/
export interface ComposeSpecification {
/**
* declared for backward compatibility, ignored.
*/
version?: string;
/**
* define the Compose project name, until user defines one explicitly.
*/
name?: string;
/**
* compose sub-projects to be included.
*/
include?: DefinitionsInclude[];
services?: PropertiesServices;
networks?: PropertiesNetworks;
volumes?: PropertiesVolumes;
secrets?: PropertiesSecrets;
configs?: PropertiesConfigs;
/**
* This interface was referenced by `ComposeSpecification`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}
export interface PropertiesServices {
[k: string]: DefinitionsService;
}
/**
* This interface was referenced by `PropertiesServices`'s JSON-Schema definition
* via the `patternProperty` "^[a-zA-Z0-9._-]+$".
*/
export interface DefinitionsService {
develop?: DefinitionsDevelopment;
deploy?: DefinitionsDeployment;
annotations?: ListOrDict;
attach?: boolean | string;
build?:
| string
| {
context?: string;
dockerfile?: string;
dockerfile_inline?: string;
entitlements?: string[];
args?: ListOrDict;
ssh?: ListOrDict;
labels?: ListOrDict;
cache_from?: string[];
cache_to?: string[];
no_cache?: boolean | string;
additional_contexts?: ListOrDict;
network?: string;
pull?: boolean | string;
target?: string;
shm_size?: number | string;
extra_hosts?: ExtraHosts;
isolation?: string;
privileged?: boolean | string;
secrets?: ServiceConfigOrSecret;
tags?: string[];
ulimits?: Ulimits;
platforms?: string[];
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
blkio_config?: {
device_read_bps?: BlkioLimit[];
device_read_iops?: BlkioLimit[];
device_write_bps?: BlkioLimit[];
device_write_iops?: BlkioLimit[];
weight?: number | string;
weight_device?: BlkioWeight[];
};
cap_add?: string[];
cap_drop?: string[];
cgroup?: 'host' | 'private';
cgroup_parent?: string;
command?: Command;
configs?: ServiceConfigOrSecret;
container_name?: string;
cpu_count?: string | number;
cpu_percent?: string | number;
cpu_shares?: number | string;
cpu_quota?: number | string;
cpu_period?: number | string;
cpu_rt_period?: number | string;
cpu_rt_runtime?: number | string;
cpus?: number | string;
cpuset?: string;
credential_spec?: {
config?: string;
file?: string;
registry?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
depends_on?:
| ListOfStrings
| {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^[a-zA-Z0-9._-]+$".
*/
[k: string]: {
restart?: boolean | string;
required?: boolean;
condition: 'service_started' | 'service_healthy' | 'service_completed_successfully';
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
};
device_cgroup_rules?: ListOfStrings;
devices?: (
| string
| {
source: string;
target?: string;
permissions?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}
)[];
dns?: StringOrList;
dns_opt?: string[];
dns_search?: StringOrList;
domainname?: string;
entrypoint?: Command;
env_file?: EnvFile;
environment?: ListOrDict;
expose?: (string | number)[];
extends?:
| string
| {
service: string;
file?: string;
};
external_links?: string[];
extra_hosts?: ExtraHosts;
group_add?: (string | number)[];
healthcheck?: DefinitionsHealthcheck;
hostname?: string;
image?: string;
init?: boolean | string;
ipc?: string;
isolation?: string;
labels?: ListOrDict;
links?: string[];
logging?: {
driver?: string;
options?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string | number | null;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
mac_address?: string;
mem_limit?: number | string;
mem_reservation?: string | number;
mem_swappiness?: number | string;
memswap_limit?: number | string;
network_mode?: string;
networks?:
| ListOfStrings
| {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^[a-zA-Z0-9._-]+$".
*/
[k: string]: {
aliases?: ListOfStrings;
ipv4_address?: string;
ipv6_address?: string;
link_local_ips?: ListOfStrings;
mac_address?: string;
driver_opts?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string | number;
};
priority?: number;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
} | null;
};
oom_kill_disable?: boolean | string;
oom_score_adj?: string | number;
pid?: string | null;
pids_limit?: number | string;
platform?: string;
ports?: (
| number
| string
| {
name?: string;
mode?: string;
host_ip?: string;
target?: number | string;
published?: string | number;
protocol?: string;
app_protocol?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}
)[];
post_start?: DefinitionsServiceHook[];
pre_stop?: DefinitionsServiceHook[];
privileged?: boolean | string;
profiles?: ListOfStrings;
pull_policy?: 'always' | 'never' | 'if_not_present' | 'build' | 'missing';
read_only?: boolean | string;
restart?: string;
runtime?: string;
scale?: number | string;
security_opt?: string[];
shm_size?: number | string;
secrets?: ServiceConfigOrSecret;
sysctls?: ListOrDict;
stdin_open?: boolean | string;
stop_grace_period?: string;
stop_signal?: string;
storage_opt?: {
[k: string]: unknown;
};
tmpfs?: StringOrList;
tty?: boolean | string;
ulimits?: Ulimits;
user?: string;
uts?: string;
userns_mode?: string;
volumes?: (
| string
| {
type: string;
source?: string;
target?: string;
read_only?: boolean | string;
consistency?: string;
bind?: {
propagation?: string;
create_host_path?: boolean | string;
selinux?: 'z' | 'Z';
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
volume?: {
nocopy?: boolean | string;
subpath?: string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
tmpfs?: {
size?: number | string;
mode?: number | string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}
)[];
volumes_from?: string[];
working_dir?: string;
/**
* This interface was referenced by `DefinitionsService`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}
export interface Ulimits {
/**
* This interface was referenced by `Ulimits`'s JSON-Schema definition
* via the `patternProperty` "^[a-z]+$".
*/
[k: string]:
| (number | string)
| {
hard: number | string;
soft: number | string;
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
};
}
export interface BlkioLimit {
path?: string;
rate?: number | string;
}
export interface BlkioWeight {
path?: string;
weight?: number | string;
}
export interface DefinitionsHealthcheck {
disable?: boolean | string;
interval?: string;
retries?: number | string;
test?: string | string[];
timeout?: string;
start_period?: string;
start_interval?: string;
/**
* This interface was referenced by `DefinitionsHealthcheck`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}
export interface DefinitionsServiceHook {
command?: Command;
user?: string;
privileged?: boolean | string;
working_dir?: string;
environment?: ListOrDict;
/**
* This interface was referenced by `DefinitionsServiceHook`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}
export interface PropertiesNetworks {
[k: string]: DefinitionsNetwork;
}
export interface PropertiesVolumes {
[k: string]: DefinitionsVolume;
}
export interface PropertiesSecrets {
[k: string]: DefinitionsSecret;
}
/**
* This interface was referenced by `PropertiesSecrets`'s JSON-Schema definition
* via the `patternProperty` "^[a-zA-Z0-9._-]+$".
*/
export interface DefinitionsSecret {
name?: string;
environment?: string;
file?: string;
external?:
| boolean
| string
| {
name?: string;
[k: string]: unknown;
};
labels?: ListOrDict;
driver?: string;
driver_opts?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.+$".
*/
[k: string]: string | number;
};
template_driver?: string;
/**
* This interface was referenced by `DefinitionsSecret`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}
export interface PropertiesConfigs {
[k: string]: DefinitionsConfig;
}
/**
* This interface was referenced by `PropertiesConfigs`'s JSON-Schema definition
* via the `patternProperty` "^[a-zA-Z0-9._-]+$".
*/
export interface DefinitionsConfig {
name?: string;
content?: string;
environment?: string;
file?: string;
external?:
| boolean
| string
| {
name?: string;
[k: string]: unknown;
};
labels?: ListOrDict;
template_driver?: string;
/**
* This interface was referenced by `DefinitionsConfig`'s JSON-Schema definition
* via the `patternProperty` "^x-".
*/
[k: string]: unknown;
}

18
docker/tsconfig.json Normal file
View file

@ -0,0 +1,18 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"module": "es2020",
"moduleResolution": "bundler",
"outDir": "./dist",
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "es2022",
"types": []
},
"include": ["src/"]
}

13
docker/vite.config.js Normal file
View file

@ -0,0 +1,13 @@
import { resolve } from 'node:path';
import { defineConfig } from 'vite';
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'immich-docker',
// the proper extensions will be added
fileName: 'immich-docker',
},
},
});