Compare commits

..

15 Commits

Author SHA1 Message Date
55bed44a53 Skip debug log at the beginning 2023-11-21 18:47:50 +08:00
e1dcbdc317 Add inspect to dev:backend 2023-11-21 16:55:23 +08:00
291d9671d8 Improvements 2023-11-21 16:47:01 +08:00
b50b1cc6e1 Trim trailing whitespace (#116) 2023-11-21 13:28:04 +08:00
2e26178d2d feat: Add Translation Guide (#111)
* add README for translations

* add ref in README aswell
2023-11-21 12:15:09 +08:00
6ef861c989 german language added (#101)
Co-authored-by: cellerich <cellerich@cello.ch>
2023-11-21 03:51:32 +08:00
853b43a876 Add Russian language translation (#107) 2023-11-21 03:50:58 +08:00
16a4dd63ac Changed: Readme (#97) 2023-11-21 00:06:31 +08:00
0847a4a0c0 chore: Add Urdu language (#77)
* Update i18n.ts

* Create ur.json

* complete
2023-11-20 23:52:35 +08:00
889f0c133f Added: Bulgarian (#93)
* Added: Bulgarian

Added Bulgarian Language Support.

* Fix: Bulgarian

* Create bg-BG.json

Bulgarian translation
2023-11-20 18:14:00 +08:00
7cff52f614 Added 한국어 (#86) 2023-11-20 13:23:41 +08:00
01398aa498 Added Español and Português (#82)
* Created spanish lang.

* Included Portuguese

* Added missing line of code.
2023-11-20 13:23:08 +08:00
afe0bc561f Added Simplified Chinese (#70)
* Added Simplified Chinese

* Added Simplified Chinese

* Fix a typo
2023-11-20 00:55:00 +08:00
c8770a9605 Improve handling of stack status, close #11 2023-11-20 00:52:33 +08:00
0208684b50 Update a stopped stack, will no longer start the stack 2023-11-20 00:15:37 +08:00
16 changed files with 896 additions and 65 deletions

View File

@ -22,10 +22,10 @@ View Video: https://youtu.be/AWAlOQeNpgU?t=48
- Reactive
- Everything is just responsive. Progress (Pull/Up/Down) and terminal output are in real-time
- Easy-to-use & fancy UI
- If you love Uptime Kuma's UI/UX, you will love this too
- If you love Uptime Kuma's UI/UX, you will love this one too
- Convert `docker run ...` commands into `compose.yaml`
- File based structure
- Dockge won't kidnap your compose files, they stored on your drive as usual. You can interact with them using normal `docker compose` commands
- Dockge won't kidnap your compose files, they are stored on your drive as usual. You can interact with them using normal `docker compose` commands
<img src="https://github.com/louislam/dockge/assets/1336778/cc071864-592e-4909-b73a-343a57494002" width=300 />
@ -37,7 +37,7 @@ Requirements:
- [Docker CE](https://docs.docker.com/engine/install/) 20+ is recommended / Podman
- (Docker only) [Docker Compose Plugin](https://docs.docker.com/compose/install/linux/)
- (Podman only) podman-docker (Debian: `apt install podman-docker`)
- OS:
- OS:
- As long as you can run Docker CE / Podman, it should be fine, but:
- Debian/Raspbian Buster or lower is not supported, please upgrade to Bullseye or higher
- Arch: armv7, arm64, amd64 (a.k.a x86_64)
@ -55,11 +55,11 @@ cd /opt/dockge
# Download the compose.yaml
curl https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml --output compose.yaml
# Start Server
# Start the Server
docker compose up -d
# If you are using docker-compose V1 or Podman
# docker-compose up -d
# docker-compose up -d
```
Dockge is now running on http://localhost:5001
@ -80,7 +80,7 @@ services:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
# If you want to use private registries, you need to share the auth file with Dockge:
# - /root/.docker/:/root/.docker
@ -117,9 +117,9 @@ docker compose up -d
## Motivations
- I have been using Portainer for some time, but for the stack management, I am sometimes not satisfied with it. For example, sometimes when I try to deploy a stack, the loading icon keeps spinning for a few minutes without progress. And sometimes error messages are not clear.
- Try to develop with ES Module + TypeScript (Originally, I planned to use Deno or Bun.js, but they do not support for arm64, so I stepped back to Node.js)
- Try to develop with ES Module + TypeScript (Originally, I planned to use Deno or Bun.js, but they don't have support for arm64, so I stepped back to Node.js)
If you love this project, please consider giving this project a ⭐.
If you love this project, please consider giving it a ⭐.
## 🗣️
@ -130,17 +130,21 @@ https://github.com/louislam/dockge/issues
### Ask for Help / Discussions
https://github.com/louislam/dockge/discussions
## Translation
If you want to translate Dockge into your language, please read [Translation Guide](https://github.com/louislam/dockge/blob/master/frontend/src/lang/README.md)
## FAQ
#### "Dockge"?
"Dockge" is a coinage word which is created by myself. I hope it sounds like `Dodge`.
The naming idea was coming from Twitch emotes like `sadge`, `bedge` or `wokege`. They are all ending with `-ge`.
The naming idea came from Twitch emotes like `sadge`, `bedge` or `wokege`. They all end in `-ge`.
#### Can I manage a single container without `compose.yaml`?
The main objective of Dockge is that try to use docker `compose.yaml` for everything. If you want to manage a single container, you can just use Portainer or Docker CLI.
The main objective of Dockge is to try to use the docker `compose.yaml` for everything. If you want to manage a single container, you can just use Portainer or Docker CLI.
#### Can I manage existing stacks?
@ -164,6 +168,4 @@ Yes, you can. However, you need to move your compose file into the stacks direct
# Others
Dockge is built on top of [Compose V2](https://docs.docker.com/compose/migrate/). `compose.yaml` is also known as `docker-compose.yml`.
Dockge is built on top of [Compose V2](https://docs.docker.com/compose/migrate/). `compose.yaml` also known as `docker-compose.yml`.

View File

@ -103,6 +103,10 @@ class Logger {
* @param level Log level. One of INFO, WARN, ERROR, DEBUG or can be customized.
*/
log(module: string, msg: unknown, level: string) {
if (level === "DEBUG" && !isDev) {
return;
}
if (this.hideLog[level] && this.hideLog[level].includes(module.toLowerCase())) {
return;
}

View File

@ -196,7 +196,7 @@ export class DockerSocketHandler extends SocketHandler {
throw new ValidationError("Stack name must be a string");
}
const stack = Stack.getStack(server, stackName);
const stack = Stack.getStack(server, stackName, true);
const serviceStatusList = Object.fromEntries(await stack.getServiceStatusList());
callback({
ok: true,

View File

@ -31,17 +31,19 @@ export class Stack {
protected static managedStackList: Map<string, Stack> = new Map();
constructor(server : DockgeServer, name : string, composeYAML? : string) {
constructor(server : DockgeServer, name : string, composeYAML? : string, skipFSOperations = false) {
this.name = name;
this.server = server;
this._composeYAML = composeYAML;
// Check if compose file name is different from compose.yaml
const supportedFileNames = [ "compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml" ];
for (const filename of supportedFileNames) {
if (fs.existsSync(path.join(this.path, filename))) {
this._composeFileName = filename;
break;
if (!skipFSOperations) {
// Check if compose file name is different from compose.yaml
const supportedFileNames = [ "compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml" ];
for (const filename of supportedFileNames) {
if (fs.existsSync(path.join(this.path, filename))) {
this._composeFileName = filename;
break;
}
}
}
}
@ -174,6 +176,17 @@ export class Stack {
return exitCode;
}
updateStatus() {
let statusList = Stack.getStatusList();
let status = statusList.get(this.name);
if (status) {
this._status = status;
} else {
this._status = UNKNOWN;
}
}
static getStackList(server : DockgeServer, useCacheForManaged = false) : Map<string, Stack> {
let stacksDir = server.stacksDir;
let stackList : Map<string, Stack>;
@ -253,37 +266,51 @@ export class Stack {
/**
* Convert the status string from `docker compose ls` to the status number
* Input Example: "exited(1), running(1)"
* @param status
*/
static statusConvert(status : string) : number {
if (status.startsWith("created")) {
return CREATED_STACK;
} else if (status.startsWith("running")) {
return RUNNING;
} else if (status.startsWith("exited")) {
} else if (status.includes("exited")) {
// If one of the service is exited, we consider the stack is exited
return EXITED;
} else if (status.startsWith("running")) {
// If there is no exited services, there should be only running services
return RUNNING;
} else {
return UNKNOWN;
}
}
static getStack(server: DockgeServer, stackName: string) : Stack {
static getStack(server: DockgeServer, stackName: string, skipFSOperations = false) : Stack {
let dir = path.join(server.stacksDir, stackName);
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) {
// Maybe it is a stack managed by docker compose directly
let stackList = this.getStackList(server);
let stack = stackList.get(stackName);
if (!skipFSOperations) {
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) {
// Maybe it is a stack managed by docker compose directly
let stackList = this.getStackList(server, true);
let stack = stackList.get(stackName);
if (stack) {
return stack;
} else {
// Really not found
throw new ValidationError("Stack not found");
if (stack) {
return stack;
} else {
// Really not found
throw new ValidationError("Stack not found");
}
}
} else {
log.debug("getStack", "Skip FS operations");
}
let stack : Stack;
if (!skipFSOperations) {
stack = new Stack(server, stackName);
} else {
stack = new Stack(server, stackName, undefined, true);
}
let stack = new Stack(server, stackName);
stack._status = UNKNOWN;
stack._configFilePath = path.resolve(dir);
return stack;
@ -322,6 +349,14 @@ export class Stack {
if (exitCode !== 0) {
throw new Error("Failed to pull, please check the terminal output for more information.");
}
// If the stack is not running, we don't need to restart it
this.updateStatus();
log.debug("update", "Status: " + this.status);
if (this.status !== RUNNING) {
return exitCode;
}
exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", [ "compose", "up", "-d", "--remove-orphans" ], this.path);
if (exitCode !== 0) {
throw new Error("Failed to restart, please check the terminal output for more information.");
@ -355,11 +390,11 @@ export class Stack {
async getServiceStatusList() {
let statusList = new Map<string, number>();
let res = childProcess.execSync("docker compose ps --format json", {
let res = childProcess.spawnSync("docker", [ "compose", "ps", "--format", "json" ], {
cwd: this.path,
});
let lines = res.toString().split("\n");
let lines = res.stdout.toString().split("\n");
for (let line of lines) {
try {

View File

@ -80,37 +80,53 @@ export class Terminal {
return;
}
this._ptyProcess = pty.spawn(this.file, this.args, {
name: this.name,
cwd: this.cwd,
cols: TERMINAL_COLS,
rows: this.rows,
});
try {
this._ptyProcess = pty.spawn(this.file, this.args, {
name: this.name,
cwd: this.cwd,
cols: TERMINAL_COLS,
rows: this.rows,
});
// On Data
this._ptyProcess.onData((data) => {
this.buffer.pushItem(data);
if (this.server.io) {
this.server.io.to(this.name).emit("terminalWrite", this.name, data);
// On Data
this._ptyProcess.onData((data) => {
this.buffer.pushItem(data);
if (this.server.io) {
this.server.io.to(this.name).emit("terminalWrite", this.name, data);
}
});
// On Exit
this._ptyProcess.onExit(this.exit);
} catch (error) {
if (error instanceof Error) {
log.error("Terminal", "Failed to start terminal: " + error.message);
const exitCode = Number(error.message.split(" ").pop());
this.exit({
exitCode,
});
}
});
// On Exit
this._ptyProcess.onExit((res) => {
this.server.io.to(this.name).emit("terminalExit", this.name, res.exitCode);
// Remove room
this.server.io.in(this.name).socketsLeave(this.name);
Terminal.terminalMap.delete(this.name);
log.debug("Terminal", "Terminal " + this.name + " exited with code " + res.exitCode);
if (this.callback) {
this.callback(res.exitCode);
}
});
}
}
/**
* Exit event handler
* @param res
*/
protected exit = (res : {exitCode: number, signal?: number | undefined}) => {
this.server.io.to(this.name).emit("terminalExit", this.name, res.exitCode);
// Remove room
this.server.io.in(this.name).socketsLeave(this.name);
Terminal.terminalMap.delete(this.name);
log.debug("Terminal", "Terminal " + this.name + " exited with code " + res.exitCode);
if (this.callback) {
this.callback(res.exitCode);
}
};
public onExit(callback : (exitCode : number) => void) {
this.callback = callback;
}

View File

@ -3,8 +3,16 @@ import { createI18n } from "vue-i18n/dist/vue-i18n.esm-browser.prod.js";
import en from "./lang/en.json";
const languageList = {
"bg-BG": "Български",
"es": "Español",
"de": "Deutsch",
"fr": "Français",
"pt": "Português",
"tr": "Türkçe",
"zh-CN": "简体中文",
"ur": "Urdu",
"ko-KR": "한국어",
"ru": "Русский",
};
let messages = {

View File

@ -0,0 +1,14 @@
# Translations
A simple guide on how to translate `Dockge` in your native language.
## How to add a new language in the dropdown
(11-21-2023) Updated
1. Add your Language at `frontend/src/lang/` by creating a new file with your language Code, format: `zh-TW.json` .
2. Copy the content from `en.json` and make translations from that.
3. Add your language at the end of `languageList` in `frontend/src/i18n.ts`, format: `"zh-TW": "繁體中文 (台灣)"`,
4. Commit to new branch and make a new Pull Request for me to approve.
*Note:* Currently we are only accepting one Pull Request per Language Translate.

View File

@ -0,0 +1,94 @@
{
"languageName": "Български",
"Create your admin account": "Създайте администраторски профил",
"authIncorrectCreds": "Грешно име или парола.",
"PasswordsDoNotMatch": "Паролите не съвпадат.",
"Repeat Password": "Повторете паролата",
"Create": "Създай",
"signedInDisp": "Вписан като {0}",
"signedInDispDisabled": "Удостоверяването е изключено.",
"home": "Начало",
"console": "Конзола",
"registry": "Регистър",
"compose": "Compose",
"addFirstStackMsg": "Създайте вашия първи стак!",
"stackName" : "Име на стак",
"deployStack": "Разположи",
"deleteStack": "Изтрий",
"stopStack": "Спри",
"restartStack": "Рестартирай",
"updateStack": "Актуализирай",
"startStack": "Стартирай",
"editStack": "Редактирай",
"discardStack": "Отхвърли",
"saveStackDraft": "Запази",
"notAvailableShort" : "N/A",
"deleteStackMsg": "Сигурни ли сте, че желаете да изтриете този стак?",
"stackNotManagedByDockgeMsg": "Този стак не се управлява от Dockge.",
"primaryHostname": "Основно име на хост",
"general": "Общи",
"container": "Контейнер | Контейнери",
"scanFolder": "Сканиране папката със стакове",
"dockerImage": "Изображение",
"restartPolicyUnlessStopped": "Докато не бъде спрян",
"restartPolicyAlways": "Винаги",
"restartPolicyOnFailure": "При неуспех",
"restartPolicyNo": "Не",
"environmentVariable": "Променлива на средата | Променливи на средата",
"restartPolicy": "Правила за рестартиране",
"containerName": "Име на контейнер",
"port": "Порт | Портове",
"volume": "Том | Томове",
"network": "Мрежа | Мрежи",
"dependsOn": "Зависимост от контейнер | Зависимост от контейнери",
"addListItem": "Добави {0}",
"deleteContainer": "Изтрий",
"addContainer": "Добави контейнер",
"addNetwork": "Добави мрежа",
"disableauth.message1": "Сигурни ли сте, че желаете да <strong>изключите удостоверяването</strong>?",
"disableauth.message2": "Използва се в случаите, <strong>когато има настроен алтернативен метод за удостоверяване</strong> преди Dockge, например Cloudflare Access, Authelia или друг механизъм за удостоверяване.",
"passwordNotMatchMsg": "Повторената парола не съвпада.",
"autoGet": "Автоматично получаване",
"add": "Добави",
"Edit": "Редактирай",
"applyToYAML": "Приложи към YAML",
"createExternalNetwork": "Създай",
"addInternalNetwork": "Добави",
"Save": "Запиши",
"Language": "Език",
"Current User": "Текущ потребител",
"Change Password": "Промени парола",
"Current Password": "Текуща парола",
"New Password": "Нова парола",
"Repeat New Password": "Повторете новата парола",
"Update Password": "Актуализирай парола",
"Advanced": "Разширени",
"Please use this option carefully!": "Моля, използвайте с повишено внимание!",
"Enable Auth": "Включи удостоверяване",
"Disable Auth": "Изключи удостоверяване",
"I understand, please disable": "Разбирам. Моля, изключи",
"Leave": "Напусни",
"Frontend Version": "Фронтенд версия",
"Check Update On GitHub": "Проверка за актуализация в GitHub",
"Show update if available": "Покажи актуализация, ако е налична",
"Also check beta release": "Проверявай и за бета версии",
"Remember me": "Запомни ме",
"Login": "Вписване",
"Username": "Потребител",
"Password": "Парола",
"Settings": "Настройки",
"Logout": "Изход",
"Lowercase only": "Само малки букви",
"Convert to Compose": "Конвертирай в \"Compose\" формат",
"Docker Run": "Стартирай Docker",
"active": "активен",
"exited": "излязъл",
"inactive": "неактивен",
"Appearance": "Изглед",
"Security": "Сигурност",
"About": "Относно",
"Allowed commands:": "Позволени команди:",
"Internal Networks": "Вътрешни мрежи",
"External Networks": "Външни мрежи",
"No External Networks": "Не са налични външни мрежи"
}

94
frontend/src/lang/de.json Normal file
View File

@ -0,0 +1,94 @@
{
"languageName": "Deutsch",
"Create your admin account": "Erstelle dein Admin-Konto",
"authIncorrectCreds": "Falscher Benutzername oder falsches Passwort.",
"PasswordsDoNotMatch": "Passwörter stimmen nicht überein.",
"Repeat Password": "Passwort wiederholen",
"Create": "Erstellen",
"signedInDisp": "Angemeldet als {0}",
"signedInDispDisabled": "Authentifizierung deaktiviert.",
"home": "Startseite",
"console": "Konsole",
"registry": "Register",
"compose": "Zusammenstellen",
"addFirstStackMsg": "Stelle deinen ersten Stack zusammen!",
"stackName" : "Stack-Name",
"deployStack": "Bereitstellen",
"deleteStack": "Löschen",
"stopStack": "Anhalten",
"restartStack": "Neustarten",
"updateStack": "Aktualisieren",
"startStack": "Starten",
"editStack": "Bearbeiten",
"discardStack": "Verwerfen",
"saveStackDraft": "Speichern",
"notAvailableShort" : "N/A",
"deleteStackMsg": "Möchtest du diesen Stack wirklich löschen?",
"stackNotManagedByDockgeMsg": "Dieser Stack wird nicht von Dockge verwaltet.",
"primaryHostname": "Primärer Hostname",
"general": "Allgemein",
"container": "Container | Container",
"scanFolder": "Stacks-Ordner durchsuchen",
"dockerImage": "Image",
"restartPolicyUnlessStopped": "Falls nicht gestoppt",
"restartPolicyAlways": "Immer",
"restartPolicyOnFailure": "Bei Fehler",
"restartPolicyNo": "Kein Neustart",
"environmentVariable": "Umgebungsvariable | Umgebungsvariablen",
"restartPolicy": "Neustart Richtlinie",
"containerName": "Container-Name",
"port": "Port | Ports",
"volume": "Volume | Volumes",
"network": "Netzwerk | Netzwerke",
"dependsOn": "Container-Abhängigkeit | Container-Abhängigkeiten",
"addListItem": "{0} hinzufügen",
"deleteContainer": "Löschen",
"addContainer": "Container hinzufügen",
"addNetwork": "Netzwerk hinzufügen",
"disableauth.message1": "Bist du sicher, dass du die <strong>Authentifizierung deaktivieren</strong> möchtest?",
"disableauth.message2": "Es ist für Szenarien vorgesehen, <strong>in denen du beabsichtigst, eine Drittanbieter-Authentifizierung</strong> vor Dockge zu implementieren, wie zum Beispiel Cloudflare Access, Authelia oder andere Authentifizierungsmechanismen.",
"passwordNotMatchMsg": "Das wiederholte Passwort stimmt nicht überein.",
"autoGet": "Automatisch holen",
"add": "Hinzufügen",
"Edit": "Bearbeiten",
"applyToYAML": "Auf YAML anwenden",
"createExternalNetwork": "Erstellen",
"addInternalNetwork": "Hinzufügen",
"Save": "Speichern",
"Language": "Sprache",
"Current User": "Aktueller Benutzer",
"Change Password": "Passwort ändern",
"Current Password": "Aktuelles Passwort",
"New Password": "Neues Passwort",
"Repeat New Password": "Neues Passwort wiederholen",
"Update Password": "Passwort aktualisieren",
"Advanced": "Erweitert",
"Please use this option carefully!": "Bitte verwende diese Option sorgfältig!",
"Enable Auth": "Authentifizierung aktivieren",
"Disable Auth": "Authentifizierung deaktivieren",
"I understand, please disable": "Ich verstehe, bitte deaktivieren",
"Leave": "Verlassen",
"Frontend Version": "Frontend Version",
"Check Update On GitHub": "Update auf GitHub überprüfen",
"Show update if available": "Update anzeigen, wenn verfügbar",
"Also check beta release": "Auch Beta-Version überprüfen",
"Remember me": "Anmeldung beibehalten",
"Login": "Anmelden",
"Username": "Benutzername",
"Password": "Passwort",
"Settings": "Einstellungen",
"Logout": "Abmelden",
"Lowercase only": "Nur Kleinbuchstaben",
"Convert to Compose": "In Compose Syntax umwandeln",
"Docker Run": "Docker ausführen",
"active": "aktiv",
"exited": "beendet",
"inactive": "inaktiv",
"Appearance": "Erscheinungsbild",
"Security": "Sicherheit",
"About": "Über",
"Allowed commands:": "Zugelassene Befehle:",
"Internal Networks": "Interne Netzwerke",
"External Networks": "Externe Netzwerke",
"No External Networks": "Keine externen Netzwerke"
}

94
frontend/src/lang/es.json Normal file
View File

@ -0,0 +1,94 @@
{
"languageName": "Español",
"Create your admin account": "Crea tu cuenta de administrador",
"authIncorrectCreds": "Nombre de usuario o contraseña incorrectos.",
"PasswordsDoNotMatch": "Las contraseñas no coinciden.",
"Repeat Password": "Repetir Contraseña",
"Create": "Crear",
"signedInDisp": "Sesión iniciada como {0}",
"signedInDispDisabled": "Autenticación deshabilitada.",
"home": "Inicio",
"console": "Consola",
"registry": "Registro",
"compose": "Componer",
"addFirstStackMsg": "¡Compón tu primera pila!",
"stackName" : "Nombre de la Pila",
"deployStack": "Desplegar",
"deleteStack": "Eliminar",
"stopStack": "Detener",
"restartStack": "Reiniciar",
"updateStack": "Actualizar",
"startStack": "Iniciar",
"editStack": "Editar",
"discardStack": "Descartar",
"saveStackDraft": "Guardar",
"notAvailableShort" : "N/D",
"deleteStackMsg": "¿Estás seguro de que quieres eliminar esta pila?",
"stackNotManagedByDockgeMsg": "Esta pila no está gestionada por Dockge.",
"primaryHostname": "Nombre de Host Primario",
"general": "General",
"container": "Contenedor | Contenedores",
"scanFolder": "Escanear Carpeta de Pilas",
"dockerImage": "Imagen",
"restartPolicyUnlessStopped": "A menos que se detenga",
"restartPolicyAlways": "Siempre",
"restartPolicyOnFailure": "En caso de fallo",
"restartPolicyNo": "No",
"environmentVariable": "Variable de Entorno | Variables de Entorno",
"restartPolicy": "Política de Reinicio",
"containerName": "Nombre del Contenedor",
"port": "Puerto | Puertos",
"volume": "Volumen | Volúmenes",
"network": "Red | Redes",
"dependsOn": "Dependencia del Contenedor | Dependencias del Contenedor",
"addListItem": "Agregar {0}",
"deleteContainer": "Eliminar",
"addContainer": "Agregar Contenedor",
"addNetwork": "Agregar Red",
"disableauth.message1": "¿Estás seguro de que deseas <strong>desactivar la autenticación</strong>?",
"disableauth.message2": "Está diseñado para escenarios <strong>donde pretendes implementar autenticación de terceros</strong> frente a Dockge, como Cloudflare Access, Authelia u otros mecanismos de autenticación.",
"passwordNotMatchMsg": "La contraseña repetida no coincide.",
"autoGet": "Obtener Automáticamente",
"add": "Agregar",
"Edit": "Editar",
"applyToYAML": "Aplicar a YAML",
"createExternalNetwork": "Crear",
"addInternalNetwork": "Agregar",
"Save": "Guardar",
"Language": "Idioma",
"Current User": "Usuario Actual",
"Change Password": "Cambiar Contraseña",
"Current Password": "Contraseña Actual",
"New Password": "Nueva Contraseña",
"Repeat New Password": "Repetir Nueva Contraseña",
"Update Password": "Actualizar Contraseña",
"Advanced": "Avanzado",
"Please use this option carefully!": "¡Por favor, usa esta opción con cuidado!",
"Enable Auth": "Habilitar Autenticación",
"Disable Auth": "Deshabilitar Autenticación",
"I understand, please disable": "Entiendo, por favor deshabilitar",
"Leave": "Salir",
"Frontend Version": "Versión del Frontend",
"Check Update On GitHub": "Comprobar Actualización en GitHub",
"Show update if available": "Mostrar actualización si está disponible",
"Also check beta release": "También verificar la versión beta",
"Remember me": "Recuérdame",
"Login": "Iniciar Sesión",
"Username": "Nombre de Usuario",
"Password": "Contraseña",
"Settings": "Configuración",
"Logout": "Cerrar Sesión",
"Lowercase only": "Solo minúsculas",
"Convert to Compose": "Convertir a Compose",
"Docker Run": "Ejecutar Docker",
"active": "activo",
"exited": "finalizado",
"inactive": "inactivo",
"Appearance": "Apariencia",
"Security": "Seguridad",
"About": "Acerca de",
"Allowed commands:": "Comandos permitidos:",
"Internal Networks": "Redes Internas",
"External Networks": "Redes Externas",
"No External Networks": "Sin Redes Externas"
}

View File

@ -0,0 +1,94 @@
{
"languageName": "한국어",
"Create your admin account": "관리자 계정 만들기",
"authIncorrectCreds": "사용자명 또는 비밀번호가 일치하지 않아요.",
"PasswordsDoNotMatch": "비밀번호가 일치하지 않아요.",
"Repeat Password": "비밀번호 재입력",
"Create": "생성",
"signedInDisp": "{0}(으)로 로그인됨",
"signedInDispDisabled": "인증 비활성화됨.",
"home": "홈",
"console": "콘솔",
"registry": "레지스트리",
"compose": "생성",
"addFirstStackMsg": "첫 번째 스택을 만들어 보세요!",
"stackName": "스택 이름",
"deployStack": "배포",
"deleteStack": "삭제",
"stopStack": "정지",
"restartStack": "재시작",
"updateStack": "업데이트",
"startStack": "시작",
"editStack": "수정",
"discardStack": "취소",
"saveStackDraft": "저장",
"notAvailableShort": "N/A",
"deleteStackMsg": "정말로 이 스택을 삭제하시겠습니까?",
"stackNotManagedByDockgeMsg": "이 스택은 Dockge에 의해 관리되지 않아요.",
"primaryHostname": "주 호스트명",
"general": "일반",
"container": "컨테이너",
"scanFolder": "스택 폴더 스캔",
"dockerImage": "이미지",
"restartPolicyUnlessStopped": "종료되기 전까지",
"restartPolicyAlways": "항상",
"restartPolicyOnFailure": "오류 발생 시",
"restartPolicyNo": "안 함",
"environmentVariable": "환경 변수",
"restartPolicy": "재시작 정책",
"containerName": "컨테이너 이름",
"port": "포트",
"volume": "볼륨",
"network": "네트워크",
"dependsOn": "컨테이너 의존성",
"addListItem": "{0} 추가",
"deleteContainer": "삭제",
"addContainer": "컨테이너 추가",
"addNetwork": "네트워크 추가",
"disableauth.message1": "정말로 <strong>인증을 비활성화</strong>하시겠습니까?",
"disableauth.message2": "이 기능은 Dockge 앞에 Cloudflare Access, Authelia 등과 같은 <strong>서드 파티 인증을 사용하려는 경우</strong>에 사용하기 위해서 만들어졌어요.",
"passwordNotMatchMsg": "비밀번호 재입력이 일치하지 않아요..",
"autoGet": "자동으로 가져오기",
"add": "추가",
"Edit": "수정",
"applyToYAML": "YAML에 적용",
"createExternalNetwork": "생성",
"addInternalNetwork": "추가",
"Save": "저장",
"Language": "언어",
"Current User": "현재 사용자",
"Change Password": "비밀번호 변경",
"Current Password": "현재 비밀번호",
"New Password": "새 비밀번호",
"Repeat New Password": "새 비밀번호 재입력",
"Update Password": "비밀번호 변경",
"Advanced": "고급",
"Please use this option carefully!": "이 설정은 신중히 사용하세요!",
"Enable Auth": "인증 활성화",
"Disable Auth": "인증 비활성화",
"I understand, please disable": "이해하고 있습니다. 비활성화해 주세요",
"Leave": "취소",
"Frontend Version": "프론트엔드 버전",
"Check Update On GitHub": "GitHub에서 업데이트 확인",
"Show update if available": "업데이트가 있을 때 표시",
"Also check beta release": "베타 버전도 확인",
"Remember me": "기억하기",
"Login": "로그인",
"Username": "사용자명",
"Password": "비밀번호",
"Settings": "설정",
"Logout": "로그아웃",
"Lowercase only": "소문자만",
"Convert to Compose": "Compose로 변환",
"Docker Run": "Docker Run",
"active": "활성",
"exited": "종료됨",
"inactive": "비활성",
"Appearance": "디스플레이",
"Security": "보안",
"About": "정보",
"Allowed commands:": "허용된 명령어:",
"Internal Networks": "내부 네트워크",
"External Networks": "외부 네트워크",
"No External Networks": "외부 네트워크 없음"
}

94
frontend/src/lang/pt.json Normal file
View File

@ -0,0 +1,94 @@
{
"languageName": "Português",
"Create your admin account": "Crie sua conta de administrador",
"authIncorrectCreds": "Nome de usuário ou senha incorretos.",
"PasswordsDoNotMatch": "As senhas não coincidem.",
"Repeat Password": "Repetir Senha",
"Create": "Criar",
"signedInDisp": "Logado como {0}",
"signedInDispDisabled": "Autenticação desativada.",
"home": "Início",
"console": "Console",
"registry": "Registro",
"compose": "Compor",
"addFirstStackMsg": "Componha sua primeira pilha!",
"stackName" : "Nome da Pilha",
"deployStack": "Implantar",
"deleteStack": "Excluir",
"stopStack": "Parar",
"restartStack": "Reiniciar",
"updateStack": "Atualizar",
"startStack": "Iniciar",
"editStack": "Editar",
"discardStack": "Descartar",
"saveStackDraft": "Salvar",
"notAvailableShort" : "N/D",
"deleteStackMsg": "Tem certeza de que deseja excluir esta pilha?",
"stackNotManagedByDockgeMsg": "Esta pilha não é gerenciada pelo Dockge.",
"primaryHostname": "Nome do Host Primário",
"general": "Geral",
"container": "Contêiner | Contêineres",
"scanFolder": "Digitalizar Pasta de Pilhas",
"dockerImage": "Imagem",
"restartPolicyUnlessStopped": "A menos que seja parado",
"restartPolicyAlways": "Sempre",
"restartPolicyOnFailure": "Em caso de falha",
"restartPolicyNo": "Não",
"environmentVariable": "Variável de Ambiente | Variáveis de Ambiente",
"restartPolicy": "Política de Reinicialização",
"containerName": "Nome do Contêiner",
"port": "Porta | Portas",
"volume": "Volume | Volumes",
"network": "Rede | Redes",
"dependsOn": "Dependência do Contêiner | Dependências do Contêiner",
"addListItem": "Adicionar {0}",
"deleteContainer": "Excluir",
"addContainer": "Adicionar Contêiner",
"addNetwork": "Adicionar Rede",
"disableauth.message1": "Tem certeza de que deseja <strong>desativar a autenticação</strong>?",
"disableauth.message2": "Isso é projetado para cenários <strong>onde você pretende implementar autenticação de terceiros</strong> no Dockge, como Cloudflare Access, Authelia ou outros mecanismos de autenticação.",
"passwordNotMatchMsg": "A senha repetida não coincide.",
"autoGet": "Obter Automaticamente",
"add": "Adicionar",
"Edit": "Editar",
"applyToYAML": "Aplicar ao YAML",
"createExternalNetwork": "Criar",
"addInternalNetwork": "Adicionar",
"Save": "Salvar",
"Language": "Idioma",
"Current User": "Usuário Atual",
"Change Password": "Alterar Senha",
"Current Password": "Senha Atual",
"New Password": "Nova Senha",
"Repeat New Password": "Repetir Nova Senha",
"Update Password": "Atualizar Senha",
"Advanced": "Avançado",
"Please use this option carefully!": "Por favor, use esta opção com cuidado!",
"Enable Auth": "Habilitar Autenticação",
"Disable Auth": "Desabilitar Autenticação",
"I understand, please disable": "Entendo, por favor desabilitar",
"Leave": "Sair",
"Frontend Version": "Versão da Interface",
"Check Update On GitHub": "Verificar Atualização no GitHub",
"Show update if available": "Mostrar atualização se disponível",
"Also check beta release": "Também verificar versão beta",
"Remember me": "Lembrar-me",
"Login": "Entrar",
"Username": "Nome de Usuário",
"Password": "Senha",
"Settings": "Configurações",
"Logout": "Sair",
"Lowercase only": "Somente minúsculas",
"Convert to Compose": "Converter para Compose",
"Docker Run": "Executar Docker",
"active": "ativo",
"exited": "encerrado",
"inactive": "inativo",
"Appearance": "Aparência",
"Security": "Segurança",
"About": "Sobre",
"Allowed commands:": "Comandos permitidos:",
"Internal Networks": "Redes Internas",
"External Networks": "Redes Externas",
"No External Networks": "Sem Redes Externas"
}

94
frontend/src/lang/ru.json Normal file
View File

@ -0,0 +1,94 @@
{
"languageName": "Русский",
"Create your admin account": "Создайте учетку администратора",
"authIncorrectCreds": "Неверный логин или пароль.",
"PasswordsDoNotMatch": "Пароль не совпадает.",
"Repeat Password": "Повторите пароль",
"Create": "Создать",
"signedInDisp": "Авторизлван как {0}",
"signedInDispDisabled": "Авторизация выключена.",
"home": "Главная",
"console": "Консоль",
"registry": "Registry",
"compose": "Compose",
"addFirstStackMsg": "Создайте свой первый стек!",
"stackName" : "Имя стека",
"deployStack": "Развернуть",
"deleteStack": "Удалить",
"stopStack": "Остановить",
"restartStack": "Перезапустить",
"updateStack": "Обновить",
"startStack": "Запустить",
"editStack": "Изменить",
"discardStack": "Отменить",
"saveStackDraft": "Сохранить",
"notAvailableShort" : "Н/Д",
"deleteStackMsg": "Вы уверены что хотите удалить этот стек?",
"stackNotManagedByDockgeMsg": "Данный стек не обслуживается Dockge.",
"primaryHostname": "Имя хоста",
"general": "Главное",
"container": "Контейнер | Контейнеры",
"scanFolder": "Сканировать папку стеков",
"dockerImage": "Образ",
"restartPolicyUnlessStopped": "Пока не будет остановлен",
"restartPolicyAlways": "Всегда",
"restartPolicyOnFailure": "При падении",
"restartPolicyNo": "Никогда",
"environmentVariable": "Переменная окружения | Переменные окружения",
"restartPolicy": "Политика рестарта",
"containerName": "Имя контейнера",
"port": "Порт | Порты",
"volume": "Хранилище | Хранилища",
"network": "Сеть | Сети",
"dependsOn": "Зависимость контейнера | Зависимости контейнера",
"addListItem": "Добавить {0}",
"deleteContainer": "Удалить",
"addContainer": "Добавить Контейнер",
"addNetwork": "Добавить Сеть",
"disableauth.message1": "Вы уверены что хотите <strong>выключить авторизацию</strong>?",
"disableauth.message2": "Он предназначен для сценариев, <strong>где вы собираетесь реализовать стороннюю аутентификацию</strong> перед Dockge, например Cloudflare Access, Authelia или другие механизмы аутентификации.",
"passwordNotMatchMsg": "Повторный пароль не совпадает.",
"autoGet": "Auto Get",
"add": "Добавить",
"Edit": "Изменить",
"applyToYAML": "Применить к YAML",
"createExternalNetwork": "Создать",
"addInternalNetwork": "Добавить",
"Save": "Сохранить",
"Language": "Язык",
"Current User": "Текущий пользователь",
"Change Password": "Изменить пароль",
"Current Password": "Текущий пароль",
"New Password": "Новый пароль",
"Repeat New Password": "Повторите новый пароль",
"Update Password": "Обновить пароль",
"Advanced": "Продвинутые опции",
"Please use this option carefully!": "Пожалуйста, используйте эту опцию осторожно!",
"Enable Auth": "Включить аутентификацию",
"Disable Auth": "Отключить аутентификацию",
"I understand, please disable": "Я понимаю, пожалуйста, отключите",
"Leave": "Покинуть",
"Frontend Version": "Версия внешнего интерфейса",
"Check Update On GitHub": "Проверьте обновление на GitHub",
"Show update if available": "Показать обновление, если оно доступно",
"Also check beta release": "Также проверьте бета-версию",
"Remember me": "Запомнить меня",
"Login": "Логин",
"Username": "Имя пользователя",
"Password": "Пароль",
"Settings": "Настройки",
"Logout": "Выйти",
"Lowercase only": "Только нижний регистр",
"Convert to Compose": "Преобразовать вCompose",
"Docker Run": "Запустить Docker",
"active": "активный",
"exited": "завершенный",
"inactive": "неактинвый",
"Appearance": "Внешний вид",
"Security": "Безопасность",
"About": "О продукте",
"Allowed commands:": "Разрешенные команды:",
"Internal Networks": "Внутренние сети",
"External Networks": "Внешние сети",
"No External Networks": "Нет внешних сетей"
}

94
frontend/src/lang/ur.json Normal file
View File

@ -0,0 +1,94 @@
{
"languageName": "اردو",
"Create your admin account": "اپنا ایڈمن اکاؤنٹ بنائیں",
"authIncorrectCreds": "غلط صارف نام یا پاس ورڈ.",
"PasswordsDoNotMatch": "پاس ورڈز کوئی مماثل نہیں ہیں۔",
"Repeat Password": "پاس ورڈ دوبارہ لکھیے",
"Create": "بنانا",
"signedInDisp": "بطور {0} سائن ان",
"signedInDispDisabled": "توثیق غیر فعال۔",
"home": "گھر",
"console": "تسلی",
"registry": "رجسٹری",
"compose": "تحریر",
"addFirstStackMsg": "اپنا پہلا اسٹیک کمپوز کریں!",
"stackName" : "اسٹیک کا نام",
"deployStack": "تعینات",
"deleteStack": "حذف کریں",
"stopStack": "روکو",
"restartStack": "دوبارہ شروع کریں",
"updateStack": "اپ ڈیٹ",
"startStack": "شروع کریں۔",
"editStack": "ترمیم",
"discardStack": "رد کر دیں۔",
"saveStackDraft": "محفوظ کریں۔",
"notAvailableShort" : "N / A",
"deleteStackMsg": "کیا آپ واقعی اس اسٹیک کو حذف کرنا چاہتے ہیں؟",
"stackNotManagedByDockgeMsg": "یہ اسٹیک Dockge کے زیر انتظام نہیں ہے۔",
"primaryHostname": "بنیادی میزبان نام",
"general": "جنرل",
"container": "کنٹینر | کنٹینرز",
"scanFolder": "اسٹیک فولڈر کو اسکین کریں۔",
"dockerImage": "تصویر",
"restartPolicyUnlessStopped": "جب تک روکا نہیں جاتا",
"restartPolicyAlways": "ہمیشہ",
"restartPolicyOnFailure": "ناکامی پر",
"restartPolicyNo": "نہیں",
"environmentVariable": "ماحولیاتی متغیر | ماحولیاتی تغیرات",
"restartPolicy": "پالیسی کو دوبارہ شروع کریں",
"containerName": "کنٹینر کا نام",
"port": "پورٹ | بندرگاہیں",
"volume": "والیوم | جلدیں",
"network": "نیٹ ورک | نیٹ ورکس",
"dependsOn": "کنٹینر انحصار | کنٹینر انحصار",
"addListItem": "شامل کریں {0}",
"deleteContainer": "حذف کریں",
"addContainer": "کنٹینر شامل کریں",
"addNetwork": "نیٹ ورک شامل کریں",
"disableauth.message1": "کیا آپ واقعی <strong>تصدیق کو غیر فعال</strong> کرنا چاہتے ہیں؟",
"disableauth.message2": "یہ ان منظرناموں کے لیے ڈیزائن کیا گیا ہے جہاں <strong>آپ کا ارادہ ہے تیسرے فریق کی توثیق کو لاگو کرنے کا</strong> Dockge کے سامنے جیسے Cloudflare Access، Authelia یا دیگر تصدیقی طریقہ کار۔",
"passwordNotMatchMsg": "دہرانے والا پاس ورڈ مماثل نہیں ہے۔",
"autoGet": "آٹو حاصل کریں",
"add": "شامل کریں",
"Edit": "ترمیم",
"applyToYAML": "YAML پر درخواست دیں۔",
"createExternalNetwork": "بنانا",
"addInternalNetwork": "شامل کریں",
"Save": "محفوظ کریں",
"Language": "زبان",
"Current User": "موجودہ صارف",
"Change Password": "پاس ورڈ تبدیل کریں",
"Current Password": "موجودہ خفیہ لفظ",
"New Password": "نیا پاس ورڈ",
"Repeat New Password": "نیا پاس ورڈ دہرائیں",
"Update Password": "پاس ورڈ اپ ڈیٹ کریں",
"Advanced": "ترقی یافتہ",
"Please use this option carefully!": "براہ کرم اس اختیار کو احتیاط سے استعمال کریں!",
"Enable Auth": "تصدیق کو فعال کریں۔",
"Disable Auth": "توثیق کو غیر فعال کریں۔",
"I understand, please disable": "میں سمجھتا ہوں، براہ کرم غیر فعال کریں۔",
"Leave": "چھوڑ دو",
"Frontend Version": "فرنٹ اینڈ ورژن",
"Check Update On GitHub": "گیتوب پر اپ ڈیٹ چیک کریں۔",
"Show update if available": "اگر دستیاب ہو تو اپ ڈیٹ دکھائیں",
"Also check beta release": "بیٹا ریلیز بھی چیک کریں",
"Remember me": "مجھے پہچانتے ہو",
"Login": "لاگ ان کریں",
"Username": "صارف نام",
"Password": "پاس ورڈ",
"Settings": "ترتیبات",
"Logout": "لاگ آوٹ",
"Lowercase only": "صرف لوئر کیس",
"Convert to Compose": "تحریر میں تبدیل کریں",
"Docker Run": "ڈاکر رن",
"active": "فعال",
"exited": "باہر نکلا",
"inactive": "غیر فعال",
"Appearance": "ظہور",
"Security": "سیکورٹی",
"About": "کے بارے میں",
"Allowed commands:": "اجازت شدہ احکامات:",
"Internal Networks": "اندرونی نیٹ ورکس",
"External Networks": "بیرونی نیٹ ورکس",
"No External Networks": "کوئی بیرونی نیٹ ورک نہیں"
}

View File

@ -0,0 +1,94 @@
{
"languageName": "简体中文",
"Create your admin account": "创建你的管理员账号",
"authIncorrectCreds": "用户名或密码错误",
"PasswordsDoNotMatch": "两次输入的密码不一致。",
"Repeat Password": "重复以确认密码",
"Create": "创建",
"signedInDisp": "当前用户: {0}",
"signedInDispDisabled": "已禁用身份验证",
"home": "主页",
"console": "终端",
"registry": "镜像仓库",
"compose": "Compose",
"addFirstStackMsg": "组合你的第一个堆栈!",
"stackName" : "堆栈名称",
"deployStack": "部署",
"deleteStack": "删除",
"stopStack": "停止",
"restartStack": "重启",
"updateStack": "更新",
"startStack": "启动",
"editStack": "编辑",
"discardStack": "放弃",
"saveStackDraft": "保存",
"notAvailableShort" : "不可用",
"deleteStackMsg": "你确定要删除这个堆栈吗?",
"stackNotManagedByDockgeMsg": "这个堆栈不由Dockge管理",
"primaryHostname": "主机名",
"general": "常规",
"container": "容器 | 容器组",
"scanFolder": "扫描堆栈文件夹",
"dockerImage": "镜像",
"restartPolicyUnlessStopped": "除非手动停止",
"restartPolicyAlways": "始终",
"restartPolicyOnFailure": "在失败时",
"restartPolicyNo": "不重启",
"environmentVariable": "环境变量 | 环境变量组",
"restartPolicy": "重启策略",
"containerName": "容器名",
"port": "端口 | 端口组",
"volume": "数据卷 | 数据卷组",
"network": "网络 | 网络组",
"dependsOn": "容器依赖 | 容器依赖关系",
"addListItem": "添加 {0}",
"deleteContainer": "删除",
"addContainer": "添加容器",
"addNetwork": "添加网络",
"disableauth.message1": "你确定要<strong>禁用身份验证</strong>吗?",
"disableauth.message2": "该选项设计用于某些场景,<strong>例如在Dockge之上接入第三方认证</strong>比如Cloudflare Access、Authelia或其他认证机制如果你不清楚这个选项的作用不要禁用验证",
"passwordNotMatchMsg": "两次输入的密码不一致。",
"autoGet": "自动获取",
"add": "添加",
"Edit": "编辑",
"applyToYAML": "应用到YAML",
"createExternalNetwork": "创建",
"addInternalNetwork": "添加",
"Save": "保存",
"Language": "语言",
"Current User": "当前用户",
"Change Password": "更换密码",
"Current Password": "当前密码",
"New Password": "新密码",
"Repeat New Password": "重复以确认新密码",
"Update Password": "更新密码",
"Advanced": "进阶",
"Please use this option carefully!": "请谨慎使用该选项!",
"Enable Auth": "启用验证",
"Disable Auth": "禁用验证",
"I understand, please disable": "我已了解风险,确认禁用",
"Leave": "离开",
"Frontend Version": "前端版本",
"Check Update On GitHub": "在GitHub上检查更新",
"Show update if available": "有更新时提醒我",
"Also check beta release": "同时检查Beta渠道更新",
"Remember me": "记住我",
"Login": "登录",
"Username": "用户名",
"Password": "密码",
"Settings": "设置",
"Logout": "登出",
"Lowercase only": "仅小写字母",
"Convert to Compose": "转换为Compose格式",
"Docker Run": "Docker启动",
"active": "已启动",
"exited": "已退出",
"inactive": "未启动",
"Appearance": "外观",
"Security": "安全",
"About": "关于",
"Allowed commands:": "允许使用的指令:",
"Internal Networks": "内部网络",
"External Networks": "外部网络",
"No External Networks": "无外部网络"
}

View File

@ -7,7 +7,7 @@
"lint": "eslint \"**/*.{ts,vue}\"",
"check-ts": "tsc --noEmit",
"start": "tsx ./backend/index.ts",
"dev:backend": "cross-env NODE_ENV=development tsx watch ./backend/index.ts",
"dev:backend": "cross-env NODE_ENV=development tsx watch --inspect ./backend/index.ts",
"dev:frontend": "cross-env NODE_ENV=development vite --host --config ./frontend/vite.config.ts",
"release-final": "tsx ./extra/test-docker.ts && tsx extra/update-version.ts && pnpm run build:frontend && npm run build:docker",
"build:frontend": "vite build --config ./frontend/vite.config.ts",