[{"data":1,"prerenderedAt":2660},["ShallowReactive",2],{"navigation_docs_en":3,"-en-self-hosting-docker-compose":427,"-en-self-hosting-docker-compose-surround":2655},[4,31,117,188,238,271,310,369,378],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":30},"Getting started","i-hugeicons-rocket-01","\u002Fen\u002Fgetting-started","en\u002F01.getting-started",[10,15,20,25],{"title":11,"path":12,"stem":13,"icon":14},"What is DDM?","\u002Fen\u002Fgetting-started\u002Fwhat-is-ddm","en\u002F01.getting-started\u002F01.what-is-ddm","i-hugeicons-information-circle",{"title":16,"path":17,"stem":18,"icon":19},"Account and sign-in","\u002Fen\u002Fgetting-started\u002Fsign-in","en\u002F01.getting-started\u002F02.sign-in","i-hugeicons-key-01",{"title":21,"path":22,"stem":23,"icon":24},"AI in DDM","\u002Fen\u002Fgetting-started\u002Fai-in-ddm","en\u002F01.getting-started\u002F03.ai-in-ddm","i-hugeicons-ai-magic",{"title":26,"path":27,"stem":28,"icon":29},"System status","\u002Fen\u002Fgetting-started\u002Fsystem-status","en\u002F01.getting-started\u002F04.system-status","i-hugeicons-activity-03",false,{"title":32,"icon":33,"path":34,"stem":35,"children":36,"page":30},"CMS","i-hugeicons-dashboard-square-01","\u002Fen\u002Fcms","en\u002F02.cms",[37,42,47,52,57,62,67,72,77,82,87,92,97,102,107,112],{"title":38,"path":39,"stem":40,"icon":41},"The CMS at a glance","\u002Fen\u002Fcms\u002Foverview","en\u002F02.cms\u002F01.overview","i-hugeicons-compass-01",{"title":43,"path":44,"stem":45,"icon":46},"Uploading documents","\u002Fen\u002Fcms\u002Fupload","en\u002F02.cms\u002F02.upload","i-hugeicons-upload-01",{"title":48,"path":49,"stem":50,"icon":51},"Categories","\u002Fen\u002Fcms\u002Fcategories","en\u002F02.cms\u002F03.categories","i-hugeicons-folder-tree",{"title":53,"path":54,"stem":55,"icon":56},"Editing documents","\u002Fen\u002Fcms\u002Fdocuments","en\u002F02.cms\u002F04.documents","i-hugeicons-file-edit",{"title":58,"path":59,"stem":60,"icon":61},"Searching and filtering","\u002Fen\u002Fcms\u002Fsearch-and-filters","en\u002F02.cms\u002F05.search-and-filters","i-hugeicons-search-01",{"title":63,"path":64,"stem":65,"icon":66},"Groups and permissions","\u002Fen\u002Fcms\u002Fgroups-and-permissions","en\u002F02.cms\u002F06.groups-and-permissions","i-hugeicons-user-multiple",{"title":68,"path":69,"stem":70,"icon":71},"Users","\u002Fen\u002Fcms\u002Fusers","en\u002F02.cms\u002F07.users","i-hugeicons-user-add-01",{"title":73,"path":74,"stem":75,"icon":76},"Approvals","\u002Fen\u002Fcms\u002Fapprovals","en\u002F02.cms\u002F08.approvals","i-hugeicons-checkmark-badge-01",{"title":78,"path":79,"stem":80,"icon":81},"Markets and translations","\u002Fen\u002Fcms\u002Fmarkets-and-translations","en\u002F02.cms\u002F09.markets-and-translations","i-hugeicons-globe-02",{"title":83,"path":84,"stem":85,"icon":86},"Note templates","\u002Fen\u002Fcms\u002Fnote-templates","en\u002F02.cms\u002F10.note-templates","i-hugeicons-layout-01",{"title":88,"path":89,"stem":90,"icon":91},"Usage and audit log","\u002Fen\u002Fcms\u002Fusage-and-audit","en\u002F02.cms\u002F11.usage-and-audit","i-hugeicons-chart-column",{"title":93,"path":94,"stem":95,"icon":96},"AI assistant","\u002Fen\u002Fcms\u002Fassistant","en\u002F02.cms\u002F12.assistant","i-hugeicons-sparkles",{"title":98,"path":99,"stem":100,"icon":101},"Settings","\u002Fen\u002Fcms\u002Fsettings","en\u002F02.cms\u002F13.settings","i-hugeicons-settings-02",{"title":103,"path":104,"stem":105,"icon":106},"Plans","\u002Fen\u002Fcms\u002Fplans","en\u002F02.cms\u002F14.plans","i-hugeicons-package",{"title":108,"path":109,"stem":110,"icon":111},"Feature requests","\u002Fen\u002Fcms\u002Ffeature-requests","en\u002F02.cms\u002F15.feature-requests","i-hugeicons-idea-01",{"title":113,"path":114,"stem":115,"icon":116},"Report a bug","\u002Fen\u002Fcms\u002Fbug-reports","en\u002F02.cms\u002F16.bug-reports","i-hugeicons-bug-01",{"title":118,"icon":119,"path":120,"stem":121,"children":122,"page":30},"App","i-hugeicons-smart-phone-01","\u002Fen\u002Fapp","en\u002F03.app",[123,128,133,138,143,147,152,157,162,167,170,173,176,179,184],{"title":124,"path":125,"stem":126,"icon":127},"Signing in and finding your way","\u002Fen\u002Fapp\u002Foverview","en\u002F03.app\u002F01.overview","i-hugeicons-login-03",{"title":129,"path":130,"stem":131,"icon":132},"Tabs and split view","\u002Fen\u002Fapp\u002Ftabs","en\u002F03.app\u002F02.tabs","i-hugeicons-layout-2-column",{"title":134,"path":135,"stem":136,"icon":137},"Finding and reading documents","\u002Fen\u002Fapp\u002Fdocuments","en\u002F03.app\u002F03.documents","i-hugeicons-file-01",{"title":139,"path":140,"stem":141,"icon":142},"Favorites","\u002Fen\u002Fapp\u002Ffavorites","en\u002F03.app\u002F04.favorites","i-hugeicons-favourite",{"title":144,"path":145,"stem":146,"icon":61},"Searching","\u002Fen\u002Fapp\u002Fsearch","en\u002F03.app\u002F05.search",{"title":148,"path":149,"stem":150,"icon":151},"Notes","\u002Fen\u002Fapp\u002Fnotes","en\u002F03.app\u002F06.notes","i-hugeicons-note-edit",{"title":153,"path":154,"stem":155,"icon":156},"Calendar and appointments","\u002Fen\u002Fapp\u002Fcalendar","en\u002F03.app\u002F07.calendar","i-hugeicons-calendar-03",{"title":158,"path":159,"stem":160,"icon":161},"Sending to customers","\u002Fen\u002Fapp\u002Foutbox","en\u002F03.app\u002F08.outbox","i-hugeicons-sent",{"title":163,"path":164,"stem":165,"icon":166},"Working offline","\u002Fen\u002Fapp\u002Foffline","en\u002F03.app\u002F09.offline","i-hugeicons-wifi-off-01",{"title":93,"path":168,"stem":169,"icon":96},"\u002Fen\u002Fapp\u002Fassistant","en\u002F03.app\u002F10.assistant",{"title":98,"path":171,"stem":172,"icon":101},"\u002Fen\u002Fapp\u002Fsettings","en\u002F03.app\u002F11.settings",{"title":108,"path":174,"stem":175,"icon":111},"\u002Fen\u002Fapp\u002Ffeature-requests","en\u002F03.app\u002F12.feature-requests",{"title":113,"path":177,"stem":178,"icon":116},"\u002Fen\u002Fapp\u002Fbug-reports","en\u002F03.app\u002F13.bug-reports",{"title":180,"path":181,"stem":182,"icon":183},"Desktop app","\u002Fen\u002Fapp\u002Fdesktop-app","en\u002F03.app\u002F14.desktop-app","i-hugeicons-computer",{"title":185,"path":186,"stem":187,"icon":119},"Mobile app","\u002Fen\u002Fapp\u002Fmobile-app","en\u002F03.app\u002F15.mobile-app",{"title":189,"icon":190,"path":191,"stem":192,"children":193,"page":30},"Sign-in & directories","i-hugeicons-security-check","\u002Fen\u002Fsign-in-and-directories","en\u002F04.sign-in-and-directories",[194,198,202,207,212,217,222,226,230,234],{"title":195,"path":196,"stem":197,"icon":19},"Sign-in methods","\u002Fen\u002Fsign-in-and-directories\u002Fsign-in-methods","en\u002F04.sign-in-and-directories\u002F01.sign-in-methods",{"title":199,"path":200,"stem":201,"icon":190},"Single sign-on","\u002Fen\u002Fsign-in-and-directories\u002Fsingle-sign-on","en\u002F04.sign-in-and-directories\u002F02.single-sign-on",{"title":203,"path":204,"stem":205,"icon":206},"Directory services (LDAP)","\u002Fen\u002Fsign-in-and-directories\u002Fdirectory-services","en\u002F04.sign-in-and-directories\u002F03.directory-services","i-hugeicons-hierarchy",{"title":208,"path":209,"stem":210,"icon":211},"Synchronisation and sign-in","\u002Fen\u002Fsign-in-and-directories\u002Fdirectory-sync","en\u002F04.sign-in-and-directories\u002F04.directory-sync","i-hugeicons-refresh",{"title":213,"path":214,"stem":215,"icon":216},"Microsoft Entra ID","\u002Fen\u002Fsign-in-and-directories\u002Fmicrosoft-entra-id","en\u002F04.sign-in-and-directories\u002F05.microsoft-entra-id","i-hugeicons-building-03",{"title":218,"path":219,"stem":220,"icon":221},"Okta","\u002Fen\u002Fsign-in-and-directories\u002Fokta","en\u002F04.sign-in-and-directories\u002F06.okta","i-hugeicons-finger-print",{"title":223,"path":224,"stem":225,"icon":81},"Google Workspace","\u002Fen\u002Fsign-in-and-directories\u002Fgoogle-workspace","en\u002F04.sign-in-and-directories\u002F07.google-workspace",{"title":227,"path":228,"stem":229,"icon":119},"Two-factor authentication","\u002Fen\u002Fsign-in-and-directories\u002Ftwo-factor-authentication","en\u002F04.sign-in-and-directories\u002F08.two-factor-authentication",{"title":231,"path":232,"stem":233,"icon":221},"Passkeys","\u002Fen\u002Fsign-in-and-directories\u002Fpasskeys","en\u002F04.sign-in-and-directories\u002F09.passkeys",{"title":235,"path":236,"stem":237,"icon":156},"Calendar access","\u002Fen\u002Fsign-in-and-directories\u002Fcalendar-access","en\u002F04.sign-in-and-directories\u002F10.calendar-access",{"title":239,"icon":240,"path":241,"stem":242,"children":243,"page":30},"MCP server","i-hugeicons-ai-network","\u002Fen\u002Fmcp-server","en\u002F05.mcp-server",[244,248,253,257,262,266],{"title":245,"path":246,"stem":247,"icon":240},"Overview","\u002Fen\u002Fmcp-server\u002Foverview","en\u002F05.mcp-server\u002F01.overview",{"title":249,"path":250,"stem":251,"icon":252},"Setup","\u002Fen\u002Fmcp-server\u002Fsetup","en\u002F05.mcp-server\u002F02.setup","i-hugeicons-plug-socket",{"title":254,"path":255,"stem":256,"icon":111},"What you can do with it","\u002Fen\u002Fmcp-server\u002Fuse-cases","en\u002F05.mcp-server\u002F03.use-cases",{"title":258,"path":259,"stem":260,"icon":261},"Tools","\u002Fen\u002Fmcp-server\u002Ftools","en\u002F05.mcp-server\u002F04.tools","i-hugeicons-wrench-01",{"title":263,"path":264,"stem":265,"icon":76},"Approving changes","\u002Fen\u002Fmcp-server\u002Fapproving-changes","en\u002F05.mcp-server\u002F05.approving-changes",{"title":267,"path":268,"stem":269,"icon":270},"Administration & security","\u002Fen\u002Fmcp-server\u002Fadmin-and-security","en\u002F05.mcp-server\u002F06.admin-and-security","i-hugeicons-shield-key",{"title":272,"icon":273,"path":274,"stem":275,"children":276,"page":30},"External sources","i-hugeicons-database-sync","\u002Fen\u002Fexternal-sources","en\u002F06.external-sources",[277,280,285,290,295,300,305],{"title":245,"path":278,"stem":279,"icon":273},"\u002Fen\u002Fexternal-sources\u002Foverview","en\u002F06.external-sources\u002F01.overview",{"title":281,"path":282,"stem":283,"icon":284},"SharePoint","\u002Fen\u002Fexternal-sources\u002Fsharepoint","en\u002F06.external-sources\u002F02.sharepoint","i-hugeicons-microsoft",{"title":286,"path":287,"stem":288,"icon":289},"OneDrive","\u002Fen\u002Fexternal-sources\u002Fonedrive","en\u002F06.external-sources\u002F03.onedrive","i-hugeicons-folder-cloud",{"title":291,"path":292,"stem":293,"icon":294},"Google Drive","\u002Fen\u002Fexternal-sources\u002Fgoogle-drive","en\u002F06.external-sources\u002F04.google-drive","i-hugeicons-google-drive",{"title":296,"path":297,"stem":298,"icon":299},"FTP \u002F SFTP","\u002Fen\u002Fexternal-sources\u002Fftp-sftp","en\u002F06.external-sources\u002F05.ftp-sftp","i-hugeicons-server-stack-01",{"title":301,"path":302,"stem":303,"icon":304},"REST interface","\u002Fen\u002Fexternal-sources\u002Frest","en\u002F06.external-sources\u002F06.rest","i-hugeicons-api",{"title":306,"path":307,"stem":308,"icon":309},"SOAP interface","\u002Fen\u002Fexternal-sources\u002Fsoap","en\u002F06.external-sources\u002F07.soap","i-hugeicons-source-code",{"title":311,"icon":304,"path":312,"stem":313,"children":314,"page":30},"Integration API","\u002Fen\u002Fintegration-api","en\u002F07.integration-api",[315,318,322,327,332,337,341,346,350,354,359,364],{"title":245,"path":316,"stem":317,"icon":14},"\u002Fen\u002Fintegration-api\u002Foverview","en\u002F07.integration-api\u002F01.overview",{"title":319,"path":320,"stem":321,"icon":19},"Authentication","\u002Fen\u002Fintegration-api\u002Fauthentication","en\u002F07.integration-api\u002F02.authentication",{"title":323,"path":324,"stem":325,"icon":326},"Conventions","\u002Fen\u002Fintegration-api\u002Fconventions","en\u002F07.integration-api\u002F03.conventions","i-hugeicons-book-open-01",{"title":328,"path":329,"stem":330,"icon":331},"Pushing documents","\u002Fen\u002Fintegration-api\u002Fpushing-documents","en\u002F07.integration-api\u002F04.pushing-documents","i-hugeicons-upload-02",{"title":333,"path":334,"stem":335,"icon":336},"Consuming content","\u002Fen\u002Fintegration-api\u002Fconsuming-content","en\u002F07.integration-api\u002F05.consuming-content","i-hugeicons-download-02",{"title":338,"path":339,"stem":340,"icon":137},"Reference: documents","\u002Fen\u002Fintegration-api\u002Freference-documents","en\u002F07.integration-api\u002F06.reference-documents",{"title":342,"path":343,"stem":344,"icon":345},"Reference: categories, tags, markets","\u002Fen\u002Fintegration-api\u002Freference-categories-tags","en\u002F07.integration-api\u002F07.reference-categories-tags","i-hugeicons-folder-01",{"title":347,"path":348,"stem":349,"icon":211},"Reference: sync manifest","\u002Fen\u002Fintegration-api\u002Freference-sync","en\u002F07.integration-api\u002F08.reference-sync",{"title":351,"path":352,"stem":353,"icon":309},"OpenAPI","\u002Fen\u002Fintegration-api\u002Fopenapi","en\u002F07.integration-api\u002F09.openapi",{"title":355,"path":356,"stem":357,"icon":358},"Changelog","\u002Fen\u002Fintegration-api\u002Fchangelog","en\u002F07.integration-api\u002F10.changelog","i-hugeicons-time-schedule",{"title":360,"path":361,"stem":362,"icon":363},"Reference: groups, markets, access","\u002Fen\u002Fintegration-api\u002Freference-groups-access","en\u002F07.integration-api\u002F11.reference-groups-access","i-hugeicons-user-lock-01",{"title":365,"path":366,"stem":367,"icon":368},"Moving from CMWS","\u002Fen\u002Fintegration-api\u002Fcmws","en\u002F07.integration-api\u002F12.cmws","i-hugeicons-arrow-reload-horizontal",{"title":370,"icon":371,"path":372,"stem":373,"children":374,"page":30},"What's new","i-hugeicons-gift","\u002Fen\u002Fwhats-new","en\u002F08.whats-new",[375],{"title":355,"path":376,"stem":377,"icon":358},"\u002Fen\u002Fwhats-new\u002Fchangelog","en\u002F08.whats-new\u002F01.changelog",{"title":379,"icon":299,"path":380,"stem":381,"children":382,"page":30},"Self-hosting","\u002Fen\u002Fself-hosting","en\u002F09.self-hosting",[383,386,390,395,399,404,408,413,418,422],{"title":245,"path":384,"stem":385,"icon":14},"\u002Fen\u002Fself-hosting\u002Foverview","en\u002F09.self-hosting\u002F01.overview",{"title":387,"path":388,"stem":389,"icon":106},"Docker Compose","\u002Fen\u002Fself-hosting\u002Fdocker-compose","en\u002F09.self-hosting\u002F02.docker-compose",{"title":391,"path":392,"stem":393,"icon":394},"Kubernetes","\u002Fen\u002Fself-hosting\u002Fkubernetes","en\u002F09.self-hosting\u002F03.kubernetes","i-hugeicons-cloud",{"title":396,"path":397,"stem":398,"icon":101},"Configuration","\u002Fen\u002Fself-hosting\u002Fconfiguration","en\u002F09.self-hosting\u002F04.configuration",{"title":400,"path":401,"stem":402,"icon":403},"Licence","\u002Fen\u002Fself-hosting\u002Flicence","en\u002F09.self-hosting\u002F05.licence","i-hugeicons-license",{"title":405,"path":406,"stem":407,"icon":211},"Updates","\u002Fen\u002Fself-hosting\u002Fupdates","en\u002F09.self-hosting\u002F06.updates",{"title":409,"path":410,"stem":411,"icon":412},"Postgres","\u002Fen\u002Fself-hosting\u002Fpostgres","en\u002F09.self-hosting\u002F07.postgres","i-hugeicons-database",{"title":414,"path":415,"stem":416,"icon":417},"Backups","\u002Fen\u002Fself-hosting\u002Fbackups","en\u002F09.self-hosting\u002F08.backups","i-hugeicons-database-restore",{"title":419,"path":420,"stem":421,"icon":261},"Troubleshooting","\u002Fen\u002Fself-hosting\u002Ftroubleshooting","en\u002F09.self-hosting\u002F09.troubleshooting",{"title":423,"path":424,"stem":425,"icon":426},"Firewall","\u002Fen\u002Fself-hosting\u002Ffirewall","en\u002F09.self-hosting\u002F10.firewall","i-hugeicons-firewall",{"id":428,"title":387,"body":429,"description":2648,"extension":2649,"links":2650,"meta":2651,"navigation":2652,"path":388,"seo":2653,"stem":389,"__hash__":2654},"docs_en\u002Fen\u002F09.self-hosting\u002F02.docker-compose.md",{"type":430,"value":431,"toc":2639},"minimark",[432,436,441,444,504,508,515,528,1899,1906,2230,2238,2246,2250,2255,2405,2439,2445,2449,2459,2486,2490,2529,2539,2543,2559,2562,2566,2624,2635],[433,434,435],"p",{},"On a single server, Docker Compose is the simplest way. Everything you need for it is on this page: three files and your deploy token.",[437,438,440],"h2",{"id":439},"_1-sign-in-to-the-registry","1. Sign in to the registry",[433,442,443],{},"Sign the server in with the deploy token you got from us:",[445,446,451],"pre",{"className":447,"code":448,"language":449,"meta":450,"style":450},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","docker login registry.gitlab.com -u \u003Ctoken name> -p \u003CToken>\n","bash","",[452,453,454],"code",{"__ignoreMap":450},[455,456,459,463,467,470,473,477,480,483,487,490,493,495,498,501],"span",{"class":457,"line":458},"line",1,[455,460,462],{"class":461},"sBMFI","docker",[455,464,466],{"class":465},"sfazB"," login",[455,468,469],{"class":465}," registry.gitlab.com",[455,471,472],{"class":465}," -u",[455,474,476],{"class":475},"sMK4o"," \u003C",[455,478,479],{"class":465},"token",[455,481,482],{"class":465}," nam",[455,484,486],{"class":485},"sTEyZ","e",[455,488,489],{"class":475},">",[455,491,492],{"class":465}," -p",[455,494,476],{"class":475},[455,496,497],{"class":465},"Toke",[455,499,500],{"class":485},"n",[455,502,503],{"class":475},">\n",[437,505,507],{"id":506},"_2-put-the-files-in-place","2. Put the files in place",[433,509,510,511,514],{},"Create a folder, for example ",[452,512,513],{},"\u002Fopt\u002Fddm",", with these three files in it.",[433,516,517,523,524,527],{},[518,519,520],"strong",{},[452,521,522],{},"compose.yaml"," – the four services, their volumes and health checks. It stays as it is; what you set goes into ",[452,525,526],{},".env",".",[445,529,533],{"className":530,"code":531,"filename":522,"language":532,"meta":450,"style":450},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# DDM on one server, with Docker Compose — as the user guide describes it\n# („Selbst betreiben\" \u002F „Self-hosting\").\n#\n#     cp .env.example .env      # and fill it in\n#     docker login registry.gitlab.com   # with the deploy token you were sent\n#     docker compose up -d\n#\n# Four services: Postgres, the cms (the management app, and the API everything\n# else talks to), the render worker (text, thumbnails and PDFs of what is\n# uploaded) and the reader app. The cms and the reader app answer on two\n# hostnames, behind a reverse proxy that terminates TLS: your own, pointed at\n# the ports below, or Caddy from this file (`docker compose --profile proxy up\n# -d`, see `Caddyfile`).\n#\n# Every setting of the user guide's „Konfiguration\" \u002F „Configuration\" can go\n# into `.env`; the ones set below are fixed by this layout. The images are those of\n# the release in `DDM_VERSION`; the cms migrates the database when it starts.\nname: ddm\n\nx-app: &app\n  restart: unless-stopped\n  # Followed by Watchtower started with `--label-enable`, for an installation\n  # that updates itself (`DDM_VERSION=stable`). Not Postgres: a new major of it\n  # needs its data upgraded by hand.\n  labels:\n    com.centurylinklabs.watchtower.enable: \"true\"\n\nservices:\n  postgres:\n    # Postgres with the German dictionary DDM searches with — by its major,\n    # which only ever changes by hand.\n    image: ${DDM_REGISTRY:-registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images}\u002Fpostgres:18\n    restart: unless-stopped\n    environment:\n      POSTGRES_USER: ddm\n      POSTGRES_DB: ddm\n      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}\n    volumes:\n      - postgres:\u002Fvar\u002Flib\u002Fpostgresql\n    healthcheck:\n      test: [CMD, pg_isready, -U, ddm, -d, ddm]\n      interval: 5s\n      timeout: 5s\n      retries: 10\n\n  cms:\n    \u003C\u003C: *app\n    image: ${DDM_REGISTRY:-registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images}\u002Fcms:${DDM_VERSION:-latest}\n    env_file: .env\n    environment:\n      # Which version of these files this is: a release that needs newer ones\n      # says so to the administrators, rather than failing (user guide, „Updates\").\n      DDM_DEPLOY_VERSION: \"1\"\n      DATABASE_URL: postgres:\u002F\u002Fddm:${POSTGRES_PASSWORD}@postgres:5432\u002Fddm\n      BETTER_AUTH_URL: https:\u002F\u002F${DDM_CMS_HOST:?set DDM_CMS_HOST in .env}\n      CLIENT_ORIGIN: https:\u002F\u002F${DDM_APP_HOST:?set DDM_APP_HOST in .env}\n      # The documents, and the database's dumps taken before each migration\n      # (the last three) — unless `S3_ENDPOINT` names a bucket for both.\n      STORAGE_DIR: \u002Fdata\u002Fstorage\n      BACKUP_DIR: \u002Fdata\u002Fbackups\n      # Uploads are stored here and drawn by the render worker.\n      RENDER_MODE: worker\n      MAX_UPLOAD_BYTES: ${MAX_UPLOAD_BYTES:-1073741824}\n    volumes:\n      - data:\u002Fdata\n    ports:\n      - ${DDM_CMS_PORT:-127.0.0.1:3000}:3000\n    depends_on:\n      postgres:\n        condition: service_healthy\n    healthcheck:\n      test: [CMD, bun, -e, \"process.exit((await fetch('http:\u002F\u002F127.0.0.1:3000\u002Fapi\u002Fauth\u002Fok')).ok ? 0 : 1)\"]\n      interval: 10s\n      timeout: 5s\n      retries: 6\n      # Migrations first, on a new release.\n      start_period: 5m\n      start_interval: 2s\n\n  render-worker:\n    \u003C\u003C: *app\n    image: ${DDM_REGISTRY:-registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images}\u002Frender-worker:${DDM_VERSION:-latest}\n    environment:\n      DATABASE_URL: postgres:\u002F\u002Fddm:${POSTGRES_PASSWORD}@postgres:5432\u002Fddm\n      STORAGE_DRIVER: ${STORAGE_DRIVER:-}\n      STORAGE_DIR: \u002Fdata\u002Fstorage\n      S3_ENDPOINT: ${S3_ENDPOINT:-}\n      S3_BUCKET: ${S3_BUCKET:-}\n      S3_REGION: ${S3_REGION:-}\n      S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-}\n      S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-}\n      S3_FORCE_PATH_STYLE: ${S3_FORCE_PATH_STYLE:-true}\n      THUMBNAILS: ${THUMBNAILS:-on}\n      RENDER_LARGE_OFFICE: ${RENDER_LARGE_OFFICE:-on}\n    volumes:\n      - data:\u002Fdata\n    # After the cms has migrated the database to this release.\n    depends_on:\n      cms:\n        condition: service_healthy\n    # It finishes the documents in hand before it stops — LibreOffice may take\n    # minutes over a large deck.\n    stop_grace_period: 11m\n\n  client:\n    \u003C\u003C: *app\n    image: ${DDM_REGISTRY:-registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images}\u002Fclient:${DDM_VERSION:-latest}\n    environment:\n      NUXT_API_ORIGIN: http:\u002F\u002Fcms:3000\n      NUXT_PUBLIC_MGMT_URL: https:\u002F\u002F${DDM_CMS_HOST}\n      # The reader app on this installation, for the mobile app's „Server\".\n      NUXT_PUBLIC_SERVER_URL: https:\u002F\u002F${DDM_APP_HOST}\n      RENDER_MODE: worker\n      THUMBNAILS: ${THUMBNAILS:-on}\n      NUXT_PUBLIC_SSO_PROVIDERS: ${NUXT_PUBLIC_SSO_PROVIDERS:-}\n    ports:\n      - ${DDM_APP_PORT:-127.0.0.1:3001}:3000\n    depends_on:\n      cms:\n        condition: service_healthy\n    # Through to the cms: what the reader app forwards answers, too.\n    healthcheck:\n      test: [CMD, bun, -e, \"process.exit((await fetch('http:\u002F\u002F127.0.0.1:3000\u002Fapi\u002Fauth\u002Fok')).ok ? 0 : 1)\"]\n      interval: 10s\n      timeout: 5s\n      retries: 6\n      start_period: 1m\n      start_interval: 2s\n\n  # TLS and both hostnames, with certificates from Let's Encrypt: only with\n  # `--profile proxy`, for a server with nothing else on ports 80 and 443.\n  caddy:\n    image: caddy:2.10-alpine\n    profiles: [proxy]\n    restart: unless-stopped\n    environment:\n      DDM_CMS_HOST: ${DDM_CMS_HOST}\n      DDM_APP_HOST: ${DDM_APP_HOST}\n    ports:\n      - 80:80\n      - 443:443\n      - 443:443\u002Fudp\n    volumes:\n      - .\u002FCaddyfile:\u002Fetc\u002Fcaddy\u002FCaddyfile:ro\n      - caddy:\u002Fdata\n    depends_on: [cms, client]\n\nvolumes:\n  postgres:\n  data:\n  caddy:\n","yaml",[452,534,535,541,547,553,559,565,571,576,582,588,594,600,606,612,617,623,629,635,648,655,670,681,687,693,699,708,725,730,738,746,752,758,769,779,787,797,807,818,826,835,843,885,896,906,918,923,931,942,952,963,970,976,982,997,1008,1019,1030,1036,1042,1053,1064,1070,1081,1092,1099,1107,1115,1123,1131,1139,1150,1157,1190,1200,1209,1219,1225,1236,1247,1252,1260,1269,1279,1286,1295,1306,1315,1326,1337,1348,1359,1370,1381,1392,1403,1410,1417,1423,1430,1438,1447,1453,1459,1470,1475,1483,1492,1502,1509,1520,1531,1537,1548,1557,1566,1577,1584,1592,1599,1606,1615,1621,1628,1657,1666,1675,1684,1694,1703,1708,1714,1720,1728,1738,1753,1762,1769,1780,1791,1798,1806,1814,1822,1829,1837,1845,1864,1869,1877,1884,1892],{"__ignoreMap":450},[455,536,537],{"class":457,"line":458},[455,538,540],{"class":539},"sHwdD","# DDM on one server, with Docker Compose — as the user guide describes it\n",[455,542,544],{"class":457,"line":543},2,[455,545,546],{"class":539},"# („Selbst betreiben\" \u002F „Self-hosting\").\n",[455,548,550],{"class":457,"line":549},3,[455,551,552],{"class":539},"#\n",[455,554,556],{"class":457,"line":555},4,[455,557,558],{"class":539},"#     cp .env.example .env      # and fill it in\n",[455,560,562],{"class":457,"line":561},5,[455,563,564],{"class":539},"#     docker login registry.gitlab.com   # with the deploy token you were sent\n",[455,566,568],{"class":457,"line":567},6,[455,569,570],{"class":539},"#     docker compose up -d\n",[455,572,574],{"class":457,"line":573},7,[455,575,552],{"class":539},[455,577,579],{"class":457,"line":578},8,[455,580,581],{"class":539},"# Four services: Postgres, the cms (the management app, and the API everything\n",[455,583,585],{"class":457,"line":584},9,[455,586,587],{"class":539},"# else talks to), the render worker (text, thumbnails and PDFs of what is\n",[455,589,591],{"class":457,"line":590},10,[455,592,593],{"class":539},"# uploaded) and the reader app. The cms and the reader app answer on two\n",[455,595,597],{"class":457,"line":596},11,[455,598,599],{"class":539},"# hostnames, behind a reverse proxy that terminates TLS: your own, pointed at\n",[455,601,603],{"class":457,"line":602},12,[455,604,605],{"class":539},"# the ports below, or Caddy from this file (`docker compose --profile proxy up\n",[455,607,609],{"class":457,"line":608},13,[455,610,611],{"class":539},"# -d`, see `Caddyfile`).\n",[455,613,615],{"class":457,"line":614},14,[455,616,552],{"class":539},[455,618,620],{"class":457,"line":619},15,[455,621,622],{"class":539},"# Every setting of the user guide's „Konfiguration\" \u002F „Configuration\" can go\n",[455,624,626],{"class":457,"line":625},16,[455,627,628],{"class":539},"# into `.env`; the ones set below are fixed by this layout. The images are those of\n",[455,630,632],{"class":457,"line":631},17,[455,633,634],{"class":539},"# the release in `DDM_VERSION`; the cms migrates the database when it starts.\n",[455,636,638,642,645],{"class":457,"line":637},18,[455,639,641],{"class":640},"swJcz","name",[455,643,644],{"class":475},":",[455,646,647],{"class":465}," ddm\n",[455,649,651],{"class":457,"line":650},19,[455,652,654],{"emptyLinePlaceholder":653},true,"\n",[455,656,658,661,663,667],{"class":457,"line":657},20,[455,659,660],{"class":640},"x-app",[455,662,644],{"class":475},[455,664,666],{"class":665},"s7zQu"," &",[455,668,669],{"class":461},"app\n",[455,671,673,676,678],{"class":457,"line":672},21,[455,674,675],{"class":640},"  restart",[455,677,644],{"class":475},[455,679,680],{"class":465}," unless-stopped\n",[455,682,684],{"class":457,"line":683},22,[455,685,686],{"class":539},"  # Followed by Watchtower started with `--label-enable`, for an installation\n",[455,688,690],{"class":457,"line":689},23,[455,691,692],{"class":539},"  # that updates itself (`DDM_VERSION=stable`). Not Postgres: a new major of it\n",[455,694,696],{"class":457,"line":695},24,[455,697,698],{"class":539},"  # needs its data upgraded by hand.\n",[455,700,702,705],{"class":457,"line":701},25,[455,703,704],{"class":640},"  labels",[455,706,707],{"class":475},":\n",[455,709,711,714,716,719,722],{"class":457,"line":710},26,[455,712,713],{"class":640},"    com.centurylinklabs.watchtower.enable",[455,715,644],{"class":475},[455,717,718],{"class":475}," \"",[455,720,721],{"class":465},"true",[455,723,724],{"class":475},"\"\n",[455,726,728],{"class":457,"line":727},27,[455,729,654],{"emptyLinePlaceholder":653},[455,731,733,736],{"class":457,"line":732},28,[455,734,735],{"class":640},"services",[455,737,707],{"class":475},[455,739,741,744],{"class":457,"line":740},29,[455,742,743],{"class":640},"  postgres",[455,745,707],{"class":475},[455,747,749],{"class":457,"line":748},30,[455,750,751],{"class":539},"    # Postgres with the German dictionary DDM searches with — by its major,\n",[455,753,755],{"class":457,"line":754},31,[455,756,757],{"class":539},"    # which only ever changes by hand.\n",[455,759,761,764,766],{"class":457,"line":760},32,[455,762,763],{"class":640},"    image",[455,765,644],{"class":475},[455,767,768],{"class":465}," ${DDM_REGISTRY:-registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images}\u002Fpostgres:18\n",[455,770,772,775,777],{"class":457,"line":771},33,[455,773,774],{"class":640},"    restart",[455,776,644],{"class":475},[455,778,680],{"class":465},[455,780,782,785],{"class":457,"line":781},34,[455,783,784],{"class":640},"    environment",[455,786,707],{"class":475},[455,788,790,793,795],{"class":457,"line":789},35,[455,791,792],{"class":640},"      POSTGRES_USER",[455,794,644],{"class":475},[455,796,647],{"class":465},[455,798,800,803,805],{"class":457,"line":799},36,[455,801,802],{"class":640},"      POSTGRES_DB",[455,804,644],{"class":475},[455,806,647],{"class":465},[455,808,810,813,815],{"class":457,"line":809},37,[455,811,812],{"class":640},"      POSTGRES_PASSWORD",[455,814,644],{"class":475},[455,816,817],{"class":465}," ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}\n",[455,819,821,824],{"class":457,"line":820},38,[455,822,823],{"class":640},"    volumes",[455,825,707],{"class":475},[455,827,829,832],{"class":457,"line":828},39,[455,830,831],{"class":475},"      -",[455,833,834],{"class":465}," postgres:\u002Fvar\u002Flib\u002Fpostgresql\n",[455,836,838,841],{"class":457,"line":837},40,[455,839,840],{"class":640},"    healthcheck",[455,842,707],{"class":475},[455,844,846,849,851,854,857,860,863,865,868,870,873,875,878,880,882],{"class":457,"line":845},41,[455,847,848],{"class":640},"      test",[455,850,644],{"class":475},[455,852,853],{"class":475}," [",[455,855,856],{"class":465},"CMD",[455,858,859],{"class":475},",",[455,861,862],{"class":465}," pg_isready",[455,864,859],{"class":475},[455,866,867],{"class":465}," -U",[455,869,859],{"class":475},[455,871,872],{"class":465}," ddm",[455,874,859],{"class":475},[455,876,877],{"class":465}," -d",[455,879,859],{"class":475},[455,881,872],{"class":465},[455,883,884],{"class":475},"]\n",[455,886,888,891,893],{"class":457,"line":887},42,[455,889,890],{"class":640},"      interval",[455,892,644],{"class":475},[455,894,895],{"class":465}," 5s\n",[455,897,899,902,904],{"class":457,"line":898},43,[455,900,901],{"class":640},"      timeout",[455,903,644],{"class":475},[455,905,895],{"class":465},[455,907,909,912,914],{"class":457,"line":908},44,[455,910,911],{"class":640},"      retries",[455,913,644],{"class":475},[455,915,917],{"class":916},"sbssI"," 10\n",[455,919,921],{"class":457,"line":920},45,[455,922,654],{"emptyLinePlaceholder":653},[455,924,926,929],{"class":457,"line":925},46,[455,927,928],{"class":640},"  cms",[455,930,707],{"class":475},[455,932,934,937,940],{"class":457,"line":933},47,[455,935,936],{"class":475},"    \u003C\u003C:",[455,938,939],{"class":665}," *",[455,941,669],{"class":485},[455,943,945,947,949],{"class":457,"line":944},48,[455,946,763],{"class":640},[455,948,644],{"class":475},[455,950,951],{"class":465}," ${DDM_REGISTRY:-registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images}\u002Fcms:${DDM_VERSION:-latest}\n",[455,953,955,958,960],{"class":457,"line":954},49,[455,956,957],{"class":640},"    env_file",[455,959,644],{"class":475},[455,961,962],{"class":465}," .env\n",[455,964,966,968],{"class":457,"line":965},50,[455,967,784],{"class":640},[455,969,707],{"class":475},[455,971,973],{"class":457,"line":972},51,[455,974,975],{"class":539},"      # Which version of these files this is: a release that needs newer ones\n",[455,977,979],{"class":457,"line":978},52,[455,980,981],{"class":539},"      # says so to the administrators, rather than failing (user guide, „Updates\").\n",[455,983,985,988,990,992,995],{"class":457,"line":984},53,[455,986,987],{"class":640},"      DDM_DEPLOY_VERSION",[455,989,644],{"class":475},[455,991,718],{"class":475},[455,993,994],{"class":465},"1",[455,996,724],{"class":475},[455,998,1000,1003,1005],{"class":457,"line":999},54,[455,1001,1002],{"class":640},"      DATABASE_URL",[455,1004,644],{"class":475},[455,1006,1007],{"class":465}," postgres:\u002F\u002Fddm:${POSTGRES_PASSWORD}@postgres:5432\u002Fddm\n",[455,1009,1011,1014,1016],{"class":457,"line":1010},55,[455,1012,1013],{"class":640},"      BETTER_AUTH_URL",[455,1015,644],{"class":475},[455,1017,1018],{"class":465}," https:\u002F\u002F${DDM_CMS_HOST:?set DDM_CMS_HOST in .env}\n",[455,1020,1022,1025,1027],{"class":457,"line":1021},56,[455,1023,1024],{"class":640},"      CLIENT_ORIGIN",[455,1026,644],{"class":475},[455,1028,1029],{"class":465}," https:\u002F\u002F${DDM_APP_HOST:?set DDM_APP_HOST in .env}\n",[455,1031,1033],{"class":457,"line":1032},57,[455,1034,1035],{"class":539},"      # The documents, and the database's dumps taken before each migration\n",[455,1037,1039],{"class":457,"line":1038},58,[455,1040,1041],{"class":539},"      # (the last three) — unless `S3_ENDPOINT` names a bucket for both.\n",[455,1043,1045,1048,1050],{"class":457,"line":1044},59,[455,1046,1047],{"class":640},"      STORAGE_DIR",[455,1049,644],{"class":475},[455,1051,1052],{"class":465}," \u002Fdata\u002Fstorage\n",[455,1054,1056,1059,1061],{"class":457,"line":1055},60,[455,1057,1058],{"class":640},"      BACKUP_DIR",[455,1060,644],{"class":475},[455,1062,1063],{"class":465}," \u002Fdata\u002Fbackups\n",[455,1065,1067],{"class":457,"line":1066},61,[455,1068,1069],{"class":539},"      # Uploads are stored here and drawn by the render worker.\n",[455,1071,1073,1076,1078],{"class":457,"line":1072},62,[455,1074,1075],{"class":640},"      RENDER_MODE",[455,1077,644],{"class":475},[455,1079,1080],{"class":465}," worker\n",[455,1082,1084,1087,1089],{"class":457,"line":1083},63,[455,1085,1086],{"class":640},"      MAX_UPLOAD_BYTES",[455,1088,644],{"class":475},[455,1090,1091],{"class":465}," ${MAX_UPLOAD_BYTES:-1073741824}\n",[455,1093,1095,1097],{"class":457,"line":1094},64,[455,1096,823],{"class":640},[455,1098,707],{"class":475},[455,1100,1102,1104],{"class":457,"line":1101},65,[455,1103,831],{"class":475},[455,1105,1106],{"class":465}," data:\u002Fdata\n",[455,1108,1110,1113],{"class":457,"line":1109},66,[455,1111,1112],{"class":640},"    ports",[455,1114,707],{"class":475},[455,1116,1118,1120],{"class":457,"line":1117},67,[455,1119,831],{"class":475},[455,1121,1122],{"class":465}," ${DDM_CMS_PORT:-127.0.0.1:3000}:3000\n",[455,1124,1126,1129],{"class":457,"line":1125},68,[455,1127,1128],{"class":640},"    depends_on",[455,1130,707],{"class":475},[455,1132,1134,1137],{"class":457,"line":1133},69,[455,1135,1136],{"class":640},"      postgres",[455,1138,707],{"class":475},[455,1140,1142,1145,1147],{"class":457,"line":1141},70,[455,1143,1144],{"class":640},"        condition",[455,1146,644],{"class":475},[455,1148,1149],{"class":465}," service_healthy\n",[455,1151,1153,1155],{"class":457,"line":1152},71,[455,1154,840],{"class":640},[455,1156,707],{"class":475},[455,1158,1160,1162,1164,1166,1168,1170,1173,1175,1178,1180,1182,1185,1188],{"class":457,"line":1159},72,[455,1161,848],{"class":640},[455,1163,644],{"class":475},[455,1165,853],{"class":475},[455,1167,856],{"class":465},[455,1169,859],{"class":475},[455,1171,1172],{"class":465}," bun",[455,1174,859],{"class":475},[455,1176,1177],{"class":465}," -e",[455,1179,859],{"class":475},[455,1181,718],{"class":475},[455,1183,1184],{"class":465},"process.exit((await fetch('http:\u002F\u002F127.0.0.1:3000\u002Fapi\u002Fauth\u002Fok')).ok ? 0 : 1)",[455,1186,1187],{"class":475},"\"",[455,1189,884],{"class":475},[455,1191,1193,1195,1197],{"class":457,"line":1192},73,[455,1194,890],{"class":640},[455,1196,644],{"class":475},[455,1198,1199],{"class":465}," 10s\n",[455,1201,1203,1205,1207],{"class":457,"line":1202},74,[455,1204,901],{"class":640},[455,1206,644],{"class":475},[455,1208,895],{"class":465},[455,1210,1212,1214,1216],{"class":457,"line":1211},75,[455,1213,911],{"class":640},[455,1215,644],{"class":475},[455,1217,1218],{"class":916}," 6\n",[455,1220,1222],{"class":457,"line":1221},76,[455,1223,1224],{"class":539},"      # Migrations first, on a new release.\n",[455,1226,1228,1231,1233],{"class":457,"line":1227},77,[455,1229,1230],{"class":640},"      start_period",[455,1232,644],{"class":475},[455,1234,1235],{"class":465}," 5m\n",[455,1237,1239,1242,1244],{"class":457,"line":1238},78,[455,1240,1241],{"class":640},"      start_interval",[455,1243,644],{"class":475},[455,1245,1246],{"class":465}," 2s\n",[455,1248,1250],{"class":457,"line":1249},79,[455,1251,654],{"emptyLinePlaceholder":653},[455,1253,1255,1258],{"class":457,"line":1254},80,[455,1256,1257],{"class":640},"  render-worker",[455,1259,707],{"class":475},[455,1261,1263,1265,1267],{"class":457,"line":1262},81,[455,1264,936],{"class":475},[455,1266,939],{"class":665},[455,1268,669],{"class":485},[455,1270,1272,1274,1276],{"class":457,"line":1271},82,[455,1273,763],{"class":640},[455,1275,644],{"class":475},[455,1277,1278],{"class":465}," ${DDM_REGISTRY:-registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images}\u002Frender-worker:${DDM_VERSION:-latest}\n",[455,1280,1282,1284],{"class":457,"line":1281},83,[455,1283,784],{"class":640},[455,1285,707],{"class":475},[455,1287,1289,1291,1293],{"class":457,"line":1288},84,[455,1290,1002],{"class":640},[455,1292,644],{"class":475},[455,1294,1007],{"class":465},[455,1296,1298,1301,1303],{"class":457,"line":1297},85,[455,1299,1300],{"class":640},"      STORAGE_DRIVER",[455,1302,644],{"class":475},[455,1304,1305],{"class":465}," ${STORAGE_DRIVER:-}\n",[455,1307,1309,1311,1313],{"class":457,"line":1308},86,[455,1310,1047],{"class":640},[455,1312,644],{"class":475},[455,1314,1052],{"class":465},[455,1316,1318,1321,1323],{"class":457,"line":1317},87,[455,1319,1320],{"class":640},"      S3_ENDPOINT",[455,1322,644],{"class":475},[455,1324,1325],{"class":465}," ${S3_ENDPOINT:-}\n",[455,1327,1329,1332,1334],{"class":457,"line":1328},88,[455,1330,1331],{"class":640},"      S3_BUCKET",[455,1333,644],{"class":475},[455,1335,1336],{"class":465}," ${S3_BUCKET:-}\n",[455,1338,1340,1343,1345],{"class":457,"line":1339},89,[455,1341,1342],{"class":640},"      S3_REGION",[455,1344,644],{"class":475},[455,1346,1347],{"class":465}," ${S3_REGION:-}\n",[455,1349,1351,1354,1356],{"class":457,"line":1350},90,[455,1352,1353],{"class":640},"      S3_ACCESS_KEY_ID",[455,1355,644],{"class":475},[455,1357,1358],{"class":465}," ${S3_ACCESS_KEY_ID:-}\n",[455,1360,1362,1365,1367],{"class":457,"line":1361},91,[455,1363,1364],{"class":640},"      S3_SECRET_ACCESS_KEY",[455,1366,644],{"class":475},[455,1368,1369],{"class":465}," ${S3_SECRET_ACCESS_KEY:-}\n",[455,1371,1373,1376,1378],{"class":457,"line":1372},92,[455,1374,1375],{"class":640},"      S3_FORCE_PATH_STYLE",[455,1377,644],{"class":475},[455,1379,1380],{"class":465}," ${S3_FORCE_PATH_STYLE:-true}\n",[455,1382,1384,1387,1389],{"class":457,"line":1383},93,[455,1385,1386],{"class":640},"      THUMBNAILS",[455,1388,644],{"class":475},[455,1390,1391],{"class":465}," ${THUMBNAILS:-on}\n",[455,1393,1395,1398,1400],{"class":457,"line":1394},94,[455,1396,1397],{"class":640},"      RENDER_LARGE_OFFICE",[455,1399,644],{"class":475},[455,1401,1402],{"class":465}," ${RENDER_LARGE_OFFICE:-on}\n",[455,1404,1406,1408],{"class":457,"line":1405},95,[455,1407,823],{"class":640},[455,1409,707],{"class":475},[455,1411,1413,1415],{"class":457,"line":1412},96,[455,1414,831],{"class":475},[455,1416,1106],{"class":465},[455,1418,1420],{"class":457,"line":1419},97,[455,1421,1422],{"class":539},"    # After the cms has migrated the database to this release.\n",[455,1424,1426,1428],{"class":457,"line":1425},98,[455,1427,1128],{"class":640},[455,1429,707],{"class":475},[455,1431,1433,1436],{"class":457,"line":1432},99,[455,1434,1435],{"class":640},"      cms",[455,1437,707],{"class":475},[455,1439,1441,1443,1445],{"class":457,"line":1440},100,[455,1442,1144],{"class":640},[455,1444,644],{"class":475},[455,1446,1149],{"class":465},[455,1448,1450],{"class":457,"line":1449},101,[455,1451,1452],{"class":539},"    # It finishes the documents in hand before it stops — LibreOffice may take\n",[455,1454,1456],{"class":457,"line":1455},102,[455,1457,1458],{"class":539},"    # minutes over a large deck.\n",[455,1460,1462,1465,1467],{"class":457,"line":1461},103,[455,1463,1464],{"class":640},"    stop_grace_period",[455,1466,644],{"class":475},[455,1468,1469],{"class":465}," 11m\n",[455,1471,1473],{"class":457,"line":1472},104,[455,1474,654],{"emptyLinePlaceholder":653},[455,1476,1478,1481],{"class":457,"line":1477},105,[455,1479,1480],{"class":640},"  client",[455,1482,707],{"class":475},[455,1484,1486,1488,1490],{"class":457,"line":1485},106,[455,1487,936],{"class":475},[455,1489,939],{"class":665},[455,1491,669],{"class":485},[455,1493,1495,1497,1499],{"class":457,"line":1494},107,[455,1496,763],{"class":640},[455,1498,644],{"class":475},[455,1500,1501],{"class":465}," ${DDM_REGISTRY:-registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images}\u002Fclient:${DDM_VERSION:-latest}\n",[455,1503,1505,1507],{"class":457,"line":1504},108,[455,1506,784],{"class":640},[455,1508,707],{"class":475},[455,1510,1512,1515,1517],{"class":457,"line":1511},109,[455,1513,1514],{"class":640},"      NUXT_API_ORIGIN",[455,1516,644],{"class":475},[455,1518,1519],{"class":465}," http:\u002F\u002Fcms:3000\n",[455,1521,1523,1526,1528],{"class":457,"line":1522},110,[455,1524,1525],{"class":640},"      NUXT_PUBLIC_MGMT_URL",[455,1527,644],{"class":475},[455,1529,1530],{"class":465}," https:\u002F\u002F${DDM_CMS_HOST}\n",[455,1532,1534],{"class":457,"line":1533},111,[455,1535,1536],{"class":539},"      # The reader app on this installation, for the mobile app's „Server\".\n",[455,1538,1540,1543,1545],{"class":457,"line":1539},112,[455,1541,1542],{"class":640},"      NUXT_PUBLIC_SERVER_URL",[455,1544,644],{"class":475},[455,1546,1547],{"class":465}," https:\u002F\u002F${DDM_APP_HOST}\n",[455,1549,1551,1553,1555],{"class":457,"line":1550},113,[455,1552,1075],{"class":640},[455,1554,644],{"class":475},[455,1556,1080],{"class":465},[455,1558,1560,1562,1564],{"class":457,"line":1559},114,[455,1561,1386],{"class":640},[455,1563,644],{"class":475},[455,1565,1391],{"class":465},[455,1567,1569,1572,1574],{"class":457,"line":1568},115,[455,1570,1571],{"class":640},"      NUXT_PUBLIC_SSO_PROVIDERS",[455,1573,644],{"class":475},[455,1575,1576],{"class":465}," ${NUXT_PUBLIC_SSO_PROVIDERS:-}\n",[455,1578,1580,1582],{"class":457,"line":1579},116,[455,1581,1112],{"class":640},[455,1583,707],{"class":475},[455,1585,1587,1589],{"class":457,"line":1586},117,[455,1588,831],{"class":475},[455,1590,1591],{"class":465}," ${DDM_APP_PORT:-127.0.0.1:3001}:3000\n",[455,1593,1595,1597],{"class":457,"line":1594},118,[455,1596,1128],{"class":640},[455,1598,707],{"class":475},[455,1600,1602,1604],{"class":457,"line":1601},119,[455,1603,1435],{"class":640},[455,1605,707],{"class":475},[455,1607,1609,1611,1613],{"class":457,"line":1608},120,[455,1610,1144],{"class":640},[455,1612,644],{"class":475},[455,1614,1149],{"class":465},[455,1616,1618],{"class":457,"line":1617},121,[455,1619,1620],{"class":539},"    # Through to the cms: what the reader app forwards answers, too.\n",[455,1622,1624,1626],{"class":457,"line":1623},122,[455,1625,840],{"class":640},[455,1627,707],{"class":475},[455,1629,1631,1633,1635,1637,1639,1641,1643,1645,1647,1649,1651,1653,1655],{"class":457,"line":1630},123,[455,1632,848],{"class":640},[455,1634,644],{"class":475},[455,1636,853],{"class":475},[455,1638,856],{"class":465},[455,1640,859],{"class":475},[455,1642,1172],{"class":465},[455,1644,859],{"class":475},[455,1646,1177],{"class":465},[455,1648,859],{"class":475},[455,1650,718],{"class":475},[455,1652,1184],{"class":465},[455,1654,1187],{"class":475},[455,1656,884],{"class":475},[455,1658,1660,1662,1664],{"class":457,"line":1659},124,[455,1661,890],{"class":640},[455,1663,644],{"class":475},[455,1665,1199],{"class":465},[455,1667,1669,1671,1673],{"class":457,"line":1668},125,[455,1670,901],{"class":640},[455,1672,644],{"class":475},[455,1674,895],{"class":465},[455,1676,1678,1680,1682],{"class":457,"line":1677},126,[455,1679,911],{"class":640},[455,1681,644],{"class":475},[455,1683,1218],{"class":916},[455,1685,1687,1689,1691],{"class":457,"line":1686},127,[455,1688,1230],{"class":640},[455,1690,644],{"class":475},[455,1692,1693],{"class":465}," 1m\n",[455,1695,1697,1699,1701],{"class":457,"line":1696},128,[455,1698,1241],{"class":640},[455,1700,644],{"class":475},[455,1702,1246],{"class":465},[455,1704,1706],{"class":457,"line":1705},129,[455,1707,654],{"emptyLinePlaceholder":653},[455,1709,1711],{"class":457,"line":1710},130,[455,1712,1713],{"class":539},"  # TLS and both hostnames, with certificates from Let's Encrypt: only with\n",[455,1715,1717],{"class":457,"line":1716},131,[455,1718,1719],{"class":539},"  # `--profile proxy`, for a server with nothing else on ports 80 and 443.\n",[455,1721,1723,1726],{"class":457,"line":1722},132,[455,1724,1725],{"class":640},"  caddy",[455,1727,707],{"class":475},[455,1729,1731,1733,1735],{"class":457,"line":1730},133,[455,1732,763],{"class":640},[455,1734,644],{"class":475},[455,1736,1737],{"class":465}," caddy:2.10-alpine\n",[455,1739,1741,1744,1746,1748,1751],{"class":457,"line":1740},134,[455,1742,1743],{"class":640},"    profiles",[455,1745,644],{"class":475},[455,1747,853],{"class":475},[455,1749,1750],{"class":465},"proxy",[455,1752,884],{"class":475},[455,1754,1756,1758,1760],{"class":457,"line":1755},135,[455,1757,774],{"class":640},[455,1759,644],{"class":475},[455,1761,680],{"class":465},[455,1763,1765,1767],{"class":457,"line":1764},136,[455,1766,784],{"class":640},[455,1768,707],{"class":475},[455,1770,1772,1775,1777],{"class":457,"line":1771},137,[455,1773,1774],{"class":640},"      DDM_CMS_HOST",[455,1776,644],{"class":475},[455,1778,1779],{"class":465}," ${DDM_CMS_HOST}\n",[455,1781,1783,1786,1788],{"class":457,"line":1782},138,[455,1784,1785],{"class":640},"      DDM_APP_HOST",[455,1787,644],{"class":475},[455,1789,1790],{"class":465}," ${DDM_APP_HOST}\n",[455,1792,1794,1796],{"class":457,"line":1793},139,[455,1795,1112],{"class":640},[455,1797,707],{"class":475},[455,1799,1801,1803],{"class":457,"line":1800},140,[455,1802,831],{"class":475},[455,1804,1805],{"class":465}," 80:80\n",[455,1807,1809,1811],{"class":457,"line":1808},141,[455,1810,831],{"class":475},[455,1812,1813],{"class":465}," 443:443\n",[455,1815,1817,1819],{"class":457,"line":1816},142,[455,1818,831],{"class":475},[455,1820,1821],{"class":465}," 443:443\u002Fudp\n",[455,1823,1825,1827],{"class":457,"line":1824},143,[455,1826,823],{"class":640},[455,1828,707],{"class":475},[455,1830,1832,1834],{"class":457,"line":1831},144,[455,1833,831],{"class":475},[455,1835,1836],{"class":465}," .\u002FCaddyfile:\u002Fetc\u002Fcaddy\u002FCaddyfile:ro\n",[455,1838,1840,1842],{"class":457,"line":1839},145,[455,1841,831],{"class":475},[455,1843,1844],{"class":465}," caddy:\u002Fdata\n",[455,1846,1848,1850,1852,1854,1857,1859,1862],{"class":457,"line":1847},146,[455,1849,1128],{"class":640},[455,1851,644],{"class":475},[455,1853,853],{"class":475},[455,1855,1856],{"class":465},"cms",[455,1858,859],{"class":475},[455,1860,1861],{"class":465}," client",[455,1863,884],{"class":475},[455,1865,1867],{"class":457,"line":1866},147,[455,1868,654],{"emptyLinePlaceholder":653},[455,1870,1872,1875],{"class":457,"line":1871},148,[455,1873,1874],{"class":640},"volumes",[455,1876,707],{"class":475},[455,1878,1880,1882],{"class":457,"line":1879},149,[455,1881,743],{"class":640},[455,1883,707],{"class":475},[455,1885,1887,1890],{"class":457,"line":1886},150,[455,1888,1889],{"class":640},"  data",[455,1891,707],{"class":475},[455,1893,1895,1897],{"class":457,"line":1894},151,[455,1896,1725],{"class":640},[455,1898,707],{"class":475},[433,1900,1901,1905],{},[518,1902,1903],{},[452,1904,526],{}," – your settings. What you fill in at least is in the next step.",[445,1907,1909],{"className":447,"code":1908,"filename":526,"language":449,"meta":450,"style":450},"# An installation's settings, read by `compose.yaml` — copied to `.env` and\n# filled in. Every setting of the user guide's „Konfiguration\" \u002F\n# „Configuration\" may be added; these are the ones an installation needs, and\n# the ones most change.\n\n# The release to run, e.g. `0.26.0`, or `0.26` for its fixes as they come.\n# `stable` follows the releases we have promoted — for an installation that\n# updates itself (user guide, „Updates\").\nDDM_VERSION=latest\n# DDM_REGISTRY=registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images\n\n# The two hostnames, each with its own certificate: the management app (and\n# API), and the reader app. DNS for both points at this server.\nDDM_CMS_HOST=cms.example.com\nDDM_APP_HOST=app.example.com\n# Their parent, so a sign-in on one counts on the other.\nAUTH_COOKIE_DOMAIN=example.com\n# …and a passkey in both apps.\nPASSKEY_RP_ID=example.com\n# Where the two apps answer on this server, for your own reverse proxy —\n# unused with `--profile proxy`.\n# DDM_CMS_PORT=127.0.0.1:3000\n# DDM_APP_PORT=127.0.0.1:3001\n\n# Secrets: `openssl rand -base64 32` for each. The database's password is\n# kept by Postgres on its first start; changing it here later locks the cms out.\nPOSTGRES_PASSWORD=\nBETTER_AUTH_SECRET=\n\n# The licence we sent you (`ddm1.…`) — needed from the first start: without\n# one, the installation is locked, and nobody can register its first account.\n# A licence entered later under Settings › Licence replaces it.\nLICENCE_KEY=\n\n# How mail leaves the installation — your own mail server.\nMAIL_DRIVER=smtp\nMAIL_FROM=ddm@example.com\nSMTP_HOST=mail.example.com\nSMTP_PORT=587\nSMTP_USER=\nSMTP_PASSWORD=\n# SMTP_ALLOW_SELF_SIGNED=true   # for an internal server with its own CA\n\n# The documents are kept on the `data` volume. To keep them in an\n# S3-compatible bucket instead (MinIO, Ceph, a cloud's), name it here; the\n# database's dumps then go to the same bucket.\n# S3_ENDPOINT=https:\u002F\u002Fs3.example.com\n# S3_BUCKET=ddm\n# S3_REGION=eu-central-1\n# S3_ACCESS_KEY_ID=\n# S3_SECRET_ACCESS_KEY=\n\n# Thumbnails and previews of uploaded documents: `off` leaves them out.\n# THUMBNAILS=on\n",[452,1910,1911,1916,1921,1926,1931,1935,1940,1945,1950,1961,1966,1970,1975,1980,1990,2000,2005,2015,2020,2029,2034,2039,2044,2049,2053,2058,2063,2071,2078,2082,2087,2092,2097,2104,2108,2113,2123,2133,2143,2153,2160,2167,2172,2176,2181,2186,2191,2196,2201,2206,2211,2216,2220,2225],{"__ignoreMap":450},[455,1912,1913],{"class":457,"line":458},[455,1914,1915],{"class":539},"# An installation's settings, read by `compose.yaml` — copied to `.env` and\n",[455,1917,1918],{"class":457,"line":543},[455,1919,1920],{"class":539},"# filled in. Every setting of the user guide's „Konfiguration\" \u002F\n",[455,1922,1923],{"class":457,"line":549},[455,1924,1925],{"class":539},"# „Configuration\" may be added; these are the ones an installation needs, and\n",[455,1927,1928],{"class":457,"line":555},[455,1929,1930],{"class":539},"# the ones most change.\n",[455,1932,1933],{"class":457,"line":561},[455,1934,654],{"emptyLinePlaceholder":653},[455,1936,1937],{"class":457,"line":567},[455,1938,1939],{"class":539},"# The release to run, e.g. `0.26.0`, or `0.26` for its fixes as they come.\n",[455,1941,1942],{"class":457,"line":573},[455,1943,1944],{"class":539},"# `stable` follows the releases we have promoted — for an installation that\n",[455,1946,1947],{"class":457,"line":578},[455,1948,1949],{"class":539},"# updates itself (user guide, „Updates\").\n",[455,1951,1952,1955,1958],{"class":457,"line":584},[455,1953,1954],{"class":485},"DDM_VERSION",[455,1956,1957],{"class":475},"=",[455,1959,1960],{"class":465},"latest\n",[455,1962,1963],{"class":457,"line":590},[455,1964,1965],{"class":539},"# DDM_REGISTRY=registry.gitlab.com\u002Fiq-me\u002Fnew-ddm-images\n",[455,1967,1968],{"class":457,"line":596},[455,1969,654],{"emptyLinePlaceholder":653},[455,1971,1972],{"class":457,"line":602},[455,1973,1974],{"class":539},"# The two hostnames, each with its own certificate: the management app (and\n",[455,1976,1977],{"class":457,"line":608},[455,1978,1979],{"class":539},"# API), and the reader app. DNS for both points at this server.\n",[455,1981,1982,1985,1987],{"class":457,"line":614},[455,1983,1984],{"class":485},"DDM_CMS_HOST",[455,1986,1957],{"class":475},[455,1988,1989],{"class":465},"cms.example.com\n",[455,1991,1992,1995,1997],{"class":457,"line":619},[455,1993,1994],{"class":485},"DDM_APP_HOST",[455,1996,1957],{"class":475},[455,1998,1999],{"class":465},"app.example.com\n",[455,2001,2002],{"class":457,"line":625},[455,2003,2004],{"class":539},"# Their parent, so a sign-in on one counts on the other.\n",[455,2006,2007,2010,2012],{"class":457,"line":631},[455,2008,2009],{"class":485},"AUTH_COOKIE_DOMAIN",[455,2011,1957],{"class":475},[455,2013,2014],{"class":465},"example.com\n",[455,2016,2017],{"class":457,"line":637},[455,2018,2019],{"class":539},"# …and a passkey in both apps.\n",[455,2021,2022,2025,2027],{"class":457,"line":650},[455,2023,2024],{"class":485},"PASSKEY_RP_ID",[455,2026,1957],{"class":475},[455,2028,2014],{"class":465},[455,2030,2031],{"class":457,"line":657},[455,2032,2033],{"class":539},"# Where the two apps answer on this server, for your own reverse proxy —\n",[455,2035,2036],{"class":457,"line":672},[455,2037,2038],{"class":539},"# unused with `--profile proxy`.\n",[455,2040,2041],{"class":457,"line":683},[455,2042,2043],{"class":539},"# DDM_CMS_PORT=127.0.0.1:3000\n",[455,2045,2046],{"class":457,"line":689},[455,2047,2048],{"class":539},"# DDM_APP_PORT=127.0.0.1:3001\n",[455,2050,2051],{"class":457,"line":695},[455,2052,654],{"emptyLinePlaceholder":653},[455,2054,2055],{"class":457,"line":701},[455,2056,2057],{"class":539},"# Secrets: `openssl rand -base64 32` for each. The database's password is\n",[455,2059,2060],{"class":457,"line":710},[455,2061,2062],{"class":539},"# kept by Postgres on its first start; changing it here later locks the cms out.\n",[455,2064,2065,2068],{"class":457,"line":727},[455,2066,2067],{"class":485},"POSTGRES_PASSWORD",[455,2069,2070],{"class":475},"=\n",[455,2072,2073,2076],{"class":457,"line":732},[455,2074,2075],{"class":485},"BETTER_AUTH_SECRET",[455,2077,2070],{"class":475},[455,2079,2080],{"class":457,"line":740},[455,2081,654],{"emptyLinePlaceholder":653},[455,2083,2084],{"class":457,"line":748},[455,2085,2086],{"class":539},"# The licence we sent you (`ddm1.…`) — needed from the first start: without\n",[455,2088,2089],{"class":457,"line":754},[455,2090,2091],{"class":539},"# one, the installation is locked, and nobody can register its first account.\n",[455,2093,2094],{"class":457,"line":760},[455,2095,2096],{"class":539},"# A licence entered later under Settings › Licence replaces it.\n",[455,2098,2099,2102],{"class":457,"line":771},[455,2100,2101],{"class":485},"LICENCE_KEY",[455,2103,2070],{"class":475},[455,2105,2106],{"class":457,"line":781},[455,2107,654],{"emptyLinePlaceholder":653},[455,2109,2110],{"class":457,"line":789},[455,2111,2112],{"class":539},"# How mail leaves the installation — your own mail server.\n",[455,2114,2115,2118,2120],{"class":457,"line":799},[455,2116,2117],{"class":485},"MAIL_DRIVER",[455,2119,1957],{"class":475},[455,2121,2122],{"class":465},"smtp\n",[455,2124,2125,2128,2130],{"class":457,"line":809},[455,2126,2127],{"class":485},"MAIL_FROM",[455,2129,1957],{"class":475},[455,2131,2132],{"class":465},"ddm@example.com\n",[455,2134,2135,2138,2140],{"class":457,"line":820},[455,2136,2137],{"class":485},"SMTP_HOST",[455,2139,1957],{"class":475},[455,2141,2142],{"class":465},"mail.example.com\n",[455,2144,2145,2148,2150],{"class":457,"line":828},[455,2146,2147],{"class":485},"SMTP_PORT",[455,2149,1957],{"class":475},[455,2151,2152],{"class":465},"587\n",[455,2154,2155,2158],{"class":457,"line":837},[455,2156,2157],{"class":485},"SMTP_USER",[455,2159,2070],{"class":475},[455,2161,2162,2165],{"class":457,"line":845},[455,2163,2164],{"class":485},"SMTP_PASSWORD",[455,2166,2070],{"class":475},[455,2168,2169],{"class":457,"line":887},[455,2170,2171],{"class":539},"# SMTP_ALLOW_SELF_SIGNED=true   # for an internal server with its own CA\n",[455,2173,2174],{"class":457,"line":898},[455,2175,654],{"emptyLinePlaceholder":653},[455,2177,2178],{"class":457,"line":908},[455,2179,2180],{"class":539},"# The documents are kept on the `data` volume. To keep them in an\n",[455,2182,2183],{"class":457,"line":920},[455,2184,2185],{"class":539},"# S3-compatible bucket instead (MinIO, Ceph, a cloud's), name it here; the\n",[455,2187,2188],{"class":457,"line":925},[455,2189,2190],{"class":539},"# database's dumps then go to the same bucket.\n",[455,2192,2193],{"class":457,"line":933},[455,2194,2195],{"class":539},"# S3_ENDPOINT=https:\u002F\u002Fs3.example.com\n",[455,2197,2198],{"class":457,"line":944},[455,2199,2200],{"class":539},"# S3_BUCKET=ddm\n",[455,2202,2203],{"class":457,"line":954},[455,2204,2205],{"class":539},"# S3_REGION=eu-central-1\n",[455,2207,2208],{"class":457,"line":965},[455,2209,2210],{"class":539},"# S3_ACCESS_KEY_ID=\n",[455,2212,2213],{"class":457,"line":972},[455,2214,2215],{"class":539},"# S3_SECRET_ACCESS_KEY=\n",[455,2217,2218],{"class":457,"line":978},[455,2219,654],{"emptyLinePlaceholder":653},[455,2221,2222],{"class":457,"line":984},[455,2223,2224],{"class":539},"# Thumbnails and previews of uploaded documents: `off` leaves them out.\n",[455,2226,2227],{"class":457,"line":999},[455,2228,2229],{"class":539},"# THUMBNAILS=on\n",[433,2231,2232,2237],{},[518,2233,2234],{},[452,2235,2236],{},"Caddyfile"," – only for the bundled reverse proxy (step 4).",[445,2239,2244],{"className":2240,"code":2242,"filename":2236,"language":2243,"meta":450},[2241],"language-text","# The reverse proxy of `compose.yaml`'s `proxy` profile: TLS for both\n# hostnames, with certificates Caddy fetches itself — the server has to be\n# reachable on ports 80 and 443 under both names. Caddy sets no limit on a\n# request's size, so uploads up to `MAX_UPLOAD_BYTES` pass; another proxy needs\n# it raised (nginx: `client_max_body_size 1g`).\n{$DDM_CMS_HOST} {\n    encode zstd gzip\n    reverse_proxy cms:3000\n}\n\n{$DDM_APP_HOST} {\n    encode zstd gzip\n    reverse_proxy client:3000\n}\n","text",[452,2245,2242],{"__ignoreMap":450},[437,2247,2249],{"id":2248},"_3-fill-in-the-settings","3. Fill in the settings",[433,2251,2252,2253,644],{},"Fill in at least this in ",[452,2254,526],{},[445,2256,2258],{"className":447,"code":2257,"language":449,"meta":450,"style":450},"DDM_VERSION=0.26          # the version; 0.26 gets its bug fixes\nDDM_CMS_HOST=cms.company.com\nDDM_APP_HOST=app.company.com\nAUTH_COOKIE_DOMAIN=company.com\nPASSKEY_RP_ID=company.com\n\nPOSTGRES_PASSWORD=...     # openssl rand -base64 32\nBETTER_AUTH_SECRET=...    # openssl rand -base64 32\n\nLICENCE_KEY=ddm1....      # the licence from us\n\nMAIL_DRIVER=smtp\nMAIL_FROM=ddm@company.com\nSMTP_HOST=mail.company.com\nSMTP_PORT=587\nSMTP_USER=...\nSMTP_PASSWORD=...\n",[452,2259,2260,2272,2281,2290,2299,2307,2311,2323,2334,2338,2350,2354,2362,2371,2380,2388,2397],{"__ignoreMap":450},[455,2261,2262,2264,2266,2269],{"class":457,"line":458},[455,2263,1954],{"class":485},[455,2265,1957],{"class":475},[455,2267,2268],{"class":465},"0.26",[455,2270,2271],{"class":539},"          # the version; 0.26 gets its bug fixes\n",[455,2273,2274,2276,2278],{"class":457,"line":543},[455,2275,1984],{"class":485},[455,2277,1957],{"class":475},[455,2279,2280],{"class":465},"cms.company.com\n",[455,2282,2283,2285,2287],{"class":457,"line":549},[455,2284,1994],{"class":485},[455,2286,1957],{"class":475},[455,2288,2289],{"class":465},"app.company.com\n",[455,2291,2292,2294,2296],{"class":457,"line":555},[455,2293,2009],{"class":485},[455,2295,1957],{"class":475},[455,2297,2298],{"class":465},"company.com\n",[455,2300,2301,2303,2305],{"class":457,"line":561},[455,2302,2024],{"class":485},[455,2304,1957],{"class":475},[455,2306,2298],{"class":465},[455,2308,2309],{"class":457,"line":567},[455,2310,654],{"emptyLinePlaceholder":653},[455,2312,2313,2315,2317,2320],{"class":457,"line":573},[455,2314,2067],{"class":485},[455,2316,1957],{"class":475},[455,2318,2319],{"class":465},"...",[455,2321,2322],{"class":539},"     # openssl rand -base64 32\n",[455,2324,2325,2327,2329,2331],{"class":457,"line":578},[455,2326,2075],{"class":485},[455,2328,1957],{"class":475},[455,2330,2319],{"class":465},[455,2332,2333],{"class":539},"    # openssl rand -base64 32\n",[455,2335,2336],{"class":457,"line":584},[455,2337,654],{"emptyLinePlaceholder":653},[455,2339,2340,2342,2344,2347],{"class":457,"line":590},[455,2341,2101],{"class":485},[455,2343,1957],{"class":475},[455,2345,2346],{"class":465},"ddm1....",[455,2348,2349],{"class":539},"      # the licence from us\n",[455,2351,2352],{"class":457,"line":596},[455,2353,654],{"emptyLinePlaceholder":653},[455,2355,2356,2358,2360],{"class":457,"line":602},[455,2357,2117],{"class":485},[455,2359,1957],{"class":475},[455,2361,2122],{"class":465},[455,2363,2364,2366,2368],{"class":457,"line":608},[455,2365,2127],{"class":485},[455,2367,1957],{"class":475},[455,2369,2370],{"class":465},"ddm@company.com\n",[455,2372,2373,2375,2377],{"class":457,"line":614},[455,2374,2137],{"class":485},[455,2376,1957],{"class":475},[455,2378,2379],{"class":465},"mail.company.com\n",[455,2381,2382,2384,2386],{"class":457,"line":619},[455,2383,2147],{"class":485},[455,2385,1957],{"class":475},[455,2387,2152],{"class":465},[455,2389,2390,2392,2394],{"class":457,"line":625},[455,2391,2157],{"class":485},[455,2393,1957],{"class":475},[455,2395,2396],{"class":465},"...\n",[455,2398,2399,2401,2403],{"class":457,"line":631},[455,2400,2164],{"class":485},[455,2402,1957],{"class":475},[455,2404,2396],{"class":465},[2406,2407,2408,2417,2427],"ul",{},[2409,2410,2411,2416],"li",{},[518,2412,2413,2415],{},[452,2414,2101],{}," is needed from the start."," Without a licence the installation starts locked, and nobody can create the first account.",[2409,2418,2419,2423,2424,2426],{},[518,2420,2421],{},[452,2422,2067],{}," is taken over by Postgres on the first start. Don't change it in ",[452,2425,526],{}," after that – otherwise the CMS can no longer reach the database.",[2409,2428,2429,2433,2434,2438],{},[518,2430,2431],{},[452,2432,2009],{}," and ",[518,2435,2436],{},[452,2437,2024],{}," are the domain both host names share. That way a sign-in and a passkey in the CMS also work in the reader app.",[433,2440,2441,2442,527],{},"All other settings are listed under ",[2443,2444,396],"a",{"href":397},[437,2446,2448],{"id":2447},"_4-choose-the-reverse-proxy","4. Choose the reverse proxy",[433,2450,2451,2452,2433,2455,2458],{},"On the server, the CMS and the reader app only answer locally, on ",[452,2453,2454],{},"127.0.0.1:3000",[452,2456,2457],{},"127.0.0.1:3001",". In front of them goes a reverse proxy that handles TLS:",[2406,2460,2461,2471],{},[2409,2462,2463,2466,2467,2470],{},[518,2464,2465],{},"The bundled Caddy",", if nothing else runs on ports 80 and 443. It fetches the certificates for both host names itself. Start with ",[452,2468,2469],{},"--profile proxy"," in that case.",[2409,2472,2473,2476,2477,2479,2480,2482,2483,527],{},[518,2474,2475],{},"Your own proxy"," (nginx, Traefik, a load balancer). Route ",[452,2478,1984],{}," to port 3000 and ",[452,2481,1994],{}," to port 3001. Allow requests of up to 1 GB, or large uploads fail – with nginx, ",[452,2484,2485],{},"client_max_body_size 1g;",[437,2487,2489],{"id":2488},"_5-start","5. Start",[445,2491,2493],{"className":447,"code":2492,"language":449,"meta":450,"style":450},"docker compose up -d                   # with your own proxy\ndocker compose --profile proxy up -d   # with Caddy\n",[452,2494,2495,2510],{"__ignoreMap":450},[455,2496,2497,2499,2502,2505,2507],{"class":457,"line":458},[455,2498,462],{"class":461},[455,2500,2501],{"class":465}," compose",[455,2503,2504],{"class":465}," up",[455,2506,877],{"class":465},[455,2508,2509],{"class":539},"                   # with your own proxy\n",[455,2511,2512,2514,2516,2519,2522,2524,2526],{"class":457,"line":543},[455,2513,462],{"class":461},[455,2515,2501],{"class":465},[455,2517,2518],{"class":465}," --profile",[455,2520,2521],{"class":465}," proxy",[455,2523,2504],{"class":465},[455,2525,877],{"class":465},[455,2527,2528],{"class":539},"   # with Caddy\n",[433,2530,2531,2532,2535,2536,527],{},"On the first start the CMS sets up the database. This takes a minute; after that, ",[452,2533,2534],{},"docker compose ps"," shows the services as ",[452,2537,2538],{},"healthy",[437,2540,2542],{"id":2541},"_6-create-the-first-account","6. Create the first account",[433,2544,2545,2546,2433,2549,2552,2553,2555,2556,527],{},"Open ",[452,2547,2548],{},"https:\u002F\u002Fcms.company.com",[518,2550,2551],{},"register"," – with your name, your company and your e-mail address. This creates your organisation, and you are its owner. Then invite your colleagues under ",[518,2554,68],{}," or connect your directory under ",[518,2557,2558],{},"Settings › Directory services",[433,2560,2561],{},"The licence states how many organisations your installation may have. Once that number is reached, nobody can create a new one.",[437,2563,2565],{"id":2564},"the-data","The data",[2567,2568,2569,2582],"table",{},[2570,2571,2572],"thead",{},[2573,2574,2575,2579],"tr",{},[2576,2577,2578],"th",{},"Volume",[2576,2580,2581],{},"Contents",[2583,2584,2585,2596,2614],"tbody",{},[2573,2586,2587,2593],{},[2588,2589,2590],"td",{},[452,2591,2592],{},"ddm_postgres",[2588,2594,2595],{},"The database.",[2573,2597,2598,2603],{},[2588,2599,2600],{},[452,2601,2602],{},"ddm_data",[2588,2604,2605,2606,2609,2610,2613],{},"The documents (",[452,2607,2608],{},"storage\u002F",") and the database backups (",[452,2611,2612],{},"backups\u002F",").",[2573,2615,2616,2621],{},[2588,2617,2618],{},[452,2619,2620],{},"ddm_caddy",[2588,2622,2623],{},"The certificates of the bundled proxy.",[433,2625,2626,2627,2630,2631,2634],{},"If the documents should live in an S3 bucket, enter it under ",[452,2628,2629],{},"S3_ENDPOINT",", ",[452,2632,2633],{},"S3_BUCKET"," and the keys. The backups then go to the same bucket.",[2636,2637,2638],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":450,"searchDepth":543,"depth":543,"links":2640},[2641,2642,2643,2644,2645,2646,2647],{"id":439,"depth":543,"text":440},{"id":506,"depth":543,"text":507},{"id":2248,"depth":543,"text":2249},{"id":2447,"depth":543,"text":2448},{"id":2488,"depth":543,"text":2489},{"id":2541,"depth":543,"text":2542},{"id":2564,"depth":543,"text":2565},"Set up DDM on one server with Docker Compose – from signing in to the registry to the first account.","md",null,{},{"icon":106},{"title":387,"description":2648},"5LMbAgkuARnqtfcbH5mQ3dyc8-wnXRofTMtCZ7Ayrnk",[2656,2658],{"title":245,"path":384,"stem":385,"description":2657,"icon":14,"children":-1},"DDM on your own servers – what it consists of, what you need and how it stays connected to us.",{"title":391,"path":392,"stem":393,"description":2659,"icon":394,"children":-1},"DDM in a Kubernetes cluster – one file with everything, two with your settings, and a secret for the registry.",1793617723223]