首页
/ Immich 开发环境搭建指南:用 mise 与 Docker Compose 一键启动 Server、Web 与 ML 全栈开发

Immich 开发环境搭建指南:用 mise 与 Docker Compose 一键启动 Server、Web 与 ML 全栈开发

2026-09-05 10:29:23作者:晏闻田Solitary

本文基于 Immich 官方开发者文档 setup.md 展开,系统讲解如何在本机搭建 Immich 的完整开发环境:包括 mise 工具链安装、docker-compose.dev.yml 多服务开发栈的启动、Web 前端对接远程后端、@immich/ui 本地联调、Flutter 移动端调试与 iOS 签名覆盖、国际化翻译生成,以及 IDE 的 lint/format 配置。读完本文后,你能够从零复制出一个支持热重载的 Immich 开发实例,并了解每个命令背后的任务定义与 compose 文件细节。

一、开发环境概览:五个核心服务

进入代码之前,官方提醒先阅读 CONTRIBUTING.md。此外,如果你计划贡献某个功能,文档建议在 Discord 的 #contributing 频道提前知会维护者,以确认功能可被接受、获得实现建议并避免重复劳动。

开发环境由以下服务组成,各服务的详细说明见其各自的 README:

服务 仓库位置 说明
Server server NestJS 后端,负责 API、任务队列与管理功能
Web app web SvelteKit 前端应用
Machine learning machine-learning Python FastAPI 机器学习服务
Redis 缓存与队列后端
PostgreSQL 开发数据库,暴露 5432 端口,可用任意数据库客户端直接访问

所有服务都打包在一条 Docker Compose 命令中启动。对应的开发用编排文件是 docker/docker-compose.dev.yml,从源码结构看它定义了 6 个容器:

  • immich_init:基于 server/Dockerfile.devdev 构建目标,容器启动后执行 mise install 并写入 /tmp/init-complete 标记,健康检查通过后才放行其他服务(retries: 300start_period: 300s),相当于整个开发栈的初始化前置任务;
  • immich_server:挂载整个仓库 ..:/usr/src/app,把 ${UPLOAD_LOCATION}/photos 映射为容器内 /data,并额外挂载 packages/plugin-core,对外暴露 923092312283 三个开发端口;
  • immich_web:SvelteKit 开发服务器,对外暴露 3000(Web 界面)与 24678 端口;
  • immich_machine_learning:从 machine-learning/Dockerfile 构建,默认 DEVICE=cpu(可改 armnncudarocmopenvinoopenvino-wslrknn 之一),将 ../machine-learning/immich_ml 源码目录直接挂载进容器以支持热重载,暴露 3003 端口;
  • redis(valkey 镜像)与 database(PostgreSQL 镜像,shm_size: 128mb,数据库数据落在 ${UPLOAD_LOCATION}/postgres)。

其中 node_modules.svelte-kit、构建缓存等都以命名卷形式挂入容器(server_node_modulesweb_node_modulessveltekit 等),避免把宿主机的权限问题带进容器。

mise:项目工具与任务管理中枢

整个项目统一使用 mise 管理工具版本并执行任务。安装 mise 后,在仓库根目录执行:

mise trust
mise install

即可装齐全部依赖工具。从根目录 mise.toml 可以确认当前锁定的工具版本:Node 24.15.0、pnpm 11.22.0、Java 21.0.2oazapfts 7.5.0openapi-generator-cli 2.40.1,以及跨平台的 jellyfin-ffmpeg 7.1.3-6[monorepo] 配置声明了 serverwebmobilee2edocsmachine-learning 等 config_roots,因此每个子目录各自还有 mise.toml 定义本服务任务。

任务从仓库根目录用 //namespace:task 语法执行,例如 mise //server:lint;用 mise tasks ls --all 列出所有可用任务。根目录 mise.toml 中与开发启动直接相关的任务包括:

  • //:dev:先依赖 //:plugins(构建 SDK、plugin-sdk、plugin-core),再在 docker/ 目录下执行 docker compose -f ./docker-compose.dev.yml up --remove-orphansCOMPOSE_BAKE=true,交互式运行),结束后自动执行 //:dev-down
  • //:dev-update:在 dev 基础上追加 --build -V,强制重建镜像并清理容器;
  • //:dev-downdocker compose -f ./docker-compose.dev.yml down --remove-orphans

二、启动 Server 与 Web 开发栈

按官方步骤操作:

  1. 克隆项目仓库;
  2. 复制环境变量模板:cp docker/example.env docker/.env
  3. 编辑 docker/.env,为必填变量 UPLOAD_LOCATION 提供值;
  4. 安装依赖:mise x -- pnpm i
  5. 在仓库根目录执行:
mise dev
  1. 在浏览器访问 http://localhost:3000,或用移动端 App 连接该实例。

所有服务启动时都启用热重载,形成快速反馈回路。Web 可通过 http://your-machine-ip:3000http://localhost:3000 访问;移动端 App 则通过 http://your-machine-ip:3000 连接开发后端。

注意事项web 开发容器以 uid 1000 运行,如果该 uid 对挂载的卷没有读写权限,可能会遇到错误。

关于 .env 文件,docker/example.env 给出了完整模板:UPLOAD_LOCATION=./library(上传文件存储位置)、DB_DATA_LOCATION=./postgres(数据库文件位置,不支持网络共享)、可选的 TZ 时区、IMMICH_VERSION(可固定到具体版本如 v2.1.0,模板中默认为 v3)、DB_PASSWORD(建议改为随机密码,仅限 A-Za-z0-9),以及无需修改的 DB_USERNAME=postgresDB_DATABASE_NAME=immich

仅开发 Web:连接远程后端

如果只想做 Web 开发并连接一个已存在的远程后端(不需要本地起 Server),在仓库根目录执行:

IMMICH_SERVER_URL=https://demo.immich.app/ mise //web:start

这一步会同时安装所有依赖(含 SDK)并启动开发服务器。若专门连接官方托管的 demo 服务器,可用简写:

mise //web:start-demo

这两个命令对应 web/mise.toml 中的任务链:start 依次执行 :installpnpm install --filter immich-web --frozen-lockfile)、//:sdk:install//:sdk:build,最后 pnpm run devstart-demo 则是在 :start 之前注入环境变量 IMMICH_SERVER_URL=https://demo.immich.app

Windows PowerShell 中可能需要单独设置环境变量:

$env:IMMICH_SERVER_URL = "https://demo.immich.app/"
mise //web:start

web/vite.config.ts 可以看到该变量如何生效:upstreamprocess.env.IMMICH_SERVER_URL,缺省为容器内服务发现地址 http://immich-server:2283/,并将 /api/.well-known/immich/custom.css 三类请求代理到该上游(ws: true 保证 WebSocket 也走代理)。这就是"Web-only 开发"模式下前端无需本地后端即可联调的底层机制。

本地联调 @immich/ui 设计系统

Web 端大量 UI 组件来自 @immich/ui 包(在 web/package.json 中以 ^0.86.0 引入,被 web/src/routes/+layout.svelteweb/src/lib/utils.ts 等上百处文件使用)。若要看到本地对 @immich/ui 的修改在 Immich 中生效,官方给出的流程是:

  1. @immich/ui 仓库安装为 immich/ 的兄弟目录,例如 /home/user/immich/home/user/ui
  2. @immich/ui 项目中执行 pnpm run build 构建;
  3. docker/docker-compose.dev.yml 的 web 服务中取消注释对应卷挂载 ../../ui:/usr/src/ui(该注释行位于 immich-app-base 基础 profile 的 volumes 中);
  4. web/vite.config.ts 中取消注释对应 alias('@immich/ui': path.resolve(..., '../../ui/packages/ui')),让模块解析指向本地源码;
  5. web/src/app.css 中取消注释 @import '../../../ui/packages/ui/dist/theme/default.css';,同时注释掉 @import '@immich/ui/theme/default.css';,让样式也来自本地构建产物;
  6. 通过 mise dev 启动整个栈;
  7. @immich/ui 中每次改动后重新构建(pnpm run build)。

三、移动端(Flutter)开发

基本启动步骤

  1. 执行 mise //mobile:install 安装 Flutter 依赖;
  2. 执行 mise //mobile:translation 生成翻译文件;
  3. 进入 mobile/ 目录,执行 flutter run 启动应用。

mobile/mise.toml 可确认工具链细节:Flutter 版本锁定为 3.47.1(安装后自动执行 ios/scripts/xcode_flutter_patch.sh 补丁脚本);install 任务先依赖 //:open-api-dart(从 OpenAPI 规范重新生成 Dart SDK),再执行 flutter pub get,并在 macOS 上自动 cd ios && pod install。App 启动时会询问要连接哪个后端:如果不需要改服务端代码或上传照片,可直接使用 demo 后端(https://demo.immich.app/);否则按上文自行启动服务。

iOS 代码签名

Immich 的 Apple Team ID 与 Bundle ID 定义在 mobile/ios/Signing.xcconfig 中,这些环境变量被各 target 与 scheme 复用,避免贡献者重复修改。本地开发提供了覆盖机制:创建 mobile/ios/Signing.local.xcconfig(该文件已被 gitignore),填入自己的签名值:

IMMICH_TEAM_ID = ABCDE12345
IMMICH_BUNDLE_ID_PROD = com.customuniqueid.immich
IMMICH_BUNDLE_ID_DEV = com.customuniqueid.immichdev
IMMICH_GROUP_ID = group.com.customuniqueid.immich

添加新的翻译文案

在仓库根目录的 i18n/en.json 中加入新的 key-value 对,然后执行:

mise //mobile:translation

对应 mobile/mise.tomlcodegen:translation 任务:它依赖 //:i18n:format-fix(规范化 JSON 格式)、i18n:loaderdart run easy_localization:generate -S ../i18n 生成 loader)和 i18n:keysdart run bin/generate_keys.dart 生成类型安全的翻译 key)。因此新增文案后必须跑这一步,才能在 Dart 代码中引用到新 key。

UI 组件与 Widget 预览

共享设计系统组件(按钮、输入框、表单等)位于 immich_uimobile/packages/ui 下:组件定义在 lib/src/components/(如 form.darttext_input.dartpassword_input.darticon_button.dart 等),并有与之对应的 lib/src/previews/ 预览文件。

要单独查看某个组件(支持明暗主题切换与热重载),启动 Flutter 的 Widget Previewer:

cd mobile/packages/ui
flutter widget-preview start

在安装了 Flutter 插件的 VS Code 或 Android Studio 中,打开侧边栏的 Flutter Widget Preview 标签页即可自动启动预览器。

四、IDE 配置

Lint / Format 扩展

在 IDE 中正确配置格式化器可以自动在保存时格式化代码,并即时反馈 lint 问题,显著提升开发体验。

Dart Code Metrics

移动端使用 DCM(Dart Code Metrics)做 lint 与度量计算,配置方式参见其官方 Getting Started 文档。注意:激活 DCM 许可证不是必需的——从 mobile/mise.toml 可以看到 analyze 任务由 dart analyze --fatal-infosdcm analyze lib --fatal-style --fatal-warnings 两部分组成,dcm 工具本身由 mise 从 GitHub 资产(各平台 zip 包)拉取,1.39.1 版本。

VS Code

推荐安装 FlutterDCMPrettierESLintSvelte 等扩展,它们已列在 .vscode/extensions.json 中,会作为工作区推荐出现。该文件实际推荐了 14 个扩展,除上述核心五件外还包括 Tailwind CSS、Playwright、Vitest Explorer、EditorConfig、Shell Format、ShellCheck、yamlfmt,以及预览阶段的 typescriptteam.native-preview

工作区设置见 .vscode/settings.json,与官方文档一致的核心内容如下:

{
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true,
    "editor.tabSize": 2
  },
  "[dart]": {
    "editor.defaultFormatter": "Dart-Code.dart-code",
    "editor.formatOnSave": true,
    "editor.selectionHighlight": false,
    "editor.suggest.snippetsPreventQuickSuggestions": false,
    "editor.suggestSelection": "first",
    "editor.tabCompletion": "onlySnippets",
    "editor.wordBasedSuggestions": "off"
  },
  "[javascript]": {
    "editor.codeActionsOnSave": {
      "source.organizeImports": "explicit",
      "source.removeUnusedImports": "explicit"
    },
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true,
    "editor.tabSize": 2
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true,
    "editor.tabSize": 2
  },
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true,
    "editor.tabSize": 2
  },
  "[svelte]": {
    "editor.codeActionsOnSave": {
      "source.organizeImports": "explicit",
      "source.removeUnusedImports": "explicit"
    },
    "editor.defaultFormatter": "svelte.svelte-vscode",
    "editor.formatOnSave": true,
    "editor.tabSize": 2
  },
  "[typescript]": {
    "editor.codeActionsOnSave": {
      "source.organizeImports": "explicit",
      "source.removeUnusedImports": "explicit"
    },
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true,
    "editor.tabSize": 2
  },
  "cSpell.words": ["immich"],
  "editor.formatOnSave": true,
  "eslint.validate": ["javascript", "svelte"],
  "explorer.fileNesting.enabled": true,
  "explorer.fileNesting.patterns": {
    "*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart",
    "*.ts": "${capture}.spec.ts,${capture}.mock.ts"
  },
  "svelte.enable-ts-plugin": true,
  "typescript.preferences.importModuleSpecifier": "non-relative"
}

几个值得注意的细节:文件嵌套规则会把 .g.dart/.drift.dart/.gr.dart 等生成产物折叠到源文件下,把 .spec.ts/.mock.ts 折叠到对应模块下;typescript.preferences.importModuleSpecifier 设为 non-relative 配合 web 端的非相对路径导入约定。

五、小结与延伸阅读

整套开发流程可以概括为:mise trust && mise install 装齐工具链 → cp docker/example.env docker/.env 并配置 UPLOAD_LOCATIONmise dev 一条命令拉起带热重载的六容器开发栈 → 浏览器访问 http://localhost:3000。仅改 Web 时可用 IMMICH_SERVER_URL 指向远程后端;改移动端时通过 mise //mobile:installmise //mobile:translation 生成 SDK 与翻译产物,iOS 签名则用 Signing.local.xcconfig 覆盖。

排错时可配合开发者文档中的 troubleshootingarchitecturetesting 继续深入;数据库结构变更参见 database-migrations,多语言协作流程参见 translations

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388