base on A fancy, easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager <div align="center" width="100%"> <img src="./frontend/public/icon.svg" width="128" alt="" /> </div> # Dockge A fancy, easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager. [![GitHub Repo stars](https://img.shields.io/github/stars/louislam/dockge?logo=github&style=flat)](https://github.com/louislam/dockge) [![Docker Pulls](https://img.shields.io/docker/pulls/louislam/dockge?logo=docker)](https://hub.docker.com/r/louislam/dockge/tags) [![Docker Image Version (latest semver)](https://img.shields.io/docker/v/louislam/dockge/latest?label=docker%20image%20ver.)](https://hub.docker.com/r/louislam/dockge/tags) [![GitHub last commit (branch)](https://img.shields.io/github/last-commit/louislam/dockge/master?logo=github)](https://github.com/louislam/dockge/commits/master/) <img src="https://github.com/louislam/dockge/assets/1336778/26a583e1-ecb1-4a8d-aedf-76157d714ad7" width="900" alt="" /> View Video: https://youtu.be/AWAlOQeNpgU?t=48 ## ⭐ Features - 🧑‍💼 Manage your `compose.yaml` files - Create/Edit/Start/Stop/Restart/Delete - Update Docker Images - ⌨️ Interactive Editor for `compose.yaml` - 🦦 Interactive Web Terminal - 🕷️ (1.4.0 🆕) Multiple agents support - You can manage multiple stacks from different Docker hosts in one single interface - 🏪 Convert `docker run ...` commands into `compose.yaml` - 📙 File based structure - 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 /> - 🚄 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 one too ![](https://github.com/louislam/dockge/assets/1336778/89fc1023-b069-42c0-a01c-918c495f1a6a) ## 🔧 How to Install Requirements: - [Docker](https://docs.docker.com/engine/install/) 20+ / Podman - (Podman only) podman-docker (Debian: `apt install podman-docker`) - OS: - Major Linux distros that can run Docker/Podman such as: - ✅ Ubuntu - ✅ Debian (Bullseye or newer) - ✅ Raspbian (Bullseye or newer) - ✅ CentOS - ✅ Fedora - ✅ ArchLinux - ❌ Debian/Raspbian Buster or lower is not supported - ❌ Windows (Will be supported later) - Arch: armv7, arm64, amd64 (a.k.a x86_64) ### Basic - Default Stacks Directory: `/opt/stacks` - Default Port: 5001 ``` # Create directories that store your stacks and stores Dockge's stack mkdir -p /opt/stacks /opt/dockge cd /opt/dockge # Download the compose.yaml curl https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml --output compose.yaml # Start the server docker compose up -d # If you are using docker-compose V1 or Podman # docker-compose up -d ``` Dockge is now running on http://localhost:5001 ### Advanced If you want to store your stacks in another directory, you can generate your compose.yaml file by using the following URL with custom query strings. ``` # Download your compose.yaml curl "https://dockge.kuma.pet/compose.yaml?port=5001&stacksPath=/opt/stacks" --output compose.yaml ``` - port=`5001` - stacksPath=`/opt/stacks` Interactive compose.yaml generator is available on: https://dockge.kuma.pet ## How to Update ```bash cd /opt/dockge docker compose pull && docker compose up -d ``` ## Screenshots ![](https://github.com/louislam/dockge/assets/1336778/e7ff0222-af2e-405c-b533-4eab04791b40) ![](https://github.com/louislam/dockge/assets/1336778/7139e88c-77ed-4d45-96e3-00b66d36d871) ![](https://github.com/louislam/dockge/assets/1336778/f019944c-0e87-405b-a1b8-625b35de1eeb) ![](https://github.com/louislam/dockge/assets/1336778/a4478d23-b1c4-4991-8768-1a7cad3472e3) ## 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 If you love this project, please consider giving it a ⭐. ## 🗣️ Community and Contribution ### Bug Report 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) ### Create a Pull Request Be sure to read the [guide](https://github.com/louislam/dockge/blob/master/CONTRIBUTING.md), as we don't accept all types of pull requests and don't want to waste your time. ## FAQ #### "Dockge"? "Dockge" is a coinage word which is created by myself. I originally hoped it sounds like `Dodge`, but apparently many people called it `Dockage`, it is also acceptable. 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 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? Yes, you can. However, you need to move your compose file into the stacks directory: 1. Stop your stack 2. Move your compose file into `/opt/stacks/<stackName>/compose.yaml` 3. In Dockge, click the " Scan Stacks Folder" button in the top-right corner's dropdown menu 4. Now you should see your stack in the list #### Is Dockge a Portainer replacement? Yes or no. Portainer provides a lot of Docker features. While Dockge is currently only focusing on docker-compose with a better user interface and better user experience. If you want to manage your container with docker-compose only, the answer may be yes. If you still need to manage something like docker networks, single containers, the answer may be no. #### Can I install both Dockge and Portainer? Yes, you can. ## Others Dockge is built on top of [Compose V2](https://docs.docker.com/compose/migrate/). `compose.yaml` also known as `docker-compose.yml`. ", Assign "at most 3 tags" to the expected json: {"id":"5166","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"