Bläddra i källkod

feat(ota): upgrade container

Jacky 1 vecka sedan
förälder
incheckning
e2c43be24a

+ 5 - 0
app/src/constants/errors/docker.ts

@@ -7,4 +7,9 @@ export default {
   500006: () => $gettext('Container status unknown'),
   500007: () => $gettext('Failed to inspect container: {0}'),
   500008: () => $gettext('Nginx is not running in another container'),
+  500009: () => $gettext('Failed to get hostname: {0}'),
+  500010: () => $gettext('Failed to pull image: {0}'),
+  500011: () => $gettext('Failed to inspect current container: {0}'),
+  500012: () => $gettext('Failed to create temp container: {0}'),
+  500013: () => $gettext('Failed to start temp container: {0}'),
 }

+ 25 - 0
app/src/language/ar/app.po

@@ -1599,6 +1599,11 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr "فشل في التفعيل %{msg}"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "فشل في التفعيل %{msg}"
+
 #: src/constants/errors/backup.ts:2
 #, fuzzy
 msgid "Failed to create temporary directory"
@@ -1721,6 +1726,11 @@ msgstr "فشل في الحصول على معلومات الشهادة"
 msgid "Failed to get certificate information"
 msgstr "فشل في الحصول على معلومات الشهادة"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "فشل في التفعيل %{msg}"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 #, fuzzy
 msgid "Failed to get Nginx performance settings"
@@ -1736,6 +1746,11 @@ msgstr "فشل في الحصول على معلومات الشهادة"
 msgid "Failed to inspect container: {0}"
 msgstr "فشل في التفعيل %{msg}"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "فشل في التفعيل %{msg}"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 #, fuzzy
 msgid "Failed to load history records"
@@ -1760,6 +1775,11 @@ msgstr "فشل في التفعيل %{msg}"
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "فشل في التفعيل %{msg}"
+
 #: src/constants/errors/backup.ts:53
 #, fuzzy
 msgid "Failed to read encrypted file: {0}"
@@ -1809,6 +1829,11 @@ msgstr "فشل في الحصول على الشهادة"
 msgid "Failed to save Nginx performance settings"
 msgstr "فشل في الحصول على معلومات الشهادة"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "فشل في التفعيل %{msg}"
+
 #: src/constants/errors/backup.ts:38
 #, fuzzy
 msgid "Failed to verify hashes: {0}"

+ 25 - 0
app/src/language/de_DE/app.po

@@ -1645,6 +1645,11 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr "Aktiviern von %{msg} fehlgeschlagen"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "Aktiviern von %{msg} fehlgeschlagen"
+
 #: src/constants/errors/backup.ts:2
 #, fuzzy
 msgid "Failed to create temporary directory"
@@ -1767,6 +1772,11 @@ msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
 msgid "Failed to get certificate information"
 msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "Aktiviern von %{msg} fehlgeschlagen"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 #, fuzzy
 msgid "Failed to get Nginx performance settings"
@@ -1782,6 +1792,11 @@ msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
 msgid "Failed to inspect container: {0}"
 msgstr "Aktiviern von %{msg} fehlgeschlagen"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "Aktiviern von %{msg} fehlgeschlagen"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 #, fuzzy
 msgid "Failed to load history records"
@@ -1806,6 +1821,11 @@ msgstr "Aktiviern von %{msg} fehlgeschlagen"
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "Aktiviern von %{msg} fehlgeschlagen"
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr ""
@@ -1851,6 +1871,11 @@ msgstr "Zertifikat ist gültig"
 msgid "Failed to save Nginx performance settings"
 msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "Aktiviern von %{msg} fehlgeschlagen"
+
 #: src/constants/errors/backup.ts:38
 #, fuzzy
 msgid "Failed to verify hashes: {0}"

+ 25 - 0
app/src/language/en/app.po

@@ -1629,6 +1629,11 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr "Failed to enable %{msg}"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "Failed to enable %{msg}"
+
 #: src/constants/errors/backup.ts:2
 #, fuzzy
 msgid "Failed to create temporary directory"
@@ -1752,6 +1757,11 @@ msgstr "Certificate is valid"
 msgid "Failed to get certificate information"
 msgstr "Certificate is valid"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "Failed to enable %{msg}"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 #, fuzzy
 msgid "Failed to get Nginx performance settings"
@@ -1767,6 +1777,11 @@ msgstr "Certificate is valid"
 msgid "Failed to inspect container: {0}"
 msgstr "Failed to enable %{msg}"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "Failed to enable %{msg}"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 #, fuzzy
 msgid "Failed to load history records"
@@ -1791,6 +1806,11 @@ msgstr "Failed to enable %{msg}"
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "Failed to enable %{msg}"
+
 #: src/constants/errors/backup.ts:53
 #, fuzzy
 msgid "Failed to read encrypted file: {0}"
@@ -1840,6 +1860,11 @@ msgstr "Certificate is valid"
 msgid "Failed to save Nginx performance settings"
 msgstr "Certificate is valid"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "Failed to enable %{msg}"
+
 #: src/constants/errors/backup.ts:38
 #, fuzzy
 msgid "Failed to verify hashes: {0}"

+ 25 - 0
app/src/language/es/app.po

@@ -1601,6 +1601,11 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr "Error al habilitar %{msg}"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "Error al habilitar %{msg}"
+
 #: src/constants/errors/backup.ts:2
 #, fuzzy
 msgid "Failed to create temporary directory"
@@ -1723,6 +1728,11 @@ msgstr "No se pudo obtener la información del certificado"
 msgid "Failed to get certificate information"
 msgstr "No se pudo obtener la información del certificado"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "Error al habilitar %{msg}"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 #, fuzzy
 msgid "Failed to get Nginx performance settings"
@@ -1738,6 +1748,11 @@ msgstr "No se pudo obtener la información del certificado"
 msgid "Failed to inspect container: {0}"
 msgstr "Error al habilitar %{msg}"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "Error al habilitar %{msg}"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 #, fuzzy
 msgid "Failed to load history records"
@@ -1762,6 +1777,11 @@ msgstr "Error al habilitar %{msg}"
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "Error al habilitar %{msg}"
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr ""
@@ -1807,6 +1827,11 @@ msgstr "Falla al obtener el certificado"
 msgid "Failed to save Nginx performance settings"
 msgstr "No se pudo obtener la información del certificado"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "Error al habilitar %{msg}"
+
 #: src/constants/errors/backup.ts:38
 #, fuzzy
 msgid "Failed to verify hashes: {0}"

+ 25 - 0
app/src/language/fr_FR/app.po

@@ -1656,6 +1656,11 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr "Impossible d'activer %{msg}"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "Impossible d'activer %{msg}"
+
 #: src/constants/errors/backup.ts:2
 #, fuzzy
 msgid "Failed to create temporary directory"
@@ -1778,6 +1783,11 @@ msgstr "Échec de l'obtention des informations sur le certificat"
 msgid "Failed to get certificate information"
 msgstr "Échec de l'obtention des informations sur le certificat"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "Impossible d'activer %{msg}"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 #, fuzzy
 msgid "Failed to get Nginx performance settings"
@@ -1793,6 +1803,11 @@ msgstr "Échec de l'obtention des informations sur le certificat"
 msgid "Failed to inspect container: {0}"
 msgstr "Impossible d'activer %{msg}"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "Impossible d'activer %{msg}"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 #, fuzzy
 msgid "Failed to load history records"
@@ -1818,6 +1833,11 @@ msgstr "Impossible d'activer %{msg}"
 msgid "Failed to parse nginx.conf"
 msgstr "Erreur lecture nginx.conf"
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "Impossible d'activer %{msg}"
+
 #: src/constants/errors/backup.ts:53
 #, fuzzy
 msgid "Failed to read encrypted file: {0}"
@@ -1868,6 +1888,11 @@ msgstr "Obtenir un certificat"
 msgid "Failed to save Nginx performance settings"
 msgstr "Échec de l'obtention des informations sur le certificat"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "Impossible d'activer %{msg}"
+
 #: src/constants/errors/backup.ts:38
 #, fuzzy
 msgid "Failed to verify hashes: {0}"

+ 25 - 0
app/src/language/ko_KR/app.po

@@ -1594,6 +1594,11 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr "%{msg} 활성화 실패"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "%{msg} 활성화 실패"
+
 #: src/constants/errors/backup.ts:2
 #, fuzzy
 msgid "Failed to create temporary directory"
@@ -1716,6 +1721,11 @@ msgstr "인증서 정보 가져오기 실패"
 msgid "Failed to get certificate information"
 msgstr "인증서 정보 가져오기 실패"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "%{msg} 활성화 실패"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 #, fuzzy
 msgid "Failed to get Nginx performance settings"
@@ -1731,6 +1741,11 @@ msgstr "인증서 정보 가져오기 실패"
 msgid "Failed to inspect container: {0}"
 msgstr "%{msg} 활성화 실패"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "%{msg} 활성화 실패"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 #, fuzzy
 msgid "Failed to load history records"
@@ -1755,6 +1770,11 @@ msgstr "%{msg} 활성화 실패"
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "%{msg} 활성화 실패"
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr ""
@@ -1800,6 +1820,11 @@ msgstr "인증서 획득 실패"
 msgid "Failed to save Nginx performance settings"
 msgstr "인증서 정보 가져오기 실패"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "%{msg} 활성화 실패"
+
 #: src/constants/errors/backup.ts:38
 #, fuzzy
 msgid "Failed to verify hashes: {0}"

+ 20 - 0
app/src/language/messages.pot

@@ -1495,6 +1495,10 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr ""
 
+#: src/constants/errors/docker.ts:13
+msgid "Failed to create temp container: {0}"
+msgstr ""
+
 #: src/constants/errors/backup.ts:2
 msgid "Failed to create temporary directory"
 msgstr ""
@@ -1599,6 +1603,10 @@ msgstr ""
 msgid "Failed to get certificate information"
 msgstr ""
 
+#: src/constants/errors/docker.ts:10
+msgid "Failed to get hostname: {0}"
+msgstr ""
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 msgid "Failed to get Nginx performance settings"
 msgstr ""
@@ -1611,6 +1619,10 @@ msgstr ""
 msgid "Failed to inspect container: {0}"
 msgstr ""
 
+#: src/constants/errors/docker.ts:12
+msgid "Failed to inspect current container: {0}"
+msgstr ""
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 msgid "Failed to load history records"
 msgstr ""
@@ -1631,6 +1643,10 @@ msgstr ""
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+msgid "Failed to pull image: {0}"
+msgstr ""
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr ""
@@ -1671,6 +1687,10 @@ msgstr ""
 msgid "Failed to save Nginx performance settings"
 msgstr ""
 
+#: src/constants/errors/docker.ts:14
+msgid "Failed to start temp container: {0}"
+msgstr ""
+
 #: src/constants/errors/backup.ts:38
 msgid "Failed to verify hashes: {0}"
 msgstr ""

+ 25 - 0
app/src/language/ru_RU/app.po

@@ -1585,6 +1585,11 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr "Не удалось включить %{msg}"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "Не удалось включить %{msg}"
+
 #: src/constants/errors/backup.ts:2
 #, fuzzy
 msgid "Failed to create temporary directory"
@@ -1707,6 +1712,11 @@ msgstr "Не удалось получить информацию о серти
 msgid "Failed to get certificate information"
 msgstr "Не удалось получить информацию о сертификате"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "Не удалось включить %{msg}"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 #, fuzzy
 msgid "Failed to get Nginx performance settings"
@@ -1722,6 +1732,11 @@ msgstr "Не удалось получить информацию о серти
 msgid "Failed to inspect container: {0}"
 msgstr "Не удалось включить %{msg}"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "Не удалось включить %{msg}"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 #, fuzzy
 msgid "Failed to load history records"
@@ -1746,6 +1761,11 @@ msgstr "Не удалось включить %{msg}"
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "Не удалось включить %{msg}"
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr ""
@@ -1791,6 +1811,11 @@ msgstr "Не удалось получить сертификат"
 msgid "Failed to save Nginx performance settings"
 msgstr "Не удалось получить информацию о сертификате"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "Не удалось включить %{msg}"
+
 #: src/constants/errors/backup.ts:38
 #, fuzzy
 msgid "Failed to verify hashes: {0}"

+ 25 - 0
app/src/language/tr_TR/app.po

@@ -1618,6 +1618,11 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr "Etkinleştirilemedi %{msg}"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "Etkinleştirilemedi %{msg}"
+
 #: src/constants/errors/backup.ts:2
 #, fuzzy
 msgid "Failed to create temporary directory"
@@ -1740,6 +1745,11 @@ msgstr "Sertifika bilgileri alınamadı"
 msgid "Failed to get certificate information"
 msgstr "Sertifika bilgileri alınamadı"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "Etkinleştirilemedi %{msg}"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 #, fuzzy
 msgid "Failed to get Nginx performance settings"
@@ -1755,6 +1765,11 @@ msgstr "Sertifika bilgileri alınamadı"
 msgid "Failed to inspect container: {0}"
 msgstr "Etkinleştirilemedi %{msg}"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "Etkinleştirilemedi %{msg}"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 #, fuzzy
 msgid "Failed to load history records"
@@ -1779,6 +1794,11 @@ msgstr "Etkinleştirilemedi %{msg}"
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "Etkinleştirilemedi %{msg}"
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr ""
@@ -1824,6 +1844,11 @@ msgstr "Sertifika alınamadı"
 msgid "Failed to save Nginx performance settings"
 msgstr "Sertifika bilgileri alınamadı"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "Etkinleştirilemedi %{msg}"
+
 #: src/constants/errors/backup.ts:38
 #, fuzzy
 msgid "Failed to verify hashes: {0}"

+ 20 - 0
app/src/language/uk_UA/app.po

@@ -1507,6 +1507,10 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr ""
 
+#: src/constants/errors/docker.ts:13
+msgid "Failed to create temp container: {0}"
+msgstr ""
+
 #: src/constants/errors/backup.ts:2
 msgid "Failed to create temporary directory"
 msgstr ""
@@ -1611,6 +1615,10 @@ msgstr ""
 msgid "Failed to get certificate information"
 msgstr ""
 
+#: src/constants/errors/docker.ts:10
+msgid "Failed to get hostname: {0}"
+msgstr ""
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 msgid "Failed to get Nginx performance settings"
 msgstr ""
@@ -1623,6 +1631,10 @@ msgstr ""
 msgid "Failed to inspect container: {0}"
 msgstr ""
 
+#: src/constants/errors/docker.ts:12
+msgid "Failed to inspect current container: {0}"
+msgstr ""
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 msgid "Failed to load history records"
 msgstr ""
@@ -1643,6 +1655,10 @@ msgstr ""
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+msgid "Failed to pull image: {0}"
+msgstr ""
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr ""
@@ -1683,6 +1699,10 @@ msgstr ""
 msgid "Failed to save Nginx performance settings"
 msgstr ""
 
+#: src/constants/errors/docker.ts:14
+msgid "Failed to start temp container: {0}"
+msgstr ""
+
 #: src/constants/errors/backup.ts:38
 msgid "Failed to verify hashes: {0}"
 msgstr ""

+ 25 - 0
app/src/language/vi_VN/app.po

@@ -1634,6 +1634,11 @@ msgstr ""
 msgid "Failed to create symbolic link: {0}"
 msgstr "Không thể bật %{msg}"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "Không thể bật %{msg}"
+
 #: src/constants/errors/backup.ts:2
 #, fuzzy
 msgid "Failed to create temporary directory"
@@ -1756,6 +1761,11 @@ msgstr "Không thể truy xuất thông tin chứng chỉ"
 msgid "Failed to get certificate information"
 msgstr "Không thể truy xuất thông tin chứng chỉ"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "Không thể bật %{msg}"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 #, fuzzy
 msgid "Failed to get Nginx performance settings"
@@ -1771,6 +1781,11 @@ msgstr "Không thể truy xuất thông tin chứng chỉ"
 msgid "Failed to inspect container: {0}"
 msgstr "Không thể bật %{msg}"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "Không thể bật %{msg}"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 #, fuzzy
 msgid "Failed to load history records"
@@ -1795,6 +1810,11 @@ msgstr "Không thể bật %{msg}"
 msgid "Failed to parse nginx.conf"
 msgstr ""
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "Không thể bật %{msg}"
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr ""
@@ -1840,6 +1860,11 @@ msgstr "Nhận chứng chỉ"
 msgid "Failed to save Nginx performance settings"
 msgstr "Không thể truy xuất thông tin chứng chỉ"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "Không thể bật %{msg}"
+
 #: src/constants/errors/backup.ts:38
 #, fuzzy
 msgid "Failed to verify hashes: {0}"

+ 40 - 26
app/src/language/zh_CN/app.po

@@ -3,7 +3,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "POT-Creation-Date: \n"
-"PO-Revision-Date: 2025-04-19 14:14+0800\n"
+"PO-Revision-Date: 2025-04-21 14:19+0800\n"
 "Last-Translator: 0xJacky <me@jackyu.cn>\n"
 "Language-Team: Chinese (Simplified Han script) <https://weblate.nginxui.com/"
 "projects/nginx-ui/frontend/zh_Hans/>\n"
@@ -679,7 +679,7 @@ msgstr "命令"
 
 #: src/constants/errors/docker.ts:6
 msgid "Command exited with unexpected exit code: {0}, error: {1}"
-msgstr ""
+msgstr "命令以意外退出代码退出:{0},错误:{1}"
 
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
 #: src/components/NgxConfigEditor/LocationEditor.vue:104
@@ -758,7 +758,7 @@ msgstr "连接超时时间"
 
 #: src/constants/errors/docker.ts:7
 msgid "Container status unknown"
-msgstr ""
+msgstr "未知容器状态"
 
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
 #: src/components/NgxConfigEditor/LocationEditor.vue:116
@@ -1168,7 +1168,7 @@ msgstr "你想删除这个 Upstream 吗?"
 
 #: src/constants/errors/docker.ts:2
 msgid "Docker client not initialized"
-msgstr ""
+msgstr "Docker 客户端未初始化"
 
 #: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
 #: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
@@ -1428,9 +1428,8 @@ msgid "Fail to obtain certificate"
 msgstr "获取证书失败"
 
 #: src/constants/errors/docker.ts:4
-#, fuzzy
 msgid "Failed to attach to exec instance: {0}"
-msgstr "解压缩失败:{0}"
+msgstr "连接执行实例失败:{0}"
 
 #: src/constants/errors/backup.ts:5
 msgid "Failed to backup Nginx config files: {0}"
@@ -1508,6 +1507,10 @@ msgstr "创建还原目录失败:{0}"
 msgid "Failed to create symbolic link: {0}"
 msgstr "创建符号链接失败:{0}"
 
+#: src/constants/errors/docker.ts:13
+msgid "Failed to create temp container: {0}"
+msgstr "创建临时容器失败:{0}"
+
 #: src/constants/errors/backup.ts:2
 msgid "Failed to create temporary directory"
 msgstr "创建临时目录失败"
@@ -1593,9 +1596,8 @@ msgid "Failed to evaluate symbolic links: {0}"
 msgstr "符号链接解析失败:{0}"
 
 #: src/constants/errors/docker.ts:3
-#, fuzzy
 msgid "Failed to exec command: {0}"
-msgstr "读取文件失败:{0}"
+msgstr "执行命令失败:{0}"
 
 #: src/constants/errors/backup.ts:35
 msgid "Failed to extract archive: {0}"
@@ -1613,6 +1615,10 @@ msgstr "生成初始化向量失败:{0}"
 msgid "Failed to get certificate information"
 msgstr "获取证书信息失败"
 
+#: src/constants/errors/docker.ts:10
+msgid "Failed to get hostname: {0}"
+msgstr "获取主机名失败: {0}"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 msgid "Failed to get Nginx performance settings"
 msgstr "获取 Nginx 性能参数失败"
@@ -1622,9 +1628,12 @@ msgid "Failed to get performance data"
 msgstr "获取性能数据失败"
 
 #: src/constants/errors/docker.ts:8
-#, fuzzy
 msgid "Failed to inspect container: {0}"
-msgstr "复制文件内容失败:{0}"
+msgstr "检查容器失败:{0}"
+
+#: src/constants/errors/docker.ts:12
+msgid "Failed to inspect current container: {0}"
+msgstr "检查当前容器失败:{0}"
 
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 msgid "Failed to load history records"
@@ -1646,6 +1655,10 @@ msgstr "打开压缩文件失败:{0}"
 msgid "Failed to parse nginx.conf"
 msgstr "解析 nginx.conf 失败"
 
+#: src/constants/errors/docker.ts:11
+msgid "Failed to pull image: {0}"
+msgstr "拉取镜像失败:{0}"
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr "读取加密文件失败:{0}"
@@ -1663,9 +1676,8 @@ msgid "Failed to read nginx.conf"
 msgstr "读取 nginx.conf 失败"
 
 #: src/constants/errors/docker.ts:5
-#, fuzzy
 msgid "Failed to read output: {0}"
-msgstr "读取文件失败:{0}"
+msgstr "读取输出失败:{0}"
 
 #: src/constants/errors/backup.ts:21
 msgid "Failed to read symlink: {0}"
@@ -1687,6 +1699,10 @@ msgstr "证书撤销失败"
 msgid "Failed to save Nginx performance settings"
 msgstr "保存 Nginx 性能参数失败"
 
+#: src/constants/errors/docker.ts:14
+msgid "Failed to start temp container: {0}"
+msgstr "启动临时容器失败:{0}"
+
 #: src/constants/errors/backup.ts:38
 msgid "Failed to verify hashes: {0}"
 msgstr "验证哈希值失败:{0}"
@@ -2535,9 +2551,8 @@ msgid "Nginx is not running"
 msgstr "Nginx 未启动"
 
 #: src/constants/errors/docker.ts:9
-#, fuzzy
 msgid "Nginx is not running in another container"
-msgstr "Nginx 未启动"
+msgstr "Nginx 未在另一个容器中运行"
 
 #: src/views/dashboard/NginxDashBoard.vue:112
 msgid "Nginx is running"
@@ -3225,9 +3240,8 @@ msgid "Reload Nginx"
 msgstr "重载 Nginx"
 
 #: src/constants/errors/nginx.ts:3
-#, fuzzy
 msgid "Reload nginx failed: {0}"
-msgstr "Nginx 重载失败:{0}"
+msgstr "重载 Nginx 失败: {0}"
 
 #: src/components/Notification/notifications.ts:10
 msgid "Reload Nginx on %{node} failed, response: %{resp}"
@@ -3653,19 +3667,19 @@ msgstr "使用 HTTP01 challenge provider"
 
 #: src/constants/errors/nginx_log.ts:8
 msgid ""
-"Settings.NginxLogSettings.AccessLogPath is empty, refer to https://nginxui."
-"com/guide/config-nginx.html for more information"
+"Settings.NginxLogSettings.AccessLogPath is empty, refer to https://"
+"nginxui.com/guide/config-nginx.html for more information"
 msgstr ""
-"Settings.NginxLogSettings.AccessLogPath 为空,更多信息请参阅 https://nginxui."
-"com/guide/config-nginx.html"
+"Settings.NginxLogSettings.AccessLogPath 为空,更多信息请参阅 https://"
+"nginxui.com/guide/config-nginx.html"
 
 #: src/constants/errors/nginx_log.ts:7
 msgid ""
-"Settings.NginxLogSettings.ErrorLogPath is empty, refer to https://nginxui."
-"com/guide/config-nginx.html for more information"
+"Settings.NginxLogSettings.ErrorLogPath is empty, refer to https://"
+"nginxui.com/guide/config-nginx.html for more information"
 msgstr ""
-"Settings.NginxLogSettings.ErrorLogPath为空,更多信息请参阅 https://nginxui."
-"com/guide/config-nginx.html"
+"Settings.NginxLogSettings.ErrorLogPath为空,更多信息请参阅 https://"
+"nginxui.com/guide/config-nginx.html"
 
 #: src/views/dashboard/components/ParamsOpt/ProxyCacheConfig.vue:147
 msgid "Shared Memory Zone"
@@ -4682,8 +4696,8 @@ msgstr "你的 Passkeys"
 #~ msgstr "请将远程 Nginx UI 升级到最新版本"
 
 #~ msgid ""
-#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
-#~ "%{resp}"
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %"
+#~ "{resp}"
 #~ msgstr ""
 #~ "将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path} 失败,响应:%{resp}"
 

+ 25 - 0
app/src/language/zh_TW/app.po

@@ -1518,6 +1518,11 @@ msgstr "無法建立還原目錄:{0}"
 msgid "Failed to create symbolic link: {0}"
 msgstr "建立符號連結失敗:{0}"
 
+#: src/constants/errors/docker.ts:13
+#, fuzzy
+msgid "Failed to create temp container: {0}"
+msgstr "無法建立壓縮項目:{0}"
+
 #: src/constants/errors/backup.ts:2
 msgid "Failed to create temporary directory"
 msgstr "無法建立臨時目錄"
@@ -1623,6 +1628,11 @@ msgstr "無法生成初始化向量:{0}"
 msgid "Failed to get certificate information"
 msgstr "取得憑證資訊失敗"
 
+#: src/constants/errors/docker.ts:10
+#, fuzzy
+msgid "Failed to get hostname: {0}"
+msgstr "複製檔案內容失敗:{0}"
+
 #: src/views/dashboard/components/ParamsOptimization.vue:61
 msgid "Failed to get Nginx performance settings"
 msgstr "無法取得 Nginx 效能設定"
@@ -1636,6 +1646,11 @@ msgstr "無法取得效能資料"
 msgid "Failed to inspect container: {0}"
 msgstr "複製檔案內容失敗:{0}"
 
+#: src/constants/errors/docker.ts:12
+#, fuzzy
+msgid "Failed to inspect current container: {0}"
+msgstr "複製檔案內容失敗:{0}"
+
 #: src/components/ConfigHistory/ConfigHistory.vue:77
 msgid "Failed to load history records"
 msgstr "無法載入歷史記錄"
@@ -1656,6 +1671,11 @@ msgstr "無法開啟壓縮檔:{0}"
 msgid "Failed to parse nginx.conf"
 msgstr "解析 nginx.conf 失敗"
 
+#: src/constants/errors/docker.ts:11
+#, fuzzy
+msgid "Failed to pull image: {0}"
+msgstr "讀取檔案失敗:{0}"
+
 #: src/constants/errors/backup.ts:53
 msgid "Failed to read encrypted file: {0}"
 msgstr "無法讀取加密檔案:{0}"
@@ -1697,6 +1717,11 @@ msgstr "撤銷憑證失敗"
 msgid "Failed to save Nginx performance settings"
 msgstr "儲存 Nginx 效能設定失敗"
 
+#: src/constants/errors/docker.ts:14
+#, fuzzy
+msgid "Failed to start temp container: {0}"
+msgstr "複製檔案內容失敗:{0}"
+
 #: src/constants/errors/backup.ts:38
 msgid "Failed to verify hashes: {0}"
 msgstr "無法驗證雜湊值:{0}"

+ 3 - 2
internal/cmd/main.go

@@ -26,10 +26,11 @@ func NewAppCmd() *cli.Command {
 				},
 			},
 			{
-				Name:  "reset-password",
-				Usage: "Reset the initial user password",
+				Name:   "reset-password",
+				Usage:  "Reset the initial user password",
 				Action: user.ResetInitUserPassword,
 			},
+			UpgradeDockerStep2Command,
 		},
 		Flags: []cli.Flag{
 			&cli.StringFlag{

+ 23 - 0
internal/cmd/upgrade_docker.go

@@ -0,0 +1,23 @@
+package cmd
+
+import (
+	"context"
+
+	"github.com/0xJacky/Nginx-UI/internal/docker"
+	"github.com/uozi-tech/cosy/logger"
+	"github.com/urfave/cli/v3"
+)
+
+// Command to be executed in the temporary container
+var UpgradeDockerStep2Command = &cli.Command{
+	Name:   "upgrade-docker-step2",
+	Usage:  "Execute the second step of Docker container upgrade (to be run inside the temp container)",
+	Action: UpgradeDockerStep2,
+}
+
+// UpgradeDockerStep2 executes the second step in the temporary container
+func UpgradeDockerStep2(ctx context.Context, command *cli.Command) error {
+	logger.Info("Starting Docker OTA upgrade step 2 from CLI...")
+
+	return docker.UpgradeStepTwo(ctx)
+}

+ 5 - 0
internal/docker/errors.go

@@ -12,4 +12,9 @@ var (
 	ErrContainerStatusUnknown            = e.New(500006, "container status unknown")
 	ErrInspectContainer                  = e.New(500007, "failed to inspect container: {0}")
 	ErrNginxNotRunningInAnotherContainer = e.New(500008, "nginx is not running in another container")
+	ErrFailedToGetHostname               = e.New(500009, "failed to get hostname: {0}")
+	ErrFailedToPullImage                 = e.New(500010, "failed to pull image: {0}")
+	ErrFailedToInspectCurrentContainer   = e.New(500011, "failed to inspect current container: {0}")
+	ErrFailedToCreateTempContainer       = e.New(500012, "failed to create temp container: {0}")
+	ErrFailedToStartTempContainer        = e.New(500013, "failed to start temp container: {0}")
 )

+ 329 - 0
internal/docker/ota.go

@@ -0,0 +1,329 @@
+package docker
+
+import (
+	"context"
+	"fmt"
+	"io"
+	"os"
+	"strings"
+	"time"
+
+	"github.com/0xJacky/Nginx-UI/internal/upgrader"
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/image"
+	"github.com/docker/docker/client"
+	"github.com/pkg/errors"
+	"github.com/uozi-tech/cosy"
+	"github.com/uozi-tech/cosy/logger"
+)
+
+const (
+	ImageName  = "uozi/nginx-ui"
+	TempPrefix = "nginx-ui-temp-"
+	OldSuffix  = "_old"
+)
+
+// getTimestampedTempName returns a temporary container name with timestamp
+func getTimestampedTempName() string {
+	return fmt.Sprintf("%s%d", TempPrefix, time.Now().Unix())
+}
+
+// removeAllTempContainers removes all containers with the TempPrefix
+func removeAllTempContainers(ctx context.Context, cli *client.Client) (err error) {
+	containers, err := cli.ContainerList(ctx, container.ListOptions{All: true})
+	if err != nil {
+		return
+	}
+
+	for _, c := range containers {
+		for _, name := range c.Names {
+			processedName := strings.TrimPrefix(name, "/")
+			if strings.HasPrefix(processedName, TempPrefix) {
+				err = cli.ContainerRemove(ctx, c.ID, container.RemoveOptions{Force: true})
+				if err != nil {
+					logger.Error("Failed to remove temp container:", err)
+				} else {
+					logger.Info("Successfully removed temp container:", processedName)
+				}
+				break
+			}
+		}
+	}
+
+	return nil
+}
+
+// UpgradeStepOne Trigger in the OTA upgrade
+func UpgradeStepOne(channel string) (err error) {
+	ctx := context.Background()
+
+	// 1. Get the tag of the latest release
+	release, err := upgrader.GetRelease(channel)
+	if err != nil {
+		return err
+	}
+	tag := release.TagName
+
+	// 2. Pull the image
+	cli, err := initClient()
+	if err != nil {
+		return cosy.WrapErrorWithParams(ErrClientNotInitialized, err.Error())
+	}
+	defer cli.Close()
+
+	// Pull the image with the specified tag
+	out, err := cli.ImagePull(ctx, fmt.Sprintf("%s:%s", ImageName, tag), image.PullOptions{})
+	if err != nil {
+		return cosy.WrapErrorWithParams(ErrFailedToPullImage, err.Error())
+	}
+	defer out.Close()
+
+	// Wait for pull to complete by reading the output
+	io.Copy(os.Stdout, out)
+
+	// 3. Create a temp container
+	// Clean up any existing temp containers
+	err = removeAllTempContainers(ctx, cli)
+	if err != nil {
+		logger.Error("Failed to clean up existing temp containers:", err)
+		// Continue execution despite cleanup errors
+	}
+
+	// Generate timestamped temp container name
+	tempContainerName := getTimestampedTempName()
+
+	// Get current container name
+	hostname, err := os.Hostname()
+	if err != nil {
+		return cosy.WrapErrorWithParams(ErrFailedToGetHostname, err.Error())
+	}
+	containerInfo, err := cli.ContainerInspect(ctx, hostname)
+	if err != nil {
+		return cosy.WrapErrorWithParams(ErrFailedToInspectCurrentContainer, err.Error())
+	}
+	currentContainerName := strings.TrimPrefix(containerInfo.Name, "/")
+
+	// Set up the command for the temp container to execute step 2
+	upgradeCmd := []string{"./nginx-ui", "upgrade-docker-step2"}
+
+	// Add old container name as environment variable
+	containerEnv := containerInfo.Config.Env
+	containerEnv = append(containerEnv, fmt.Sprintf("NGINX_UI_CONTAINER_NAME=%s", currentContainerName))
+
+	// Create temp container using new image
+	_, err = cli.ContainerCreate(
+		ctx,
+		&container.Config{
+			Image: fmt.Sprintf("%s:%s", ImageName, tag),
+			Cmd:   upgradeCmd, // Use upgrade command instead of original command
+			Env:   containerEnv,
+		},
+		&container.HostConfig{
+			Binds:         containerInfo.HostConfig.Binds,
+			PortBindings:  containerInfo.HostConfig.PortBindings,
+			RestartPolicy: containerInfo.HostConfig.RestartPolicy,
+		},
+		nil,
+		nil,
+		tempContainerName,
+	)
+	if err != nil {
+		return cosy.WrapErrorWithParams(ErrFailedToCreateTempContainer, err.Error())
+	}
+
+	// Start the temp container to execute step 2
+	err = cli.ContainerStart(ctx, tempContainerName, container.StartOptions{})
+	if err != nil {
+		return cosy.WrapErrorWithParams(ErrFailedToStartTempContainer, err.Error())
+	}
+
+	// Output status information
+	logger.Info("Docker OTA upgrade step 1 completed. Temp container started to execute step 2.")
+
+	return nil
+}
+
+// UpgradeStepTwo Trigger in the temp container
+func UpgradeStepTwo(ctx context.Context) (err error) {
+	// 1. Copy the old config
+	cli, err := initClient()
+	if err != nil {
+		return
+	}
+	defer cli.Close()
+
+	// Get old container name from environment variable, fallback to settings if not available
+	currentContainerName := os.Getenv("NGINX_UI_CONTAINER_NAME")
+	if currentContainerName == "" {
+		return errors.New("could not find old container name")
+	}
+	// Get the current running temp container name
+	// Since we can't directly get our own container name from inside, we'll search all temp containers
+	containers, err := cli.ContainerList(ctx, container.ListOptions{All: true})
+	if err != nil {
+		return errors.Wrap(err, "failed to list containers")
+	}
+
+	// Find containers with the temp prefix
+	var tempContainerName string
+	for _, c := range containers {
+		for _, name := range c.Names {
+			processedName := strings.TrimPrefix(name, "/")
+			if strings.HasPrefix(processedName, TempPrefix) {
+				tempContainerName = processedName
+				break
+			}
+		}
+		if tempContainerName != "" {
+			break
+		}
+	}
+
+	if tempContainerName == "" {
+		return errors.New("could not find temp container")
+	}
+
+	// Get temp container info to get the new image
+	tempContainerInfo, err := cli.ContainerInspect(ctx, tempContainerName)
+	if err != nil {
+		return errors.Wrap(err, "failed to inspect temp container")
+	}
+	newImage := tempContainerInfo.Config.Image
+
+	// Get current container info
+	oldContainerInfo, err := cli.ContainerInspect(ctx, currentContainerName)
+	if err != nil {
+		return errors.Wrap(err, "failed to inspect current container")
+	}
+
+	// 2. Stop the old container and rename to _old
+	err = cli.ContainerStop(ctx, currentContainerName, container.StopOptions{})
+	if err != nil {
+		return errors.Wrap(err, "failed to stop current container")
+	}
+
+	// Rename the old container with _old suffix
+	err = cli.ContainerRename(ctx, currentContainerName, currentContainerName+OldSuffix)
+	if err != nil {
+		return errors.Wrap(err, "failed to rename old container")
+	}
+
+	// 3. Use the old config to create and start a new container with the updated image
+	// Create new container with original config but using the new image
+	newContainerEnv := oldContainerInfo.Config.Env
+	// Pass the old container name to the new container
+	newContainerEnv = append(newContainerEnv, fmt.Sprintf("NGINX_UI_CONTAINER_NAME=%s", currentContainerName))
+
+	_, err = cli.ContainerCreate(
+		ctx,
+		&container.Config{
+			Image:        newImage,
+			Cmd:          oldContainerInfo.Config.Cmd,
+			Env:          newContainerEnv,
+			Entrypoint:   oldContainerInfo.Config.Entrypoint,
+			Labels:       oldContainerInfo.Config.Labels,
+			ExposedPorts: oldContainerInfo.Config.ExposedPorts,
+			Volumes:      oldContainerInfo.Config.Volumes,
+			WorkingDir:   oldContainerInfo.Config.WorkingDir,
+		},
+		&container.HostConfig{
+			Binds:         oldContainerInfo.HostConfig.Binds,
+			PortBindings:  oldContainerInfo.HostConfig.PortBindings,
+			RestartPolicy: oldContainerInfo.HostConfig.RestartPolicy,
+			NetworkMode:   oldContainerInfo.HostConfig.NetworkMode,
+			Mounts:        oldContainerInfo.HostConfig.Mounts,
+			Privileged:    oldContainerInfo.HostConfig.Privileged,
+		},
+		nil,
+		nil,
+		currentContainerName,
+	)
+	if err != nil {
+		// If creation fails, try to recover
+		recoverErr := cli.ContainerRename(ctx, currentContainerName+OldSuffix, currentContainerName)
+		if recoverErr == nil {
+			// Start old container
+			recoverErr = cli.ContainerStart(ctx, currentContainerName, container.StartOptions{})
+			if recoverErr == nil {
+				return errors.Wrap(err, "failed to create new container, recovered to old container")
+			}
+		}
+		return errors.Wrap(err, "failed to create new container and failed to recover")
+	}
+
+	// Start the new container
+	err = cli.ContainerStart(ctx, currentContainerName, container.StartOptions{})
+	if err != nil {
+		// If startup fails, try to recover
+		// First remove the failed new container
+		removeErr := cli.ContainerRemove(ctx, currentContainerName, container.RemoveOptions{Force: true})
+		if removeErr != nil {
+			logger.Error("Failed to remove failed new container:", removeErr)
+		}
+
+		// Rename the old container back to original
+		recoverErr := cli.ContainerRename(ctx, currentContainerName+OldSuffix, currentContainerName)
+		if recoverErr == nil {
+			// Start old container
+			recoverErr = cli.ContainerStart(ctx, currentContainerName, container.StartOptions{})
+			if recoverErr == nil {
+				return errors.Wrap(err, "failed to start new container, recovered to old container")
+			}
+		}
+		return errors.Wrap(err, "failed to start new container and failed to recover")
+	}
+
+	logger.Info("Docker OTA upgrade step 2 completed successfully. New container is running.")
+	return nil
+}
+
+// UpgradeStepThree Trigger in the new container
+func UpgradeStepThree() error {
+	ctx := context.Background()
+	// Remove the old container
+	cli, err := initClient()
+	if err != nil {
+		return cosy.WrapErrorWithParams(ErrClientNotInitialized, err.Error())
+	}
+	defer cli.Close()
+
+	// Get old container name from environment variable, fallback to settings if not available
+	currentContainerName := os.Getenv("NGINX_UI_CONTAINER_NAME")
+	if currentContainerName == "" {
+		logger.Warn("Old container name not found in environment, skipping cleanup")
+		return nil
+	}
+	oldContainerName := currentContainerName + OldSuffix
+
+	// Check if old container exists and remove it if it does
+	containers, err := cli.ContainerList(ctx, container.ListOptions{All: true})
+	if err != nil {
+		return errors.Wrap(err, "failed to list containers")
+	}
+
+	for _, c := range containers {
+		for _, name := range c.Names {
+			processedName := strings.TrimPrefix(name, "/")
+			// Remove old container
+			if processedName == oldContainerName {
+				err = cli.ContainerRemove(ctx, c.ID, container.RemoveOptions{Force: true})
+				if err != nil {
+					logger.Error("Failed to remove old container:", err)
+					// Continue execution, don't interrupt because of failure to remove old container
+				} else {
+					logger.Info("Successfully removed old container:", oldContainerName)
+				}
+				break
+			}
+		}
+	}
+
+	// Clean up all temp containers
+	err = removeAllTempContainers(ctx, cli)
+	if err != nil {
+		logger.Error("Failed to clean up temp containers:", err)
+		// Continue execution despite cleanup errors
+	}
+
+	return nil
+}

+ 13 - 0
internal/kernel/boot.go

@@ -12,6 +12,7 @@ import (
 	"github.com/0xJacky/Nginx-UI/internal/cert"
 	"github.com/0xJacky/Nginx-UI/internal/cluster"
 	"github.com/0xJacky/Nginx-UI/internal/cron"
+	"github.com/0xJacky/Nginx-UI/internal/docker"
 	"github.com/0xJacky/Nginx-UI/internal/passkey"
 	"github.com/0xJacky/Nginx-UI/internal/validation"
 	"github.com/0xJacky/Nginx-UI/model"
@@ -35,6 +36,7 @@ func Boot() {
 		InitCryptoSecret,
 		validation.Init,
 		cache.Init,
+		CheckAndCleanupOTAContainers,
 	}
 
 	syncs := []func(){
@@ -129,3 +131,14 @@ func InitJsExtensionType() {
 	// See https://github.com/golang/go/issues/32350
 	_ = mime.AddExtensionType(".js", "text/javascript; charset=utf-8")
 }
+
+// CheckAndCleanupOTAContainers Check and cleanup OTA update temporary containers
+func CheckAndCleanupOTAContainers() {
+	// Execute the third step cleanup operation at startup
+	err := docker.UpgradeStepThree()
+	if err != nil {
+		logger.Error("Failed to cleanup OTA containers:", err)
+	} else {
+		logger.Info("OTA container cleanup completed successfully")
+	}
+}