diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 51e36ede7..02d9bce92 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -31,28 +31,6 @@ jobs: - name: Run Build run: pnpm build - - build-docker-on-pr: - if: github.event_name == 'pull_request' - needs: build-app - runs-on: ubuntu-latest - steps: - - name: Check out the code - uses: actions/checkout@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Prepare .env file - run: | - cp .env.production.example .env.production - - - name: Run custom Docker build script - run: | - chmod +x ./docker/build.sh - echo "Building Docker image for ${{ github.base_ref }}" - ./docker/build.sh ${{ github.base_ref == 'canary' && 'canary' || '' }} - build-and-push-docker-on-push: if: github.event_name == 'push' runs-on: ubuntu-latest @@ -75,7 +53,5 @@ jobs: - name: Build and push Docker image using custom script run: | - chmod +x ./docker/build.sh chmod +x ./docker/push.sh - ./docker/build.sh ${{ github.ref_name == 'canary' && 'canary' || '' }} ./docker/push.sh ${{ github.ref_name == 'canary' && 'canary' || '' }} \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bbda3053c..67a8e3ece 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,7 +107,7 @@ pnpm run docker:push In the case you lost your password, you can reset it using the following command ```bash -pnpm run build-server +pnpm run reset-password ``` If you want to test the webhooks on development mode using localtunnel, make sure to install `localtunnel` @@ -150,4 +150,4 @@ curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.32.1/pack-v0. - If your pull request fixes an open issue, please reference the issue in the pull request description. - Once your pull request is merged, you will be automatically added as a contributor to the project. -Thank you for your contribution! \ No newline at end of file +Thank you for your contribution! diff --git a/LICENSE.MD b/LICENSE.MD index abf659ebf..9b02d8669 100644 --- a/LICENSE.MD +++ b/LICENSE.MD @@ -1,4 +1,4 @@ -Copyright 2024-2024 Mauricio Siu. +Copyright 2024 Mauricio Siu. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13,23 +13,12 @@ See the License for the specific language governing permissions and limitations under the License. Appendix: -In case of a conflict, the terms of this appendix supersede the general apache license. -- Unless provided with a written agreement or permission, the paid features of Dokploy (as a service) cannot be modified. -- Unless provided with a written agreement or permission, no persons are permitted to redistribute another paid version of Dokploy. -- Unless provided with a written agreement or permission, no persons are permitted to create the same paid version of Dokploy. -- Furthermore, any modifications of free features of Dokploy should be distributed as free & opensource software. - -Appendix B: - -- **Prohibition of Resale Without Permission:** Notwithstanding any provisions in the main body of the Apache License, Version 2.0, no party is permitted to sell, resell, or otherwise distribute for commercial gain, the software or any of its components, including both original and modified versions, through any form of commercial distribution channels, including but not limited to online marketplaces, software as a service (SaaS) platforms, or physical media distribution, without prior written consent from the copyright holder. - -- **Commercial Distribution:** Any form of distribution of Dokploy, whether for direct profit or indirect financial benefit, through commercial channels is strictly prohibited without a separate commercial agreement negotiated with the copyright holder. This includes but is not limited to, offerings on software marketplaces or through third-party distributors. - -- **Modification of Paid Features:** The paid features of Dokploy (as a service) may not be modified, integrated into other software, or redistributed in any form without explicit written permission from the copyright holder. - -- **Open Source Distribution of Free Features:** Any modifications to the free features of Dokploy must be distributed freely and must not be included in any paid or commercial package without complying with the open-source license terms stipulated in this agreement. - -If you have any questions, please feel free to reach out to us. +In cases of conflict, the provisions in this appendix supersede those in the general Apache License. +- **Modification of Paid Features:** Written consent or a formal agreement is required for modifying any paid features of Dokploy. +- **Prohibition of Unauthorized Resale:** No party is permitted to sell, resell, or otherwise distribute for commercial gain, the software or any of its components, including both original and modified versions, without prior written consent from the copyright holder. +- **Commercial Distribution:** Any distribution of Dokploy, whether for direct profit or indirect financial benefit, through commercial channels is strictly prohibited without a separate commercial agreement negotiated with the copyright holder. +- **Open Source Distribution of Free Features:** Any modifications to the free features of Dokploy must be distributed freely and must not be included in any paid or commercial package unless they comply with the license and appendix terms specified in this agreement. +For further inquiries or permissions, please contact us directly. diff --git a/README-zh.md b/README-zh.md new file mode 100644 index 000000000..0e4982e08 --- /dev/null +++ b/README-zh.md @@ -0,0 +1,47 @@ + + +
+

Dokploy

+
+ +
+Reflex Logo +
+
+ + + +Dokploy 是一个免费的自托管平台即服务 (PaaS),它使用 Docker 和 Traefik 简化了应用程序和数据库的部署和管理。 Dokploy 旨在提高效率和安全性,允许您在任何 VPS 上部署应用程序。 + +## 语言 +[English](README.md) + +[中文](README-zh.md) + + + + + +## 🌟 功能 + +- **应用程序**: 轻松部署任何类型的应用程序(Node.js,PHP,Python,Go、Ruby 等)。数据库: 创建和管理数据库,支持 MySQL,PostgreSQL,MongoDB、MariaDB、Redis 等。 +- **Docker 管理**: 轻松部署和管理 Docker 容器。 +- **Traefik 集成**: 自动与 Traefik 集成,用于路由和负载均衡。 +- **实时监控**: 监控 CPU,内存,存储和网络使用情况。 +- **数据库备份**: 支持多种存储目的地自动备份。 + +## 🚀 入门 +要开始使用 请在VPS 上运行以下命令: + +```bash +curl -sSL https://dokploy.com/install.sh | sh +``` + +经过测试的系统: + +- Ubuntu 20.04 +- Debian 11 + +## 📄 文档 + +如需查看详细的文档资料 请访问[docs.dokploy.com/docs](https://docs.dokploy.com) diff --git a/README.md b/README.md index 19e44df07..a1c4708a9 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,12 @@ Dokploy is a free self-hostable Platform as a Service (PaaS) that simplifies the +## Explanation +[English](README.md) | [中文](README-zh.md) + + + + ## 🌟 Features - **Applications**: Deploy any type of application (Node.js, PHP, Python, Go, Ruby, etc.) with ease. diff --git a/TERMS_AND_CONDITIONS.md b/TERMS_AND_CONDITIONS.md index acf376cd0..56ef97fb1 100644 --- a/TERMS_AND_CONDITIONS.md +++ b/TERMS_AND_CONDITIONS.md @@ -1,25 +1,22 @@ # Terms & Conditions +**Dokploy core** is a free and open-source solution intended as an alternative to established cloud platforms like Vercel and Netlify. -Dokploy core is a free and open-source program alternative to Vercel, Netlify, and other cloud services. +The Dokploy team endeavors to mitigate potential defects and issues through stringent testing and adherence to principles of clean coding. Dokploy is provided "AS IS" without any warranties, express or implied. Refer to the [License](https://github.com/Dokploy/Dokploy/blob/main/LICENSE) for details on permissions and restrictions. -Developers of Dokploy do their best to prevent bugs and issues through rigorous testing processes and clean code principles. Dokploy is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and limitations under the [License](https://github.com/Dokploy/Dokploy/blob/main/LICENSE). - -By using Dokploy you agree to Terms and Conditions, and the license of Dokploy. ### Description of Service: -Dokploy core is an open-source program designed to streamline application deployment processes for personal and commercial use. Users are free to install, modify, and run Dokploy on their own machines or within their organizations to enhance their development and deployment workflows. While Dokploy encourages a wide range of uses to foster innovation and efficiency, it is crucial to note that selling Dokploy itself as a service or repackaging it as part of a commercial offering without explicit permission is strictly prohibited. This ensures that the open-source nature of Dokploy remains intact and benefits the community as a whole. +**Dokploy core** is an open-source tool designed to simplify the deployment of applications for both personal and business use. Users are permitted to install, modify, and operate Dokploy independently or within their organizations to improve their development and deployment operations. It is important to note that any commercial resale or redistribution of Dokploy as a service is strictly forbidden without explicit consent. This prohibition ensures the preservation of Dokploy's open-source character for the benefit of the entire community. ### Our Responsibility -Dokploy developers will do their best to ensure that Dokploy remains functional and major bugs are resolved quickly. If you have a feature request, you are more than welcome to open a request for it, but the ultimate decision whether or not the feature will be added is taken by Dokploy's core developers. +The Dokploy development team commits to maintaining the functionality of the software and addressing major issues promptly. While we welcome suggestions for new features, the decision to include them rests solely with the core developers of Dokploy. ### Usage Data -Dokploy doesn't collect any usage data. It is a free and open-source program, and it is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +**Dokploy** does not collect any user data. It is distributed as a free and open-source tool under the terms of "AS IS", without any implied warranties or conditions. -### Future changes +### Future Changes -Terms of Service / Terms & Conditions may change at any point without a prior notice. \ No newline at end of file +The Terms of Service and Terms & Conditions are subject to change without prior notice. diff --git a/components/dashboard/postgres/general/show-external-postgres-credentials.tsx b/components/dashboard/postgres/general/show-external-postgres-credentials.tsx index 08bae8c61..215356cee 100644 --- a/components/dashboard/postgres/general/show-external-postgres-credentials.tsx +++ b/components/dashboard/postgres/general/show-external-postgres-credentials.tsx @@ -80,7 +80,7 @@ export const ShowExternalPostgresCredentials = ({ postgresId }: Props) => { const hostname = window.location.hostname; const port = form.watch("externalPort") || data?.externalPort; - return `postgresql://${data?.databasePassword}:${data?.databasePassword}@${hostname}:${port}/${data?.databaseName}`; + return `postgresql://${data?.databaseUser}:${data?.databasePassword}@${hostname}:${port}/${data?.databaseName}`; }; setConnectionUrl(buildConnectionUrl()); diff --git a/docker/build.sh b/docker/build.sh index 22104934d..ef38fa4fa 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -10,9 +10,8 @@ else TAG="$VERSION" fi -docker build --platform linux/amd64 --pull --rm -f 'Dockerfile' -t "dokploy/dokploy:${TAG}" . +BUILDER=$(docker buildx create --use) -if [ "$BUILD_TYPE" != "canary" ]; then - # Tag the production build as latest - docker tag "dokploy/dokploy:${TAG}" "dokploy/dokploy:latest" -fi +docker buildx build --platform linux/amd64,linux/arm64 --pull --rm -t "dokploy/dokploy:${TAG}" -f 'Dockerfile' . + +docker buildx rm $BUILDER diff --git a/docker/push.sh b/docker/push.sh index 1e9fbecaf..1c41f68aa 100755 --- a/docker/push.sh +++ b/docker/push.sh @@ -3,13 +3,16 @@ # Determine the type of build based on the first script argument BUILD_TYPE=${1:-production} +BUILDER=$(docker buildx create --use) + if [ "$BUILD_TYPE" == "canary" ]; then TAG="canary" echo PUSHING CANARY - docker push "dokploy/dokploy:${TAG}" + docker buildx build --platform linux/amd64,linux/arm64 --pull --rm -t "dokploy/dokploy:${TAG}" -f 'Dockerfile' --push . else echo "PUSHING PRODUCTION" VERSION=$(node -p "require('./package.json').version") - docker push "dokploy/dokploy:${VERSION}" - docker push "dokploy/dokploy:latest" + docker buildx build --platform linux/amd64,linux/arm64 --pull --rm -t "dokploy/dokploy:latest" -t "dokploy/dokploy:${VERSION}" -f 'Dockerfile' --push . fi + +docker buildx rm $BUILDER \ No newline at end of file diff --git a/next.config.mjs b/next.config.mjs index 95e4a206d..3dc0f83c7 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -6,11 +6,6 @@ /** @type {import("next").NextConfig} */ const nextConfig = { reactStrictMode: true, - logging:{ - fetches:{ - fullUrl:false - } - }, /** * If you are using `appDir` then you must comment the below `i18n` config out. diff --git a/package.json b/package.json index 258f32bf7..bb7284270 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dokploy", - "version": "v0.0.1", + "version": "v0.0.3", "private": true, "license": "AGPL-3.0-only", "type": "module", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21d314ee7..61d1677b7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,7 +85,7 @@ dependencies: version: 10.45.2(@trpc/server@10.45.2) '@trpc/next': specifier: ^10.43.6 - version: 10.45.2(@tanstack/react-query@4.36.1)(@trpc/client@10.45.2)(@trpc/react-query@10.45.2)(@trpc/server@10.45.2)(next@14.1.3)(react-dom@18.2.0)(react@18.2.0) + version: 10.45.2(@tanstack/react-query@4.36.1)(@trpc/client@10.45.2)(@trpc/react-query@10.45.2)(@trpc/server@10.45.2)(next@14.2.3)(react-dom@18.2.0)(react@18.2.0) '@trpc/react-query': specifier: ^10.43.6 version: 10.45.2(@tanstack/react-query@4.36.1)(@trpc/client@10.45.2)(@trpc/server@10.45.2)(react-dom@18.2.0)(react@18.2.0) @@ -157,10 +157,10 @@ dependencies: version: 3.3.7 next: specifier: ^14.1.3 - version: 14.1.3(react-dom@18.2.0)(react@18.2.0) + version: 14.2.3(react-dom@18.2.0)(react@18.2.0) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.1.3)(react-dom@18.2.0)(react@18.2.0) + version: 0.2.1(next@14.2.3)(react-dom@18.2.0)(react@18.2.0) node-os-utils: specifier: 1.3.7 version: 1.3.7 @@ -1853,12 +1853,12 @@ packages: dev: false optional: true - /@next/env@14.1.3: - resolution: {integrity: sha512-VhgXTvrgeBRxNPjyfBsDIMvgsKDxjlpw4IAUsHCX8Gjl1vtHUYRT3+xfQ/wwvLPDd/6kqfLqk9Pt4+7gysuCKQ==} + /@next/env@14.2.3: + resolution: {integrity: sha512-W7fd7IbkfmeeY2gXrzJYDx8D2lWKbVoTIj1o1ScPHNzvp30s1AuoEFSdr39bC5sjxJaxTtq3OTCZboNp0lNWHA==} dev: false - /@next/swc-darwin-arm64@14.1.3: - resolution: {integrity: sha512-LALu0yIBPRiG9ANrD5ncB3pjpO0Gli9ZLhxdOu6ZUNf3x1r3ea1rd9Q+4xxUkGrUXLqKVK9/lDkpYIJaCJ6AHQ==} + /@next/swc-darwin-arm64@14.2.3: + resolution: {integrity: sha512-3pEYo/RaGqPP0YzwnlmPN2puaF2WMLM3apt5jLW2fFdXD9+pqcoTzRk+iZsf8ta7+quAe4Q6Ms0nR0SFGFdS1A==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -1866,8 +1866,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64@14.1.3: - resolution: {integrity: sha512-E/9WQeXxkqw2dfcn5UcjApFgUq73jqNKaE5bysDm58hEUdUGedVrnRhblhJM7HbCZNhtVl0j+6TXsK0PuzXTCg==} + /@next/swc-darwin-x64@14.2.3: + resolution: {integrity: sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -1875,8 +1875,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu@14.1.3: - resolution: {integrity: sha512-USArX9B+3rZSXYLFvgy0NVWQgqh6LHWDmMt38O4lmiJNQcwazeI6xRvSsliDLKt+78KChVacNiwvOMbl6g6BBw==} + /@next/swc-linux-arm64-gnu@14.2.3: + resolution: {integrity: sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1884,8 +1884,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl@14.1.3: - resolution: {integrity: sha512-esk1RkRBLSIEp1qaQXv1+s6ZdYzuVCnDAZySpa62iFTMGTisCyNQmqyCTL9P+cLJ4N9FKCI3ojtSfsyPHJDQNw==} + /@next/swc-linux-arm64-musl@14.2.3: + resolution: {integrity: sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1893,8 +1893,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu@14.1.3: - resolution: {integrity: sha512-8uOgRlYEYiKo0L8YGeS+3TudHVDWDjPVDUcST+z+dUzgBbTEwSSIaSgF/vkcC1T/iwl4QX9iuUyUdQEl0Kxalg==} + /@next/swc-linux-x64-gnu@14.2.3: + resolution: {integrity: sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1902,8 +1902,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl@14.1.3: - resolution: {integrity: sha512-DX2zqz05ziElLoxskgHasaJBREC5Y9TJcbR2LYqu4r7naff25B4iXkfXWfcp69uD75/0URmmoSgT8JclJtrBoQ==} + /@next/swc-linux-x64-musl@14.2.3: + resolution: {integrity: sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1911,8 +1911,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc@14.1.3: - resolution: {integrity: sha512-HjssFsCdsD4GHstXSQxsi2l70F/5FsRTRQp8xNgmQs15SxUfUJRvSI9qKny/jLkY3gLgiCR3+6A7wzzK0DBlfA==} + /@next/swc-win32-arm64-msvc@14.2.3: + resolution: {integrity: sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -1920,8 +1920,8 @@ packages: dev: false optional: true - /@next/swc-win32-ia32-msvc@14.1.3: - resolution: {integrity: sha512-DRuxD5axfDM1/Ue4VahwSxl1O5rn61hX8/sF0HY8y0iCbpqdxw3rB3QasdHn/LJ6Wb2y5DoWzXcz3L1Cr+Thrw==} + /@next/swc-win32-ia32-msvc@14.2.3: + resolution: {integrity: sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -1929,8 +1929,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc@14.1.3: - resolution: {integrity: sha512-uC2DaDoWH7h1P/aJ4Fok3Xiw6P0Lo4ez7NbowW2VGNXw/Xv6tOuLUcxhBYZxsSUJtpeknCi8/fvnSpyCFp4Rcg==} + /@next/swc-win32-x64-msvc@14.2.3: + resolution: {integrity: sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -4124,9 +4124,14 @@ packages: tslib: 2.6.2 dev: false - /@swc/helpers@0.5.2: - resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: false + + /@swc/helpers@0.5.5: + resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} dependencies: + '@swc/counter': 0.1.3 tslib: 2.6.2 dev: false @@ -4184,7 +4189,7 @@ packages: '@trpc/server': 10.45.2 dev: false - /@trpc/next@10.45.2(@tanstack/react-query@4.36.1)(@trpc/client@10.45.2)(@trpc/react-query@10.45.2)(@trpc/server@10.45.2)(next@14.1.3)(react-dom@18.2.0)(react@18.2.0): + /@trpc/next@10.45.2(@tanstack/react-query@4.36.1)(@trpc/client@10.45.2)(@trpc/react-query@10.45.2)(@trpc/server@10.45.2)(next@14.2.3)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-RSORmfC+/nXdmRY1pQ0AalsVgSzwNAFbZLYHiTvPM5QQ8wmMEHilseCYMXpu0se/TbPt9zVR6Ka2d7O6zxKkXg==} peerDependencies: '@tanstack/react-query': ^4.18.0 @@ -4199,7 +4204,7 @@ packages: '@trpc/client': 10.45.2(@trpc/server@10.45.2) '@trpc/react-query': 10.45.2(@tanstack/react-query@4.36.1)(@trpc/client@10.45.2)(@trpc/server@10.45.2)(react-dom@18.2.0)(react@18.2.0) '@trpc/server': 10.45.2 - next: 14.1.3(react-dom@18.2.0)(react@18.2.0) + next: 14.2.3(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -6182,14 +6187,14 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - /next-themes@0.2.1(next@14.1.3)(react-dom@18.2.0)(react@18.2.0): + /next-themes@0.2.1(next@14.2.3)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==} peerDependencies: next: '*' react: '*' react-dom: '*' dependencies: - next: 14.1.3(react-dom@18.2.0)(react@18.2.0) + next: 14.2.3(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -6198,23 +6203,26 @@ packages: resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} dev: true - /next@14.1.3(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-oexgMV2MapI0UIWiXKkixF8J8ORxpy64OuJ/J9oVUmIthXOUCcuVEZX+dtpgq7wIfIqtBwQsKEDXejcjTsan9g==} + /next@14.2.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-dowFkFTR8v79NPJO4QsBUtxv0g9BrS/phluVpMAt2ku7H+cbcBJlopXjkWlwxrk/xGqMemr7JkGPGemPrLLX7A==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 react: ^18.2.0 react-dom: ^18.2.0 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': optional: true + '@playwright/test': + optional: true sass: optional: true dependencies: - '@next/env': 14.1.3 - '@swc/helpers': 0.5.2 + '@next/env': 14.2.3 + '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001598 graceful-fs: 4.2.11 @@ -6223,15 +6231,15 @@ packages: react-dom: 18.2.0(react@18.2.0) styled-jsx: 5.1.1(react@18.2.0) optionalDependencies: - '@next/swc-darwin-arm64': 14.1.3 - '@next/swc-darwin-x64': 14.1.3 - '@next/swc-linux-arm64-gnu': 14.1.3 - '@next/swc-linux-arm64-musl': 14.1.3 - '@next/swc-linux-x64-gnu': 14.1.3 - '@next/swc-linux-x64-musl': 14.1.3 - '@next/swc-win32-arm64-msvc': 14.1.3 - '@next/swc-win32-ia32-msvc': 14.1.3 - '@next/swc-win32-x64-msvc': 14.1.3 + '@next/swc-darwin-arm64': 14.2.3 + '@next/swc-darwin-x64': 14.2.3 + '@next/swc-linux-arm64-gnu': 14.2.3 + '@next/swc-linux-arm64-musl': 14.2.3 + '@next/swc-linux-x64-gnu': 14.2.3 + '@next/swc-linux-x64-musl': 14.2.3 + '@next/swc-win32-arm64-msvc': 14.2.3 + '@next/swc-win32-ia32-msvc': 14.2.3 + '@next/swc-win32-x64-msvc': 14.2.3 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros diff --git a/server/api/routers/domain.ts b/server/api/routers/domain.ts index 2abe710c3..ace938c01 100644 --- a/server/api/routers/domain.ts +++ b/server/api/routers/domain.ts @@ -52,7 +52,7 @@ export const domainRouter = createTRPCRouter({ .mutation(async ({ input }) => { const domain = await findDomainById(input.domainId); const result = await removeDomainById(input.domainId); - removeDomain(domain.application.appName, domain.uniqueConfigKey); + await removeDomain(domain.application.appName, domain.uniqueConfigKey); return result; }), diff --git a/server/api/services/application.ts b/server/api/services/application.ts index d7efc4339..d5da79c40 100644 --- a/server/api/services/application.ts +++ b/server/api/services/application.ts @@ -36,9 +36,8 @@ export const createApplication = async ( }); } - createTraefikConfig(newApplication.appName); - if (process.env.NODE_ENV === "development") { + createTraefikConfig(newApplication.appName); await tx.insert(domains).values({ applicationId: newApplication.applicationId, host: `${newApplication.appName}.docker.localhost`, diff --git a/server/server.ts b/server/server.ts index 20af88ade..8a15362ad 100644 --- a/server/server.ts +++ b/server/server.ts @@ -48,9 +48,9 @@ void app.prepare().then(async () => { await initializeNetwork(); createDefaultTraefikConfig(); createDefaultServerTraefikConfig(); + await initializePostgres(); await initializeTraefik(); await initializeRedis(); - await initializePostgres(); initCronJobs(); welcomeServer(); @@ -74,7 +74,7 @@ async function welcomeServer() { "", "Dokploy server is up and running!", "Please wait for 15 seconds before opening the browser.", - ` http://${ip}:3000`, + ` http://${ip}:${PORT}`, "", "", ].join("\n"), diff --git a/server/utils/docker/utils.ts b/server/utils/docker/utils.ts index 21a6614b7..2cd881bbc 100644 --- a/server/utils/docker/utils.ts +++ b/server/utils/docker/utils.ts @@ -5,6 +5,7 @@ import { APPLICATIONS_PATH, docker } from "@/server/constants"; import type { ContainerInfo, ResourceRequirements } from "dockerode"; import type { ApplicationNested } from "../builders"; import { execAsync } from "../process/execAsync"; +import { parse } from "dotenv"; interface RegistryAuth { username: string; @@ -154,15 +155,7 @@ export const removeService = async (appName: string) => { }; export const prepareEnvironmentVariables = (env: string | null) => - env - ?.split("\n") - .map((line) => line.trim()) // Trim whitespace - .filter((line) => line && !line.startsWith("#")) // Exclude empty lines and comments - .map((envVar) => { - let [key, value] = envVar.split("=", 2); - value = value?.replace(/^"(.*)"$/, "$1"); // Remove surrounding double quotes - return `${key}=${value}`; - }) || []; + Object.entries(parse(env ?? "")).map(([key, value]) => `${key}=${value}`); export const generateVolumeMounts = (mounts: ApplicationNested["mounts"]) => { if (!mounts || mounts.length === 0) { diff --git a/server/utils/traefik/domain.ts b/server/utils/traefik/domain.ts index cf0faa17e..689afbbb9 100644 --- a/server/utils/traefik/domain.ts +++ b/server/utils/traefik/domain.ts @@ -1,6 +1,7 @@ import { createServiceConfig, loadOrCreateConfig, + removeTraefikConfig, writeTraefikConfig, } from "./application"; import type { ApplicationNested } from "../builders"; @@ -23,7 +24,7 @@ export const manageDomain = async (app: ApplicationNested, domain: Domain) => { writeTraefikConfig(config, appName); }; -export const removeDomain = (appName: string, uniqueKey: number) => { +export const removeDomain = async (appName: string, uniqueKey: number) => { const config: FileConfig = loadOrCreateConfig(appName); const routerKey = `${appName}-router-${uniqueKey}`; @@ -35,7 +36,15 @@ export const removeDomain = (appName: string, uniqueKey: number) => { delete config.http.services[serviceKey]; } - writeTraefikConfig(config, appName); + // verify if is the last router if so we delete the router + if ( + config?.http?.routers && + Object.keys(config?.http?.routers).length === 0 + ) { + await removeTraefikConfig(appName); + } else { + writeTraefikConfig(config, appName); + } }; export const createRouterConfig = async (