@intlayer/docs 9.5.6 → 9.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/ar/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ar/i18next_vs_intlayer.md +130 -16
- package/blog/ar/lingui_vs_intlayer.md +122 -15
- package/blog/ar/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/ar/next-intl_vs_intlayer.md +136 -20
- package/blog/ar/vue-i18n_vs_intlayer-vue-i18n.md +119 -17
- package/blog/ar/vue-i18n_vs_intlayer.md +193 -31
- package/blog/ar/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/de/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/de/i18next_vs_intlayer.md +128 -14
- package/blog/de/lingui_vs_intlayer.md +122 -15
- package/blog/de/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/de/next-intl_vs_intlayer.md +125 -15
- package/blog/de/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/de/vue-i18n_vs_intlayer.md +193 -31
- package/blog/en/i18next_vs_intlayer-i18next.md +121 -14
- package/blog/en/i18next_vs_intlayer.md +128 -14
- package/blog/en/lingui_vs_intlayer.md +124 -15
- package/blog/en/next-intl_vs_intlayer-next-intl.md +123 -14
- package/blog/en/next-intl_vs_intlayer.md +125 -13
- package/blog/en/vue-i18n_vs_intlayer-vue-i18n.md +115 -15
- package/blog/en/vue-i18n_vs_intlayer.md +188 -27
- package/blog/en-GB/i18next_vs_intlayer-i18next.md +121 -14
- package/blog/en-GB/i18next_vs_intlayer.md +128 -14
- package/blog/en-GB/lingui_vs_intlayer.md +122 -15
- package/blog/en-GB/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/en-GB/next-intl_vs_intlayer.md +125 -15
- package/blog/en-GB/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/en-GB/vue-i18n_vs_intlayer.md +187 -25
- package/blog/en-GB/vue-i18n_vs_intlayer_benchmark.md +116 -0
- package/blog/es/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/es/i18next_vs_intlayer.md +128 -14
- package/blog/es/lingui_vs_intlayer.md +122 -15
- package/blog/es/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/es/next-intl_vs_intlayer.md +125 -15
- package/blog/es/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/es/vue-i18n_vs_intlayer.md +193 -31
- package/blog/fr/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/fr/i18next_vs_intlayer.md +128 -14
- package/blog/fr/lingui_vs_intlayer.md +122 -15
- package/blog/fr/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/fr/next-intl_vs_intlayer.md +127 -15
- package/blog/fr/vue-i18n_vs_intlayer-vue-i18n.md +118 -17
- package/blog/fr/vue-i18n_vs_intlayer.md +192 -31
- package/blog/fr/vue-i18n_vs_intlayer_benchmark.md +329 -7
- package/blog/hi/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/hi/i18next_vs_intlayer.md +130 -16
- package/blog/hi/lingui_vs_intlayer.md +122 -15
- package/blog/hi/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/hi/next-intl_vs_intlayer.md +135 -19
- package/blog/hi/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/hi/vue-i18n_vs_intlayer.md +193 -31
- package/blog/hi/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/id/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/id/i18next_vs_intlayer.md +128 -14
- package/blog/id/lingui_vs_intlayer.md +122 -15
- package/blog/id/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/id/next-intl_vs_intlayer.md +135 -19
- package/blog/id/vue-i18n_vs_intlayer-vue-i18n.md +354 -2
- package/blog/id/vue-i18n_vs_intlayer.md +188 -26
- package/blog/id/vue-i18n_vs_intlayer_benchmark.md +327 -7
- package/blog/it/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/it/i18next_vs_intlayer.md +128 -14
- package/blog/it/lingui_vs_intlayer.md +122 -15
- package/blog/it/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/it/next-intl_vs_intlayer.md +125 -15
- package/blog/it/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/it/vue-i18n_vs_intlayer.md +191 -31
- package/blog/it/vue-i18n_vs_intlayer_benchmark.md +332 -5
- package/blog/ja/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ja/i18next_vs_intlayer.md +129 -17
- package/blog/ja/lingui_vs_intlayer.md +122 -15
- package/blog/ja/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/ja/next-intl_vs_intlayer.md +124 -14
- package/blog/ja/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/ja/vue-i18n_vs_intlayer.md +193 -31
- package/blog/ja/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/ko/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ko/i18next_vs_intlayer.md +129 -17
- package/blog/ko/lingui_vs_intlayer.md +122 -15
- package/blog/ko/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/ko/next-intl_vs_intlayer.md +134 -18
- package/blog/ko/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/ko/vue-i18n_vs_intlayer.md +193 -31
- package/blog/pl/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/pl/i18next_vs_intlayer.md +128 -14
- package/blog/pl/lingui_vs_intlayer.md +122 -15
- package/blog/pl/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/pl/next-intl_vs_intlayer.md +134 -18
- package/blog/pl/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/pl/vue-i18n_vs_intlayer.md +188 -26
- package/blog/pl/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/pt/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/pt/i18next_vs_intlayer.md +128 -14
- package/blog/pt/lingui_vs_intlayer.md +122 -15
- package/blog/pt/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/pt/next-intl_vs_intlayer.md +131 -15
- package/blog/pt/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/pt/vue-i18n_vs_intlayer.md +193 -31
- package/blog/pt/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/ru/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ru/i18next_vs_intlayer.md +130 -16
- package/blog/ru/lingui_vs_intlayer.md +122 -15
- package/blog/ru/next-intl_vs_intlayer-next-intl.md +125 -16
- package/blog/ru/next-intl_vs_intlayer.md +123 -13
- package/blog/ru/vue-i18n_vs_intlayer-vue-i18n.md +127 -27
- package/blog/ru/vue-i18n_vs_intlayer.md +193 -31
- package/blog/ru/vue-i18n_vs_intlayer_benchmark.md +326 -19
- package/blog/tr/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/tr/i18next_vs_intlayer.md +128 -14
- package/blog/tr/lingui_vs_intlayer.md +122 -15
- package/blog/tr/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/tr/next-intl_vs_intlayer.md +136 -20
- package/blog/tr/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/tr/vue-i18n_vs_intlayer.md +188 -26
- package/blog/tr/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/uk/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/uk/i18next_vs_intlayer.md +130 -16
- package/blog/uk/lingui_vs_intlayer.md +122 -15
- package/blog/uk/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/uk/next-intl_vs_intlayer.md +135 -19
- package/blog/uk/vue-i18n_vs_intlayer-vue-i18n.md +135 -17
- package/blog/uk/vue-i18n_vs_intlayer.md +188 -27
- package/blog/uk/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/vi/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/vi/i18next_vs_intlayer.md +128 -14
- package/blog/vi/lingui_vs_intlayer.md +122 -15
- package/blog/vi/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/vi/next-intl_vs_intlayer.md +135 -19
- package/blog/vi/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/vi/vue-i18n_vs_intlayer.md +188 -26
- package/blog/vi/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/zh/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/zh/i18next_vs_intlayer.md +128 -14
- package/blog/zh/lingui_vs_intlayer.md +122 -15
- package/blog/zh/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/zh/next-intl_vs_intlayer.md +125 -15
- package/blog/zh/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/zh/vue-i18n_vs_intlayer.md +192 -31
- package/blog/zh/vue-i18n_vs_intlayer_benchmark.md +340 -9
- package/dist/cjs/generated/docs.entry.cjs +40 -40
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/index.cjs +2 -2
- package/dist/esm/generated/docs.entry.mjs +40 -40
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/index.mjs +2 -2
- package/dist/types/generated/docs.entry.d.ts +2 -2
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/benchmark/nextjs.md +13 -13
- package/docs/ar/benchmark/solid.md +5 -5
- package/docs/ar/benchmark/svelte.md +4 -4
- package/docs/ar/benchmark/tanstack.md +14 -13
- package/docs/ar/benchmark/vue.md +5 -5
- package/docs/ar/chrome_extension.md +130 -0
- package/docs/ar/cli/index.md +6 -1
- package/docs/ar/cli/infra.md +162 -0
- package/docs/ar/cli/init.md +24 -1
- package/docs/ar/dictionary/html.md +173 -5
- package/docs/ar/dictionary/markdown.md +263 -1
- package/docs/ar/intlayer_with_analog.md +23 -1
- package/docs/ar/intlayer_with_angular_19.md +24 -1
- package/docs/ar/intlayer_with_angular_21.md +24 -1
- package/docs/ar/intlayer_with_astro.md +24 -1
- package/docs/ar/intlayer_with_astro_lit.md +25 -1
- package/docs/ar/intlayer_with_astro_preact.md +26 -1
- package/docs/ar/intlayer_with_astro_react.md +26 -1
- package/docs/ar/intlayer_with_astro_solid.md +26 -1
- package/docs/ar/intlayer_with_astro_svelte.md +25 -1
- package/docs/ar/intlayer_with_astro_vue.md +25 -1
- package/docs/ar/intlayer_with_remix_3.md +22 -1
- package/docs/ar/self_hosting.md +406 -231
- package/docs/de/benchmark/nextjs.md +13 -13
- package/docs/de/benchmark/solid.md +5 -5
- package/docs/de/benchmark/svelte.md +4 -4
- package/docs/de/benchmark/tanstack.md +14 -13
- package/docs/de/benchmark/vue.md +5 -5
- package/docs/de/chrome_extension.md +130 -0
- package/docs/de/cli/index.md +6 -1
- package/docs/de/cli/infra.md +162 -0
- package/docs/de/cli/init.md +24 -1
- package/docs/de/dictionary/html.md +173 -5
- package/docs/de/dictionary/markdown.md +263 -1
- package/docs/de/intlayer_with_analog.md +23 -1
- package/docs/de/intlayer_with_angular_19.md +24 -1
- package/docs/de/intlayer_with_angular_21.md +24 -1
- package/docs/de/intlayer_with_astro.md +24 -1
- package/docs/de/intlayer_with_astro_lit.md +25 -1
- package/docs/de/intlayer_with_astro_preact.md +26 -1
- package/docs/de/intlayer_with_astro_react.md +26 -1
- package/docs/de/intlayer_with_astro_solid.md +26 -1
- package/docs/de/intlayer_with_astro_svelte.md +25 -1
- package/docs/de/intlayer_with_astro_vue.md +25 -1
- package/docs/de/intlayer_with_remix_3.md +22 -1
- package/docs/de/self_hosting.md +404 -227
- package/docs/en/benchmark/nextjs.md +13 -13
- package/docs/en/benchmark/solid.md +5 -5
- package/docs/en/benchmark/svelte.md +4 -4
- package/docs/en/benchmark/tanstack.md +14 -13
- package/docs/en/benchmark/vue.md +5 -5
- package/docs/en/chrome_extension.md +130 -0
- package/docs/en/cli/index.md +6 -1
- package/docs/en/cli/infra.md +175 -0
- package/docs/en/cli/init.md +25 -1
- package/docs/en/dictionary/html.md +173 -5
- package/docs/en/dictionary/markdown.md +263 -1
- package/docs/en/intlayer_with_analog.md +23 -1
- package/docs/en/intlayer_with_angular_19.md +24 -1
- package/docs/en/intlayer_with_angular_21.md +24 -1
- package/docs/en/intlayer_with_astro.md +24 -1
- package/docs/en/intlayer_with_astro_lit.md +25 -1
- package/docs/en/intlayer_with_astro_preact.md +26 -1
- package/docs/en/intlayer_with_astro_react.md +26 -1
- package/docs/en/intlayer_with_astro_solid.md +26 -1
- package/docs/en/intlayer_with_astro_svelte.md +25 -1
- package/docs/en/intlayer_with_astro_vue.md +25 -1
- package/docs/en/intlayer_with_remix_3.md +22 -1
- package/docs/en/self_hosting.md +418 -176
- package/docs/en-GB/benchmark/nextjs.md +13 -13
- package/docs/en-GB/benchmark/solid.md +5 -5
- package/docs/en-GB/benchmark/svelte.md +4 -4
- package/docs/en-GB/benchmark/tanstack.md +14 -13
- package/docs/en-GB/benchmark/vue.md +5 -5
- package/docs/en-GB/chrome_extension.md +130 -0
- package/docs/en-GB/cli/index.md +6 -1
- package/docs/en-GB/cli/infra.md +162 -0
- package/docs/en-GB/cli/init.md +24 -1
- package/docs/en-GB/dictionary/html.md +173 -5
- package/docs/en-GB/dictionary/markdown.md +263 -1
- package/docs/en-GB/intlayer_with_analog.md +23 -1
- package/docs/en-GB/intlayer_with_angular_19.md +24 -1
- package/docs/en-GB/intlayer_with_angular_21.md +24 -1
- package/docs/en-GB/intlayer_with_astro.md +24 -1
- package/docs/en-GB/intlayer_with_astro_lit.md +25 -1
- package/docs/en-GB/intlayer_with_astro_preact.md +26 -1
- package/docs/en-GB/intlayer_with_astro_react.md +26 -1
- package/docs/en-GB/intlayer_with_astro_solid.md +26 -1
- package/docs/en-GB/intlayer_with_astro_svelte.md +25 -1
- package/docs/en-GB/intlayer_with_astro_vue.md +25 -1
- package/docs/en-GB/intlayer_with_remix_3.md +22 -1
- package/docs/en-GB/self_hosting.md +381 -206
- package/docs/es/benchmark/nextjs.md +13 -13
- package/docs/es/benchmark/solid.md +5 -5
- package/docs/es/benchmark/svelte.md +4 -4
- package/docs/es/benchmark/tanstack.md +14 -13
- package/docs/es/benchmark/vue.md +5 -5
- package/docs/es/chrome_extension.md +130 -0
- package/docs/es/cli/index.md +6 -1
- package/docs/es/cli/infra.md +162 -0
- package/docs/es/cli/init.md +24 -1
- package/docs/es/dictionary/html.md +173 -5
- package/docs/es/dictionary/markdown.md +263 -1
- package/docs/es/intlayer_with_analog.md +23 -1
- package/docs/es/intlayer_with_angular_19.md +24 -1
- package/docs/es/intlayer_with_angular_21.md +24 -1
- package/docs/es/intlayer_with_astro.md +24 -1
- package/docs/es/intlayer_with_astro_lit.md +25 -1
- package/docs/es/intlayer_with_astro_preact.md +26 -1
- package/docs/es/intlayer_with_astro_react.md +26 -1
- package/docs/es/intlayer_with_astro_solid.md +26 -1
- package/docs/es/intlayer_with_astro_svelte.md +25 -1
- package/docs/es/intlayer_with_astro_vue.md +25 -1
- package/docs/es/intlayer_with_remix_3.md +22 -1
- package/docs/es/self_hosting.md +400 -223
- package/docs/fr/benchmark/nextjs.md +13 -13
- package/docs/fr/benchmark/solid.md +5 -5
- package/docs/fr/benchmark/svelte.md +4 -4
- package/docs/fr/benchmark/tanstack.md +14 -13
- package/docs/fr/benchmark/vue.md +5 -5
- package/docs/fr/chrome_extension.md +130 -0
- package/docs/fr/cli/index.md +6 -1
- package/docs/fr/cli/infra.md +162 -0
- package/docs/fr/cli/init.md +24 -1
- package/docs/fr/dictionary/html.md +173 -5
- package/docs/fr/dictionary/markdown.md +265 -4
- package/docs/fr/intlayer_with_analog.md +23 -1
- package/docs/fr/intlayer_with_angular_19.md +24 -1
- package/docs/fr/intlayer_with_angular_21.md +24 -1
- package/docs/fr/intlayer_with_astro.md +24 -1
- package/docs/fr/intlayer_with_astro_lit.md +25 -1
- package/docs/fr/intlayer_with_astro_preact.md +26 -1
- package/docs/fr/intlayer_with_astro_react.md +26 -1
- package/docs/fr/intlayer_with_astro_solid.md +26 -1
- package/docs/fr/intlayer_with_astro_svelte.md +25 -1
- package/docs/fr/intlayer_with_astro_vue.md +25 -1
- package/docs/fr/intlayer_with_remix_3.md +22 -1
- package/docs/fr/self_hosting.md +401 -224
- package/docs/hi/benchmark/nextjs.md +13 -13
- package/docs/hi/benchmark/solid.md +5 -5
- package/docs/hi/benchmark/svelte.md +4 -4
- package/docs/hi/benchmark/tanstack.md +14 -13
- package/docs/hi/benchmark/vue.md +5 -5
- package/docs/hi/chrome_extension.md +130 -0
- package/docs/hi/cli/index.md +6 -1
- package/docs/hi/cli/infra.md +162 -0
- package/docs/hi/cli/init.md +24 -1
- package/docs/hi/dictionary/html.md +173 -5
- package/docs/hi/dictionary/markdown.md +263 -1
- package/docs/hi/intlayer_with_analog.md +23 -1
- package/docs/hi/intlayer_with_angular_19.md +24 -1
- package/docs/hi/intlayer_with_angular_21.md +24 -1
- package/docs/hi/intlayer_with_astro.md +24 -1
- package/docs/hi/intlayer_with_astro_lit.md +25 -1
- package/docs/hi/intlayer_with_astro_preact.md +26 -1
- package/docs/hi/intlayer_with_astro_react.md +26 -1
- package/docs/hi/intlayer_with_astro_solid.md +26 -1
- package/docs/hi/intlayer_with_astro_svelte.md +25 -1
- package/docs/hi/intlayer_with_astro_vue.md +25 -1
- package/docs/hi/intlayer_with_remix_3.md +22 -1
- package/docs/hi/self_hosting.md +409 -235
- package/docs/id/benchmark/nextjs.md +13 -13
- package/docs/id/benchmark/solid.md +5 -5
- package/docs/id/benchmark/svelte.md +4 -4
- package/docs/id/benchmark/tanstack.md +14 -13
- package/docs/id/benchmark/vue.md +5 -5
- package/docs/id/chrome_extension.md +130 -0
- package/docs/id/cli/index.md +6 -1
- package/docs/id/cli/infra.md +162 -0
- package/docs/id/cli/init.md +24 -1
- package/docs/id/dictionary/html.md +173 -5
- package/docs/id/dictionary/markdown.md +263 -1
- package/docs/id/intlayer_with_analog.md +23 -1
- package/docs/id/intlayer_with_angular_19.md +24 -1
- package/docs/id/intlayer_with_angular_21.md +24 -1
- package/docs/id/intlayer_with_astro.md +24 -1
- package/docs/id/intlayer_with_astro_lit.md +25 -1
- package/docs/id/intlayer_with_astro_preact.md +26 -1
- package/docs/id/intlayer_with_astro_react.md +26 -1
- package/docs/id/intlayer_with_astro_solid.md +26 -1
- package/docs/id/intlayer_with_astro_svelte.md +25 -1
- package/docs/id/intlayer_with_astro_vue.md +25 -1
- package/docs/id/intlayer_with_remix_3.md +22 -1
- package/docs/id/self_hosting.md +416 -243
- package/docs/it/benchmark/nextjs.md +13 -13
- package/docs/it/benchmark/solid.md +5 -5
- package/docs/it/benchmark/svelte.md +4 -4
- package/docs/it/benchmark/tanstack.md +14 -13
- package/docs/it/benchmark/vue.md +5 -5
- package/docs/it/chrome_extension.md +130 -0
- package/docs/it/cli/index.md +6 -1
- package/docs/it/cli/infra.md +162 -0
- package/docs/it/cli/init.md +24 -1
- package/docs/it/dictionary/html.md +173 -5
- package/docs/it/dictionary/markdown.md +263 -1
- package/docs/it/intlayer_with_analog.md +23 -1
- package/docs/it/intlayer_with_angular_19.md +24 -1
- package/docs/it/intlayer_with_angular_21.md +24 -1
- package/docs/it/intlayer_with_astro.md +24 -1
- package/docs/it/intlayer_with_astro_lit.md +25 -1
- package/docs/it/intlayer_with_astro_preact.md +26 -1
- package/docs/it/intlayer_with_astro_react.md +26 -1
- package/docs/it/intlayer_with_astro_solid.md +26 -1
- package/docs/it/intlayer_with_astro_svelte.md +25 -1
- package/docs/it/intlayer_with_astro_vue.md +25 -1
- package/docs/it/intlayer_with_remix_3.md +22 -1
- package/docs/it/self_hosting.md +412 -237
- package/docs/ja/benchmark/nextjs.md +13 -13
- package/docs/ja/benchmark/solid.md +5 -5
- package/docs/ja/benchmark/svelte.md +4 -4
- package/docs/ja/benchmark/tanstack.md +13 -12
- package/docs/ja/benchmark/vue.md +5 -5
- package/docs/ja/chrome_extension.md +130 -0
- package/docs/ja/cli/index.md +6 -1
- package/docs/ja/cli/infra.md +162 -0
- package/docs/ja/cli/init.md +24 -1
- package/docs/ja/dictionary/html.md +173 -5
- package/docs/ja/dictionary/markdown.md +263 -1
- package/docs/ja/intlayer_with_analog.md +23 -1
- package/docs/ja/intlayer_with_angular_19.md +24 -1
- package/docs/ja/intlayer_with_angular_21.md +24 -1
- package/docs/ja/intlayer_with_astro.md +24 -1
- package/docs/ja/intlayer_with_astro_lit.md +25 -1
- package/docs/ja/intlayer_with_astro_preact.md +26 -1
- package/docs/ja/intlayer_with_astro_react.md +26 -1
- package/docs/ja/intlayer_with_astro_solid.md +26 -1
- package/docs/ja/intlayer_with_astro_svelte.md +25 -1
- package/docs/ja/intlayer_with_astro_vue.md +25 -1
- package/docs/ja/intlayer_with_remix_3.md +22 -1
- package/docs/ja/self_hosting.md +398 -223
- package/docs/ko/benchmark/nextjs.md +13 -13
- package/docs/ko/benchmark/solid.md +5 -5
- package/docs/ko/benchmark/svelte.md +4 -4
- package/docs/ko/benchmark/tanstack.md +14 -13
- package/docs/ko/benchmark/vue.md +5 -5
- package/docs/ko/chrome_extension.md +130 -0
- package/docs/ko/cli/index.md +6 -1
- package/docs/ko/cli/infra.md +162 -0
- package/docs/ko/cli/init.md +24 -1
- package/docs/ko/dictionary/html.md +173 -5
- package/docs/ko/dictionary/markdown.md +263 -1
- package/docs/ko/intlayer_with_analog.md +23 -1
- package/docs/ko/intlayer_with_angular_19.md +24 -1
- package/docs/ko/intlayer_with_angular_21.md +24 -1
- package/docs/ko/intlayer_with_astro.md +24 -1
- package/docs/ko/intlayer_with_astro_lit.md +25 -1
- package/docs/ko/intlayer_with_astro_preact.md +26 -1
- package/docs/ko/intlayer_with_astro_react.md +26 -1
- package/docs/ko/intlayer_with_astro_solid.md +26 -1
- package/docs/ko/intlayer_with_astro_svelte.md +25 -1
- package/docs/ko/intlayer_with_astro_vue.md +25 -1
- package/docs/ko/intlayer_with_remix_3.md +22 -1
- package/docs/ko/self_hosting.md +411 -238
- package/docs/pl/benchmark/nextjs.md +13 -13
- package/docs/pl/benchmark/solid.md +5 -5
- package/docs/pl/benchmark/svelte.md +4 -4
- package/docs/pl/benchmark/tanstack.md +14 -13
- package/docs/pl/benchmark/vue.md +5 -5
- package/docs/pl/chrome_extension.md +130 -0
- package/docs/pl/cli/index.md +6 -1
- package/docs/pl/cli/infra.md +162 -0
- package/docs/pl/cli/init.md +24 -1
- package/docs/pl/dictionary/html.md +173 -5
- package/docs/pl/dictionary/markdown.md +263 -1
- package/docs/pl/intlayer_with_analog.md +23 -1
- package/docs/pl/intlayer_with_angular_19.md +24 -1
- package/docs/pl/intlayer_with_angular_21.md +24 -1
- package/docs/pl/intlayer_with_astro.md +24 -1
- package/docs/pl/intlayer_with_astro_lit.md +25 -1
- package/docs/pl/intlayer_with_astro_preact.md +26 -1
- package/docs/pl/intlayer_with_astro_react.md +26 -1
- package/docs/pl/intlayer_with_astro_solid.md +26 -1
- package/docs/pl/intlayer_with_astro_svelte.md +25 -1
- package/docs/pl/intlayer_with_astro_vue.md +25 -1
- package/docs/pl/intlayer_with_remix_3.md +22 -1
- package/docs/pl/self_hosting.md +408 -233
- package/docs/pt/benchmark/nextjs.md +13 -13
- package/docs/pt/benchmark/solid.md +5 -5
- package/docs/pt/benchmark/svelte.md +4 -4
- package/docs/pt/benchmark/tanstack.md +14 -13
- package/docs/pt/benchmark/vue.md +5 -5
- package/docs/pt/chrome_extension.md +130 -0
- package/docs/pt/cli/index.md +6 -1
- package/docs/pt/cli/infra.md +162 -0
- package/docs/pt/cli/init.md +24 -1
- package/docs/pt/dictionary/html.md +173 -5
- package/docs/pt/dictionary/markdown.md +263 -1
- package/docs/pt/intlayer_with_analog.md +23 -1
- package/docs/pt/intlayer_with_angular_19.md +24 -1
- package/docs/pt/intlayer_with_angular_21.md +24 -1
- package/docs/pt/intlayer_with_astro.md +24 -1
- package/docs/pt/intlayer_with_astro_lit.md +25 -1
- package/docs/pt/intlayer_with_astro_preact.md +26 -1
- package/docs/pt/intlayer_with_astro_react.md +26 -1
- package/docs/pt/intlayer_with_astro_solid.md +26 -1
- package/docs/pt/intlayer_with_astro_svelte.md +25 -1
- package/docs/pt/intlayer_with_astro_vue.md +25 -1
- package/docs/pt/intlayer_with_remix_3.md +22 -1
- package/docs/pt/self_hosting.md +399 -224
- package/docs/ru/benchmark/nextjs.md +13 -13
- package/docs/ru/benchmark/solid.md +5 -5
- package/docs/ru/benchmark/svelte.md +4 -4
- package/docs/ru/benchmark/tanstack.md +14 -13
- package/docs/ru/benchmark/vue.md +5 -5
- package/docs/ru/chrome_extension.md +130 -0
- package/docs/ru/cli/index.md +6 -1
- package/docs/ru/cli/infra.md +162 -0
- package/docs/ru/cli/init.md +24 -1
- package/docs/ru/dictionary/html.md +173 -5
- package/docs/ru/dictionary/markdown.md +263 -1
- package/docs/ru/intlayer_with_analog.md +23 -1
- package/docs/ru/intlayer_with_angular_19.md +24 -1
- package/docs/ru/intlayer_with_angular_21.md +24 -1
- package/docs/ru/intlayer_with_astro.md +24 -1
- package/docs/ru/intlayer_with_astro_lit.md +25 -1
- package/docs/ru/intlayer_with_astro_preact.md +26 -1
- package/docs/ru/intlayer_with_astro_react.md +26 -1
- package/docs/ru/intlayer_with_astro_solid.md +26 -1
- package/docs/ru/intlayer_with_astro_svelte.md +25 -1
- package/docs/ru/intlayer_with_astro_vue.md +25 -1
- package/docs/ru/intlayer_with_remix_3.md +22 -1
- package/docs/ru/self_hosting.md +403 -228
- package/docs/tr/benchmark/nextjs.md +13 -13
- package/docs/tr/benchmark/solid.md +5 -5
- package/docs/tr/benchmark/svelte.md +4 -4
- package/docs/tr/benchmark/tanstack.md +14 -13
- package/docs/tr/benchmark/vue.md +5 -5
- package/docs/tr/chrome_extension.md +130 -0
- package/docs/tr/cli/index.md +6 -1
- package/docs/tr/cli/infra.md +162 -0
- package/docs/tr/cli/init.md +24 -1
- package/docs/tr/dictionary/html.md +173 -5
- package/docs/tr/dictionary/markdown.md +263 -1
- package/docs/tr/intlayer_with_analog.md +23 -1
- package/docs/tr/intlayer_with_angular_19.md +24 -1
- package/docs/tr/intlayer_with_angular_21.md +24 -1
- package/docs/tr/intlayer_with_astro.md +24 -1
- package/docs/tr/intlayer_with_astro_lit.md +25 -1
- package/docs/tr/intlayer_with_astro_preact.md +26 -1
- package/docs/tr/intlayer_with_astro_react.md +26 -1
- package/docs/tr/intlayer_with_astro_solid.md +26 -1
- package/docs/tr/intlayer_with_astro_svelte.md +25 -1
- package/docs/tr/intlayer_with_astro_vue.md +25 -1
- package/docs/tr/intlayer_with_remix_3.md +22 -1
- package/docs/tr/self_hosting.md +410 -234
- package/docs/uk/benchmark/nextjs.md +13 -13
- package/docs/uk/benchmark/solid.md +5 -5
- package/docs/uk/benchmark/svelte.md +4 -4
- package/docs/uk/benchmark/tanstack.md +14 -13
- package/docs/uk/benchmark/vue.md +5 -5
- package/docs/uk/chrome_extension.md +130 -0
- package/docs/uk/cli/index.md +6 -1
- package/docs/uk/cli/infra.md +162 -0
- package/docs/uk/cli/init.md +24 -1
- package/docs/uk/dictionary/html.md +173 -5
- package/docs/uk/dictionary/markdown.md +263 -1
- package/docs/uk/intlayer_with_analog.md +23 -1
- package/docs/uk/intlayer_with_angular_19.md +24 -1
- package/docs/uk/intlayer_with_angular_21.md +24 -1
- package/docs/uk/intlayer_with_astro.md +24 -1
- package/docs/uk/intlayer_with_astro_lit.md +25 -1
- package/docs/uk/intlayer_with_astro_preact.md +26 -1
- package/docs/uk/intlayer_with_astro_react.md +26 -1
- package/docs/uk/intlayer_with_astro_solid.md +26 -1
- package/docs/uk/intlayer_with_astro_svelte.md +25 -1
- package/docs/uk/intlayer_with_astro_vue.md +25 -1
- package/docs/uk/intlayer_with_remix_3.md +22 -1
- package/docs/uk/self_hosting.md +413 -238
- package/docs/vi/benchmark/nextjs.md +13 -13
- package/docs/vi/benchmark/solid.md +5 -5
- package/docs/vi/benchmark/svelte.md +4 -4
- package/docs/vi/benchmark/tanstack.md +14 -13
- package/docs/vi/benchmark/vue.md +5 -5
- package/docs/vi/chrome_extension.md +130 -0
- package/docs/vi/cli/index.md +6 -1
- package/docs/vi/cli/infra.md +162 -0
- package/docs/vi/cli/init.md +24 -1
- package/docs/vi/dictionary/html.md +173 -5
- package/docs/vi/dictionary/markdown.md +263 -1
- package/docs/vi/intlayer_with_analog.md +23 -1
- package/docs/vi/intlayer_with_angular_19.md +24 -1
- package/docs/vi/intlayer_with_angular_21.md +24 -1
- package/docs/vi/intlayer_with_astro.md +24 -1
- package/docs/vi/intlayer_with_astro_lit.md +25 -1
- package/docs/vi/intlayer_with_astro_preact.md +26 -1
- package/docs/vi/intlayer_with_astro_react.md +26 -1
- package/docs/vi/intlayer_with_astro_solid.md +26 -1
- package/docs/vi/intlayer_with_astro_svelte.md +25 -1
- package/docs/vi/intlayer_with_astro_vue.md +25 -1
- package/docs/vi/intlayer_with_remix_3.md +22 -1
- package/docs/vi/self_hosting.md +408 -234
- package/docs/zh/benchmark/nextjs.md +13 -13
- package/docs/zh/benchmark/solid.md +5 -5
- package/docs/zh/benchmark/svelte.md +4 -4
- package/docs/zh/benchmark/tanstack.md +14 -13
- package/docs/zh/benchmark/vue.md +5 -5
- package/docs/zh/chrome_extension.md +130 -0
- package/docs/zh/cli/index.md +6 -1
- package/docs/zh/cli/infra.md +162 -0
- package/docs/zh/cli/init.md +24 -1
- package/docs/zh/dictionary/html.md +172 -5
- package/docs/zh/dictionary/markdown.md +262 -1
- package/docs/zh/intlayer_with_analog.md +23 -1
- package/docs/zh/intlayer_with_angular_19.md +24 -1
- package/docs/zh/intlayer_with_angular_21.md +24 -1
- package/docs/zh/intlayer_with_astro.md +24 -1
- package/docs/zh/intlayer_with_astro_lit.md +25 -1
- package/docs/zh/intlayer_with_astro_preact.md +26 -1
- package/docs/zh/intlayer_with_astro_react.md +26 -1
- package/docs/zh/intlayer_with_astro_solid.md +26 -1
- package/docs/zh/intlayer_with_astro_svelte.md +25 -1
- package/docs/zh/intlayer_with_astro_vue.md +25 -1
- package/docs/zh/intlayer_with_remix_3.md +22 -1
- package/docs/zh/self_hosting.md +410 -237
- package/legal/ar/privacy_notice.md +9 -3
- package/legal/de/privacy_notice.md +9 -3
- package/legal/en/privacy_notice.md +10 -3
- package/legal/en-GB/privacy_notice.md +9 -3
- package/legal/es/privacy_notice.md +9 -3
- package/legal/fr/privacy_notice.md +9 -3
- package/legal/hi/privacy_notice.md +9 -3
- package/legal/id/privacy_notice.md +9 -3
- package/legal/it/privacy_notice.md +9 -3
- package/legal/ja/privacy_notice.md +9 -3
- package/legal/ko/privacy_notice.md +9 -3
- package/legal/pl/privacy_notice.md +9 -3
- package/legal/pt/privacy_notice.md +9 -3
- package/legal/ru/privacy_notice.md +9 -3
- package/legal/tr/privacy_notice.md +9 -3
- package/legal/uk/privacy_notice.md +9 -3
- package/legal/vi/privacy_notice.md +9 -3
- package/legal/zh/privacy_notice.md +9 -3
- package/package.json +1 -1
- package/src/generated/docs.entry.ts +40 -40
- package/docs/ar/roadmap.md +0 -321
- package/docs/de/roadmap.md +0 -322
- package/docs/en/intlayer_with_astro_vanilla.md +0 -713
- package/docs/en/roadmap.md +0 -325
- package/docs/en-GB/roadmap.md +0 -322
- package/docs/es/roadmap.md +0 -322
- package/docs/fr/roadmap.md +0 -322
- package/docs/hi/roadmap.md +0 -322
- package/docs/id/roadmap.md +0 -325
- package/docs/it/roadmap.md +0 -322
- package/docs/ja/roadmap.md +0 -322
- package/docs/ko/roadmap.md +0 -322
- package/docs/pl/roadmap.md +0 -325
- package/docs/pt/roadmap.md +0 -322
- package/docs/ru/roadmap.md +0 -322
- package/docs/tr/roadmap.md +0 -325
- package/docs/uk/roadmap.md +0 -325
- package/docs/vi/roadmap.md +0 -325
- package/docs/zh/roadmap.md +0 -322
package/docs/en/self_hosting.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-30
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-09-21
|
|
4
4
|
title: Self-Hosting Intlayer
|
|
5
|
-
description: Run
|
|
5
|
+
description: "Run Intlayer on your own infrastructure: as a desktop app, a single all-in-one Docker container, or a scalable Docker Compose stack. No Intlayer Cloud account required."
|
|
6
6
|
keywords:
|
|
7
7
|
- Self-Hosting
|
|
8
8
|
- Docker
|
|
9
|
+
- Docker Compose
|
|
10
|
+
- Desktop app
|
|
9
11
|
- Intlayer
|
|
10
12
|
- CMS
|
|
11
13
|
- Installation
|
|
@@ -18,23 +20,78 @@ author: aymericzip
|
|
|
18
20
|
|
|
19
21
|
# Self-Hosting Intlayer
|
|
20
22
|
|
|
21
|
-
Intlayer can run on your own infrastructure
|
|
23
|
+
Intlayer can run on your own infrastructure, no Intlayer Cloud account required. Three setups are available, all driven by the same installer (`install.sh`, `install.ps1` on Windows, or `npx intlayer init infra`):
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
| Setup | What it is | Pick it for |
|
|
26
|
+
| --------------------- | ------------------------------------------------------------------------------- | --------------------------------------- |
|
|
27
|
+
| **Desktop app** | Native dashboard for macOS, Linux and Windows | A local client, nothing to host |
|
|
28
|
+
| **All-in-one Docker** | Dashboard, API, MongoDB, Redis and MinIO in a **single container** | Trials and small single-box installs |
|
|
29
|
+
| **Docker Compose** | **One container per service**, each datastore replaceable by a managed offering | Production, scaling, managed datastores |
|
|
30
|
+
|
|
31
|
+
## Table of Contents
|
|
32
|
+
|
|
33
|
+
<TOC/>
|
|
34
|
+
|
|
35
|
+
## Published images and packages
|
|
36
|
+
|
|
37
|
+
| Artifact | Docker Hub | GHCR mirror | Contents |
|
|
38
|
+
| -------------------- | ------------------------------------------------------------------------- | ------------------------------------------ | -------------------------------------------------------------------------------- |
|
|
39
|
+
| All-in-one container | [`intlayer/cms-all`](https://hub.docker.com/r/intlayer/cms-all) | `ghcr.io/aymericzip/intlayer/cms-all` | app + backend + MongoDB 8 + Redis + MinIO + Chromium |
|
|
40
|
+
| Dashboard (frontend) | [`intlayer/cms-frontend`](https://hub.docker.com/r/intlayer/cms-frontend) | `ghcr.io/aymericzip/intlayer/cms-frontend` | TanStack Start dashboard on Bun |
|
|
41
|
+
| API (backend) | [`intlayer/cms-backend`](https://hub.docker.com/r/intlayer/cms-backend) | `ghcr.io/aymericzip/intlayer/cms-backend` | Fastify REST API on Bun + Chromium |
|
|
42
|
+
| Desktop app | [GitHub releases](https://github.com/aymericzip/intlayer/releases/latest) | n/a | `.dmg` (macOS), `.deb` / `.rpm` / `.AppImage` (Linux), `.exe` / `.msi` (Windows) |
|
|
43
|
+
|
|
44
|
+
All three images are built from the same [`docker/selfhost/Dockerfile`](https://github.com/aymericzip/intlayer/tree/main/docker/selfhost) and published on every release. The Compose stack also pulls the official `mongo:8`, `redis:8-alpine` and `quay.io/minio/minio` images.
|
|
45
|
+
|
|
46
|
+
## Setup
|
|
47
|
+
|
|
48
|
+
The installer asks which setup you want, checks the prerequisites (offering to install Docker), writes the environment file with the secrets already generated, and pulls the images. It never starts anything on its own: the Docker modes need a mailer first, so it ends by printing the command to run. Re-running it is safe: an existing environment file is never overwritten, which makes it the upgrade path too.
|
|
49
|
+
|
|
50
|
+
<Tabs group="mode">
|
|
51
|
+
<Tab label="Desktop app" value="desktop">
|
|
52
|
+
|
|
53
|
+
The Intlayer dashboard as a native application, built with Tauri. It signs in to the Intlayer Cloud (`https://app.intlayer.org`), so there is nothing to host. It is the right choice when you want a local client rather than a browser tab.
|
|
54
|
+
|
|
55
|
+
### Install
|
|
56
|
+
|
|
57
|
+
The installer downloads the package for your OS and CPU, then opens it (macOS), installs it (`dpkg` / `rpm` on Linux) or launches the setup wizard (Windows). You can also download it by hand from the [releases page](https://github.com/aymericzip/intlayer/releases/latest).
|
|
58
|
+
|
|
59
|
+
<Tabs group="os">
|
|
60
|
+
<Tab label="macOS / Linux" value="unix">
|
|
24
61
|
|
|
25
62
|
```sh
|
|
26
|
-
curl -fsSL https://intlayer.org/install.sh | sh
|
|
63
|
+
curl -fsSL https://intlayer.org/install.sh | sh -s -- --mode desktop
|
|
27
64
|
```
|
|
28
65
|
|
|
29
|
-
|
|
66
|
+
</Tab>
|
|
67
|
+
<Tab label="Windows" value="windows">
|
|
30
68
|
|
|
31
|
-
|
|
69
|
+
In PowerShell:
|
|
32
70
|
|
|
33
|
-
|
|
71
|
+
```powershell
|
|
72
|
+
$env:INTLAYER_MODE = "desktop"; irm https://intlayer.org/install.ps1 | iex
|
|
73
|
+
```
|
|
34
74
|
|
|
35
|
-
|
|
75
|
+
</Tab>
|
|
76
|
+
<Tab label="Intlayer CLI" value="cli">
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx intlayer init infra --mode desktop
|
|
80
|
+
```
|
|
36
81
|
|
|
37
|
-
|
|
82
|
+
</Tab>
|
|
83
|
+
</Tabs>
|
|
84
|
+
|
|
85
|
+
### Requirements
|
|
86
|
+
|
|
87
|
+
- **Node.js**: the app embeds the dashboard's server and starts it with the machine's own `node` binary. Install it from [nodejs.org](https://nodejs.org) if the app does not start.
|
|
88
|
+
|
|
89
|
+
> The published desktop build talks to the Intlayer Cloud backend. Pointing it at a self-hosted backend requires rebuilding the app with `VITE_BACKEND_URL` set to your API, see [Limitations](#limitations).
|
|
90
|
+
|
|
91
|
+
</Tab>
|
|
92
|
+
<Tab label="All-in-one Docker" value="docker">
|
|
93
|
+
|
|
94
|
+
Everything runs inside the single `intlayer/cms-all` container, supervised by [s6-overlay](https://github.com/just-containers/s6-overlay), with every datastore persisted under one volume.
|
|
38
95
|
|
|
39
96
|
```
|
|
40
97
|
┌─────────────────────────────┐
|
|
@@ -43,170 +100,410 @@ The only external dependency is **MongoDB**: the backend connects to a MongoDB *
|
|
|
43
100
|
┌─────────────────────────────┐ │
|
|
44
101
|
│ backend (Fastify/Bun) :3100│ ◀─┘
|
|
45
102
|
└──────────────┬──────────────┘
|
|
46
|
-
|
|
47
|
-
▼ ▼ ▼
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
(console)
|
|
103
|
+
┌──────────┬─────────┼──────────────┐
|
|
104
|
+
▼ ▼ ▼ ▼
|
|
105
|
+
mongo:27017 redis:6379 minio:9000 Chromium
|
|
106
|
+
/data/mongo /data/redis /data/minio (in-image)
|
|
107
|
+
(1-node RS) minio:9001
|
|
52
108
|
```
|
|
53
109
|
|
|
54
|
-
|
|
110
|
+
| Service | Host port(s) | Purpose |
|
|
111
|
+
| ----------- | ----------------------------- | -------------------------------------------------------- |
|
|
112
|
+
| **app** | `3000` | Dashboard (CMS UI) |
|
|
113
|
+
| **backend** | `3100` | REST API (`/health` endpoint) |
|
|
114
|
+
| **mongo** | internal | MongoDB 8, single-node replica set `rs0` |
|
|
115
|
+
| **redis** | internal | Job queues (BullMQ) and caching |
|
|
116
|
+
| **minio** | `9000` (S3), `9001` (console) | S3-compatible object storage for avatars and screenshots |
|
|
55
117
|
|
|
56
|
-
|
|
118
|
+
Boot order is enforced by s6 dependencies (`mongod` → replica-set init, `minio` → bucket creation, then `backend`, then `app`), and services restart on exit, so the first boot recovers on its own.
|
|
57
119
|
|
|
58
|
-
|
|
59
|
-
- Ports `3000`, `3100`, `9000`, and `9001` available on the host.
|
|
60
|
-
- A Linux or macOS host (or WSL2 on Windows).
|
|
61
|
-
- A **MongoDB Atlas** cluster (a free tier works). Create one at [mongodb.com/atlas](https://www.mongodb.com/atlas).
|
|
62
|
-
- A **Resend** API key for transactional email. Get one at [resend.com](https://resend.com). A [global SMTP mailer](#global-mailer) works instead.
|
|
120
|
+
### Prerequisites
|
|
63
121
|
|
|
64
|
-
|
|
122
|
+
- **Docker** ≥ 24: the installer offers to install it (via [get.docker.com](https://get.docker.com) on Linux, Homebrew on macOS). On Windows, install [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/) (WSL 2 backend) first.
|
|
123
|
+
- Ports `3000`, `3100`, `9000` and `9001` free on the host. MinIO `9000` must stay reachable by the browser, which loads assets straight from `S3_PUBLIC_URL`.
|
|
124
|
+
- A mailer: a [Resend](https://resend.com) API key or an SMTP relay.
|
|
65
125
|
|
|
66
|
-
|
|
126
|
+
### 1. Install
|
|
67
127
|
|
|
68
|
-
|
|
128
|
+
Writes `./intlayer.env` with `BETTER_AUTH_SECRET` and `S3_SECRET_ACCESS_KEY` generated, asks a few questions to fill in the rest, and pulls `intlayer/cms-all:latest`.
|
|
129
|
+
|
|
130
|
+
<Tabs group="os">
|
|
131
|
+
<Tab label="macOS / Linux" value="unix">
|
|
69
132
|
|
|
70
133
|
```sh
|
|
71
|
-
curl -fsSL https://intlayer.org/install.sh | sh
|
|
134
|
+
curl -fsSL https://intlayer.org/install.sh | sh -s -- --mode docker
|
|
72
135
|
```
|
|
73
136
|
|
|
74
|
-
|
|
137
|
+
</Tab>
|
|
138
|
+
<Tab label="Windows" value="windows">
|
|
139
|
+
|
|
140
|
+
In PowerShell:
|
|
75
141
|
|
|
76
|
-
|
|
142
|
+
```powershell
|
|
143
|
+
$env:INTLAYER_MODE = "docker"; irm https://intlayer.org/install.ps1 | iex
|
|
144
|
+
```
|
|
77
145
|
|
|
78
|
-
|
|
146
|
+
</Tab>
|
|
147
|
+
<Tab label="Intlayer CLI" value="cli">
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx intlayer init infra --mode docker
|
|
151
|
+
```
|
|
79
152
|
|
|
80
|
-
|
|
153
|
+
</Tab>
|
|
154
|
+
</Tabs>
|
|
155
|
+
|
|
156
|
+
### 2. Answer the setup questions
|
|
157
|
+
|
|
158
|
+
The installer asks for (press Enter to accept a suggestion, every answer can be changed in the file later):
|
|
159
|
+
|
|
160
|
+
- **The domain** Intlayer is served on. Leave it empty to stay on `localhost`. With a domain such as `example.org`, it suggests `https://cms.example.org` for the dashboard, `https://back.example.org` for the API and `https://s3.example.org/intlayer` for the object storage, and writes `DOMAIN`, `APP_URL`, `BACKEND_URL` and `S3_PUBLIC_URL`. See [Custom domain](#custom-domain) for what follows.
|
|
161
|
+
- **The mailer**: Resend (API key) or an SMTP relay (host, port, credentials), plus the sender address. This can be skipped and done by hand later.
|
|
162
|
+
- An optional **OpenAI API key** for the AI features.
|
|
163
|
+
|
|
164
|
+
Without a terminal (for instance when the script is run from CI), the questions are skipped and only the secrets are generated. Open `intlayer.env` and fill in Resend **or** SMTP by hand (details in [Global mailer](#global-mailer)):
|
|
81
165
|
|
|
82
166
|
```sh fileName="intlayer.env"
|
|
83
|
-
|
|
84
|
-
DB_MDP=<atlas-password>
|
|
85
|
-
DB_CLUSTER=<cluster>.xxxxx.mongodb.net
|
|
167
|
+
# Option A: Resend
|
|
86
168
|
RESEND_API_KEY=<your-resend-key>
|
|
87
|
-
```
|
|
88
169
|
|
|
89
|
-
|
|
170
|
+
# Option B: SMTP (takes over from Resend as soon as MAIL_SMTP_HOST is set)
|
|
171
|
+
MAIL_SMTP_HOST=smtp.example.com
|
|
172
|
+
MAIL_SMTP_PORT=587
|
|
173
|
+
MAIL_SMTP_USER=<user>
|
|
174
|
+
MAIL_SMTP_PASSWORD=<password>
|
|
175
|
+
MAIL_FROM=Intlayer <no-reply@example.com>
|
|
176
|
+
```
|
|
90
177
|
|
|
91
|
-
|
|
178
|
+
### 3. Start
|
|
92
179
|
|
|
93
|
-
|
|
180
|
+
This is the command the installer prints (with a custom domain, it is preceded by the `docker build` that produces `intlayer/cms-all:custom`, see [Custom domain](#custom-domain)):
|
|
94
181
|
|
|
95
|
-
|
|
182
|
+
<Tabs group="os">
|
|
183
|
+
<Tab label="macOS / Linux" value="unix">
|
|
96
184
|
|
|
97
185
|
```sh
|
|
98
186
|
docker run -d --name intlayer \
|
|
99
187
|
--restart unless-stopped \
|
|
100
|
-
-p 3000:3000 \
|
|
101
|
-
-p 3100:3100 \
|
|
102
|
-
-p 9000:9000 \
|
|
103
|
-
-p 9001:9001 \
|
|
188
|
+
-p 3000:3000 -p 3100:3100 -p 9000:9000 -p 9001:9001 \
|
|
104
189
|
-v intlayer-data:/data \
|
|
105
190
|
--env-file ./intlayer.env \
|
|
106
|
-
|
|
191
|
+
intlayer/cms-all:latest
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
</Tab>
|
|
195
|
+
<Tab label="Windows" value="windows">
|
|
196
|
+
|
|
197
|
+
```powershell
|
|
198
|
+
docker run -d --name intlayer `
|
|
199
|
+
--restart unless-stopped `
|
|
200
|
+
-p 3000:3000 -p 3100:3100 -p 9000:9000 -p 9001:9001 `
|
|
201
|
+
-v intlayer-data:/data `
|
|
202
|
+
--env-file ./intlayer.env `
|
|
203
|
+
intlayer/cms-all:latest
|
|
107
204
|
```
|
|
108
205
|
|
|
109
|
-
|
|
206
|
+
</Tab>
|
|
207
|
+
<Tab label="Intlayer CLI" value="cli">
|
|
110
208
|
|
|
111
|
-
|
|
209
|
+
The CLI runs the installer, which prints the `docker run …` command shown in the other tabs. Copy it into your terminal once the mailer is configured.
|
|
210
|
+
|
|
211
|
+
</Tab>
|
|
212
|
+
</Tabs>
|
|
213
|
+
|
|
214
|
+
Open **http://localhost:3000** (or your dashboard URL) and follow [First-run setup](#first-run-setup). The first boot initialises the replica set and the bucket, so give it a minute.
|
|
215
|
+
|
|
216
|
+
### Backup and upgrade
|
|
217
|
+
|
|
218
|
+
All state lives in the `intlayer-data` volume (`/data/mongo`, `/data/redis`, `/data/minio`).
|
|
219
|
+
|
|
220
|
+
```sh
|
|
221
|
+
# Backup (stop the container first so MongoDB's files are consistent)
|
|
222
|
+
docker stop intlayer
|
|
223
|
+
docker run --rm -v intlayer-data:/data -v "$(pwd)":/backup busybox tar czf /backup/intlayer-data.tar.gz /data
|
|
224
|
+
docker start intlayer
|
|
225
|
+
|
|
226
|
+
# Restore
|
|
227
|
+
docker run --rm -v intlayer-data:/data -v "$(pwd)":/backup busybox tar xzf /backup/intlayer-data.tar.gz -C /
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
To upgrade, re-run the installer (it pulls the latest image and keeps `intlayer.env`), then `docker rm -f intlayer` and run the start command again. To use a managed MongoDB instead of the bundled one, set `MONGODB_URI` in `intlayer.env`.
|
|
231
|
+
|
|
232
|
+
</Tab>
|
|
233
|
+
<Tab label="Docker Compose" value="compose">
|
|
234
|
+
|
|
235
|
+
One container per service on a private Compose network. The dashboard and the API use the published `intlayer/cms-frontend` and `intlayer/cms-backend` images; the datastores use the official `mongo`, `redis` and `minio` images.
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
┌───────────────────┐
|
|
239
|
+
browser ──────▶ │ app :3000 │ ── SSR ──▶ http://backend:3100
|
|
240
|
+
(localhost) └───────────────────┘
|
|
241
|
+
┌───────────────────┐
|
|
242
|
+
browser ──────▶ │ backend :3100 │
|
|
243
|
+
(localhost) └─────────┬─────────┘
|
|
244
|
+
┌───────────────┼───────────────┐
|
|
245
|
+
▼ ▼ ▼
|
|
246
|
+
mongo:27017 redis:6379 minio:9000 ◀── browser (assets)
|
|
247
|
+
(1-node RS) minio:9001
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
| Service | Image | Role |
|
|
251
|
+
| ------------ | ----------------------- | ------------------------------------------------------------------------- |
|
|
252
|
+
| `app` | `intlayer/cms-frontend` | Dashboard on `:3000`; waits for the backend to be healthy |
|
|
253
|
+
| `backend` | `intlayer/cms-backend` | API on `:3100` with Chromium; waits for Mongo, Redis and the MinIO bucket |
|
|
254
|
+
| `mongo` | `mongo:8` | Single-node replica set `rs0`, initiated by its own healthcheck |
|
|
255
|
+
| `redis` | `redis:8-alpine` | Queues and caching, append-only persistence |
|
|
256
|
+
| `minio` | `quay.io/minio/minio` | S3 storage on `:9000`, console on `:9001` |
|
|
257
|
+
| `minio-init` | `quay.io/minio/mc` | One-shot: creates the bucket and its anonymous-download policy |
|
|
258
|
+
|
|
259
|
+
Data is kept in the `intlayer_mongo-data`, `intlayer_redis-data` and `intlayer_minio-data` volumes. The service wiring (`MONGODB_URI`, `REDIS_URL`, `S3_ENDPOINT`, the internal backend URL used by server-side rendering) is fixed in the compose file and takes precedence over `.env`, which only carries secrets and optional integrations.
|
|
260
|
+
|
|
261
|
+
### Prerequisites
|
|
262
|
+
|
|
263
|
+
- **Docker** ≥ 24 with the Compose plugin: the installer offers to install it on Linux and macOS. On Windows, install [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/) (WSL 2 backend) first.
|
|
264
|
+
- Ports `3000`, `3100`, `9000` and `9001` free on the host.
|
|
265
|
+
- A mailer: a [Resend](https://resend.com) API key or an SMTP relay.
|
|
266
|
+
|
|
267
|
+
### 1. Install
|
|
268
|
+
|
|
269
|
+
Writes `docker-compose.yml` and a `.env` with the secrets generated into `./intlayer/`, asks the same setup questions as the all-in-one mode (domain, mailer, OpenAI key), and pulls the images.
|
|
270
|
+
|
|
271
|
+
<Tabs group="os">
|
|
272
|
+
<Tab label="macOS / Linux" value="unix">
|
|
273
|
+
|
|
274
|
+
```sh
|
|
275
|
+
curl -fsSL https://intlayer.org/install.sh | sh -s -- --mode compose
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Or by hand:
|
|
279
|
+
|
|
280
|
+
```sh
|
|
281
|
+
mkdir intlayer && cd intlayer
|
|
282
|
+
curl -fsSLO https://raw.githubusercontent.com/aymericzip/intlayer/main/docker/selfhost/docker-compose.yml
|
|
283
|
+
curl -fsSL https://raw.githubusercontent.com/aymericzip/intlayer/main/docker/selfhost/.env.template -o .env
|
|
284
|
+
# fill in BETTER_AUTH_SECRET and S3_SECRET_ACCESS_KEY (openssl rand -hex 32)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
</Tab>
|
|
288
|
+
<Tab label="Windows" value="windows">
|
|
289
|
+
|
|
290
|
+
In PowerShell:
|
|
291
|
+
|
|
292
|
+
```powershell
|
|
293
|
+
$env:INTLAYER_MODE = "compose"; irm https://intlayer.org/install.ps1 | iex
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Or by hand:
|
|
297
|
+
|
|
298
|
+
```powershell
|
|
299
|
+
mkdir intlayer; cd intlayer
|
|
300
|
+
irm https://raw.githubusercontent.com/aymericzip/intlayer/main/docker/selfhost/docker-compose.yml -OutFile docker-compose.yml
|
|
301
|
+
irm https://raw.githubusercontent.com/aymericzip/intlayer/main/docker/selfhost/.env.template -OutFile .env
|
|
302
|
+
# fill in BETTER_AUTH_SECRET and S3_SECRET_ACCESS_KEY
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
</Tab>
|
|
306
|
+
<Tab label="Intlayer CLI" value="cli">
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
npx intlayer init infra --mode compose
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
</Tab>
|
|
313
|
+
</Tabs>
|
|
314
|
+
|
|
315
|
+
### 2. Configure a mailer
|
|
316
|
+
|
|
317
|
+
If you skipped the mailer question, fill in Resend **or** SMTP in `intlayer/.env`, exactly as for the all-in-one container (see [Global mailer](#global-mailer)).
|
|
318
|
+
|
|
319
|
+
### 3. Start
|
|
320
|
+
|
|
321
|
+
```sh
|
|
322
|
+
cd intlayer && docker compose up -d
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
With a custom domain, the installer also downloads `docker-compose.build.yml` and the start command becomes `docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build` (see [Custom domain](#custom-domain)).
|
|
326
|
+
|
|
327
|
+
Open **http://localhost:3000** (or your dashboard URL) and follow [First-run setup](#first-run-setup).
|
|
328
|
+
|
|
329
|
+
### Managed datastores
|
|
330
|
+
|
|
331
|
+
Delete the service you are replacing from the compose file (and its `depends_on` entry on `backend`), then override the matching variable:
|
|
332
|
+
|
|
333
|
+
```yaml fileName="docker-compose.yml"
|
|
334
|
+
services:
|
|
335
|
+
backend:
|
|
336
|
+
environment:
|
|
337
|
+
MONGODB_URI: mongodb+srv://user:password@cluster0.xxxxx.mongodb.net/intlayer
|
|
338
|
+
REDIS_URL: rediss://default:password@redis.example.com:6380
|
|
339
|
+
S3_ENDPOINT: https://s3.eu-west-1.amazonaws.com
|
|
340
|
+
S3_PUBLIC_URL: https://intlayer-assets.s3.eu-west-1.amazonaws.com
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
`S3_ACCESS_KEY_ID` / `S3_SECRET_ACCESS_KEY` / `S3_BUCKET_NAME` keep their meaning against any S3-compatible provider.
|
|
344
|
+
|
|
345
|
+
### Scaling
|
|
346
|
+
|
|
347
|
+
`app` and `backend` are stateless. Behind a load balancer, `docker compose up -d --scale backend=3` works once the fixed host port mappings are removed and the proxy addresses the services by name. Background jobs are coordinated through Redis (BullMQ), so several backend replicas share the queue safely.
|
|
348
|
+
|
|
349
|
+
### Building from source
|
|
350
|
+
|
|
351
|
+
An override switches the two Intlayer services from `image:` to `build:`. From a checkout of the repository:
|
|
352
|
+
|
|
353
|
+
```sh
|
|
354
|
+
cd docker/selfhost
|
|
355
|
+
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Without a checkout, point the build context at the repository itself by setting `INTLAYER_BUILD_CONTEXT=https://github.com/aymericzip/intlayer.git#main` in `.env`. The dashboard's `VITE_*` build args follow `DOMAIN`, `APP_URL` and `BACKEND_URL` from the same file, which is how a [custom domain](#custom-domain) is applied.
|
|
359
|
+
|
|
360
|
+
### Backup and upgrade
|
|
361
|
+
|
|
362
|
+
```sh
|
|
363
|
+
# Backup one volume (repeat for intlayer_redis-data and intlayer_minio-data)
|
|
364
|
+
docker compose stop
|
|
365
|
+
docker run --rm -v intlayer_mongo-data:/data -v "$(pwd)":/backup busybox tar czf /backup/mongo-data.tar.gz /data
|
|
366
|
+
docker compose start
|
|
367
|
+
|
|
368
|
+
# Upgrade, volumes are kept
|
|
369
|
+
docker compose pull && docker compose up -d
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
</Tab>
|
|
373
|
+
</Tabs>
|
|
112
374
|
|
|
113
375
|
### Installer settings
|
|
114
376
|
|
|
115
|
-
|
|
377
|
+
Without `--mode` (or `INTLAYER_MODE`), the installer shows a menu: `desktop`, `docker` (all-in-one) or `compose`. It also reads a few environment variables. Because it is piped into the shell, pass them to the shell rather than to `curl`:
|
|
116
378
|
|
|
117
379
|
```sh
|
|
118
|
-
curl -fsSL https://intlayer.org/install.sh |
|
|
380
|
+
curl -fsSL https://intlayer.org/install.sh | INTLAYER_COMPOSE_DIR=./cms sh -s -- --mode compose
|
|
119
381
|
```
|
|
120
382
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
| `INTLAYER_ENV_FILE` | `./intlayer.env` | Where to write the env file |
|
|
125
|
-
| `INTLAYER_CONTAINER_NAME` | `intlayer` | Container name |
|
|
126
|
-
| `INTLAYER_DATA_VOLUME` | `intlayer-data` | Named volume mounted at `/data` |
|
|
127
|
-
| `INTLAYER_APP_PORT` | `3000` | Host port for the dashboard |
|
|
128
|
-
| `INTLAYER_API_PORT` | `3100` | Host port for the API |
|
|
129
|
-
| `INTLAYER_S3_PORT` | `9000` | Host port for the MinIO S3 API |
|
|
130
|
-
| `INTLAYER_CONSOLE_PORT` | `9001` | Host port for the MinIO console |
|
|
383
|
+
```powershell
|
|
384
|
+
$env:INTLAYER_MODE = "compose"; $env:INTLAYER_COMPOSE_DIR = ".\cms"; irm https://intlayer.org/install.ps1 | iex
|
|
385
|
+
```
|
|
131
386
|
|
|
132
|
-
|
|
387
|
+
| Variable | Default | Applies to | Description |
|
|
388
|
+
| ------------------------- | ------------------------- | ---------- | ---------------------------------------------------------- |
|
|
389
|
+
| `INTLAYER_MODE` | _(asked)_ | all | `desktop`, `docker` or `compose`, same as `--mode` |
|
|
390
|
+
| `INTLAYER_DOWNLOAD_DIR` | `~/Downloads` | desktop | Where the app installer is saved |
|
|
391
|
+
| `INTLAYER_IMAGE` | `intlayer/cms-all:latest` | docker | All-in-one image to pull |
|
|
392
|
+
| `INTLAYER_ENV_FILE` | `./intlayer.env` | docker | Where to write the environment file |
|
|
393
|
+
| `INTLAYER_CONTAINER_NAME` | `intlayer` | docker | Container name |
|
|
394
|
+
| `INTLAYER_DATA_VOLUME` | `intlayer-data` | docker | Named volume mounted at `/data` |
|
|
395
|
+
| `INTLAYER_APP_PORT` | `3000` | docker | Host port for the dashboard |
|
|
396
|
+
| `INTLAYER_API_PORT` | `3100` | docker | Host port for the API |
|
|
397
|
+
| `INTLAYER_S3_PORT` | `9000` | docker | Host port for the MinIO S3 API |
|
|
398
|
+
| `INTLAYER_CONSOLE_PORT` | `9001` | docker | Host port for the MinIO console |
|
|
399
|
+
| `INTLAYER_COMPOSE_DIR` | `./intlayer` | compose | Where `docker-compose.yml` and `.env` are written |
|
|
400
|
+
| `INTLAYER_SELFHOST_REF` | `main` | both | Git ref the compose file and env template are fetched from |
|
|
401
|
+
| `INTLAYER_BUILD_CONTEXT` | `…/intlayer.git#main` | both | Build context used when a custom domain requires a rebuild |
|
|
402
|
+
| `INTLAYER_CUSTOM_IMAGE` | `intlayer/cms-all:custom` | docker | Tag of the all-in-one image built for a custom domain |
|
|
403
|
+
|
|
404
|
+
> The port variables only change the **host** side of the mapping. The published images have `http://localhost:3000`, `http://localhost:3100` and `http://localhost:9000` compiled into the dashboard bundle, so remapping them leaves the browser pointing at the old ports. Keep the defaults unless you build your own images, see [Limitations](#limitations).
|
|
133
405
|
|
|
134
406
|
## First-run setup
|
|
135
407
|
|
|
136
408
|
On a fresh instance (empty database), opening the dashboard redirects you to the **`/init`** page:
|
|
137
409
|
|
|
138
410
|
1. Create the first account. Because the users collection is empty, this account is automatically promoted to **super admin**.
|
|
139
|
-
2. A verification email is sent
|
|
411
|
+
2. A verification email is sent through Resend or your SMTP relay. Email verification is **mandatory**, this is why a mailer must be configured before you start.
|
|
140
412
|
3. Click the link in the email, then sign in.
|
|
141
413
|
|
|
142
414
|
Once an admin exists, `/init` redirects to the standard sign-in page.
|
|
143
415
|
|
|
144
|
-
##
|
|
416
|
+
## Environment variables
|
|
145
417
|
|
|
146
|
-
|
|
147
|
-
| ----------- | ------------------ | ----------------------------- | ------------------------------------------------------------- |
|
|
148
|
-
| **app** | bundled | `3000` | TanStack Start dashboard (CMS UI) |
|
|
149
|
-
| **backend** | bundled | `3100` | Fastify REST API (`/health` endpoint) |
|
|
150
|
-
| **redis** | bundled | internal | Job queues (BullMQ) and caching (ioredis) |
|
|
151
|
-
| **minio** | bundled | `9000` (S3), `9001` (console) | S3-compatible object storage for avatars and screenshots |
|
|
152
|
-
| **mongo** | **external** (you) | — | MongoDB Atlas, provided via `DB_ID` / `DB_MDP` / `DB_CLUSTER` |
|
|
418
|
+
Both Docker modes read the same file (`intlayer.env` for the container, `.env` for Compose), generated from [`docker/selfhost/.env.template`](https://github.com/aymericzip/intlayer/blob/main/docker/selfhost/.env.template).
|
|
153
419
|
|
|
154
|
-
|
|
420
|
+
### Required
|
|
155
421
|
|
|
156
|
-
|
|
422
|
+
| Variable | Example | Description |
|
|
423
|
+
| ---------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
424
|
+
| `BETTER_AUTH_SECRET` | _(generated)_ | 32-byte secret for session signing |
|
|
425
|
+
| `S3_SECRET_ACCESS_KEY` | _(generated)_ | Secret for the bundled MinIO |
|
|
426
|
+
| `RESEND_API_KEY` | _(your key)_ | Transactional email via Resend. Required for first-run setup unless an SMTP relay is configured instead (see [Global mailer](#global-mailer)) |
|
|
157
427
|
|
|
158
|
-
###
|
|
428
|
+
### Fixed by the deployment
|
|
429
|
+
|
|
430
|
+
These are set by the image (all-in-one) or by the compose file, and only need overriding for a non-standard topology. `DOMAIN`, `APP_URL`, `BACKEND_URL` and `S3_PUBLIC_URL` are the exception: set in the env file, they take precedence in both modes (see [Custom domain](#custom-domain)).
|
|
431
|
+
|
|
432
|
+
| Variable | All-in-one | Docker Compose | Description |
|
|
433
|
+
| ------------------ | --------------------------------------------------- | -------------------------------- | ----------------------------------------------------------------------------- |
|
|
434
|
+
| `PORT` | `3100` | `3100` | Backend listening port |
|
|
435
|
+
| `APP_URL` | `http://localhost:3000` | `http://localhost:3000` | Public URL of the dashboard |
|
|
436
|
+
| `BACKEND_URL` | `http://localhost:3100` | `http://localhost:3100` | Public URL of the backend API |
|
|
437
|
+
| `DOMAIN` | `localhost` | `localhost` | Cookie domain |
|
|
438
|
+
| `SELF_HOSTED` | `true` | `true` | Disables the cloud-only API endpoints (billing, subscriptions, marketplace) |
|
|
439
|
+
| `MONGODB_URI` | `mongodb://127.0.0.1:27017/intlayer?replicaSet=rs0` | `mongodb://mongo:27017/…` | MongoDB connection string, any `mongodb://` or `mongodb+srv://` cluster works |
|
|
440
|
+
| `REDIS_URL` | `redis://127.0.0.1:6379` | `redis://redis:6379` | Redis |
|
|
441
|
+
| `S3_ENDPOINT` | `http://127.0.0.1:9000` | `http://minio:9000` | MinIO (server-to-server) |
|
|
442
|
+
| `S3_PUBLIC_URL` | `http://localhost:9000/intlayer` | `http://localhost:9000/intlayer` | Public URL for browser asset loading |
|
|
443
|
+
| `S3_BUCKET_NAME` | `intlayer` | `intlayer` | Bucket name |
|
|
444
|
+
| `S3_ACCESS_KEY_ID` | `intlayer` | `intlayer` | MinIO access key |
|
|
445
|
+
|
|
446
|
+
The Compose `app` service additionally receives `INTLAYER_BACKEND_INTERNAL_URL=http://backend:3100`: the browser reaches the API on `localhost:3100`, but server-side rendering runs inside the Compose network and must use the service name.
|
|
447
|
+
|
|
448
|
+
### Custom domain
|
|
449
|
+
|
|
450
|
+
The backend reads its public URLs at runtime, but the dashboard has them **compiled in**: the published `intlayer/cms-frontend` and `intlayer/cms-all` images only work on `http://localhost:3000`. Serving Intlayer on your own domain therefore takes two things, both prepared by the installer when you answer the domain question:
|
|
159
451
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
452
|
+
1. **Four variables in the env file**, read by the backend (cookies, email links, OAuth callbacks, asset URLs) and used as build args by `docker-compose.build.yml`:
|
|
453
|
+
|
|
454
|
+
```sh fileName="intlayer.env"
|
|
455
|
+
DOMAIN=example.org # cookie domain, parent of the hosts below
|
|
456
|
+
APP_URL=https://cms.example.org
|
|
457
|
+
BACKEND_URL=https://back.example.org
|
|
458
|
+
S3_PUBLIC_URL=https://s3.example.org/intlayer
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
2. **A dashboard image built with those URLs.** Docker builds it straight from the repository, no checkout needed:
|
|
462
|
+
|
|
463
|
+
```sh
|
|
464
|
+
# Docker Compose: the override reads the build args from .env
|
|
465
|
+
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build
|
|
466
|
+
|
|
467
|
+
# All-in-one
|
|
468
|
+
docker build -f docker/selfhost/Dockerfile \
|
|
469
|
+
--build-arg VITE_DOMAIN=example.org \
|
|
470
|
+
--build-arg VITE_SITE_URL=https://cms.example.org \
|
|
471
|
+
--build-arg VITE_IDE_URL=https://cms.example.org \
|
|
472
|
+
--build-arg VITE_BACKEND_URL=https://back.example.org \
|
|
473
|
+
-t intlayer/cms-all:custom \
|
|
474
|
+
https://github.com/aymericzip/intlayer.git#main
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
Then put a reverse proxy with TLS in front of the container: `cms.example.org` → port `3000`, `back.example.org` → `3100`, `s3.example.org` → `9000`. The three hosts must share the `DOMAIN` suffix, since the session cookie is scoped to it.
|
|
183
478
|
|
|
184
479
|
### Optional (features degrade gracefully when absent)
|
|
185
480
|
|
|
186
|
-
| Variable
|
|
187
|
-
|
|
|
188
|
-
| `OPENAI_API_KEY`
|
|
189
|
-
| `
|
|
190
|
-
| `
|
|
191
|
-
| `
|
|
192
|
-
| `
|
|
193
|
-
| `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` | Microsoft OAuth login |
|
|
481
|
+
| Variable | Feature |
|
|
482
|
+
| ------------------------------------------------ | ----------------------------------------- |
|
|
483
|
+
| `OPENAI_API_KEY` | AI-assisted translation and content audit |
|
|
484
|
+
| `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | GitHub OAuth login |
|
|
485
|
+
| `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Google OAuth login |
|
|
486
|
+
| `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` | GitLab OAuth login |
|
|
487
|
+
| `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` | Microsoft OAuth login |
|
|
194
488
|
|
|
195
489
|
### Global mailer
|
|
196
490
|
|
|
197
|
-
|
|
491
|
+
Every transactional email, including non-organization emails such as password resets and magic links, goes through one of two global transports:
|
|
198
492
|
|
|
199
|
-
|
|
493
|
+
- **Resend**, using `RESEND_API_KEY`.
|
|
494
|
+
- **SMTP**, using the `MAIL_SMTP_*` variables. As soon as `MAIL_SMTP_HOST` is set, SMTP is used and `RESEND_API_KEY` is ignored.
|
|
200
495
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
|
204
|
-
|
|
|
205
|
-
| `
|
|
206
|
-
| `
|
|
207
|
-
| `
|
|
208
|
-
| `
|
|
209
|
-
| `
|
|
496
|
+
`MAIL_PROVIDER` is only needed to force one transport when both are configured (for instance `MAIL_PROVIDER=resend` to keep Resend while an SMTP host is present).
|
|
497
|
+
|
|
498
|
+
| Variable | Example | Description |
|
|
499
|
+
| -------------------- | ------------------------------ | ---------------------------------------------------------------------------- |
|
|
500
|
+
| `MAIL_FROM` | `Intlayer <no-reply@acme.com>` | Sender header for either transport. Accepts a bare address or `Name <email>` |
|
|
501
|
+
| `MAIL_SMTP_HOST` | `smtp.acme.com` | SMTP host. Setting it selects the SMTP transport |
|
|
502
|
+
| `MAIL_SMTP_PORT` | `587` | SMTP port (defaults to `587`) |
|
|
503
|
+
| `MAIL_SMTP_SECURE` | `false` | Implicit TLS. Set `true` for port `465` |
|
|
504
|
+
| `MAIL_SMTP_USER` | _(your user)_ | SMTP username (optional; omit for unauthenticated relays) |
|
|
505
|
+
| `MAIL_SMTP_PASSWORD` | _(your password)_ | SMTP password |
|
|
506
|
+
| `MAIL_PROVIDER` | `resend` | Optional override: `smtp` or `resend`. Leave unset to auto-select |
|
|
210
507
|
|
|
211
508
|
> Precedence: an organization's own mailer (configured from the **Organization** dashboard) takes priority over the global mailer, which in turn takes priority over the default Resend key.
|
|
212
509
|
|
|
@@ -271,73 +568,18 @@ const cms = createIntlayerCMS({
|
|
|
271
568
|
const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();
|
|
272
569
|
```
|
|
273
570
|
|
|
274
|
-
## Upgrading
|
|
275
|
-
|
|
276
|
-
Re-run the installer to pull the latest image, then recreate the container. Your `intlayer.env` is left untouched, and your data is preserved in the named volume (MinIO/Redis) and in your Atlas cluster (MongoDB):
|
|
277
|
-
|
|
278
|
-
```sh
|
|
279
|
-
curl -fsSL https://intlayer.org/install.sh | sh
|
|
280
|
-
docker rm -f intlayer
|
|
281
|
-
# re-run the `docker run …` command from step 3 of Quick start
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
## Backup and restore
|
|
285
|
-
|
|
286
|
-
MongoDB data lives in your Atlas cluster — back it up with Atlas' own tools. The bundled local datastores live under the `intlayer-data` volume.
|
|
287
|
-
|
|
288
|
-
### Backup
|
|
289
|
-
|
|
290
|
-
```sh
|
|
291
|
-
docker run --rm \
|
|
292
|
-
-v intlayer-data:/data \
|
|
293
|
-
-v "$(pwd)":/backup \
|
|
294
|
-
busybox tar czf /backup/intlayer-data.tar.gz /data
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
### Restore
|
|
298
|
-
|
|
299
|
-
```sh
|
|
300
|
-
docker run --rm \
|
|
301
|
-
-v intlayer-data:/data \
|
|
302
|
-
-v "$(pwd)":/backup \
|
|
303
|
-
busybox tar xzf /backup/intlayer-data.tar.gz -C /
|
|
304
|
-
```
|
|
305
|
-
|
|
306
571
|
## Limitations
|
|
307
572
|
|
|
308
|
-
- **
|
|
309
|
-
- **
|
|
310
|
-
- **
|
|
311
|
-
|
|
312
|
-
## Troubleshooting
|
|
313
|
-
|
|
314
|
-
### Dashboard loads but the API resets the connection (`ERR_CONNECTION_RESET` on `:3100`)
|
|
315
|
-
|
|
316
|
-
The backend crashed on startup and is not listening. The most common cause is a missing or invalid MongoDB connection — usually the `TODO` values in `intlayer.env` were never filled in:
|
|
317
|
-
|
|
318
|
-
```sh
|
|
319
|
-
grep -E '^DB_(ID|MDP|CLUSTER)=' intlayer.env
|
|
320
|
-
docker logs intlayer
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
Look for `MongoDB connection error` near the top of the log. After correcting `intlayer.env`, recreate the container (`docker rm -f intlayer`, then the `docker run …` command again) — `--env-file` is read at creation time, so editing the file does not affect a running container.
|
|
324
|
-
|
|
325
|
-
### First account can't be verified
|
|
326
|
-
|
|
327
|
-
Email verification is mandatory. Make sure a mailer is configured — either `RESEND_API_KEY`, or a [global SMTP mailer](#global-mailer) (`MAIL_PROVIDER=smtp` + `MAIL_SMTP_*`) — then re-check your inbox (and spam). Without a working mailer, the verification link is never delivered. Delivery failures are logged by the backend (`docker logs intlayer`) with the underlying error message.
|
|
328
|
-
|
|
329
|
-
### MinIO bucket missing
|
|
330
|
-
|
|
331
|
-
The `init-minio` one-shot creates the bucket on first boot. If assets fail to load, restart the container so it runs again:
|
|
332
|
-
|
|
333
|
-
```sh
|
|
334
|
-
docker restart intlayer
|
|
335
|
-
```
|
|
573
|
+
- **A custom domain means a rebuild.** All browser-facing `VITE_*` URLs are inlined into the dashboard at build time, and the published images (and the desktop app) ship with `localhost` / Intlayer Cloud values. Out of the box the dashboard must be accessed at `http://localhost:3000`, the API at `:3100` and MinIO at `:9000`; remapping the host ports has the same effect. The installer wires everything for a rebuild from the repository when you give it a domain (see [Custom domain](#custom-domain)), but the build itself takes several minutes. Pointing the desktop app at a self-hosted backend is not supported.
|
|
574
|
+
- **Email requires a working mailer.** First-run setup enforces email verification, so either `RESEND_API_KEY` or an [SMTP relay](#global-mailer) (`MAIL_SMTP_*`) must be configured. After the first admin signs in, each organization can also configure its own SMTP or Resend mailer from the dashboard.
|
|
575
|
+
- **The desktop app needs Node.js** on the machine to start its embedded server.
|
|
576
|
+
- **No documentation assistant.** The AI doc assistant of intlayer.org (`/api/ai/ask`, `/api/search/doc`) relies on ~130 MB of pre-computed documentation embeddings that the self-host images do not ship; those two routes are not registered in self-hosted mode. The dashboard's own AI features (translation, audit, autocomplete, chat) are unaffected and only need `OPENAI_API_KEY`.
|
|
336
577
|
|
|
337
578
|
## Useful links
|
|
338
579
|
|
|
339
580
|
- [Intlayer CMS documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_CMS.md)
|
|
340
581
|
- [Configuration reference](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/configuration.md)
|
|
341
|
-
- [CMS SDK
|
|
342
|
-
- [
|
|
343
|
-
-
|
|
582
|
+
- [CMS SDK: `@intlayer/api`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_CMS.md#programmatic-access-with-the-intlayerapi-sdk)
|
|
583
|
+
- [Desktop app releases](https://github.com/aymericzip/intlayer/releases/latest)
|
|
584
|
+
- Docker Hub: [`intlayer/cms-all`](https://hub.docker.com/r/intlayer/cms-all), [`intlayer/cms-frontend`](https://hub.docker.com/r/intlayer/cms-frontend), [`intlayer/cms-backend`](https://hub.docker.com/r/intlayer/cms-backend), mirrored on GHCR under `ghcr.io/aymericzip/intlayer/`
|
|
585
|
+
- [`docker/selfhost/`](https://github.com/aymericzip/intlayer/tree/main/docker/selfhost): Dockerfile, `docker-compose.yml` and `.env.template`
|