@intlayer/docs 9.5.6 → 9.5.8

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.
Files changed (643) hide show
  1. package/blog/ar/i18next_vs_intlayer-i18next.md +122 -15
  2. package/blog/ar/i18next_vs_intlayer.md +130 -16
  3. package/blog/ar/is_intlayer_lighter_than_paraglide.md +284 -0
  4. package/blog/ar/lingui_vs_intlayer.md +122 -15
  5. package/blog/ar/next-intl_vs_intlayer-next-intl.md +124 -15
  6. package/blog/ar/next-intl_vs_intlayer.md +136 -20
  7. package/blog/ar/vue-i18n_vs_intlayer-vue-i18n.md +119 -17
  8. package/blog/ar/vue-i18n_vs_intlayer.md +193 -31
  9. package/blog/ar/vue-i18n_vs_intlayer_benchmark.md +361 -0
  10. package/blog/de/i18next_vs_intlayer-i18next.md +122 -15
  11. package/blog/de/i18next_vs_intlayer.md +128 -14
  12. package/blog/de/is_intlayer_lighter_than_paraglide.md +284 -0
  13. package/blog/de/lingui_vs_intlayer.md +122 -15
  14. package/blog/de/next-intl_vs_intlayer-next-intl.md +124 -15
  15. package/blog/de/next-intl_vs_intlayer.md +125 -15
  16. package/blog/de/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  17. package/blog/de/vue-i18n_vs_intlayer.md +193 -31
  18. package/blog/en/i18next_vs_intlayer-i18next.md +121 -14
  19. package/blog/en/i18next_vs_intlayer.md +128 -14
  20. package/blog/en/is_intlayer_lighter_than_paraglide.md +288 -0
  21. package/blog/en/lingui_vs_intlayer.md +124 -15
  22. package/blog/en/next-intl_vs_intlayer-next-intl.md +123 -14
  23. package/blog/en/next-intl_vs_intlayer.md +125 -13
  24. package/blog/en/vue-i18n_vs_intlayer-vue-i18n.md +115 -15
  25. package/blog/en/vue-i18n_vs_intlayer.md +188 -27
  26. package/blog/en-GB/i18next_vs_intlayer-i18next.md +121 -14
  27. package/blog/en-GB/i18next_vs_intlayer.md +128 -14
  28. package/blog/en-GB/is_intlayer_lighter_than_paraglide.md +285 -0
  29. package/blog/en-GB/lingui_vs_intlayer.md +122 -15
  30. package/blog/en-GB/next-intl_vs_intlayer-next-intl.md +124 -15
  31. package/blog/en-GB/next-intl_vs_intlayer.md +125 -15
  32. package/blog/en-GB/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  33. package/blog/en-GB/vue-i18n_vs_intlayer.md +187 -25
  34. package/blog/en-GB/vue-i18n_vs_intlayer_benchmark.md +116 -0
  35. package/blog/es/i18next_vs_intlayer-i18next.md +122 -15
  36. package/blog/es/i18next_vs_intlayer.md +128 -14
  37. package/blog/es/is_intlayer_lighter_than_paraglide.md +284 -0
  38. package/blog/es/lingui_vs_intlayer.md +122 -15
  39. package/blog/es/next-intl_vs_intlayer-next-intl.md +124 -15
  40. package/blog/es/next-intl_vs_intlayer.md +125 -15
  41. package/blog/es/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  42. package/blog/es/vue-i18n_vs_intlayer.md +193 -31
  43. package/blog/fr/i18next_vs_intlayer-i18next.md +122 -15
  44. package/blog/fr/i18next_vs_intlayer.md +128 -14
  45. package/blog/fr/is_intlayer_lighter_than_paraglide.md +284 -0
  46. package/blog/fr/lingui_vs_intlayer.md +122 -15
  47. package/blog/fr/next-intl_vs_intlayer-next-intl.md +124 -15
  48. package/blog/fr/next-intl_vs_intlayer.md +127 -15
  49. package/blog/fr/vue-i18n_vs_intlayer-vue-i18n.md +118 -17
  50. package/blog/fr/vue-i18n_vs_intlayer.md +192 -31
  51. package/blog/fr/vue-i18n_vs_intlayer_benchmark.md +329 -7
  52. package/blog/hi/i18next_vs_intlayer-i18next.md +122 -15
  53. package/blog/hi/i18next_vs_intlayer.md +130 -16
  54. package/blog/hi/is_intlayer_lighter_than_paraglide.md +284 -0
  55. package/blog/hi/lingui_vs_intlayer.md +122 -15
  56. package/blog/hi/next-intl_vs_intlayer-next-intl.md +124 -15
  57. package/blog/hi/next-intl_vs_intlayer.md +135 -19
  58. package/blog/hi/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  59. package/blog/hi/vue-i18n_vs_intlayer.md +193 -31
  60. package/blog/hi/vue-i18n_vs_intlayer_benchmark.md +361 -0
  61. package/blog/id/i18next_vs_intlayer-i18next.md +122 -15
  62. package/blog/id/i18next_vs_intlayer.md +128 -14
  63. package/blog/id/is_intlayer_lighter_than_paraglide.md +284 -0
  64. package/blog/id/lingui_vs_intlayer.md +122 -15
  65. package/blog/id/next-intl_vs_intlayer-next-intl.md +124 -15
  66. package/blog/id/next-intl_vs_intlayer.md +135 -19
  67. package/blog/id/vue-i18n_vs_intlayer-vue-i18n.md +354 -2
  68. package/blog/id/vue-i18n_vs_intlayer.md +188 -26
  69. package/blog/id/vue-i18n_vs_intlayer_benchmark.md +327 -7
  70. package/blog/it/i18next_vs_intlayer-i18next.md +122 -15
  71. package/blog/it/i18next_vs_intlayer.md +128 -14
  72. package/blog/it/is_intlayer_lighter_than_paraglide.md +284 -0
  73. package/blog/it/lingui_vs_intlayer.md +122 -15
  74. package/blog/it/next-intl_vs_intlayer-next-intl.md +124 -15
  75. package/blog/it/next-intl_vs_intlayer.md +125 -15
  76. package/blog/it/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  77. package/blog/it/vue-i18n_vs_intlayer.md +191 -31
  78. package/blog/it/vue-i18n_vs_intlayer_benchmark.md +332 -5
  79. package/blog/ja/i18next_vs_intlayer-i18next.md +122 -15
  80. package/blog/ja/i18next_vs_intlayer.md +129 -17
  81. package/blog/ja/is_intlayer_lighter_than_paraglide.md +284 -0
  82. package/blog/ja/lingui_vs_intlayer.md +122 -15
  83. package/blog/ja/next-intl_vs_intlayer-next-intl.md +124 -15
  84. package/blog/ja/next-intl_vs_intlayer.md +124 -14
  85. package/blog/ja/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  86. package/blog/ja/vue-i18n_vs_intlayer.md +193 -31
  87. package/blog/ja/vue-i18n_vs_intlayer_benchmark.md +361 -0
  88. package/blog/ko/i18next_vs_intlayer-i18next.md +122 -15
  89. package/blog/ko/i18next_vs_intlayer.md +129 -17
  90. package/blog/ko/is_intlayer_lighter_than_paraglide.md +284 -0
  91. package/blog/ko/lingui_vs_intlayer.md +122 -15
  92. package/blog/ko/next-intl_vs_intlayer-next-intl.md +124 -15
  93. package/blog/ko/next-intl_vs_intlayer.md +134 -18
  94. package/blog/ko/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  95. package/blog/ko/vue-i18n_vs_intlayer.md +193 -31
  96. package/blog/pl/i18next_vs_intlayer-i18next.md +122 -15
  97. package/blog/pl/i18next_vs_intlayer.md +128 -14
  98. package/blog/pl/is_intlayer_lighter_than_paraglide.md +284 -0
  99. package/blog/pl/lingui_vs_intlayer.md +122 -15
  100. package/blog/pl/next-intl_vs_intlayer-next-intl.md +124 -15
  101. package/blog/pl/next-intl_vs_intlayer.md +134 -18
  102. package/blog/pl/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  103. package/blog/pl/vue-i18n_vs_intlayer.md +188 -26
  104. package/blog/pl/vue-i18n_vs_intlayer_benchmark.md +361 -0
  105. package/blog/pt/i18next_vs_intlayer-i18next.md +122 -15
  106. package/blog/pt/i18next_vs_intlayer.md +128 -14
  107. package/blog/pt/is_intlayer_lighter_than_paraglide.md +284 -0
  108. package/blog/pt/lingui_vs_intlayer.md +122 -15
  109. package/blog/pt/next-intl_vs_intlayer-next-intl.md +124 -15
  110. package/blog/pt/next-intl_vs_intlayer.md +131 -15
  111. package/blog/pt/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  112. package/blog/pt/vue-i18n_vs_intlayer.md +193 -31
  113. package/blog/pt/vue-i18n_vs_intlayer_benchmark.md +361 -0
  114. package/blog/ru/i18next_vs_intlayer-i18next.md +122 -15
  115. package/blog/ru/i18next_vs_intlayer.md +130 -16
  116. package/blog/ru/is_intlayer_lighter_than_paraglide.md +284 -0
  117. package/blog/ru/lingui_vs_intlayer.md +122 -15
  118. package/blog/ru/next-intl_vs_intlayer-next-intl.md +125 -16
  119. package/blog/ru/next-intl_vs_intlayer.md +123 -13
  120. package/blog/ru/vue-i18n_vs_intlayer-vue-i18n.md +127 -27
  121. package/blog/ru/vue-i18n_vs_intlayer.md +193 -31
  122. package/blog/ru/vue-i18n_vs_intlayer_benchmark.md +326 -19
  123. package/blog/tr/i18next_vs_intlayer-i18next.md +122 -15
  124. package/blog/tr/i18next_vs_intlayer.md +128 -14
  125. package/blog/tr/is_intlayer_lighter_than_paraglide.md +284 -0
  126. package/blog/tr/lingui_vs_intlayer.md +122 -15
  127. package/blog/tr/next-intl_vs_intlayer-next-intl.md +124 -15
  128. package/blog/tr/next-intl_vs_intlayer.md +136 -20
  129. package/blog/tr/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  130. package/blog/tr/vue-i18n_vs_intlayer.md +188 -26
  131. package/blog/tr/vue-i18n_vs_intlayer_benchmark.md +361 -0
  132. package/blog/uk/i18next_vs_intlayer-i18next.md +122 -15
  133. package/blog/uk/i18next_vs_intlayer.md +130 -16
  134. package/blog/uk/is_intlayer_lighter_than_paraglide.md +284 -0
  135. package/blog/uk/lingui_vs_intlayer.md +122 -15
  136. package/blog/uk/next-intl_vs_intlayer-next-intl.md +124 -15
  137. package/blog/uk/next-intl_vs_intlayer.md +135 -19
  138. package/blog/uk/vue-i18n_vs_intlayer-vue-i18n.md +135 -17
  139. package/blog/uk/vue-i18n_vs_intlayer.md +188 -27
  140. package/blog/uk/vue-i18n_vs_intlayer_benchmark.md +361 -0
  141. package/blog/vi/i18next_vs_intlayer-i18next.md +122 -15
  142. package/blog/vi/i18next_vs_intlayer.md +128 -14
  143. package/blog/vi/is_intlayer_lighter_than_paraglide.md +284 -0
  144. package/blog/vi/lingui_vs_intlayer.md +122 -15
  145. package/blog/vi/next-intl_vs_intlayer-next-intl.md +124 -15
  146. package/blog/vi/next-intl_vs_intlayer.md +135 -19
  147. package/blog/vi/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  148. package/blog/vi/vue-i18n_vs_intlayer.md +188 -26
  149. package/blog/vi/vue-i18n_vs_intlayer_benchmark.md +361 -0
  150. package/blog/zh/i18next_vs_intlayer-i18next.md +122 -15
  151. package/blog/zh/i18next_vs_intlayer.md +128 -14
  152. package/blog/zh/is_intlayer_lighter_than_paraglide.md +284 -0
  153. package/blog/zh/lingui_vs_intlayer.md +122 -15
  154. package/blog/zh/next-intl_vs_intlayer-next-intl.md +124 -15
  155. package/blog/zh/next-intl_vs_intlayer.md +125 -15
  156. package/blog/zh/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
  157. package/blog/zh/vue-i18n_vs_intlayer.md +192 -31
  158. package/blog/zh/vue-i18n_vs_intlayer_benchmark.md +340 -9
  159. package/dist/cjs/generated/blog.entry.cjs +20 -0
  160. package/dist/cjs/generated/blog.entry.cjs.map +1 -1
  161. package/dist/cjs/generated/docs.entry.cjs +60 -40
  162. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  163. package/dist/esm/generated/blog.entry.mjs +20 -0
  164. package/dist/esm/generated/blog.entry.mjs.map +1 -1
  165. package/dist/esm/generated/docs.entry.mjs +60 -40
  166. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  167. package/dist/types/generated/blog.entry.d.ts +1 -0
  168. package/dist/types/generated/blog.entry.d.ts.map +1 -1
  169. package/dist/types/generated/docs.entry.d.ts +3 -2
  170. package/dist/types/generated/docs.entry.d.ts.map +1 -1
  171. package/docs/ar/benchmark/nextjs.md +19 -16
  172. package/docs/ar/benchmark/solid.md +26 -9
  173. package/docs/ar/benchmark/svelte.md +22 -7
  174. package/docs/ar/benchmark/tanstack.md +20 -16
  175. package/docs/ar/benchmark/vue.md +19 -10
  176. package/docs/ar/chrome_extension.md +130 -0
  177. package/docs/ar/cli/index.md +11 -1
  178. package/docs/ar/cli/infra.md +162 -0
  179. package/docs/ar/cli/init.md +24 -1
  180. package/docs/ar/cli/upgrade.md +125 -0
  181. package/docs/ar/dictionary/html.md +173 -5
  182. package/docs/ar/dictionary/markdown.md +263 -1
  183. package/docs/ar/intlayer_with_analog.md +23 -1
  184. package/docs/ar/intlayer_with_angular_19.md +24 -1
  185. package/docs/ar/intlayer_with_angular_21.md +24 -1
  186. package/docs/ar/intlayer_with_astro.md +24 -1
  187. package/docs/ar/intlayer_with_astro_lit.md +25 -1
  188. package/docs/ar/intlayer_with_astro_preact.md +26 -1
  189. package/docs/ar/intlayer_with_astro_react.md +26 -1
  190. package/docs/ar/intlayer_with_astro_solid.md +26 -1
  191. package/docs/ar/intlayer_with_astro_svelte.md +25 -1
  192. package/docs/ar/intlayer_with_astro_vue.md +25 -1
  193. package/docs/ar/intlayer_with_remix_3.md +22 -1
  194. package/docs/ar/self_hosting.md +406 -231
  195. package/docs/de/benchmark/nextjs.md +19 -16
  196. package/docs/de/benchmark/solid.md +26 -9
  197. package/docs/de/benchmark/svelte.md +22 -7
  198. package/docs/de/benchmark/tanstack.md +20 -16
  199. package/docs/de/benchmark/vue.md +19 -10
  200. package/docs/de/chrome_extension.md +130 -0
  201. package/docs/de/cli/index.md +11 -1
  202. package/docs/de/cli/infra.md +162 -0
  203. package/docs/de/cli/init.md +24 -1
  204. package/docs/de/cli/upgrade.md +125 -0
  205. package/docs/de/dictionary/html.md +173 -5
  206. package/docs/de/dictionary/markdown.md +263 -1
  207. package/docs/de/intlayer_with_analog.md +23 -1
  208. package/docs/de/intlayer_with_angular_19.md +24 -1
  209. package/docs/de/intlayer_with_angular_21.md +24 -1
  210. package/docs/de/intlayer_with_astro.md +24 -1
  211. package/docs/de/intlayer_with_astro_lit.md +25 -1
  212. package/docs/de/intlayer_with_astro_preact.md +26 -1
  213. package/docs/de/intlayer_with_astro_react.md +26 -1
  214. package/docs/de/intlayer_with_astro_solid.md +26 -1
  215. package/docs/de/intlayer_with_astro_svelte.md +25 -1
  216. package/docs/de/intlayer_with_astro_vue.md +25 -1
  217. package/docs/de/intlayer_with_remix_3.md +22 -1
  218. package/docs/de/self_hosting.md +404 -227
  219. package/docs/en/agent_skills.md +29 -1
  220. package/docs/en/benchmark/nextjs.md +19 -16
  221. package/docs/en/benchmark/solid.md +26 -9
  222. package/docs/en/benchmark/svelte.md +22 -7
  223. package/docs/en/benchmark/tanstack.md +21 -17
  224. package/docs/en/benchmark/vue.md +20 -11
  225. package/docs/en/chrome_extension.md +130 -0
  226. package/docs/en/cli/index.md +11 -1
  227. package/docs/en/cli/infra.md +175 -0
  228. package/docs/en/cli/init.md +25 -1
  229. package/docs/en/cli/upgrade.md +125 -0
  230. package/docs/en/dictionary/html.md +173 -5
  231. package/docs/en/dictionary/markdown.md +263 -1
  232. package/docs/en/intlayer_with_analog.md +23 -1
  233. package/docs/en/intlayer_with_angular_19.md +24 -1
  234. package/docs/en/intlayer_with_angular_21.md +24 -1
  235. package/docs/en/intlayer_with_astro.md +24 -1
  236. package/docs/en/intlayer_with_astro_lit.md +25 -1
  237. package/docs/en/intlayer_with_astro_preact.md +26 -1
  238. package/docs/en/intlayer_with_astro_react.md +26 -1
  239. package/docs/en/intlayer_with_astro_solid.md +26 -1
  240. package/docs/en/intlayer_with_astro_svelte.md +25 -1
  241. package/docs/en/intlayer_with_astro_vue.md +25 -1
  242. package/docs/en/intlayer_with_remix_3.md +22 -1
  243. package/docs/en/self_hosting.md +418 -176
  244. package/docs/en-GB/benchmark/nextjs.md +19 -16
  245. package/docs/en-GB/benchmark/solid.md +26 -9
  246. package/docs/en-GB/benchmark/svelte.md +22 -7
  247. package/docs/en-GB/benchmark/tanstack.md +20 -16
  248. package/docs/en-GB/benchmark/vue.md +20 -11
  249. package/docs/en-GB/chrome_extension.md +130 -0
  250. package/docs/en-GB/cli/index.md +11 -1
  251. package/docs/en-GB/cli/infra.md +162 -0
  252. package/docs/en-GB/cli/init.md +24 -1
  253. package/docs/en-GB/cli/upgrade.md +125 -0
  254. package/docs/en-GB/dictionary/html.md +173 -5
  255. package/docs/en-GB/dictionary/markdown.md +263 -1
  256. package/docs/en-GB/intlayer_with_analog.md +23 -1
  257. package/docs/en-GB/intlayer_with_angular_19.md +24 -1
  258. package/docs/en-GB/intlayer_with_angular_21.md +24 -1
  259. package/docs/en-GB/intlayer_with_astro.md +24 -1
  260. package/docs/en-GB/intlayer_with_astro_lit.md +25 -1
  261. package/docs/en-GB/intlayer_with_astro_preact.md +26 -1
  262. package/docs/en-GB/intlayer_with_astro_react.md +26 -1
  263. package/docs/en-GB/intlayer_with_astro_solid.md +26 -1
  264. package/docs/en-GB/intlayer_with_astro_svelte.md +25 -1
  265. package/docs/en-GB/intlayer_with_astro_vue.md +25 -1
  266. package/docs/en-GB/intlayer_with_remix_3.md +22 -1
  267. package/docs/en-GB/self_hosting.md +381 -206
  268. package/docs/es/benchmark/nextjs.md +19 -16
  269. package/docs/es/benchmark/solid.md +26 -9
  270. package/docs/es/benchmark/svelte.md +22 -7
  271. package/docs/es/benchmark/tanstack.md +20 -16
  272. package/docs/es/benchmark/vue.md +19 -10
  273. package/docs/es/chrome_extension.md +130 -0
  274. package/docs/es/cli/index.md +11 -1
  275. package/docs/es/cli/infra.md +162 -0
  276. package/docs/es/cli/init.md +24 -1
  277. package/docs/es/cli/upgrade.md +125 -0
  278. package/docs/es/dictionary/html.md +173 -5
  279. package/docs/es/dictionary/markdown.md +263 -1
  280. package/docs/es/intlayer_with_analog.md +23 -1
  281. package/docs/es/intlayer_with_angular_19.md +24 -1
  282. package/docs/es/intlayer_with_angular_21.md +24 -1
  283. package/docs/es/intlayer_with_astro.md +24 -1
  284. package/docs/es/intlayer_with_astro_lit.md +25 -1
  285. package/docs/es/intlayer_with_astro_preact.md +26 -1
  286. package/docs/es/intlayer_with_astro_react.md +26 -1
  287. package/docs/es/intlayer_with_astro_solid.md +26 -1
  288. package/docs/es/intlayer_with_astro_svelte.md +25 -1
  289. package/docs/es/intlayer_with_astro_vue.md +25 -1
  290. package/docs/es/intlayer_with_remix_3.md +22 -1
  291. package/docs/es/self_hosting.md +400 -223
  292. package/docs/fr/benchmark/nextjs.md +19 -16
  293. package/docs/fr/benchmark/solid.md +26 -9
  294. package/docs/fr/benchmark/svelte.md +22 -7
  295. package/docs/fr/benchmark/tanstack.md +20 -16
  296. package/docs/fr/benchmark/vue.md +20 -11
  297. package/docs/fr/chrome_extension.md +130 -0
  298. package/docs/fr/cli/index.md +11 -1
  299. package/docs/fr/cli/infra.md +162 -0
  300. package/docs/fr/cli/init.md +24 -1
  301. package/docs/fr/cli/upgrade.md +125 -0
  302. package/docs/fr/dictionary/html.md +173 -5
  303. package/docs/fr/dictionary/markdown.md +265 -4
  304. package/docs/fr/intlayer_with_analog.md +23 -1
  305. package/docs/fr/intlayer_with_angular_19.md +24 -1
  306. package/docs/fr/intlayer_with_angular_21.md +24 -1
  307. package/docs/fr/intlayer_with_astro.md +24 -1
  308. package/docs/fr/intlayer_with_astro_lit.md +25 -1
  309. package/docs/fr/intlayer_with_astro_preact.md +26 -1
  310. package/docs/fr/intlayer_with_astro_react.md +26 -1
  311. package/docs/fr/intlayer_with_astro_solid.md +26 -1
  312. package/docs/fr/intlayer_with_astro_svelte.md +25 -1
  313. package/docs/fr/intlayer_with_astro_vue.md +25 -1
  314. package/docs/fr/intlayer_with_remix_3.md +22 -1
  315. package/docs/fr/self_hosting.md +401 -224
  316. package/docs/hi/benchmark/nextjs.md +19 -16
  317. package/docs/hi/benchmark/solid.md +26 -9
  318. package/docs/hi/benchmark/svelte.md +22 -7
  319. package/docs/hi/benchmark/tanstack.md +20 -16
  320. package/docs/hi/benchmark/vue.md +20 -11
  321. package/docs/hi/chrome_extension.md +130 -0
  322. package/docs/hi/cli/index.md +11 -1
  323. package/docs/hi/cli/infra.md +162 -0
  324. package/docs/hi/cli/init.md +24 -1
  325. package/docs/hi/cli/upgrade.md +125 -0
  326. package/docs/hi/dictionary/html.md +173 -5
  327. package/docs/hi/dictionary/markdown.md +263 -1
  328. package/docs/hi/intlayer_with_analog.md +23 -1
  329. package/docs/hi/intlayer_with_angular_19.md +24 -1
  330. package/docs/hi/intlayer_with_angular_21.md +24 -1
  331. package/docs/hi/intlayer_with_astro.md +24 -1
  332. package/docs/hi/intlayer_with_astro_lit.md +25 -1
  333. package/docs/hi/intlayer_with_astro_preact.md +26 -1
  334. package/docs/hi/intlayer_with_astro_react.md +26 -1
  335. package/docs/hi/intlayer_with_astro_solid.md +26 -1
  336. package/docs/hi/intlayer_with_astro_svelte.md +25 -1
  337. package/docs/hi/intlayer_with_astro_vue.md +25 -1
  338. package/docs/hi/intlayer_with_remix_3.md +22 -1
  339. package/docs/hi/self_hosting.md +409 -235
  340. package/docs/id/benchmark/nextjs.md +19 -16
  341. package/docs/id/benchmark/solid.md +26 -9
  342. package/docs/id/benchmark/svelte.md +22 -7
  343. package/docs/id/benchmark/tanstack.md +20 -16
  344. package/docs/id/benchmark/vue.md +20 -11
  345. package/docs/id/chrome_extension.md +130 -0
  346. package/docs/id/cli/index.md +11 -1
  347. package/docs/id/cli/infra.md +162 -0
  348. package/docs/id/cli/init.md +24 -1
  349. package/docs/id/cli/upgrade.md +125 -0
  350. package/docs/id/dictionary/html.md +173 -5
  351. package/docs/id/dictionary/markdown.md +263 -1
  352. package/docs/id/intlayer_with_analog.md +23 -1
  353. package/docs/id/intlayer_with_angular_19.md +24 -1
  354. package/docs/id/intlayer_with_angular_21.md +24 -1
  355. package/docs/id/intlayer_with_astro.md +24 -1
  356. package/docs/id/intlayer_with_astro_lit.md +25 -1
  357. package/docs/id/intlayer_with_astro_preact.md +26 -1
  358. package/docs/id/intlayer_with_astro_react.md +26 -1
  359. package/docs/id/intlayer_with_astro_solid.md +26 -1
  360. package/docs/id/intlayer_with_astro_svelte.md +25 -1
  361. package/docs/id/intlayer_with_astro_vue.md +25 -1
  362. package/docs/id/intlayer_with_remix_3.md +22 -1
  363. package/docs/id/self_hosting.md +416 -243
  364. package/docs/it/benchmark/nextjs.md +19 -16
  365. package/docs/it/benchmark/solid.md +26 -9
  366. package/docs/it/benchmark/svelte.md +22 -7
  367. package/docs/it/benchmark/tanstack.md +20 -16
  368. package/docs/it/benchmark/vue.md +19 -10
  369. package/docs/it/chrome_extension.md +130 -0
  370. package/docs/it/cli/index.md +11 -1
  371. package/docs/it/cli/infra.md +162 -0
  372. package/docs/it/cli/init.md +24 -1
  373. package/docs/it/cli/upgrade.md +125 -0
  374. package/docs/it/dictionary/html.md +173 -5
  375. package/docs/it/dictionary/markdown.md +263 -1
  376. package/docs/it/intlayer_with_analog.md +23 -1
  377. package/docs/it/intlayer_with_angular_19.md +24 -1
  378. package/docs/it/intlayer_with_angular_21.md +24 -1
  379. package/docs/it/intlayer_with_astro.md +24 -1
  380. package/docs/it/intlayer_with_astro_lit.md +25 -1
  381. package/docs/it/intlayer_with_astro_preact.md +26 -1
  382. package/docs/it/intlayer_with_astro_react.md +26 -1
  383. package/docs/it/intlayer_with_astro_solid.md +26 -1
  384. package/docs/it/intlayer_with_astro_svelte.md +25 -1
  385. package/docs/it/intlayer_with_astro_vue.md +25 -1
  386. package/docs/it/intlayer_with_remix_3.md +22 -1
  387. package/docs/it/self_hosting.md +412 -237
  388. package/docs/ja/benchmark/nextjs.md +19 -16
  389. package/docs/ja/benchmark/solid.md +26 -9
  390. package/docs/ja/benchmark/svelte.md +22 -7
  391. package/docs/ja/benchmark/tanstack.md +18 -14
  392. package/docs/ja/benchmark/vue.md +19 -10
  393. package/docs/ja/chrome_extension.md +130 -0
  394. package/docs/ja/cli/index.md +11 -1
  395. package/docs/ja/cli/infra.md +162 -0
  396. package/docs/ja/cli/init.md +24 -1
  397. package/docs/ja/cli/upgrade.md +125 -0
  398. package/docs/ja/dictionary/html.md +173 -5
  399. package/docs/ja/dictionary/markdown.md +263 -1
  400. package/docs/ja/intlayer_with_analog.md +23 -1
  401. package/docs/ja/intlayer_with_angular_19.md +24 -1
  402. package/docs/ja/intlayer_with_angular_21.md +24 -1
  403. package/docs/ja/intlayer_with_astro.md +24 -1
  404. package/docs/ja/intlayer_with_astro_lit.md +25 -1
  405. package/docs/ja/intlayer_with_astro_preact.md +26 -1
  406. package/docs/ja/intlayer_with_astro_react.md +26 -1
  407. package/docs/ja/intlayer_with_astro_solid.md +26 -1
  408. package/docs/ja/intlayer_with_astro_svelte.md +25 -1
  409. package/docs/ja/intlayer_with_astro_vue.md +25 -1
  410. package/docs/ja/intlayer_with_remix_3.md +22 -1
  411. package/docs/ja/self_hosting.md +398 -223
  412. package/docs/ko/benchmark/nextjs.md +19 -16
  413. package/docs/ko/benchmark/solid.md +26 -9
  414. package/docs/ko/benchmark/svelte.md +22 -7
  415. package/docs/ko/benchmark/tanstack.md +20 -16
  416. package/docs/ko/benchmark/vue.md +20 -11
  417. package/docs/ko/chrome_extension.md +130 -0
  418. package/docs/ko/cli/index.md +11 -1
  419. package/docs/ko/cli/infra.md +162 -0
  420. package/docs/ko/cli/init.md +24 -1
  421. package/docs/ko/cli/upgrade.md +126 -0
  422. package/docs/ko/dictionary/html.md +173 -5
  423. package/docs/ko/dictionary/markdown.md +263 -1
  424. package/docs/ko/intlayer_with_analog.md +23 -1
  425. package/docs/ko/intlayer_with_angular_19.md +24 -1
  426. package/docs/ko/intlayer_with_angular_21.md +24 -1
  427. package/docs/ko/intlayer_with_astro.md +24 -1
  428. package/docs/ko/intlayer_with_astro_lit.md +25 -1
  429. package/docs/ko/intlayer_with_astro_preact.md +26 -1
  430. package/docs/ko/intlayer_with_astro_react.md +26 -1
  431. package/docs/ko/intlayer_with_astro_solid.md +26 -1
  432. package/docs/ko/intlayer_with_astro_svelte.md +25 -1
  433. package/docs/ko/intlayer_with_astro_vue.md +25 -1
  434. package/docs/ko/intlayer_with_remix_3.md +22 -1
  435. package/docs/ko/self_hosting.md +411 -238
  436. package/docs/pl/benchmark/nextjs.md +19 -16
  437. package/docs/pl/benchmark/solid.md +26 -9
  438. package/docs/pl/benchmark/svelte.md +22 -7
  439. package/docs/pl/benchmark/tanstack.md +20 -16
  440. package/docs/pl/benchmark/vue.md +20 -11
  441. package/docs/pl/chrome_extension.md +130 -0
  442. package/docs/pl/cli/index.md +11 -1
  443. package/docs/pl/cli/infra.md +162 -0
  444. package/docs/pl/cli/init.md +24 -1
  445. package/docs/pl/cli/upgrade.md +125 -0
  446. package/docs/pl/dictionary/html.md +173 -5
  447. package/docs/pl/dictionary/markdown.md +263 -1
  448. package/docs/pl/intlayer_with_analog.md +23 -1
  449. package/docs/pl/intlayer_with_angular_19.md +24 -1
  450. package/docs/pl/intlayer_with_angular_21.md +24 -1
  451. package/docs/pl/intlayer_with_astro.md +24 -1
  452. package/docs/pl/intlayer_with_astro_lit.md +25 -1
  453. package/docs/pl/intlayer_with_astro_preact.md +26 -1
  454. package/docs/pl/intlayer_with_astro_react.md +26 -1
  455. package/docs/pl/intlayer_with_astro_solid.md +26 -1
  456. package/docs/pl/intlayer_with_astro_svelte.md +25 -1
  457. package/docs/pl/intlayer_with_astro_vue.md +25 -1
  458. package/docs/pl/intlayer_with_remix_3.md +22 -1
  459. package/docs/pl/self_hosting.md +408 -233
  460. package/docs/pt/benchmark/nextjs.md +19 -16
  461. package/docs/pt/benchmark/solid.md +26 -9
  462. package/docs/pt/benchmark/svelte.md +22 -7
  463. package/docs/pt/benchmark/tanstack.md +20 -16
  464. package/docs/pt/benchmark/vue.md +19 -10
  465. package/docs/pt/chrome_extension.md +130 -0
  466. package/docs/pt/cli/index.md +11 -1
  467. package/docs/pt/cli/infra.md +162 -0
  468. package/docs/pt/cli/init.md +24 -1
  469. package/docs/pt/cli/upgrade.md +125 -0
  470. package/docs/pt/dictionary/html.md +173 -5
  471. package/docs/pt/dictionary/markdown.md +263 -1
  472. package/docs/pt/intlayer_with_analog.md +23 -1
  473. package/docs/pt/intlayer_with_angular_19.md +24 -1
  474. package/docs/pt/intlayer_with_angular_21.md +24 -1
  475. package/docs/pt/intlayer_with_astro.md +24 -1
  476. package/docs/pt/intlayer_with_astro_lit.md +25 -1
  477. package/docs/pt/intlayer_with_astro_preact.md +26 -1
  478. package/docs/pt/intlayer_with_astro_react.md +26 -1
  479. package/docs/pt/intlayer_with_astro_solid.md +26 -1
  480. package/docs/pt/intlayer_with_astro_svelte.md +25 -1
  481. package/docs/pt/intlayer_with_astro_vue.md +25 -1
  482. package/docs/pt/intlayer_with_remix_3.md +22 -1
  483. package/docs/pt/self_hosting.md +399 -224
  484. package/docs/ru/benchmark/nextjs.md +19 -16
  485. package/docs/ru/benchmark/solid.md +26 -9
  486. package/docs/ru/benchmark/svelte.md +22 -7
  487. package/docs/ru/benchmark/tanstack.md +20 -16
  488. package/docs/ru/benchmark/vue.md +20 -11
  489. package/docs/ru/chrome_extension.md +130 -0
  490. package/docs/ru/cli/index.md +11 -1
  491. package/docs/ru/cli/infra.md +162 -0
  492. package/docs/ru/cli/init.md +24 -1
  493. package/docs/ru/cli/upgrade.md +125 -0
  494. package/docs/ru/dictionary/html.md +173 -5
  495. package/docs/ru/dictionary/markdown.md +263 -1
  496. package/docs/ru/intlayer_with_analog.md +23 -1
  497. package/docs/ru/intlayer_with_angular_19.md +24 -1
  498. package/docs/ru/intlayer_with_angular_21.md +24 -1
  499. package/docs/ru/intlayer_with_astro.md +24 -1
  500. package/docs/ru/intlayer_with_astro_lit.md +25 -1
  501. package/docs/ru/intlayer_with_astro_preact.md +26 -1
  502. package/docs/ru/intlayer_with_astro_react.md +26 -1
  503. package/docs/ru/intlayer_with_astro_solid.md +26 -1
  504. package/docs/ru/intlayer_with_astro_svelte.md +25 -1
  505. package/docs/ru/intlayer_with_astro_vue.md +25 -1
  506. package/docs/ru/intlayer_with_remix_3.md +22 -1
  507. package/docs/ru/self_hosting.md +403 -228
  508. package/docs/tr/benchmark/nextjs.md +19 -16
  509. package/docs/tr/benchmark/solid.md +26 -9
  510. package/docs/tr/benchmark/svelte.md +22 -7
  511. package/docs/tr/benchmark/tanstack.md +20 -16
  512. package/docs/tr/benchmark/vue.md +20 -11
  513. package/docs/tr/chrome_extension.md +130 -0
  514. package/docs/tr/cli/index.md +11 -1
  515. package/docs/tr/cli/infra.md +162 -0
  516. package/docs/tr/cli/init.md +24 -1
  517. package/docs/tr/cli/upgrade.md +125 -0
  518. package/docs/tr/dictionary/html.md +173 -5
  519. package/docs/tr/dictionary/markdown.md +263 -1
  520. package/docs/tr/intlayer_with_analog.md +23 -1
  521. package/docs/tr/intlayer_with_angular_19.md +24 -1
  522. package/docs/tr/intlayer_with_angular_21.md +24 -1
  523. package/docs/tr/intlayer_with_astro.md +24 -1
  524. package/docs/tr/intlayer_with_astro_lit.md +25 -1
  525. package/docs/tr/intlayer_with_astro_preact.md +26 -1
  526. package/docs/tr/intlayer_with_astro_react.md +26 -1
  527. package/docs/tr/intlayer_with_astro_solid.md +26 -1
  528. package/docs/tr/intlayer_with_astro_svelte.md +25 -1
  529. package/docs/tr/intlayer_with_astro_vue.md +25 -1
  530. package/docs/tr/intlayer_with_remix_3.md +22 -1
  531. package/docs/tr/self_hosting.md +410 -234
  532. package/docs/uk/benchmark/nextjs.md +19 -16
  533. package/docs/uk/benchmark/solid.md +26 -9
  534. package/docs/uk/benchmark/svelte.md +22 -7
  535. package/docs/uk/benchmark/tanstack.md +20 -16
  536. package/docs/uk/benchmark/vue.md +20 -11
  537. package/docs/uk/chrome_extension.md +130 -0
  538. package/docs/uk/cli/index.md +11 -1
  539. package/docs/uk/cli/infra.md +162 -0
  540. package/docs/uk/cli/init.md +24 -1
  541. package/docs/uk/cli/upgrade.md +125 -0
  542. package/docs/uk/dictionary/html.md +173 -5
  543. package/docs/uk/dictionary/markdown.md +263 -1
  544. package/docs/uk/intlayer_with_analog.md +23 -1
  545. package/docs/uk/intlayer_with_angular_19.md +24 -1
  546. package/docs/uk/intlayer_with_angular_21.md +24 -1
  547. package/docs/uk/intlayer_with_astro.md +24 -1
  548. package/docs/uk/intlayer_with_astro_lit.md +25 -1
  549. package/docs/uk/intlayer_with_astro_preact.md +26 -1
  550. package/docs/uk/intlayer_with_astro_react.md +26 -1
  551. package/docs/uk/intlayer_with_astro_solid.md +26 -1
  552. package/docs/uk/intlayer_with_astro_svelte.md +25 -1
  553. package/docs/uk/intlayer_with_astro_vue.md +25 -1
  554. package/docs/uk/intlayer_with_remix_3.md +22 -1
  555. package/docs/uk/self_hosting.md +413 -238
  556. package/docs/vi/benchmark/nextjs.md +19 -16
  557. package/docs/vi/benchmark/solid.md +26 -9
  558. package/docs/vi/benchmark/svelte.md +22 -7
  559. package/docs/vi/benchmark/tanstack.md +20 -16
  560. package/docs/vi/benchmark/vue.md +20 -11
  561. package/docs/vi/chrome_extension.md +130 -0
  562. package/docs/vi/cli/index.md +11 -1
  563. package/docs/vi/cli/infra.md +162 -0
  564. package/docs/vi/cli/init.md +24 -1
  565. package/docs/vi/cli/upgrade.md +125 -0
  566. package/docs/vi/dictionary/html.md +173 -5
  567. package/docs/vi/dictionary/markdown.md +263 -1
  568. package/docs/vi/intlayer_with_analog.md +23 -1
  569. package/docs/vi/intlayer_with_angular_19.md +24 -1
  570. package/docs/vi/intlayer_with_angular_21.md +24 -1
  571. package/docs/vi/intlayer_with_astro.md +24 -1
  572. package/docs/vi/intlayer_with_astro_lit.md +25 -1
  573. package/docs/vi/intlayer_with_astro_preact.md +26 -1
  574. package/docs/vi/intlayer_with_astro_react.md +26 -1
  575. package/docs/vi/intlayer_with_astro_solid.md +26 -1
  576. package/docs/vi/intlayer_with_astro_svelte.md +25 -1
  577. package/docs/vi/intlayer_with_astro_vue.md +25 -1
  578. package/docs/vi/intlayer_with_remix_3.md +22 -1
  579. package/docs/vi/self_hosting.md +408 -234
  580. package/docs/zh/benchmark/nextjs.md +19 -16
  581. package/docs/zh/benchmark/solid.md +26 -9
  582. package/docs/zh/benchmark/svelte.md +22 -7
  583. package/docs/zh/benchmark/tanstack.md +19 -15
  584. package/docs/zh/benchmark/vue.md +20 -11
  585. package/docs/zh/chrome_extension.md +130 -0
  586. package/docs/zh/cli/index.md +11 -1
  587. package/docs/zh/cli/infra.md +162 -0
  588. package/docs/zh/cli/init.md +24 -1
  589. package/docs/zh/cli/upgrade.md +125 -0
  590. package/docs/zh/dictionary/html.md +172 -5
  591. package/docs/zh/dictionary/markdown.md +262 -1
  592. package/docs/zh/intlayer_with_analog.md +23 -1
  593. package/docs/zh/intlayer_with_angular_19.md +24 -1
  594. package/docs/zh/intlayer_with_angular_21.md +24 -1
  595. package/docs/zh/intlayer_with_astro.md +24 -1
  596. package/docs/zh/intlayer_with_astro_lit.md +25 -1
  597. package/docs/zh/intlayer_with_astro_preact.md +26 -1
  598. package/docs/zh/intlayer_with_astro_react.md +26 -1
  599. package/docs/zh/intlayer_with_astro_solid.md +26 -1
  600. package/docs/zh/intlayer_with_astro_svelte.md +25 -1
  601. package/docs/zh/intlayer_with_astro_vue.md +25 -1
  602. package/docs/zh/intlayer_with_remix_3.md +22 -1
  603. package/docs/zh/self_hosting.md +410 -237
  604. package/legal/ar/privacy_notice.md +9 -3
  605. package/legal/de/privacy_notice.md +9 -3
  606. package/legal/en/privacy_notice.md +10 -3
  607. package/legal/en-GB/privacy_notice.md +9 -3
  608. package/legal/es/privacy_notice.md +9 -3
  609. package/legal/fr/privacy_notice.md +9 -3
  610. package/legal/hi/privacy_notice.md +9 -3
  611. package/legal/id/privacy_notice.md +9 -3
  612. package/legal/it/privacy_notice.md +9 -3
  613. package/legal/ja/privacy_notice.md +9 -3
  614. package/legal/ko/privacy_notice.md +9 -3
  615. package/legal/pl/privacy_notice.md +9 -3
  616. package/legal/pt/privacy_notice.md +9 -3
  617. package/legal/ru/privacy_notice.md +9 -3
  618. package/legal/tr/privacy_notice.md +9 -3
  619. package/legal/uk/privacy_notice.md +9 -3
  620. package/legal/vi/privacy_notice.md +9 -3
  621. package/legal/zh/privacy_notice.md +9 -3
  622. package/package.json +6 -6
  623. package/src/generated/blog.entry.ts +20 -0
  624. package/src/generated/docs.entry.ts +60 -40
  625. package/docs/ar/roadmap.md +0 -321
  626. package/docs/de/roadmap.md +0 -322
  627. package/docs/en/intlayer_with_astro_vanilla.md +0 -713
  628. package/docs/en/roadmap.md +0 -325
  629. package/docs/en-GB/roadmap.md +0 -322
  630. package/docs/es/roadmap.md +0 -322
  631. package/docs/fr/roadmap.md +0 -322
  632. package/docs/hi/roadmap.md +0 -322
  633. package/docs/id/roadmap.md +0 -325
  634. package/docs/it/roadmap.md +0 -322
  635. package/docs/ja/roadmap.md +0 -322
  636. package/docs/ko/roadmap.md +0 -322
  637. package/docs/pl/roadmap.md +0 -325
  638. package/docs/pt/roadmap.md +0 -322
  639. package/docs/ru/roadmap.md +0 -322
  640. package/docs/tr/roadmap.md +0 -325
  641. package/docs/uk/roadmap.md +0 -325
  642. package/docs/vi/roadmap.md +0 -325
  643. package/docs/zh/roadmap.md +0 -322
@@ -1,232 +1,473 @@
1
1
  ---
2
2
  createdAt: 2026-06-30
3
- updatedAt: 2026-06-30
4
- title: Tự host Intlayer
5
- description: Chạy một phiên bản Intlayer hoàn chỉnh trên hạ tầng của riêng bạn chỉ với một lệnh duy nhất. Không yêu cầu tài khoản Intlayer Cloud.
3
+ updatedAt: 2026-09-21
4
+ title: Tự lưu trữ Intlayer (Self-Hosting)
5
+ description: "Chạy Intlayer trên cơ sở hạ tầng của riêng bạn: ứng dụng desktop, một container Docker all-in-one duy nhất hoặc stack Docker Compose có thể mở rộng. Không cần tài khoản Intlayer Cloud."
6
6
  keywords:
7
7
  - Self-Hosting
8
+ - Tự lưu trữ
8
9
  - Docker
9
10
  - Docker Compose
11
+ - Ứng dụng Desktop
10
12
  - Intlayer
11
13
  - CMS
12
- - Installation
13
- - Infrastructure
14
+ - Cài đặt
15
+ - Cơ sở hạ tầng
14
16
  slugs:
15
17
  - doc
16
18
  - self-hosting
17
19
  author: aymericzip
18
20
  ---
19
21
 
20
- # Tự host Intlayer
22
+ # Tự lưu trữ Intlayer (Self-Hosting)
21
23
 
22
- Intlayer có thể chạy hoàn toàn trên hạ tầng của riêng bạn — không yêu cầu tài khoản Intlayer Cloud. Chỉ một lệnh duy nhất sẽ khởi động một stack sẵn sàng cho production:
24
+ Intlayer có thể chạy trên cơ sở hạ tầng của riêng bạn mà không cần tài khoản Intlayer Cloud. Ba cấu hình được cung cấp, tất cả đều có thể thiết lập bằng cùng một trình cài đặt (`install.sh`, `install.ps1` trên Windows, hoặc `npx intlayer init infra`):
23
25
 
24
- Một lệnh cài đặt mọi thứ:
26
+ | Setup | What it is | Pick it for |
27
+ | --------------------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
28
+ | **Ứng dụng Desktop** | Bảng điều khiển gốc cho macOS, Linux và Windows | Một ứng dụng máy khách cục bộ, không cần lưu trữ |
29
+ | **Docker All-in-One** | Bảng điều khiển, API, MongoDB, Redis và MinIO trong **một container duy nhất** | Thử nghiệm và cài đặt trên máy đơn quy mô nhỏ |
30
+ | **Docker Compose** | **Một container cho mỗi dịch vụ**, mọi kho lưu trữ dữ liệu đều có thể thay thế bằng dịch vụ được quản lý | Môi trường sản xuất, mở rộng quy mô, cơ sở dữ liệu được quản lý |
31
+
32
+ ## Table of Contents
33
+
34
+ <TOC/>
35
+
36
+ ## Hình ảnh và Gói đã xuất bản
37
+
38
+ | Artifact | Docker Hub | GHCR mirror | Contents |
39
+ | -------------------- | ------------------------------------------------------------------------- | ------------------------------------------ | -------------------------------------------------------------------------------- |
40
+ | 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 |
41
+ | Dashboard (frontend) | [`intlayer/cms-frontend`](https://hub.docker.com/r/intlayer/cms-frontend) | `ghcr.io/aymericzip/intlayer/cms-frontend` | TanStack Start dashboard on Bun |
42
+ | 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 |
43
+ | Desktop app | [GitHub releases](https://github.com/aymericzip/intlayer/releases/latest) | n/a | `.dmg` (macOS), `.deb` / `.rpm` / `.AppImage` (Linux), `.exe` / `.msi` (Windows) |
44
+
45
+ Cả ba hình ảnh đều được xây dựng từ cùng một tệp [`docker/selfhost/Dockerfile`](https://github.com/aymericzip/intlayer/tree/main/docker/selfhost) và được xuất bản theo từng bản phát hành. Stack Compose cũng kéo các hình ảnh chính thức `mongo:8`, `redis:8-alpine` và `quay.io/minio/minio`.
46
+
47
+ ## Thiết lập
48
+
49
+ Trình cài đặt sẽ hỏi cấu hình bạn mong muốn, kiểm tra các điều kiện tiên quyết (đề xuất cài đặt Docker), ghi tệp môi trường với các secret đã được tạo sẵn và kéo các hình ảnh. Nó không tự khởi động bất cứ điều gì: các chế độ Docker yêu cầu cấu hình trình gửi thư trước, vì vậy nó kết thúc bằng việc in lệnh cần chạy. Việc chạy lại là an toàn: tệp môi trường hiện có sẽ không bao giờ bị ghi đè, điều này cũng làm cho nó trở thành phương thức nâng cấp.
50
+
51
+ <Tabs group="mode">
52
+ <Tab label="Ứng dụng Desktop" value="desktop">
53
+
54
+ Bảng điều khiển Intlayer dưới dạng ứng dụng gốc được xây dựng bằng Tauri. Đăng nhập vào Intlayer Cloud (`https://app.intlayer.org`), vì vậy không cần lưu trữ máy chủ. Đây là lựa chọn phù hợp khi bạn muốn dùng ứng dụng cục bộ thay vì tab trình duyệt.
55
+
56
+ ### Cài đặt
57
+
58
+ Trình cài đặt sẽ tải xuống gói thích hợp cho hệ điều hành và CPU của bạn rồi mở nó (macOS), cài đặt nó (`dpkg` / `rpm` trên Linux), hoặc khởi chạy trình hướng dẫn cài đặt (Windows). Bạn cũng có thể tải xuống thủ công từ [trang Bản phát hành](https://github.com/aymericzip/intlayer/releases/latest).
59
+
60
+ <Tabs group="os">
61
+ <Tab label="macOS / Linux" value="unix">
25
62
 
26
63
  ```sh
27
- curl -fsSL https://intlayer.org/install.sh | sh
64
+ curl -fsSL https://intlayer.org/install.sh | sh -s -- --mode desktop
28
65
  ```
29
66
 
30
- Trình cài đặt sẽ tải xuống `docker-compose.yml` và `.env`, tự động tạo các secret cần thiết, và khởi động tất cả các container với `docker compose up -d`.
67
+ </Tab>
68
+ <Tab label="Windows" value="windows">
31
69
 
32
- Sự phụ thuộc duy nhất bên ngoài là **MongoDB**: backend kết nối với một cluster **Atlas** MongoDB mà bạn cung cấp. Mọi thứ khác chạy bên trong container.
70
+ In PowerShell:
33
71
 
34
- ## Mục lục
72
+ ```powershell
73
+ $env:INTLAYER_MODE = "desktop"; irm https://intlayer.org/install.ps1 | iex
74
+ ```
35
75
 
36
- <TOC/>
76
+ </Tab>
77
+ <Tab label="Intlayer CLI" value="cli">
78
+
79
+ ```bash
80
+ npx intlayer init infra --mode desktop
81
+ ```
82
+
83
+ </Tab>
84
+ </Tabs>
37
85
 
38
- ## Kiến trúc
86
+ ### Yêu cầu
87
+
88
+ - **Node.js**: Ứng dụng nhúng máy chủ bảng điều khiển và khởi động bằng tệp thực thi `node` của máy. Cài đặt từ [nodejs.org](https://nodejs.org) nếu ứng dụng không mở.
89
+
90
+ > Bản dựng desktop đã xuất bản giao tiếp với backend Intlayer Cloud. Để trỏ nó đến backend tự lưu trữ, cần phải xây dựng lại ứng dụng với `VITE_BACKEND_URL` được đặt thành API của bạn, xem [Giới hạn](#limitations).
91
+
92
+ </Tab>
93
+ <Tab label="Docker All-in-One" value="docker">
94
+
95
+ Mọi thứ chạy bên trong một container `intlayer/cms-all` duy nhất, được giám sát bởi [s6-overlay](https://github.com/just-containers/s6-overlay), với mọi kho dữ liệu được lưu trữ liên tục trên một volume duy nhất.
39
96
 
40
97
  ```
41
98
  ┌─────────────────────────────┐
42
99
  browser ──────▶ │ app (TanStack Start) :3000│ ──┐
43
- └─────────────────────────────┘ │ VITE_BACKEND_URL
100
+ (localhost) └─────────────────────────────┘ │ VITE_BACKEND_URL (baked at build)
44
101
  ┌─────────────────────────────┐ │
45
102
  │ backend (Fastify/Bun) :3100│ ◀─┘
46
103
  └──────────────┬──────────────┘
47
- ┌──────────┬─────────┼──────────┬───────────┐
48
- ▼ ▼ ▼ ▼ ▼
49
- mongo:27017 redis:6379 minio:9000 mailpit:1025 Chromium
50
- (1-node RS) (S3 API) (SMTP) (in-image)
51
- minio:9001 mailpit:8025
52
- (console) (web UI)
104
+ ┌──────────┬─────────┼──────────────┐
105
+ ▼ ▼ ▼ ▼
106
+ mongo:27017 redis:6379 minio:9000 Chromium
107
+ /data/mongo /data/redis /data/minio (in-image)
108
+ (1-node RS) minio:9001
53
109
  ```
54
110
 
55
- Chromium (được sử dụng để tạo ảnh chụp màn hình Puppeteer) được đóng gói bên trong image backend — không cần container riêng.
111
+ | Dịch vụ | Cổng máy chủ | Mục đích |
112
+ | ----------- | ----------------------------- | ---------------------------------------------------------------------- |
113
+ | **app** | `3000` | Bảng điều khiển (Giao diện người dùng CMS) |
114
+ | **backend** | `3100` | REST API (endpoint `/health`) |
115
+ | **mongo** | nội bộ | MongoDB 8, replica-set nút đơn `rs0` |
116
+ | **redis** | nội bộ | Hàng đợi tác vụ (BullMQ) và bộ nhớ đệm |
117
+ | **minio** | `9000` (S3), `9001` (console) | Lưu trữ đối tượng tương thích S3 cho ảnh đại diện và ảnh chụp màn hình |
118
+
119
+ Thứ tự khởi động được kiểm soát bởi các phụ thuộc s6 (`mongod` → khởi tạo replica-set, `minio` → tạo bucket, sau đó là `backend`, rồi đến `app`), và các dịch vụ sẽ tự khởi động lại khi kết thúc, do đó lần khởi động đầu tiên sẽ tự phục hồi.
56
120
 
57
- ## Điều kiện tiên quyết
121
+ ### Điều kiện tiên quyết
58
122
 
59
- - **Docker** ≥ 24 và **Docker Compose** ≥ v2. Nếu thiếu một trong hai, trình cài đặt sẽ in liên kết cài đặt và thoát.
60
- - Các cổng `3000`, `3100`, `8025`, `9000`, và `9001` phải khả dụng trên host.
61
- - Host chạy Linux hoặc macOS (hoặc WSL2 trên Windows).
123
+ - **Docker** ≥ 24: Trình cài đặt đề xuất cài đặt nó (qua [get.docker.com](https://get.docker.com) trên Linux, Homebrew trên macOS). Trên Windows, trước tiên hãy cài đặt [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/) (backend WSL 2).
124
+ - Các cổng `3000`, `3100`, `9000`, và `9001` còn trống trên máy chủ. Cổng MinIO `9000` phải duy trì khả năng truy cập từ trình duyệt vì tài nguyên được tải trực tiếp từ `S3_PUBLIC_URL`.
125
+ - Trình gửi thư (mailer): Khóa API [Resend](https://resend.com) hoặc relay SMTP.
62
126
 
63
- Mọi thứ khác — Bun, Redis, MinIO, Chromium — đều được đóng gói trong image.
127
+ ### 1. Cài đặt
64
128
 
65
- ## Bắt đầu nhanh
129
+ Ghi `./intlayer.env` với `BETTER_AUTH_SECRET` và `S3_SECRET_ACCESS_KEY` đã tạo, sau đó kéo `intlayer/cms-all:latest`.
66
130
 
67
- ### 1. Chạy trình cài đặt
131
+ <Tabs group="os">
132
+ <Tab label="macOS / Linux" value="unix">
68
133
 
69
134
  ```sh
70
- curl -fsSL https://intlayer.org/install.sh | sh
135
+ curl -fsSL https://intlayer.org/install.sh | sh -s -- --mode docker
136
+ ```
137
+
138
+ </Tab>
139
+ <Tab label="Windows" value="windows">
140
+
141
+ In PowerShell:
142
+
143
+ ```powershell
144
+ $env:INTLAYER_MODE = "docker"; irm https://intlayer.org/install.ps1 | iex
71
145
  ```
72
146
 
73
- Nó xác minh Docker đã được cài đặt và đang chạy, ghi `./intlayer.env` với `BETTER_AUTH_SECRET` và `S3_SECRET_ACCESS_KEY` đã được tạo sẵn, và kéo image. Nó không khởi động container — backend không thể khởi động mà không có thông tin đăng nhập cơ sở dữ liệu của bạn.
147
+ </Tab>
148
+ <Tab label="Intlayer CLI" value="cli">
74
149
 
75
- Chạy lại trình cài đặt là an toàn: một `intlayer.env` hiện có sẽ không bao giờ bị ghi đè, vì vậy nó cũng đóng vai trò là đường dâng cập nhật.
150
+ CLI chạy trình cài đặt và in lệnh `docker run …` như hiển thị ở các tab khác. Hãy dán vào terminal của bạn sau khi đã định cấu hình mailer.
76
151
 
77
- ### 2. Điền thông tin đăng nhập của bạn
152
+ </Tab>
153
+ </Tabs>
78
154
 
79
- Mở `intlayer.env` và hoàn thành các giá trị được đánh dấu `TODO`:
155
+ ### 2. Cấu hình Mailer
156
+
157
+ Mở `intlayer.env` và điền Resend **hoặc** SMTP (xem chi tiết tại [Trình gửi thư toàn cục](#global-mailer)):
80
158
 
81
159
  ```sh fileName="intlayer.env"
82
- DB_ID=<atlas-user>
83
- DB_MDP=<atlas-password>
84
- DB_CLUSTER=<cluster>.xxxxx.mongodb.net
160
+ # Option A: Resend
85
161
  RESEND_API_KEY=<your-resend-key>
86
- ```
87
162
 
88
- Tệp này cũng chứa các khối được comment cho các tính năng tùy chọn — [SMTP mailer](#global-mailer), `OPENAI_API_KEY`, và các nhà cung cấp OAuth. Bỏ comment những tính năng bạn cần.
163
+ # Option B: SMTP (takes over from Resend as soon as MAIL_SMTP_HOST is set)
164
+ MAIL_SMTP_HOST=smtp.example.com
165
+ MAIL_SMTP_PORT=587
166
+ MAIL_SMTP_USER=<user>
167
+ MAIL_SMTP_PASSWORD=<password>
168
+ MAIL_FROM=Intlayer <no-reply@example.com>
169
+ ```
89
170
 
90
- > Tệp được đọc bởi `docker run --env-file`, tệp này không loại bỏ dấu ngoặc kép và xem mọi thứ sau `=` là giá trị. Viết các giá trị không có dấu ngoặc kép, và giữ các comment trên các dòng riêng biệt.
171
+ ### 3. Khởi chạy
91
172
 
92
- ### 3. Khởi động container
173
+ Đây là lệnh khởi chạy do trình cài đặt in ra:
93
174
 
94
- Đây là lệnh mà trình cài đặt in ra khi hoàn thành:
175
+ <Tabs group="os">
176
+ <Tab label="macOS / Linux" value="unix">
95
177
 
96
178
  ```sh
97
179
  docker run -d --name intlayer \
98
180
  --restart unless-stopped \
99
- -p 3000:3000 \
100
- -p 3100:3100 \
101
- -p 9000:9000 \
102
- -p 9001:9001 \
181
+ -p 3000:3000 -p 3100:3100 -p 9000:9000 -p 9001:9001 \
103
182
  -v intlayer-data:/data \
104
183
  --env-file ./intlayer.env \
105
- ghcr.io/aymericzip/intlayer-selfhost:latest
184
+ intlayer/cms-all:latest
185
+ ```
186
+
187
+ </Tab>
188
+ <Tab label="Windows" value="windows">
189
+
190
+ ```powershell
191
+ docker run -d --name intlayer `
192
+ --restart unless-stopped `
193
+ -p 3000:3000 -p 3100:3100 -p 9000:9000 -p 9001:9001 `
194
+ -v intlayer-data:/data `
195
+ --env-file ./intlayer.env `
196
+ intlayer/cms-all:latest
197
+ ```
198
+
199
+ </Tab>
200
+ <Tab label="Intlayer CLI" value="cli">
201
+
202
+ CLI chạy trình cài đặt và in lệnh `docker run …` như hiển thị ở các tab khác. Hãy dán vào terminal của bạn sau khi đã định cấu hình mailer.
203
+
204
+ </Tab>
205
+ </Tabs>
206
+
207
+ Mở **http://localhost:3000** và làm theo hướng dẫn [Thiết lập lần đầu](#first-run-setup). Lần khởi động đầu tiên sẽ khởi tạo replica-set và bucket, vui lòng đợi trong giây lát.
208
+
209
+ ### Sao lưu và Nâng cấp
210
+
211
+ Toàn bộ trạng thái được lưu trong volume `intlayer-data` (`/data/mongo`, `/data/redis`, `/data/minio`).
212
+
213
+ ```sh
214
+ # Backup (stop the container first so MongoDB's files are consistent)
215
+ docker stop intlayer
216
+ docker run --rm -v intlayer-data:/data -v "$(pwd)":/backup busybox tar czf /backup/intlayer-data.tar.gz /data
217
+ docker start intlayer
218
+
219
+ # Restore
220
+ docker run --rm -v intlayer-data:/data -v "$(pwd)":/backup busybox tar xzf /backup/intlayer-data.tar.gz -C /
221
+ ```
222
+
223
+ Để nâng cấp, hãy chạy lại trình cài đặt (nó sẽ kéo hình ảnh mới nhất và giữ nguyên `intlayer.env`), sau đó chạy `docker rm -f intlayer` và chạy lại lệnh khởi chạy. Để sử dụng MongoDB được quản lý thay vì bản đi kèm, hãy đặt `MONGODB_URI` trong `intlayer.env`.
224
+
225
+ </Tab>
226
+ <Tab label="Docker Compose" value="compose">
227
+
228
+ Một container cho mỗi dịch vụ trên mạng Compose riêng tư. Bảng điều khiển và API sử dụng các hình ảnh `intlayer/cms-frontend` và `intlayer/cms-backend` đã xuất bản; các kho dữ liệu sử dụng hình ảnh chính thức của `mongo`, `redis` và `minio`.
229
+
230
+ ```
231
+ ┌───────────────────┐
232
+ browser ──────▶ │ app :3000 │ ── SSR ──▶ http://backend:3100
233
+ (localhost) └───────────────────┘
234
+ ┌───────────────────┐
235
+ browser ──────▶ │ backend :3100 │
236
+ (localhost) └─────────┬─────────┘
237
+ ┌───────────────┼───────────────┐
238
+ ▼ ▼ ▼
239
+ mongo:27017 redis:6379 minio:9000 ◀── browser (assets)
240
+ (1-node RS) minio:9001
241
+ ```
242
+
243
+ | Dịch vụ | Hình ảnh | Vai trò |
244
+ | ------------ | ----------------------- | --------------------------------------------------------------------- |
245
+ | `app` | `intlayer/cms-frontend` | Bảng điều khiển trên `:3000`; chờ backend khỏe mạnh |
246
+ | `backend` | `intlayer/cms-backend` | API trên `:3100` với Chromium; chờ Mongo, Redis và bucket MinIO |
247
+ | `mongo` | `mongo:8` | Replica-set nút đơn `rs0`, được khởi tạo bởi chính healthcheck của nó |
248
+ | `redis` | `redis:8-alpine` | Hàng đợi và bộ nhớ đệm, lưu trữ liên tục chỉ nối thêm (append-only) |
249
+ | `minio` | `quay.io/minio/minio` | Lưu trữ S3 trên `:9000`, console trên `:9001` |
250
+ | `minio-init` | `quay.io/minio/mc` | Chạy một lần: tạo bucket và chính sách tải xuống ẩn danh |
251
+
252
+ Dữ liệu được lưu trữ trong các volume `intlayer_mongo-data`, `intlayer_redis-data` và `intlayer_minio-data`. Các kết nối dịch vụ (`MONGODB_URI`, `REDIS_URL`, `S3_ENDPOINT`, URL backend nội bộ cho render phía máy chủ) được gắn cố định trong tệp compose và được ưu tiên hơn tệp `.env` (chỉ chứa các secret và tích hợp tùy chọn).
253
+
254
+ ### Điều kiện tiên quyết
255
+
256
+ - **Docker** ≥ 24 với plugin Compose: Trình cài đặt đề xuất cài đặt nó trên Linux và macOS. Trên Windows, trước tiên hãy cài đặt [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/) (backend WSL 2) terlebih dahulu.
257
+ - Các cổng `3000`, `3100`, `9000` và `9001` còn trống trên máy chủ.
258
+ - Trình gửi thư: Khóa API [Resend](https://resend.com) hoặc relay SMTP.
259
+
260
+ ### 1. Cài đặt
261
+
262
+ Ghi `docker-compose.yml` và `.env` với các secret đã tạo vào `./intlayer/` và kéo các hình ảnh.
263
+
264
+ <Tabs group="os">
265
+ <Tab label="macOS / Linux" value="unix">
266
+
267
+ ```sh
268
+ curl -fsSL https://intlayer.org/install.sh | sh -s -- --mode compose
269
+ ```
270
+
271
+ Or by hand:
272
+
273
+ ```sh
274
+ mkdir intlayer && cd intlayer
275
+ curl -fsSLO https://raw.githubusercontent.com/aymericzip/intlayer/main/docker/selfhost/docker-compose.yml
276
+ curl -fsSL https://raw.githubusercontent.com/aymericzip/intlayer/main/docker/selfhost/.env.template -o .env
277
+ # fill in BETTER_AUTH_SECRET and S3_SECRET_ACCESS_KEY (openssl rand -hex 32)
278
+ ```
279
+
280
+ </Tab>
281
+ <Tab label="Windows" value="windows">
282
+
283
+ In PowerShell:
284
+
285
+ ```powershell
286
+ $env:INTLAYER_MODE = "compose"; irm https://intlayer.org/install.ps1 | iex
287
+ ```
288
+
289
+ Or by hand:
290
+
291
+ ```powershell
292
+ mkdir intlayer; cd intlayer
293
+ irm https://raw.githubusercontent.com/aymericzip/intlayer/main/docker/selfhost/docker-compose.yml -OutFile docker-compose.yml
294
+ irm https://raw.githubusercontent.com/aymericzip/intlayer/main/docker/selfhost/.env.template -OutFile .env
295
+ # fill in BETTER_AUTH_SECRET and S3_SECRET_ACCESS_KEY
296
+ ```
297
+
298
+ </Tab>
299
+ <Tab label="Intlayer CLI" value="cli">
300
+
301
+ ```bash
302
+ npx intlayer init infra --mode compose
303
+ ```
304
+
305
+ </Tab>
306
+ </Tabs>
307
+
308
+ ### 2. Cấu hình Mailer
309
+
310
+ Điền Resend **hoặc** SMTP vào `intlayer/.env`, tương tự như container all-in-one (xem [Trình gửi thư toàn cục](#global-mailer)).
311
+
312
+ ### 3. Khởi chạy
313
+
314
+ ```sh
315
+ cd intlayer && docker compose up -d
106
316
  ```
107
317
 
108
- Sau đó mở **http://localhost:3000**. Lần khởi động đầu tiên sẽ khởi tạo các datastores, vì vậy hãy chờ một phút.
318
+ Mở **http://localhost:3000** và làm theo hướng dẫn [Thiết lập lần đầu](#first-run-setup).
319
+
320
+ ### Kho dữ liệu được quản lý
321
+
322
+ Xóa dịch vụ bạn đang thay thế khỏi tệp compose (cùng với mục `depends_on` của nó trong `backend`), và ghi đè biến tương ứng:
323
+
324
+ ```yaml fileName="docker-compose.yml"
325
+ services:
326
+ backend:
327
+ environment:
328
+ MONGODB_URI: mongodb+srv://user:password@cluster0.xxxxx.mongodb.net/intlayer
329
+ REDIS_URL: rediss://default:password@redis.example.com:6380
330
+ S3_ENDPOINT: https://s3.eu-west-1.amazonaws.com
331
+ S3_PUBLIC_URL: https://intlayer-assets.s3.eu-west-1.amazonaws.com
332
+ ```
333
+
334
+ `S3_ACCESS_KEY_ID` / `S3_SECRET_ACCESS_KEY` / `S3_BUCKET_NAME` hoạt động trực tiếp với bất kỳ nhà cung cấp nào tương thích với S3.
335
+
336
+ ### Mở rộng quy mô
337
+
338
+ `app` và `backend` là stateless. Đằng sau bộ cân bằng tải, giả sử loại bỏ các ánh xạ cổng máy chủ cố định và proxy định tuyến theo tên dịch vụ, `docker compose up -d --scale backend=3` sẽ hoạt động. Các tác vụ nền được điều phối qua Redis (BullMQ), vì vậy nhiều bản sao backend chia sẻ hàng đợi một cách an toàn.
339
+
340
+ ### Xây dựng từ nguồn
341
+
342
+ Từ bản sao lưu trữ, chuyển đổi hai dịch vụ Intlayer từ `image:` sang `build:` bằng cấu hình ghi đè:
109
343
 
110
- > Dashboard được phục vụ trên `localhost`. Xem [Limitations](#limitations) — các custom domains không được hỗ trợ bởi image được công bố.
344
+ ```sh
345
+ cd docker/selfhost
346
+ docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build
347
+ ```
111
348
 
112
- ### Cài đặt Installer
349
+ Sử dụng cách này khi xây dựng hình ảnh cho miền tùy chỉnh: truyền các giá trị `VITE_*` dưới dạng đối số bản dựng (xem [Giới hạn](#limitations)).
113
350
 
114
- Installer đọc một số biến môi trường. Vì nó được pipe vào `sh`, hãy truyền chúng cho shell thay vì cho `curl`:
351
+ ### Sao lưu và Nâng cấp
115
352
 
116
353
  ```sh
117
- curl -fsSL https://intlayer.org/install.sh | INTLAYER_ENV_FILE=./config/intlayer.env sh
354
+ # Backup one volume (repeat for intlayer_redis-data and intlayer_minio-data)
355
+ docker compose stop
356
+ docker run --rm -v intlayer_mongo-data:/data -v "$(pwd)":/backup busybox tar czf /backup/mongo-data.tar.gz /data
357
+ docker compose start
358
+
359
+ # Upgrade, volumes are kept
360
+ docker compose pull && docker compose up -d
118
361
  ```
119
362
 
120
- | Variable | Default | Description |
121
- | ------------------------- | --------------------------------------------- | -------------------------------- |
122
- | `INTLAYER_IMAGE` | `ghcr.io/aymericzip/intlayer-selfhost:latest` | Image để pull |
123
- | `INTLAYER_ENV_FILE` | `./intlayer.env` | Nơi ghi file env |
124
- | `INTLAYER_CONTAINER_NAME` | `intlayer` | Tên container |
125
- | `INTLAYER_DATA_VOLUME` | `intlayer-data` | Named volume mounted tại `/data` |
126
- | `INTLAYER_APP_PORT` | `3000` | Host port cho dashboard |
127
- | `INTLAYER_API_PORT` | `3100` | Host port cho API |
128
- | `INTLAYER_S3_PORT` | `9000` | Host port cho MinIO S3 API |
129
- | `INTLAYER_CONSOLE_PORT` | `9001` | Host port cho MinIO console |
363
+ </Tab>
364
+ </Tabs>
130
365
 
131
- > Bốn biến port chỉ thay đổi phía **host** của mapping được in trong lệnh `docker run`. Image được công bố có `http://localhost:3000`, `http://localhost:3100` và `http://localhost:9000` được biên dịch vào dashboard bundle tại thời điểm build, vì vậy việc ánh xạ lại chúng làm cho trình duyệt chỉ đến các port cũ. Giữ các giá trị mặc định trừ khi bạn đang xây dựng image của riêng mình — xem [Limitations](#limitations).
366
+ ### Cài đặt của Trình cài đặt
132
367
 
133
- ## Bắt đầu nhanh
368
+ Nếu không có `--mode` (hoặc `INTLAYER_MODE`), trình cài đặt sẽ nhắc menu: `desktop`, `docker` (all-in-one), hoặc `compose`. Nó cũng đọc một số biến môi trường; hãy truyền chúng vào shell thay vì `curl` vì lệnh này được truyền qua đường ống (piped):
134
369
 
135
- Những gì trình cài đặt thực hiện:
370
+ ```sh
371
+ curl -fsSL https://intlayer.org/install.sh | INTLAYER_COMPOSE_DIR=./cms sh -s -- --mode compose
372
+ ```
136
373
 
137
- 1. Kiểm tra xem `docker` và `docker compose` có tồn tại không.
138
- 2. Tải xuống `docker-compose.yml` và `.env.example` vào `./intlayer/`.
139
- 3. Nếu không có `.env` tồn tại, sao chép file ví dụ và tạo các secret ngẫu nhiên cho `BETTER_AUTH_SECRET`, `S3_ACCESS_KEY_ID`, và `S3_SECRET_ACCESS_KEY` thông qua `openssl rand`.
140
- 4. Chạy `docker compose pull` + `docker compose up -d`.
141
- 5. In các URL: dashboard `:3000`, API `:3100`, UI email `:8025`, console MinIO `:9001`.
374
+ ```powershell
375
+ $env:INTLAYER_MODE = "compose"; $env:INTLAYER_COMPOSE_DIR = ".\cms"; irm https://intlayer.org/install.ps1 | iex
376
+ ```
377
+
378
+ | Variable | Default | Applies to | Description |
379
+ | ------------------------- | ------------------------- | ---------- | ---------------------------------------------------------- |
380
+ | `INTLAYER_MODE` | _(asked)_ | all | `desktop`, `docker` or `compose`, same as `--mode` |
381
+ | `INTLAYER_DOWNLOAD_DIR` | `~/Downloads` | desktop | Where the app installer is saved |
382
+ | `INTLAYER_IMAGE` | `intlayer/cms-all:latest` | docker | All-in-one image to pull |
383
+ | `INTLAYER_ENV_FILE` | `./intlayer.env` | docker | Where to write the environment file |
384
+ | `INTLAYER_CONTAINER_NAME` | `intlayer` | docker | Container name |
385
+ | `INTLAYER_DATA_VOLUME` | `intlayer-data` | docker | Named volume mounted at `/data` |
386
+ | `INTLAYER_APP_PORT` | `3000` | docker | Host port for the dashboard |
387
+ | `INTLAYER_API_PORT` | `3100` | docker | Host port for the API |
388
+ | `INTLAYER_S3_PORT` | `9000` | docker | Host port for the MinIO S3 API |
389
+ | `INTLAYER_CONSOLE_PORT` | `9001` | docker | Host port for the MinIO console |
390
+ | `INTLAYER_COMPOSE_DIR` | `./intlayer` | compose | Where `docker-compose.yml` and `.env` are written |
391
+ | `INTLAYER_SELFHOST_REF` | `main` | both | Git ref the compose file and env template are fetched from |
142
392
 
143
- Sau khi stack hoạt động, mở **http://localhost:3000** và tạo tài khoản đầu tiên của bạn.
393
+ > Các biến cổng chỉ thay đổi phía **máy chủ** của ánh xạ. Các hình ảnh đã xuất bản có `http://localhost:3000`, `http://localhost:3100`, `http://localhost:9000` được biên dịch sẵn vào gói bảng điều khiển, vì vậy hãy giữ nguyên các giá trị mặc định trừ khi bạn tự xây dựng hình ảnh, xem [Giới hạn](#limitations).
144
394
 
145
- ## Các dịch vụ
395
+ ## Thiết lập lần đầu
146
396
 
147
- | Dịch vụ | Image | Cổng Host | Mục đích |
148
- | ----------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------------------------- |
149
- | **app** | được xây dựng từ `apps/app/Dockerfile` | `3000` | Dashboard TanStack Start (UI của CMS) |
150
- | **backend** | được xây dựng từ `apps/backend/Dockerfile` | `3100` | API REST Fastify (endpoint `/health`) |
151
- | **mongo** | `mongo:7` | nội bộ | Bộ nhân bản một node (`rs0`) |
152
- | **redis** | `redis:7-alpine` | nội bộ | Hàng đợi công việc (BullMQ) và caching (ioredis) |
153
- | **minio** | `minio/minio` | `9000` (S3), `9001` (console) | Lưu trữ đối tượng tương thích S3 cho avatar và ảnh chụp màn hình |
154
- | **mailpit** | `axllent/mailpit` | `1025` (SMTP), `8025` (web UI) | Nơi nhận email giao dịch cục bộ |
397
+ Khi mở bảng điều khiển trên một phiên bản mới (cơ sở dữ liệu trống), bạn sẽ tự động được chuyển hướng đến trang **`/init`**:
155
398
 
156
- > Cổng MinIO `9000` phải có thể truy cập được bởi trình duyệt vì các tài sản được tải lên (avatars, ảnh chụp màn hình) được tải trực tiếp từ `S3_PUBLIC_URL=http://localhost:9000/intlayer`.
399
+ 1. Tạo tài khoản đầu tiên. Vì bộ sưu tập người dùng đang trống, tài khoản này sẽ tự động được nâng cấp thành **Super Admin**.
400
+ 2. Một email xác minh sẽ được gửi qua Resend hoặc relay SMTP của bạn. Xác minh email là **bắt buộc**, đó là lý do tại sao phải cấu hình trình gửi thư trước khi khởi chạy.
401
+ 3. Nhấp vào liên kết trong email và đăng nhập.
402
+
403
+ Sau khi đã có quản trị viên, `/init` sẽ chuyển hướng đến trang đăng nhập thông thường.
157
404
 
158
405
  ## Biến môi trường
159
406
 
407
+ Cả hai chế độ Docker đều đọc cùng một tệp (tệp `intlayer.env` cho container hoặc `.env` cho Compose) được tạo từ [`docker/selfhost/.env.template`](https://github.com/aymericzip/intlayer/blob/main/docker/selfhost/.env.template).
408
+
160
409
  ### Bắt buộc
161
410
 
162
- | Variable | Example | Description |
163
- | ---------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
164
- | `DB_ID` | `intlayer` | MongoDB Atlas user |
165
- | `DB_MDP` | _(your password)_ | MongoDB Atlas password |
166
- | `DB_CLUSTER` | `cluster0.xxxxx.mongodb.net` | MongoDB Atlas cluster host (used in the `mongodb+srv://` URI) |
167
- | `BETTER_AUTH_SECRET` | _(generated)_ | 32-byte secret for session signing |
168
- | `S3_SECRET_ACCESS_KEY` | _(generated)_ | Secret for the bundled MinIO |
169
- | `RESEND_API_KEY` | _(your key)_ | Transactional email via Resend. Required for first-run setup unless you configure a global SMTP mailer (see [Global mailer](#global-mailer)) |
170
-
171
- ### Bắt buộc (tự động tạo hoặc được nhắc nhở)
172
-
173
- | Biến | Ví dụ | Mô tả |
174
- | ---------------------- | ----------------------------------------------- | ------------------------------------------------- |
175
- | `NODE_ENV` | `production` | Môi trường runtime |
176
- | `PORT` | `3100` | Cổng lắng nghe của Backend |
177
- | `BACKEND_URL` | `http://localhost:3100` | URL công khai của API backend |
178
- | `APP_URL` | `http://localhost:3000` | URL công khai của dashboard |
179
- | `DOMAIN` | `localhost` | Miền cookie |
180
- | `MONGODB_URI` | `mongodb://mongo:27017/intlayer?replicaSet=rs0` | URI kết nối MongoDB đầy đủ |
181
- | `REDIS_URL` | `redis://redis:6379` | URL kết nối Redis |
182
- | `BETTER_AUTH_SECRET` | _(được tạo)_ | Secret 32-byte để ký session |
183
- | `MAIL_PROVIDER` | `smtp` | Phương thức gửi mail: `smtp` hoặc `resend` |
184
- | `MAIL_SMTP_HOST` | `mailpit` | Tên host SMTP (tên container Mailpit) |
185
- | `MAIL_SMTP_PORT` | `1025` | Cổng SMTP |
186
- | `MAIL_FROM` | `Intlayer <no-reply@localhost>` | Địa chỉ người gửi |
187
- | `S3_ENDPOINT` | `http://minio:9000` | Endpoint tương thích S3 |
188
- | `S3_PUBLIC_URL` | `http://localhost:9000/intlayer` | URL công khai để trình duyệt tải tài sản |
189
- | `S3_BUCKET_NAME` | `intlayer` | Tên bucket |
190
- | `S3_ACCESS_KEY_ID` | _(được tạo)_ | Khóa truy cập MinIO |
191
- | `S3_SECRET_ACCESS_KEY` | _(được tạo)_ | Khóa bí mật MinIO |
192
- | `VITE_BACKEND_URL` | `http://localhost:3100` | URL backend được tích hợp vào dashboard khi build |
193
- | `VITE_DOMAIN` | `localhost` | Miền được tích hợp vào dashboard khi build |
194
-
195
- ### Tùy chọn (tính năng sẽ suy giảm khi không có)
196
-
197
- | Biến | Tính năng |
198
- | -------------------------------------------------------- | -------------------------------------------------------------- |
199
- | `OPENAI_API_KEY` | Dịch thuật và kiểm tra nội dung có sự hỗ trợ của AI |
200
- | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_*` | Quản lý thanh toán và đăng ký |
201
- | `RESEND_API_KEY` | Email giao dịch qua Resend (ghi đè Mailpit khi được thiết lập) |
202
- | `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | Đăng nhập GitHub OAuth |
203
- | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Đăng nhập Google OAuth |
204
- | `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` | Đăng nhập GitLab OAuth |
205
- | `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` | Đăng nhập Microsoft OAuth |
206
- | `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET` | Đăng nhập LinkedIn OAuth |
207
- | `ATLASSIAN_CLIENT_ID`, `ATLASSIAN_CLIENT_SECRET` | Đăng nhập Atlassian OAuth |
208
-
209
- ### Mailer toàn cầu
210
-
211
- Theo mặc định, tất cả các email giao dịch được gửi qua Resend sử dụng `RESEND_API_KEY`. Các triển khai tự lưu trữ có thể thay vào đó định tuyến **mọi** email — bao gồm các email không thuộc tổ chức như đặt lại mật khẩu và liên kết ma thuật — qua một mailer toàn cầu được định cấu hình bằng các biến môi trường.
212
-
213
- Đặt `MAIL_PROVIDER` để kích hoạt nó. Khi không được đặt, mailer Resend mặc định được sử dụng.
214
-
215
- | Variable | Example | Description |
216
- | -------------------- | ------------------------------ | -------------------------------------------------------------------------------- |
217
- | `MAIL_PROVIDER` | `smtp` | Vận chuyển toàn cầu: `smtp` hoặc `resend`. Để không được đặt để sử dụng mặc định |
218
- | `MAIL_FROM` | `Intlayer <no-reply@acme.com>` | Tiêu đề người gửi. Chấp nhận địa chỉ đơn thuần hoặc định dạng `Name <email>` |
219
- | `MAIL_SMTP_HOST` | `smtp.acme.com` | SMTP host (bắt buộc khi `MAIL_PROVIDER=smtp`) |
220
- | `MAIL_SMTP_PORT` | `587` | SMTP port (mặc định là `587`) |
221
- | `MAIL_SMTP_SECURE` | `false` | TLS ẩn. Đặt `true` cho cổng `465` |
222
- | `MAIL_SMTP_USER` | _(your user)_ | Tên người dùng SMTP (tùy chọn; bỏ qua đối với relay không xác thực) |
223
- | `MAIL_SMTP_PASSWORD` | _(your password)_ | Mật khẩu SMTP |
224
-
225
- > Thứ tự ưu tiên: mailer riêng của một tổ chức (được định cấu hình từ bảng điều khiển **Organization**) có ưu tiên hơn mailer toàn cầu, cái này lần lượt có ưu tiên hơn khóa Resend mặc định.
226
-
227
- ## Kết nối dự án Intlayer của bạn
228
-
229
- Khi stack đang chạy, hãy trỏ dự án của bạn đến backend và dashboard được tự host thay vì `intlayer.org`.
411
+ | Variable | Example | Description |
412
+ | ---------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
413
+ | `BETTER_AUTH_SECRET` | _(generated)_ | 32-byte secret for session signing |
414
+ | `S3_SECRET_ACCESS_KEY` | _(generated)_ | Secret for the bundled MinIO |
415
+ | `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)) |
416
+
417
+ ### Được cố định bởi việc triển khai
418
+
419
+ These are set by the image (all-in-one) or by the compose file, and only need overriding for a non-standard topology.
420
+
421
+ | Variable | All-in-one | Docker Compose | Description |
422
+ | ------------------ | --------------------------------------------------- | -------------------------------- | ----------------------------------------------------------------------------- |
423
+ | `PORT` | `3100` | `3100` | Backend listening port |
424
+ | `APP_URL` | `http://localhost:3000` | `http://localhost:3000` | Public URL of the dashboard |
425
+ | `BACKEND_URL` | `http://localhost:3100` | `http://localhost:3100` | Public URL of the backend API |
426
+ | `DOMAIN` | `localhost` | `localhost` | Cookie domain |
427
+ | `SELF_HOSTED` | `true` | `true` | Disables the cloud-only API endpoints (billing, subscriptions, marketplace) |
428
+ | `MONGODB_URI` | `mongodb://127.0.0.1:27017/intlayer?replicaSet=rs0` | `mongodb://mongo:27017/…` | MongoDB connection string, any `mongodb://` or `mongodb+srv://` cluster works |
429
+ | `REDIS_URL` | `redis://127.0.0.1:6379` | `redis://redis:6379` | Redis |
430
+ | `S3_ENDPOINT` | `http://127.0.0.1:9000` | `http://minio:9000` | MinIO (server-to-server) |
431
+ | `S3_PUBLIC_URL` | `http://localhost:9000/intlayer` | `http://localhost:9000/intlayer` | Public URL for browser asset loading |
432
+ | `S3_BUCKET_NAME` | `intlayer` | `intlayer` | Bucket name |
433
+ | `S3_ACCESS_KEY_ID` | `intlayer` | `intlayer` | MinIO access key |
434
+
435
+ Dịch vụ Compose `app` nhận thêm `INTLAYER_BACKEND_INTERNAL_URL=http://backend:3100`: trình duyệt tiếp cận API tại `localhost:3100`, nhưng quá trình kết xuất phía máy chủ chạy bên trong mạng Compose nên nó phải sử dụng tên dịch vụ.
436
+
437
+ ### Tùy chọn (các tính năng sẽ giảm cấp nhẹ nhàng khi không được đặt)
438
+
439
+ | Variable | Feature |
440
+ | ------------------------------------------------ | ----------------------------------------- |
441
+ | `OPENAI_API_KEY` | AI-assisted translation and content audit |
442
+ | `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | GitHub OAuth login |
443
+ | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Google OAuth login |
444
+ | `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` | GitLab OAuth login |
445
+ | `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` | Microsoft OAuth login |
446
+
447
+ ### Trình gửi thư toàn cục (Mailer)
448
+
449
+ Tất cả các email giao dịch, bao gồm các email ngoài tổ chức như đặt lại mật khẩu và magic links, đều đi qua một trong hai cổng truyền tải toàn cục:
450
+
451
+ - **Resend**: Sử dụng `RESEND_API_KEY`.
452
+ - **SMTP**: Sử dụng các biến `MAIL_SMTP_*`. Đặt `MAIL_SMTP_HOST` sẽ lập tức chọn giao thức SMTP và bỏ qua `RESEND_API_KEY`.
453
+
454
+ `MAIL_PROVIDER` chỉ cần thiết khi muốn buộc sử dụng một phương thức truyền tải nếu cả hai đều được cấu hình (ví dụ: `MAIL_PROVIDER=resend` để giữ Resend khi máy chủ SMTP tồn tại).
455
+
456
+ | Variable | Example | Description |
457
+ | -------------------- | ------------------------------ | ---------------------------------------------------------------------------- |
458
+ | `MAIL_FROM` | `Intlayer <no-reply@acme.com>` | Sender header for either transport. Accepts a bare address or `Name <email>` |
459
+ | `MAIL_SMTP_HOST` | `smtp.acme.com` | SMTP host. Setting it selects the SMTP transport |
460
+ | `MAIL_SMTP_PORT` | `587` | SMTP port (defaults to `587`) |
461
+ | `MAIL_SMTP_SECURE` | `false` | Implicit TLS. Set `true` for port `465` |
462
+ | `MAIL_SMTP_USER` | _(your user)_ | SMTP username (optional; omit for unauthenticated relays) |
463
+ | `MAIL_SMTP_PASSWORD` | _(your password)_ | SMTP password |
464
+ | `MAIL_PROVIDER` | `resend` | Optional override: `smtp` or `resend`. Leave unset to auto-select |
465
+
466
+ > Thứ tự ưu tiên: Trình gửi thư riêng của tổ chức (được cấu hình từ bảng điều khiển **Tổ chức**) sẽ ghi đè trình gửi thư toàn cục, và trình gửi thư toàn cục sẽ ghi đè khóa Resend mặc định.
467
+
468
+ ## Kết nối Dự án Intlayer của bạn
469
+
470
+ Sau khi stack đang chạy, hãy cấu hình dự án của bạn để trỏ đến backend và bảng điều khiển tự lưu trữ thay vì `intlayer.org`.
230
471
 
231
472
  ### Cấu hình dự án
232
473
 
@@ -239,23 +480,23 @@ const config: IntlayerConfig = {
239
480
  clientSecret: process.env.INTLAYER_CLIENT_SECRET,
240
481
 
241
482
  /**
242
- * URL của dashboard CMS được tự host.
243
- * Mặc định: https://app.intlayer.org
483
+ * URL of the self-hosted CMS dashboard.
484
+ * Default: https://app.intlayer.org
244
485
  */
245
- cmsURL: process.env.INTLAYER_CMS_URL, // ví dụ: http://localhost:3000
486
+ cmsURL: process.env.INTLAYER_CMS_URL, // e.g. http://localhost:3000
246
487
 
247
488
  /**
248
- * URL của API backend được tự host.
249
- * Mặc định: https://back.intlayer.org
489
+ * URL of the self-hosted backend API.
490
+ * Default: https://back.intlayer.org
250
491
  */
251
- backendURL: process.env.INTLAYER_BACKEND_URL, // ví dụ: http://localhost:3100
492
+ backendURL: process.env.INTLAYER_BACKEND_URL, // e.g. http://localhost:3100
252
493
  },
253
494
  };
254
495
 
255
496
  export default config;
256
497
  ```
257
498
 
258
- Thiết lập các biến môi trường trong file `.env` của dự án bạn:
499
+ Set the environment variables in your project's `.env`:
259
500
 
260
501
  ```sh
261
502
  INTLAYER_CMS_URL=http://localhost:3000
@@ -264,11 +505,11 @@ INTLAYER_CLIENT_ID=<your-client-id>
264
505
  INTLAYER_CLIENT_SECRET=<your-client-secret>
265
506
  ```
266
507
 
267
- Tạo thông tin truy cập trong dashboard được tự host của bạn dưới mục **Projects → Access keys** tại `http://localhost:3000/projects`.
508
+ Tạo thông tin đăng nhập truy cập trong bảng điều khiển tự lưu trữ của bạn tại **Dự án → Khóa truy cập** (`http://localhost:3000/projects`).
268
509
 
269
510
  ### SDK `@intlayer/api`
270
511
 
271
- Khi sử dụng SDK `@intlayer/api` theo cách lập trình, hãy truyền `backendURL` một cách rõ ràng:
512
+ Khi sử dụng SDK `@intlayer/api` theo phương thức lập trình, hãy truyền `backendURL` một cách rõ ràng:
272
513
 
273
514
  ```typescript fileName="cms.ts" codeFormat="typescript"
274
515
  import { createIntlayerCMS } from "@intlayer/api";
@@ -285,84 +526,17 @@ const cms = createIntlayerCMS({
285
526
  const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();
286
527
  ```
287
528
 
288
- ## Nâng cấp
289
-
290
- Thao tác này sẽ kéo các image mới nhất và khởi động lại các container với `docker compose pull && docker compose up -d`. Các volume hiện có (`mongo-data`, `redis-data`, `minio-data`) được bảo toàn — không mất dữ liệu.
291
-
292
- ```sh
293
- docker compose pull
294
- docker compose up -d
295
- ```
296
-
297
- ## Sao lưu và phục hồi
298
-
299
- Tất cả dữ liệu bền vững nằm trong ba Docker volume được đặt tên.
300
-
301
- ### Sao lưu
302
-
303
- ```sh
304
- docker run --rm \
305
- -v intlayer_mongo-data:/data \
306
- -v "$(pwd)":/backup \
307
- busybox tar czf /backup/mongo-data.tar.gz /data
308
-
309
- docker run --rm \
310
- -v intlayer_redis-data:/data \
311
- -v "$(pwd)":/backup \
312
- busybox tar czf /backup/redis-data.tar.gz /data
313
-
314
- docker run --rm \
315
- -v intlayer_minio-data:/data \
316
- -v "$(pwd)":/backup \
317
- busybox tar czf /backup/minio-data.tar.gz /data
318
- ```
319
-
320
- ### Phục hồi
321
-
322
- ```sh
323
- docker run --rm \
324
- -v intlayer_mongo-data:/data \
325
- -v "$(pwd)":/backup \
326
- busybox tar xzf /backup/mongo-data.tar.gz -C /
529
+ ## Giới hạn
327
530
 
328
- # Lặp lại cho redis-data và minio-data
329
- ```
330
-
331
- ## Hạn chế
332
-
333
- - **MongoDB phải là external (Atlas).** Backend chỉ kết nối qua `mongodb+srv://` (được xây dựng từ `DB_ID` / `DB_MDP` / `DB_CLUSTER`), do đó `mongodb://host:27017` đơn giản — bao gồm cả `mongod` được bao gồm của container — không thể được sử dụng. Cung cấp một cluster MongoDB Atlas.
334
- - **Không có tên miền tùy chỉnh.** Tất cả các `VITE_*` URLs hướng tới trình duyệt được nhúng inline vào ứng dụng tại thời điểm xây dựng, và hình ảnh được xuất bản có các giá trị `localhost`. Dashboard phải được truy cập tại `http://localhost:3000`; phục vụ nó trên một tên miền công khai sẽ yêu cầu xây dựng lại hình ảnh với các URL mục tiêu được xây dựng sẵn và không được hỗ trợ ra khỏi hộp.
335
- - **Email yêu cầu một mailer hoạt động.** Thiết lập lần chạy đầu tiên thực thi xác minh email, do đó `RESEND_API_KEY` hoặc một [mailer SMTP toàn cục](#global-mailer) (`MAIL_PROVIDER=smtp` + `MAIL_SMTP_*`) phải được cấu hình. Sau khi admin đầu tiên đăng nhập, mỗi tổ chức cũng có thể cấu hình mailer SMTP hoặc Resend riêng của nó từ dashboard.
336
-
337
- ## Khắc phục sự cố
338
-
339
- ### Backend bị crash-loop khi khởi động lần đầu
340
-
341
- MongoDB và Redis phải hoạt động tốt trước khi backend khởi động. File compose sử dụng `depends_on` với `condition: service_healthy`. Nếu bạn thấy backend khởi động lại liên tục, hãy kiểm tra xem healthcheck của `mongo` và `redis` có vượt qua không:
342
-
343
- ```sh
344
- docker compose ps
345
- docker compose logs mongo
346
- docker compose logs redis
347
- ```
348
-
349
- Tìm kiếm `MongoDB connection error` gần phía trên của log.
350
-
351
- ### Dashboard không thể kết nối tới API
352
-
353
- Xác minh rằng `VITE_BACKEND_URL` khớp với URL mà backend có thể truy cập được từ **trình duyệt** (không phải mạng Docker). Nếu bạn đã thay đổi cổng backend hoặc thêm reverse proxy, hãy build lại image dashboard:
354
-
355
- ### Thiếu MinIO bucket
356
-
357
- Nếu dịch vụ một lần chạy `minio-init` không chạy (hoặc chạy trước khi MinIO sẵn sàng), hãy tạo bucket thủ công:
358
-
359
- ```sh
360
- docker compose run --rm minio-init
361
- ```
531
+ - **Chưa hỗ trợ tên miền tùy chỉnh và ánh xạ lại cổng.** Tất cả các URL `VITE_*` hướng đến trình duyệt đều được nhúng sẵn vào bảng điều khiển tại thời điểm xây dựng, và các hình ảnh đã xuất bản (cùng với ứng dụng desktop) có sẵn các giá trị `localhost` / Intlayer Cloud. Bảng điều khiển phải được truy cập tại `http://localhost:3000`, API tại `:3100` và MinIO tại `:9000`. Việc lưu trữ trên miền công khai hoặc trỏ ứng dụng desktop đến backend tự lưu trữ yêu cầu xây dựng lại với các URL mục tiêu được nhúng sẵn (trên `docker/selfhost/Dockerfile` hoặc `docker-compose.build.yml` với `--build-arg VITE_BACKEND_URL=… VITE_SITE_URL=… VITE_DOMAIN=…`), điều này không được hỗ trợ sẵn ngay khi cài đặt.
532
+ - **Gửi thư yêu cầu một mailer hoạt động.** Thiết lập lần đầu bắt buộc phải xác minh email, vì vậy phải định cấu hình `RESEND_API_KEY` hoặc một [relay SMTP](#global-mailer) (`MAIL_SMTP_*`). Sau khi quản trị viên đầu tiên đăng nhập, các tổ chức cũng có thể cấu hình mailer SMTP hoặc Resend riêng của họ từ bảng điều khiển.
533
+ - **Ứng dụng desktop yêu cầu Node.js trên máy để khởi động máy chủ nhúng.**
362
534
 
363
- ## Các liên kết hữu ích
535
+ ## Liên kết hữu ích
364
536
 
365
537
  - [Tài liệu Intlayer CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/intlayer_CMS.md)
366
538
  - [Tham chiếu cấu hình](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/configuration.md)
367
- - [CMS SDK — `@intlayer/api`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/intlayer_CMS.md#programmatic-access-with-the-intlayerapi-sdk)
368
- - [Docker Image (aymercizip/intlayer-selfhost)](https://hub.docker.com/repository/docker/aymercizip/intlayer-selfhost/general)
539
+ - [CMS SDK: `@intlayer/api`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/intlayer_CMS.md#programmatic-access-with-the-intlayerapi-sdk)
540
+ - [Bản phát hành ứng dụng Desktop](https://github.com/aymericzip/intlayer/releases/latest)
541
+ - 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), mirror GHCR: `ghcr.io/aymericzip/intlayer/`
542
+ - [`docker/selfhost/`](https://github.com/aymericzip/intlayer/tree/main/docker/selfhost): Dockerfile, `docker-compose.yml`, `.env.template`