Merge branch 'next' into feat/disable-default-redirect

This commit is contained in:
Kael
2024-10-14 21:25:56 +11:00
39 changed files with 941 additions and 392 deletions

View File

@@ -1,4 +1,4 @@
name: Coolify Helper Image Development (v4) name: Coolify Helper Image Development
on: on:
push: push:
@@ -8,7 +8,8 @@ on:
- docker/coolify-helper/Dockerfile - docker/coolify-helper/Dockerfile
env: env:
REGISTRY: ghcr.io GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-helper" IMAGE_NAME: "coollabsio/coolify-helper"
jobs: jobs:
@@ -19,25 +20,36 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/coolify-helper/Dockerfile file: docker/coolify-helper/Dockerfile
platforms: linux/amd64 platforms: linux/amd64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
labels: | labels: |
coolify.managed=true coolify.managed=true
aarch64: aarch64:
@@ -47,27 +59,39 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/coolify-helper/Dockerfile file: docker/coolify-helper/Dockerfile
platforms: linux/aarch64 platforms: linux/aarch64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
labels: | labels: |
coolify.managed=true coolify.managed=true
merge-manifest: merge-manifest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
@@ -75,25 +99,42 @@ jobs:
packages: write packages: write
needs: [ amd64, aarch64 ] needs: [ amd64, aarch64 ]
steps: steps:
- name: Checkout - uses: actions/checkout@v4
uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v3 - name: Login to ${{ env.GITHUB_REGISTRY }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Create & publish manifest
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: | run: |
docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:next docker buildx imagetools create \
--append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
--append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next
- uses: sarisia/actions-status-discord@v1 - uses: sarisia/actions-status-discord@v1
if: always() if: always()
with: with:

View File

@@ -1,4 +1,4 @@
name: Coolify Helper Image (v4) name: Coolify Helper Image
on: on:
push: push:
@@ -8,7 +8,8 @@ on:
- docker/coolify-helper/Dockerfile - docker/coolify-helper/Dockerfile
env: env:
REGISTRY: ghcr.io GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-helper" IMAGE_NAME: "coollabsio/coolify-helper"
jobs: jobs:
@@ -19,25 +20,36 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/coolify-helper/Dockerfile file: docker/coolify-helper/Dockerfile
platforms: linux/amd64 platforms: linux/amd64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
labels: | labels: |
coolify.managed=true coolify.managed=true
aarch64: aarch64:
@@ -47,25 +59,36 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/coolify-helper/Dockerfile file: docker/coolify-helper/Dockerfile
platforms: linux/aarch64 platforms: linux/aarch64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
labels: | labels: |
coolify.managed=true coolify.managed=true
merge-manifest: merge-manifest:
@@ -75,25 +98,43 @@ jobs:
packages: write packages: write
needs: [ amd64, aarch64 ] needs: [ amd64, aarch64 ]
steps: steps:
- name: Checkout - uses: actions/checkout@v4
uses: actions/checkout@v4
- name: Set up QEMU - uses: docker/setup-buildx-action@v3
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Create & publish manifest
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: | run: |
docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest docker buildx imagetools create \
--append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
--append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- uses: sarisia/actions-status-discord@v1 - uses: sarisia/actions-status-discord@v1
if: always() if: always()
with: with:

View File

@@ -0,0 +1,143 @@
name: Production Build (v4)
on:
push:
branches: ["main"]
paths-ignore:
- .github/workflows/coolify-helper.yml
- .github/workflows/coolify-helper-next.yml
- .github/workflows/coolify-realtime.yml
- .github/workflows/coolify-realtime-next.yml
- docker/coolify-helper/Dockerfile
- docker/coolify-realtime/Dockerfile
- docker/testing-host/Dockerfile
- templates/service-templates.json
env:
GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify"
jobs:
amd64:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version
id: version
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT]
- name: Build and Push Image
uses: docker/build-push-action@v6
with:
context: .
file: docker/prod/Dockerfile
platforms: linux/amd64
push: true
tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
labels: |
coolify.managed=true
aarch64:
runs-on: [self-hosted, arm64]
steps:
- uses: actions/checkout@v4
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version
id: version
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT]
- name: Build and Push Image
uses: docker/build-push-action@v6
with:
context: .
file: docker/prod/Dockerfile
platforms: linux/aarch64
push: true
tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
labels: |
coolify.managed=true
merge-manifest:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
needs: [amd64, aarch64]
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version
id: version
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: |
docker buildx imagetools create \
--append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
--append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- uses: sarisia/actions-status-discord@v1
if: always()
with:
webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }}

View File

@@ -1,17 +1,18 @@
name: Coolify Realtime Development (v4) name: Coolify Realtime Development
on: on:
push: push:
branches: [ "next" ] branches: [ "next" ]
paths: paths:
- .github/workflows/coolify-realtime.yml - .github/workflows/coolify-realtime-next.yml
- docker/coolify-realtime/Dockerfile - docker/coolify-realtime/Dockerfile
- docker/coolify-realtime/terminal-server.js - docker/coolify-realtime/terminal-server.js
- docker/coolify-realtime/package.json - docker/coolify-realtime/package.json
- docker/coolify-realtime/soketi-entrypoint.sh - docker/coolify-realtime/soketi-entrypoint.sh
env: env:
REGISTRY: ghcr.io GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-realtime" IMAGE_NAME: "coollabsio/coolify-realtime"
jobs: jobs:
@@ -22,27 +23,39 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/coolify-realtime/Dockerfile file: docker/coolify-realtime/Dockerfile
platforms: linux/amd64 platforms: linux/amd64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
labels: | labels: |
coolify.managed=true coolify.managed=true
aarch64: aarch64:
runs-on: [ self-hosted, arm64 ] runs-on: [ self-hosted, arm64 ]
permissions: permissions:
@@ -50,27 +63,39 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/coolify-realtime/Dockerfile file: docker/coolify-realtime/Dockerfile
platforms: linux/aarch64 platforms: linux/aarch64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
labels: | labels: |
coolify.managed=true coolify.managed=true
merge-manifest: merge-manifest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
@@ -78,26 +103,44 @@ jobs:
packages: write packages: write
needs: [ amd64, aarch64 ] needs: [ amd64, aarch64 ]
steps: steps:
- name: Checkout - uses: actions/checkout@v4
uses: actions/checkout@v4
- name: Set up QEMU - uses: docker/setup-buildx-action@v3
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Create & publish manifest
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: | run: |
docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next docker buildx imagetools create \
--append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
--append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next
- uses: sarisia/actions-status-discord@v1 - uses: sarisia/actions-status-discord@v1
if: always() if: always()
with: with:
webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }} webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }}

View File

@@ -1,4 +1,4 @@
name: Coolify Realtime (v4) name: Coolify Realtime
on: on:
push: push:
@@ -11,7 +11,8 @@ on:
- docker/coolify-realtime/soketi-entrypoint.sh - docker/coolify-realtime/soketi-entrypoint.sh
env: env:
REGISTRY: ghcr.io GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-realtime" IMAGE_NAME: "coollabsio/coolify-realtime"
jobs: jobs:
@@ -22,27 +23,39 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/coolify-realtime/Dockerfile file: docker/coolify-realtime/Dockerfile
platforms: linux/amd64 platforms: linux/amd64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
labels: | labels: |
coolify.managed=true coolify.managed=true
aarch64: aarch64:
runs-on: [ self-hosted, arm64 ] runs-on: [ self-hosted, arm64 ]
permissions: permissions:
@@ -50,27 +63,39 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/coolify-realtime/Dockerfile file: docker/coolify-realtime/Dockerfile
platforms: linux/aarch64 platforms: linux/aarch64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
labels: | labels: |
coolify.managed=true coolify.managed=true
merge-manifest: merge-manifest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
@@ -78,25 +103,43 @@ jobs:
packages: write packages: write
needs: [ amd64, aarch64 ] needs: [ amd64, aarch64 ]
steps: steps:
- name: Checkout - uses: actions/checkout@v4
uses: actions/checkout@v4
- name: Set up QEMU - uses: docker/setup-buildx-action@v3
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Get Version - name: Get Version
id: version id: version
run: | run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT
- name: Create & publish manifest
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: | run: |
docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest docker buildx imagetools create \
--append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
--append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- uses: sarisia/actions-status-discord@v1 - uses: sarisia/actions-status-discord@v1
if: always() if: always()
with: with:

View File

@@ -0,0 +1,129 @@
name: Staging Build
on:
push:
branches-ignore: ["main", "v3"]
paths-ignore:
- .github/workflows/coolify-helper.yml
- .github/workflows/coolify-helper-next.yml
- .github/workflows/coolify-realtime.yml
- .github/workflows/coolify-realtime-next.yml
- docker/coolify-helper/Dockerfile
- docker/coolify-realtime/Dockerfile
- docker/testing-host/Dockerfile
- templates/service-templates.json
env:
GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify"
jobs:
amd64:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and Push Image
uses: docker/build-push-action@v6
with:
context: .
file: docker/prod/Dockerfile
platforms: linux/amd64
push: true
tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
labels: |
coolify.managed=true
aarch64:
runs-on: [self-hosted, arm64]
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and Push Image
uses: docker/build-push-action@v6
with:
context: .
file: docker/prod/Dockerfile
platforms: linux/aarch64
push: true
tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64
labels: |
coolify.managed=true
merge-manifest:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
needs: [amd64, aarch64]
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: |
docker buildx imagetools create \
--append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
--append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
- uses: sarisia/actions-status-discord@v1
if: always()
with:
webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }}

View File

@@ -1,14 +1,15 @@
name: Coolify Testing Host (v4-non-prod) name: Coolify Testing Host
on: on:
push: push:
branches: [ "main", "next" ] branches: [ "next" ]
paths: paths:
- .github/workflows/coolify-testing-host.yml - .github/workflows/coolify-testing-host.yml
- docker/testing-host/Dockerfile - docker/testing-host/Dockerfile
env: env:
REGISTRY: ghcr.io GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-testing-host" IMAGE_NAME: "coollabsio/coolify-testing-host"
jobs: jobs:
@@ -19,21 +20,34 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/testing-host/Dockerfile file: docker/testing-host/Dockerfile
platforms: linux/amd64 platforms: linux/amd64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
labels: |
coolify.managed=true
aarch64: aarch64:
runs-on: [ self-hosted, arm64 ] runs-on: [ self-hosted, arm64 ]
permissions: permissions:
@@ -41,21 +55,34 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to ghcr.io
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image and push to registry
uses: docker/build-push-action@v5 - name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and Push Image
uses: docker/build-push-action@v6
with: with:
no-cache: true
context: . context: .
file: docker/testing-host/Dockerfile file: docker/testing-host/Dockerfile
platforms: linux/aarch64 platforms: linux/aarch64
push: true push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64
labels: |
coolify.managed=true
merge-manifest: merge-manifest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
@@ -63,21 +90,36 @@ jobs:
packages: write packages: write
needs: [ amd64, aarch64 ] needs: [ amd64, aarch64 ]
steps: steps:
- name: Checkout - uses: actions/checkout@v4
uses: actions/checkout@v4
- name: Set up QEMU - uses: docker/setup-buildx-action@v3
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Create & publish manifest
- name: Login to ${{ env.DOCKER_REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: | run: |
docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest docker buildx imagetools create \
--append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
--append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- uses: sarisia/actions-status-discord@v1 - uses: sarisia/actions-status-discord@v1
if: always() if: always()
with: with:

View File

@@ -1,79 +0,0 @@
name: Development Build (v4)
on:
push:
branches-ignore: ["main", "v3"]
paths-ignore:
- .github/workflows/coolify-helper.yml
- docker/coolify-helper/Dockerfile
env:
REGISTRY: ghcr.io
IMAGE_NAME: "coollabsio/coolify"
jobs:
amd64:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image and push to registry
uses: docker/build-push-action@v5
with:
context: .
file: docker/prod/Dockerfile
platforms: linux/amd64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
aarch64:
runs-on: [self-hosted, arm64]
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image and push to registry
uses: docker/build-push-action@v5
with:
context: .
file: docker/prod/Dockerfile
platforms: linux/aarch64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64
merge-manifest:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
needs: [amd64, aarch64]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create & publish manifest
run: |
docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
- uses: sarisia/actions-status-discord@v1
if: always()
with:
webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }}

View File

@@ -1,89 +0,0 @@
name: Production Build (v4)
on:
push:
branches: ["main"]
paths-ignore:
- .github/workflows/coolify-helper.yml
- docker/coolify-helper/Dockerfile
- templates/service-templates.json
env:
REGISTRY: ghcr.io
IMAGE_NAME: "coollabsio/coolify"
jobs:
amd64:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get Version
id: version
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5
with:
context: .
file: docker/prod/Dockerfile
platforms: linux/amd64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
aarch64:
runs-on: [self-hosted, arm64]
steps:
- uses: actions/checkout@v4
- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get Version
id: version
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT
- name: Build image and push to registry
uses: docker/build-push-action@v5
with:
context: .
file: docker/prod/Dockerfile
platforms: linux/aarch64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
merge-manifest:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
needs: [amd64, aarch64]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get Version
id: version
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT
- name: Create & publish manifest
run: |
docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- uses: sarisia/actions-status-discord@v1
if: always()
with:
webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }}

View File

@@ -17,7 +17,7 @@ class InstallDocker
throw new \Exception('Server OS type is not supported for automated installation. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://coolify.io/docs/installation#manually">documentation</a>.'); throw new \Exception('Server OS type is not supported for automated installation. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://coolify.io/docs/installation#manually">documentation</a>.');
} }
ray('Installing Docker on server: '.$server->name.' ('.$server->ip.')'.' with OS type: '.$supported_os_type); ray('Installing Docker on server: '.$server->name.' ('.$server->ip.')'.' with OS type: '.$supported_os_type);
$dockerVersion = '24.0'; $dockerVersion = '26.0';
$config = base64_encode('{ $config = base64_encode('{
"log-driver": "json-file", "log-driver": "json-file",
"log-opts": { "log-opts": {

View File

@@ -2,6 +2,7 @@
namespace App\Actions\Server; namespace App\Actions\Server;
use App\Models\InstanceSettings;
use App\Models\Server; use App\Models\Server;
use Lorisleiva\Actions\Concerns\AsAction; use Lorisleiva\Actions\Concerns\AsAction;
@@ -16,11 +17,25 @@ class StartSentinel
} }
$metrics_history = $server->settings->metrics_history_days; $metrics_history = $server->settings->metrics_history_days;
$refresh_rate = $server->settings->metrics_refresh_rate_seconds; $refresh_rate = $server->settings->metrics_refresh_rate_seconds;
$token = $server->settings->metrics_token; $token = $server->settings->sentinel_token;
instant_remote_process([ $fqdn = InstanceSettings::get()->fqdn;
"docker run --rm --pull always -d -e \"TOKEN={$token}\" -e \"SCHEDULER=true\" -e \"METRICS_HISTORY={$metrics_history}\" -e \"REFRESH_RATE={$refresh_rate}\" --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify/metrics:/app/metrics -v /data/coolify/logs:/app/logs --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 ghcr.io/coollabsio/sentinel:$version", if (str($fqdn)->startsWith('http')) {
'chown -R 9999:root /data/coolify/metrics /data/coolify/logs', throw new \Exception('You should use https to run Sentinel.');
'chmod -R 700 /data/coolify/metrics /data/coolify/logs', }
], $server, true); $environments = [
'TOKEN' => $token,
'ENDPOINT' => InstanceSettings::get()->fqdn,
'COLLECTOR_ENABLED' => 'true',
'COLLECTOR_REFRESH_RATE_SECONDS' => $refresh_rate,
'COLLECTOR_RETENTION_PERIOD_DAYS' => $metrics_history
];
$docker_environments = "-e \"" . implode("\" -e \"", array_map(fn($key, $value) => "$key=$value", array_keys($environments), $environments)) . "\"";
ray($docker_environments);
return true;
// instant_remote_process([
// "docker run --rm --pull always -d $docker_environments --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify/sentinel:/app/sentinel --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 ghcr.io/coollabsio/sentinel:$version",
// 'chown -R 9999:root /data/coolify/sentinel',
// 'chmod -R 700 /data/coolify/sentinel',
// ], $server, true);
} }
} }

View File

@@ -23,7 +23,7 @@ class ServersController extends Controller
return serializeApiResponse($settings); return serializeApiResponse($settings);
} }
$settings = $settings->makeHidden([ $settings = $settings->makeHidden([
'metrics_token', 'sentinel_token',
]); ]);
return serializeApiResponse($settings); return serializeApiResponse($settings);

View File

@@ -0,0 +1,53 @@
<?php
namespace App\Jobs;
use App\Models\Server;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
class PushServerUpdateJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 1;
public $timeout = 60;
public function backoff(): int
{
return isDev() ? 1 : 3;
}
public function __construct(public Server $server, public $data) {}
public function handle()
{
if (!$this->data) {
throw new \Exception('No data provided');
}
$data = collect($this->data);
$containers = collect(data_get($data, 'containers'));
if ($containers->isEmpty()) {
return;
}
foreach ($containers as $container) {
$containerStatus = data_get($container, 'status', 'exited');
$containerHealth = data_get($container, 'health', 'unhealthy');
$containerStatus = "$containerStatus ($containerHealth)";
$labels = collect(data_get($container, 'labels'));
if ($labels->has('coolify.applicationId')) {
$applicationId = $labels->get('coolify.applicationId');
}
Log::info("$applicationId, $containerStatus");
}
}
}

View File

@@ -7,6 +7,7 @@ use App\Actions\Server\StopSentinel;
use App\Jobs\DockerCleanupJob; use App\Jobs\DockerCleanupJob;
use App\Jobs\PullSentinelImageJob; use App\Jobs\PullSentinelImageJob;
use App\Models\Server; use App\Models\Server;
use Illuminate\Support\Facades\Http;
use Livewire\Component; use Livewire\Component;
class Form extends Component class Form extends Component
@@ -54,9 +55,9 @@ class Form extends Component
'server.settings.concurrent_builds' => 'required|integer|min:1', 'server.settings.concurrent_builds' => 'required|integer|min:1',
'server.settings.dynamic_timeout' => 'required|integer|min:1', 'server.settings.dynamic_timeout' => 'required|integer|min:1',
'server.settings.is_metrics_enabled' => 'required|boolean', 'server.settings.is_metrics_enabled' => 'required|boolean',
'server.settings.metrics_token' => 'required', 'server.settings.sentinel_token' => 'required',
'server.settings.metrics_refresh_rate_seconds' => 'required|integer|min:1', 'server.settings.sentinel_metrics_refresh_rate_seconds' => 'required|integer|min:1',
'server.settings.metrics_history_days' => 'required|integer|min:1', 'server.settings.sentinel_metrics_history_days' => 'required|integer|min:1',
'wildcard_domain' => 'nullable|url', 'wildcard_domain' => 'nullable|url',
'server.settings.is_server_api_enabled' => 'required|boolean', 'server.settings.is_server_api_enabled' => 'required|boolean',
'server.settings.server_timezone' => 'required|string|timezone', 'server.settings.server_timezone' => 'required|string|timezone',
@@ -81,9 +82,9 @@ class Form extends Component
'server.settings.concurrent_builds' => 'Concurrent Builds', 'server.settings.concurrent_builds' => 'Concurrent Builds',
'server.settings.dynamic_timeout' => 'Dynamic Timeout', 'server.settings.dynamic_timeout' => 'Dynamic Timeout',
'server.settings.is_metrics_enabled' => 'Metrics', 'server.settings.is_metrics_enabled' => 'Metrics',
'server.settings.metrics_token' => 'Metrics Token', 'server.settings.sentinel_token' => 'Metrics Token',
'server.settings.metrics_refresh_rate_seconds' => 'Metrics Interval', 'server.settings.sentinel_metrics_refresh_rate_seconds' => 'Metrics Interval',
'server.settings.metrics_history_days' => 'Metrics History', 'server.settings.sentinel_metrics_history_days' => 'Metrics History',
'server.settings.is_server_api_enabled' => 'Server API', 'server.settings.is_server_api_enabled' => 'Server API',
'server.settings.server_timezone' => 'Server Timezone', 'server.settings.server_timezone' => 'Server Timezone',
'server.settings.delete_unused_volumes' => 'Delete Unused Volumes', 'server.settings.delete_unused_volumes' => 'Delete Unused Volumes',
@@ -100,7 +101,15 @@ class Form extends Component
$this->server->settings->delete_unused_volumes = $server->settings->delete_unused_volumes; $this->server->settings->delete_unused_volumes = $server->settings->delete_unused_volumes;
$this->server->settings->delete_unused_networks = $server->settings->delete_unused_networks; $this->server->settings->delete_unused_networks = $server->settings->delete_unused_networks;
} }
public function regenerateSentinelToken() {
try {
$this->server->generateSentinelToken();
$this->server->settings->refresh();
$this->dispatch('success', 'Metrics token regenerated.');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function updated($field) public function updated($field)
{ {
if ($field === 'server.settings.docker_cleanup_frequency') { if ($field === 'server.settings.docker_cleanup_frequency') {
@@ -174,6 +183,28 @@ class Form extends Component
} }
} }
public function getPushData()
{
try {
if (!isDev()) {
throw new \Exception('This feature is only available in dev mode.');
}
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->server->settings->sentinel_token,
])->post('http://host.docker.internal:8888/api/push', [
'data' => 'test',
]);
if ($response->successful()) {
$this->dispatch('success', 'Push data sent.');
return;
}
$error = data_get($response->json(), 'error');
throw new \Exception($error);
} catch(\Throwable $e) {
return handleError($e, $this);
}
}
public function restartSentinel() public function restartSentinel()
{ {
try { try {

View File

@@ -1406,7 +1406,7 @@ class Application extends BaseModel
$container_name = $this->uuid; $container_name = $this->uuid;
if ($server->isMetricsEnabled()) { if ($server->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false);
if (str($metrics)->contains('error')) { if (str($metrics)->contains('error')) {
$error = json_decode($metrics, true); $error = json_decode($metrics, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -21,6 +21,7 @@ class InstanceSettings extends Model implements SendsEmail
'is_auto_update_enabled' => 'boolean', 'is_auto_update_enabled' => 'boolean',
'auto_update_frequency' => 'string', 'auto_update_frequency' => 'string',
'update_check_frequency' => 'string', 'update_check_frequency' => 'string',
'sentinel_token' => 'encrypted',
]; ];
public function fqdn(): Attribute public function fqdn(): Attribute

View File

@@ -17,6 +17,8 @@ use Spatie\SchemalessAttributes\Casts\SchemalessAttributes;
use Spatie\SchemalessAttributes\SchemalessAttributesTrait; use Spatie\SchemalessAttributes\SchemalessAttributesTrait;
use Spatie\Url\Url; use Spatie\Url\Url;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
use Illuminate\Support\Str;
#[OA\Schema( #[OA\Schema(
description: 'Server model', description: 'Server model',
@@ -177,7 +179,7 @@ class Server extends BaseModel
$banner = $banner =
"# This file is generated by Coolify, do not edit it manually.\n" . "# This file is generated by Coolify, do not edit it manually.\n" .
"# Disable the default redirect to customize (only if you know what are you doing).\n\n"; "# Disable the default redirect to customize (only if you know what are you doing).\n\n";
$dynamic_conf_path = $this->proxyPath().'/dynamic'; $dynamic_conf_path = $this->proxyPath() . '/dynamic';
$proxy_type = $this->proxyType(); $proxy_type = $this->proxyType();
$redirect_enabled = $this->proxy->redirect_enabled ?? true; $redirect_enabled = $this->proxy->redirect_enabled ?? true;
$redirect_url = $this->proxy->redirect_url; $redirect_url = $this->proxy->redirect_url;
@@ -267,7 +269,7 @@ class Server extends BaseModel
public function setupDynamicProxyConfiguration() public function setupDynamicProxyConfiguration()
{ {
$settings = instanceSettings(); $settings = instanceSettings();
$dynamic_config_path = $this->proxyPath().'/dynamic'; $dynamic_config_path = $this->proxyPath() . '/dynamic';
if ($this->proxyType() === ProxyTypes::TRAEFIK->value) { if ($this->proxyType() === ProxyTypes::TRAEFIK->value) {
$file = "$dynamic_config_path/coolify.yaml"; $file = "$dynamic_config_path/coolify.yaml";
if (empty($settings->fqdn) || (isCloud() && $this->id !== 0) || ! $this->isLocalhost()) { if (empty($settings->fqdn) || (isCloud() && $this->id !== 0) || ! $this->isLocalhost()) {
@@ -386,8 +388,8 @@ class Server extends BaseModel
} }
$yaml = Yaml::dump($traefik_dynamic_conf, 12, 2); $yaml = Yaml::dump($traefik_dynamic_conf, 12, 2);
$yaml = $yaml =
"# This file is automatically generated by Coolify.\n". "# This file is automatically generated by Coolify.\n" .
"# Do not edit it manually (only if you know what are you doing).\n\n". "# Do not edit it manually (only if you know what are you doing).\n\n" .
$yaml; $yaml;
$base64 = base64_encode($yaml); $base64 = base64_encode($yaml);
@@ -451,13 +453,13 @@ $schema://$host {
if (isDev()) { if (isDev()) {
$proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/caddy'; $proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/caddy';
} else { } else {
$proxy_path = $proxy_path.'/caddy'; $proxy_path = $proxy_path . '/caddy';
} }
} elseif ($proxyType === ProxyTypes::NGINX->value) { } elseif ($proxyType === ProxyTypes::NGINX->value) {
if (isDev()) { if (isDev()) {
$proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/nginx'; $proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/nginx';
} else { } else {
$proxy_path = $proxy_path.'/nginx'; $proxy_path = $proxy_path . '/nginx';
} }
} }
@@ -520,6 +522,17 @@ $schema://$host {
Storage::disk('ssh-mux')->delete($this->muxFilename()); Storage::disk('ssh-mux')->delete($this->muxFilename());
} }
public function generateSentinelToken()
{
$data = [
'server_uuid' => $this->uuid,
];
$token = json_encode($data);
$encrypted = encrypt($token);
$this->settings->sentinel_token = $encrypted;
$this->settings->save();
return $encrypted;
}
public function isSentinelEnabled() public function isSentinelEnabled()
{ {
return $this->isMetricsEnabled() || $this->isServerApiEnabled(); return $this->isMetricsEnabled() || $this->isServerApiEnabled();
@@ -550,7 +563,6 @@ $schema://$host {
ray($process->exitCode(), $process->output(), $process->errorOutput()); ray($process->exitCode(), $process->output(), $process->errorOutput());
throw new \Exception("Server API is not reachable on http://{$server_ip}:12172"); throw new \Exception("Server API is not reachable on http://{$server_ip}:12172");
} }
} }
} }
@@ -574,7 +586,7 @@ $schema://$host {
{ {
if ($this->isMetricsEnabled()) { if ($this->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$cpu = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$this->settings->metrics_token}\" http://localhost:8888/api/cpu/history?from=$from'"], $this, false); $cpu = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$this->settings->sentinel_token}\" http://localhost:8888/api/cpu/history?from=$from'"], $this, false);
if (str($cpu)->contains('error')) { if (str($cpu)->contains('error')) {
$error = json_decode($cpu, true); $error = json_decode($cpu, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');
@@ -601,7 +613,7 @@ $schema://$host {
{ {
if ($this->isMetricsEnabled()) { if ($this->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$memory = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$this->settings->metrics_token}\" http://localhost:8888/api/memory/history?from=$from'"], $this, false); $memory = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$this->settings->sentinel_token}\" http://localhost:8888/api/memory/history?from=$from'"], $this, false);
if (str($memory)->contains('error')) { if (str($memory)->contains('error')) {
$error = json_decode($memory, true); $error = json_decode($memory, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -35,9 +35,9 @@ use OpenApi\Attributes as OA;
'logdrain_highlight_project_id' => ['type' => 'string'], 'logdrain_highlight_project_id' => ['type' => 'string'],
'logdrain_newrelic_base_uri' => ['type' => 'string'], 'logdrain_newrelic_base_uri' => ['type' => 'string'],
'logdrain_newrelic_license_key' => ['type' => 'string'], 'logdrain_newrelic_license_key' => ['type' => 'string'],
'metrics_history_days' => ['type' => 'integer'], 'sentinel_metrics_history_days' => ['type' => 'integer'],
'metrics_refresh_rate_seconds' => ['type' => 'integer'], 'sentinel_metrics_refresh_rate_seconds' => ['type' => 'integer'],
'metrics_token' => ['type' => 'string'], 'sentinel_token' => ['type' => 'string'],
'docker_cleanup_frequency' => ['type' => 'string'], 'docker_cleanup_frequency' => ['type' => 'string'],
'docker_cleanup_threshold' => ['type' => 'integer'], 'docker_cleanup_threshold' => ['type' => 'integer'],
'server_id' => ['type' => 'integer'], 'server_id' => ['type' => 'integer'],
@@ -53,6 +53,7 @@ class ServerSetting extends Model
protected $casts = [ protected $casts = [
'force_docker_cleanup' => 'boolean', 'force_docker_cleanup' => 'boolean',
'docker_cleanup_threshold' => 'integer', 'docker_cleanup_threshold' => 'integer',
'sentinel_token' => 'encrypted',
]; ];
public function server() public function server()

View File

@@ -272,7 +272,7 @@ class StandaloneClickhouse extends BaseModel
$container_name = $this->uuid; $container_name = $this->uuid;
if ($server->isMetricsEnabled()) { if ($server->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false);
if (str($metrics)->contains('error')) { if (str($metrics)->contains('error')) {
$error = json_decode($metrics, true); $error = json_decode($metrics, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -272,7 +272,7 @@ class StandaloneDragonfly extends BaseModel
$container_name = $this->uuid; $container_name = $this->uuid;
if ($server->isMetricsEnabled()) { if ($server->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false);
if (str($metrics)->contains('error')) { if (str($metrics)->contains('error')) {
$error = json_decode($metrics, true); $error = json_decode($metrics, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -272,7 +272,7 @@ class StandaloneKeydb extends BaseModel
$container_name = $this->uuid; $container_name = $this->uuid;
if ($server->isMetricsEnabled()) { if ($server->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false);
if (str($metrics)->contains('error')) { if (str($metrics)->contains('error')) {
$error = json_decode($metrics, true); $error = json_decode($metrics, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -272,7 +272,7 @@ class StandaloneMariadb extends BaseModel
$container_name = $this->uuid; $container_name = $this->uuid;
if ($server->isMetricsEnabled()) { if ($server->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false);
if (str($metrics)->contains('error')) { if (str($metrics)->contains('error')) {
$error = json_decode($metrics, true); $error = json_decode($metrics, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -292,7 +292,7 @@ class StandaloneMongodb extends BaseModel
$container_name = $this->uuid; $container_name = $this->uuid;
if ($server->isMetricsEnabled()) { if ($server->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false);
if (str($metrics)->contains('error')) { if (str($metrics)->contains('error')) {
$error = json_decode($metrics, true); $error = json_decode($metrics, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -273,7 +273,7 @@ class StandaloneMysql extends BaseModel
$container_name = $this->uuid; $container_name = $this->uuid;
if ($server->isMetricsEnabled()) { if ($server->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false);
if (str($metrics)->contains('error')) { if (str($metrics)->contains('error')) {
$error = json_decode($metrics, true); $error = json_decode($metrics, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -274,7 +274,7 @@ class StandalonePostgresql extends BaseModel
$container_name = $this->uuid; $container_name = $this->uuid;
if ($server->isMetricsEnabled()) { if ($server->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false);
if (str($metrics)->contains('error')) { if (str($metrics)->contains('error')) {
$error = json_decode($metrics, true); $error = json_decode($metrics, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -268,7 +268,7 @@ class StandaloneRedis extends BaseModel
$container_name = $this->uuid; $container_name = $this->uuid;
if ($server->isMetricsEnabled()) { if ($server->isMetricsEnabled()) {
$from = now()->subMinutes($mins)->toIso8601ZuluString(); $from = now()->subMinutes($mins)->toIso8601ZuluString();
$metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false);
if (str($metrics)->contains('error')) { if (str($metrics)->contains('error')) {
$error = json_decode($metrics, true); $error = json_decode($metrics, true);
$error = data_get($error, 'error', 'Something is not okay, are you okay?'); $error = data_get($error, 'error', 'Something is not okay, are you okay?');

View File

@@ -1338,13 +1338,6 @@ function isAnyDeploymentInprogress()
exit(0); exit(0);
} }
function generateSentinelToken()
{
$token = Str::random(64);
return $token;
}
function isBase64Encoded($strValue) function isBase64Encoded($strValue)
{ {
return base64_encode(base64_decode($strValue, true)) === $strValue; return base64_encode(base64_decode($strValue, true)) === $strValue;

View File

@@ -8,6 +8,7 @@ return [
// The release version of your application // The release version of your application
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
'release' => '4.0.0-beta.361', 'release' => '4.0.0-beta.361',
// When left empty or `null` the Laravel environment will be used // When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'), 'environment' => config('app.env'),

View File

@@ -18,7 +18,7 @@ return new class extends Migration
$table->boolean('is_metrics_enabled')->default(false); $table->boolean('is_metrics_enabled')->default(false);
$table->integer('metrics_refresh_rate_seconds')->default(5); $table->integer('metrics_refresh_rate_seconds')->default(5);
$table->integer('metrics_history_days')->default(30); $table->integer('metrics_history_days')->default(30);
$table->string('metrics_token')->default(generateSentinelToken()); $table->string('metrics_token')->nullable();
}); });
} }

View File

@@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('server_settings', function (Blueprint $table) {
$table->dropColumn('metrics_token');
$table->dropColumn('metrics_refresh_rate_seconds');
$table->dropColumn('metrics_history_days');
$table->text('sentinel_token')->nullable();
$table->integer('sentinel_metrics_refresh_rate_seconds')->default(5);
$table->integer('sentinel_metrics_history_days')->default(30);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('server_settings', function (Blueprint $table) {
$table->string('metrics_token')->nullable();
$table->integer('metrics_refresh_rate_seconds')->default(5);
$table->integer('metrics_history_days')->default(30);
$table->dropColumn('sentinel_token');
$table->dropColumn('sentinel_metrics_refresh_rate_seconds');
$table->dropColumn('sentinel_metrics_history_days');
});
}
};

View File

@@ -26,5 +26,12 @@
"input.code": "الرمز لمرة واحدة", "input.code": "الرمز لمرة واحدة",
"input.recovery_code": "رمز الاسترداد", "input.recovery_code": "رمز الاسترداد",
"button.save": "حفظ", "button.save": "حفظ",
"repository.url": "<span class='text-helper'>أمثلة</span><br>للمستودعات العامة، استخدم <span class='text-helper'>https://...</span>.<br>للمستودعات الخاصة، استخدم <span class='text-helper'>git@...</span>.<br><br>سيتم تحديد الفرع <span class='text-helper'>main</span> لـ <span class='text-helper'>https://github.com/coollabsio/coolify-examples</span><br>سيتم تحديد الفرع <span class='text-helper'>nodejs-fastify</span> لـ <span class='text-helper'>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify</span><br>سيتم تحديد الفرع <span class='text-helper'>main</span> لـ <span class='text-helper'>https://gitea.com/sedlav/expressjs.git</span><br>سيتم تحديد الفرع <span class='text-helper'>main</span> لـ <span class='text-helper'>https://gitlab.com/andrasbacsai/nodejs-example.git</span>." "repository.url": "<span class='text-helper'>أمثلة</span><br>للمستودعات العامة، استخدم <span class='text-helper'>https://...</span>.<br>للمستودعات الخاصة، استخدم <span class='text-helper'>git@...</span>.<br><br>سيتم تحديد الفرع <span class='text-helper'>main</span> لـ <span class='text-helper'>https://github.com/coollabsio/coolify-examples</span><br>سيتم تحديد الفرع <span class='text-helper'>nodejs-fastify</span> لـ <span class='text-helper'>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify</span><br>سيتم تحديد الفرع <span class='text-helper'>main</span> لـ <span class='text-helper'>https://gitea.com/sedlav/expressjs.git</span><br>سيتم تحديد الفرع <span class='text-helper'>main</span> لـ <span class='text-helper'>https://gitlab.com/andrasbacsai/nodejs-example.git</span>.",
"service.stop": "سيتم إيقاف هذه الخدمة.",
"resource.docker_cleanup": "قم بتشغيل Docker Cleanup (قم بإزالة الصور غير المستخدمة وذاكرة التخزين المؤقت للمنشئ).",
"resource.non_persistent": "سيتم حذف جميع البيانات غير الدائمة.",
"resource.delete_volumes": "حذف جميع المجلدات والملفات المرتبطة بهذا المورد بشكل دائم.",
"resource.delete_connected_networks": "حذف جميع الشبكات غير المحددة مسبقًا والمرتبطة بهذا المورد بشكل دائم.",
"resource.delete_configurations": "حذف جميع ملفات التعريف من الخادم بشكل دائم.",
"database.delete_backups_locally": "حذف كافة النسخ الاحتياطية نهائيًا من التخزين المحلي."
} }

37
lang/ro.json Normal file
View File

@@ -0,0 +1,37 @@
{
"auth.login": "Autentificare",
"auth.login.azure": "Autentificare prin Microsoft",
"auth.login.bitbucket": "Autentificare prin Bitbucket",
"auth.login.github": "Autentificare prin GitHub",
"auth.login.gitlab": "Autentificare prin Gitlab",
"auth.login.google": "Autentificare prin Google",
"auth.already_registered": "Sunteți deja înregistrat?",
"auth.confirm_password": "Confirmați parola",
"auth.forgot_password": "Ați uitat parola",
"auth.forgot_password_send_email": "Trimiteți e-mail-ul pentru resetarea parolei",
"auth.register_now": "Înregistrare",
"auth.logout": "Deconectare",
"auth.register": "Înregistrare",
"auth.registration_disabled": "Înregistrarea este dezactivată. Vă rugăm să contactați administratorul site-ului.",
"auth.reset_password": "Resetare parolă",
"auth.failed": "Autentificare nereușită. Vă rugăm să verificați datele introduse.",
"auth.failed.callback": "A apărut o eroare în timpul autentificării cu furnizorul extern.",
"auth.failed.password": "Parola furnizată este incorectă.",
"auth.failed.email": "Nu putem găsi un utilizator cu această adresă de e-mail.",
"auth.throttle": "Prea multe încercări de autentificare. Vă rugăm să încercați din nou în :seconds secunde.",
"input.name": "Nume",
"input.email": "E-mail",
"input.password": "Parolă",
"input.password.again": "Repetați parola",
"input.code": "Cod de unică folosință",
"input.recovery_code": "Cod de recuperare",
"button.save": "Salvare",
"repository.url": "<span class='text-helper'>Exemple</span><br>Pentru depozite publice, utilizați <span class='text-helper'>https://...</span>.<br>Pentru depozite private, utilizați <span class='text-helper'>git@...</span>.<br><br>https://github.com/coollabsio/coolify-examples va fi selectată ramura <span class='text-helper'>main</span><br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify va fi selectată ramura <span class='text-helper'>nodejs-fastify</span>.<br>https://gitea.com/sedlav/expressjs.git va fi selectată ramura <span class='text-helper'>main</span>.<br>https://gitlab.com/andrasbacsai/nodejs-example.git va fi selectată ramura <span class='text-helper'>main</span>.",
"service.stop": "Acest serviciu va fi oprit.",
"resource.docker_cleanup": "Executați curățarea Docker (eliminați imaginile neutilizate și memoria cache a constructorului).",
"resource.non_persistent": "Toate datele nepersistente vor fi șterse.",
"resource.delete_volumes": "Ștergeți definitiv toate volumele asociate cu această resursă.",
"resource.delete_connected_networks": "Ștergeți definitiv toate rețelele non-predefinite asociate cu această resursă.",
"resource.delete_configurations": "Ștergeți definitiv toate fișierele de configurare de pe server.",
"database.delete_backups_locally": "Toate copiile de rezervă vor fi șterse definitiv din stocarea locală."
}

View File

@@ -4981,11 +4981,11 @@ components:
type: string type: string
logdrain_newrelic_license_key: logdrain_newrelic_license_key:
type: string type: string
metrics_history_days: sentinel_metrics_refresh_rate_seconds:
type: integer type: integer
metrics_refresh_rate_seconds: sentinel_metrics_history_days:
type: integer type: integer
metrics_token: sentinel_token:
type: string type: string
docker_cleanup_frequency: docker_cleanup_frequency:
type: string type: string

View File

@@ -68,7 +68,8 @@
</div> </div>
<div class="flex flex-col gap-2 w-full lg:flex-row"> <div class="flex flex-col gap-2 w-full lg:flex-row">
<x-forms.input type="password" id="server.ip" label="IP Address/Domain" <x-forms.input type="password" id="server.ip" label="IP Address/Domain"
helper="An IP Address (127.0.0.1) or domain (example.com). Make sure there is no protocol like http(s):// so you provide a FQDN not a URL." required /> helper="An IP Address (127.0.0.1) or domain (example.com). Make sure there is no protocol like http(s):// so you provide a FQDN not a URL."
required />
<div class="flex gap-2"> <div class="flex gap-2">
<x-forms.input id="server.user" label="User" required /> <x-forms.input id="server.user" label="User" required />
<x-forms.input type="number" id="server.port" label="Port" required /> <x-forms.input type="number" id="server.port" label="Port" required />
@@ -94,7 +95,8 @@
</div> </div>
<div class="relative"> <div class="relative">
<div class="inline-flex relative items-center w-64"> <div class="inline-flex relative items-center w-64">
<input autocomplete="off" wire:dirty.class.remove='dark:focus:ring-coolgray-300 dark:ring-coolgray-300' <input autocomplete="off"
wire:dirty.class.remove='dark:focus:ring-coolgray-300 dark:ring-coolgray-300'
wire:dirty.class="dark:focus:ring-warning dark:ring-warning" x-model="search" wire:dirty.class="dark:focus:ring-warning dark:ring-warning" x-model="search"
@focus="open = true" @click.away="open = false" @input="open = true" class="w-full input" @focus="open = true" @click.away="open = false" @input="open = true" class="w-full input"
:placeholder="placeholder" wire:model.debounce.300ms="server.settings.server_timezone"> :placeholder="placeholder" wire:model.debounce.300ms="server.settings.server_timezone">
@@ -129,23 +131,32 @@
</div> </div>
@if ($server->settings->is_cloudflare_tunnel) @if ($server->settings->is_cloudflare_tunnel)
<div class="w-64"> <div class="w-64">
<x-forms.checkbox instantSave id="server.settings.is_cloudflare_tunnel" label="Enabled" /> <x-forms.checkbox instantSave id="server.settings.is_cloudflare_tunnel"
label="Enabled" />
</div> </div>
@elseif (!$server->isFunctional()) @elseif (!$server->isFunctional())
<div class="p-4 mb-4 w-full text-sm text-yellow-800 bg-yellow-100 rounded dark:bg-yellow-900 dark:text-yellow-300"> <div
To <span class="font-semibold">automatically</span> configure Cloudflare Tunnels, please validate your server first.</span> Then you will need a Cloudflare token and an SSH domain configured. class="p-4 mb-4 w-full text-sm text-yellow-800 bg-yellow-100 rounded dark:bg-yellow-900 dark:text-yellow-300">
<br/> To <span class="font-semibold">automatically</span> configure Cloudflare Tunnels, please
To <span class="font-semibold">manually</span> configure Cloudflare Tunnels, please click <span wire:click="manualCloudflareConfig" class="underline cursor-pointer">here</span>, then you should validate the server. validate your server first.</span> Then you will need a Cloudflare token and an SSH
<br/><br/> domain configured.
For more information, please read our <a href="https://coolify.io/docs/knowledge-base/cloudflare/tunnels/" target="_blank" class="font-medium underline hover:text-yellow-600 dark:hover:text-yellow-200">documentation</a>. <br />
To <span class="font-semibold">manually</span> configure Cloudflare Tunnels, please
click <span wire:click="manualCloudflareConfig"
class="underline cursor-pointer">here</span>, then you should validate the server.
<br /><br />
For more information, please read our <a
href="https://coolify.io/docs/knowledge-base/cloudflare/tunnels/" target="_blank"
class="font-medium underline hover:text-yellow-600 dark:hover:text-yellow-200">documentation</a>.
</div> </div>
@endif @endif
@if (!$server->settings->is_cloudflare_tunnel && $server->isFunctional()) @if (!$server->settings->is_cloudflare_tunnel && $server->isFunctional())
<x-modal-input buttonTitle="Automated Configuration" title="Cloudflare Tunnels" class="w-full" :closeOutside="false"> <x-modal-input buttonTitle="Automated Configuration" title="Cloudflare Tunnels"
class="w-full" :closeOutside="false">
<livewire:server.configure-cloudflare-tunnels :server_id="$server->id" /> <livewire:server.configure-cloudflare-tunnels :server_id="$server->id" />
</x-modal-input> </x-modal-input>
@endif @endif
@if ($server->isFunctional() &&!$server->settings->is_cloudflare_tunnel) @if ($server->isFunctional() && !$server->settings->is_cloudflare_tunnel)
<div wire:click="manualCloudflareConfig" class="w-full underline cursor-pointer"> <div wire:click="manualCloudflareConfig" class="w-full underline cursor-pointer">
I have configured Cloudflare Tunnels manually I have configured Cloudflare Tunnels manually
</div> </div>
@@ -201,57 +212,58 @@
</ul>" </ul>"
instantSave id="server.settings.force_docker_cleanup" label="Force Docker Cleanup" /> instantSave id="server.settings.force_docker_cleanup" label="Force Docker Cleanup" />
</div> </div>
<x-modal-confirmation <x-modal-confirmation title="Confirm Docker Cleanup?" buttonTitle="Trigger Docker Cleanup"
title="Confirm Docker Cleanup?" submitAction="manualCleanup" :actions="[
buttonTitle="Trigger Docker Cleanup"
submitAction="manualCleanup"
:actions="[
'Permanently deletes all stopped containers managed by Coolify (as containers are non-persistent, no data will be lost)', 'Permanently deletes all stopped containers managed by Coolify (as containers are non-persistent, no data will be lost)',
'Permanently deletes all unused images', 'Permanently deletes all unused images',
'Clears build cache', 'Clears build cache',
'Removes old versions of the Coolify helper image', 'Removes old versions of the Coolify helper image',
'Optionally permanently deletes all unused volumes (if enabled in advanced options).', 'Optionally permanently deletes all unused volumes (if enabled in advanced options).',
'Optionally permanently deletes all unused networks (if enabled in advanced options).' 'Optionally permanently deletes all unused networks (if enabled in advanced options).',
]" ]" :confirmWithText="false" :confirmWithPassword="false"
:confirmWithText="false" step2ButtonText="Trigger Docker Cleanup" />
:confirmWithPassword="false"
step2ButtonText="Trigger Docker Cleanup"
/>
</div> </div>
@if ($server->settings->force_docker_cleanup) @if ($server->settings->force_docker_cleanup)
<x-forms.input placeholder="*/10 * * * *" id="server.settings.docker_cleanup_frequency" <x-forms.input placeholder="*/10 * * * *" id="server.settings.docker_cleanup_frequency"
label="Docker cleanup frequency" required label="Docker cleanup frequency" required
helper="Cron expression for Docker Cleanup.<br>You can use every_minute, hourly, daily, weekly, monthly, yearly.<br><br>Default is every night at midnight." /> helper="Cron expression for Docker Cleanup.<br>You can use every_minute, hourly, daily, weekly, monthly, yearly.<br><br>Default is every night at midnight." />
@else @else
<x-forms.input id="server.settings.docker_cleanup_threshold" <x-forms.input id="server.settings.docker_cleanup_threshold"
label="Docker cleanup threshold (%)" required label="Docker cleanup threshold (%)" required
helper="The Docker cleanup tasks will run when the disk usage exceeds this threshold." /> helper="The Docker cleanup tasks will run when the disk usage exceeds this threshold." />
@endif @endif
<div x-data="{ open: false }" class="mt-4 max-w-md"> <div x-data="{ open: false }" class="mt-4 max-w-md">
<button @click="open = !open" type="button" class="flex items-center justify-between w-full text-left text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100"> <button @click="open = !open" type="button"
class="flex items-center justify-between w-full text-left text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100">
<span>Advanced Options</span> <span>Advanced Options</span>
<svg :class="{'rotate-180': open}" class="w-5 h-5 transition-transform duration-200" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"> <svg :class="{ 'rotate-180': open }" class="w-5 h-5 transition-transform duration-200"
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /> xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd" />
</svg> </svg>
</button> </button>
<div x-show="open" class="mt-2 space-y-2"> <div x-show="open" class="mt-2 space-y-2">
<p class="text-sm text-gray-600 dark:text-gray-400 mb-2"><strong>Warning: Enable these options only if you fully understand their implications and consequences!</strong><br>Improper use will result in data loss and could cause functional issues.</p> <p class="text-sm text-gray-600 dark:text-gray-400 mb-2"><strong>Warning: Enable these
<x-forms.checkbox instantSave id="server.settings.delete_unused_volumes" label="Delete Unused Volumes" options only if you fully understand their implications and
consequences!</strong><br>Improper use will result in data loss and could cause
functional issues.</p>
<x-forms.checkbox instantSave id="server.settings.delete_unused_volumes"
label="Delete Unused Volumes"
helper="This option will remove all unused Docker volumes during cleanup.<br><br><strong>Warning: Data form stopped containers will be lost!</strong><br><br>Consequences include:<br> helper="This option will remove all unused Docker volumes during cleanup.<br><br><strong>Warning: Data form stopped containers will be lost!</strong><br><br>Consequences include:<br>
<ul class='list-disc pl-4 mt-2'> <ul class='list-disc pl-4 mt-2'>
<li>Volumes not attached to running containers will be deleted and data will be permanently lost (stopped containers are affected).</li> <li>Volumes not attached to running containers will be deleted and data will be permanently lost (stopped containers are affected).</li>
<li>Data from stopped containers volumes will be permanently lost.</li> <li>Data from stopped containers volumes will be permanently lost.</li>
<li>No way to recover deleted volume data.</li> <li>No way to recover deleted volume data.</li>
</ul>" </ul>" />
/> <x-forms.checkbox instantSave id="server.settings.delete_unused_networks"
<x-forms.checkbox instantSave id="server.settings.delete_unused_networks" label="Delete Unused Networks" label="Delete Unused Networks"
helper="This option will remove all unused Docker networks during cleanup.<br><br><strong>Warning: Functionality may be lost and containers may not be able to communicate with each other!</strong><br><br>Consequences include:<br> helper="This option will remove all unused Docker networks during cleanup.<br><br><strong>Warning: Functionality may be lost and containers may not be able to communicate with each other!</strong><br><br>Consequences include:<br>
<ul class='list-disc pl-4 mt-2'> <ul class='list-disc pl-4 mt-2'>
<li>Networks not attached to running containers will be permanently deleted (stopped containers are affected).</li> <li>Networks not attached to running containers will be permanently deleted (stopped containers are affected).</li>
<li>Custom networks for stopped containers will be permanently deleted.</li> <li>Custom networks for stopped containers will be permanently deleted.</li>
<li>Functionality may be lost and containers may not be able to communicate with each other.</li> <li>Functionality may be lost and containers may not be able to communicate with each other.</li>
</ul>" </ul>" />
/>
</div> </div>
</div> </div>
</div> </div>
@@ -269,21 +281,30 @@
{{-- <x-forms.button wire:click='restartSentinel'>Restart</x-forms.button> --}} {{-- <x-forms.button wire:click='restartSentinel'>Restart</x-forms.button> --}}
{{-- @endif --}} {{-- @endif --}}
</div> </div>
<div>Metrics are disabled until a few bugs are fixed.</div> @if (isDev())
{{-- <div class="w-64"> <x-forms.button wire:click="getPushData">Get Push Data</x-forms.button>
{{-- <div class="w-64">
<x-forms.checkbox instantSave id="server.settings.is_metrics_enabled" label="Enable Metrics" /> <x-forms.checkbox instantSave id="server.settings.is_metrics_enabled" label="Enable Metrics" />
</div> <x-forms.button>Start Sentinel</x-forms.button>
<div class="pt-4"> </div> --}}
<div class="flex flex-wrap gap-2 sm:flex-nowrap"> <div class="flex flex-col gap-2">
<x-forms.input type="password" id="server.settings.metrics_token" label="Metrics token" required <div class="flex flex-wrap gap-2 sm:flex-nowrap items-end">
helper="Token for collector (Sentinel)." /> <x-forms.input type="password" id="server.settings.sentinel_token" label="Metrics token"
<x-forms.input id="server.settings.metrics_refresh_rate_seconds" label="Metrics rate (seconds)" required helper="Token for collector (Sentinel)." />
required <x-forms.button wire:click="regenerateSentinelToken">Regenerate</x-forms.button>
helper="The interval for gathering metrics. Lower means more disk space will be used." /> </div>
<x-forms.input id="server.settings.metrics_history_days" label="Metrics history (days)" required <div class="flex flex-wrap gap-2 sm:flex-nowrap">
helper="How many days should the metrics data should be reserved." /> <x-forms.input id="server.settings.sentinel_metrics_refresh_rate_seconds"
label="Metrics rate (seconds)" required
helper="The interval for gathering metrics. Lower means more disk space will be used." />
<x-forms.input id="server.settings.sentinel_metrics_history_days"
label="Metrics history (days)" required
helper="How many days should the metrics data should be reserved." />
</div>
</div> </div>
</div> --}} @else
<div>Metrics are disabled until a few bugs are fixed.</div>
@endif
@endif @endif
</form> </form>
</div> </div>

View File

@@ -13,6 +13,9 @@ use App\Http\Controllers\Api\TeamController;
use App\Http\Middleware\ApiAllowed; use App\Http\Middleware\ApiAllowed;
use App\Http\Middleware\IgnoreReadOnlyApiToken; use App\Http\Middleware\IgnoreReadOnlyApiToken;
use App\Http\Middleware\OnlyRootApiToken; use App\Http\Middleware\OnlyRootApiToken;
use App\Jobs\PushServerUpdateJob;
use App\Models\Server;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::get('/health', [OtherController::class, 'healthcheck']); Route::get('/health', [OtherController::class, 'healthcheck']);
@@ -129,6 +132,28 @@ Route::group([
}); });
Route::group([
'prefix' => 'v1',
], function () {
Route::post('/sentinel/push', function () {
$token = request()->header('Authorization');
if (!$token) {
return response()->json(['message' => 'Unauthorized'], 401);
}
$naked_token = str_replace('Bearer ', '', $token);
$decrypted = decrypt($naked_token);
$decrypted_token = json_decode($decrypted, true);
$server_uuid = data_get($decrypted_token, 'server_uuid');
$server = Server::where('uuid', $server_uuid)->first();
if (!$server) {
return response()->json(['message' => 'Server not found'], 404);
}
$data = request()->all();
PushServerUpdateJob::dispatch($server, $data);
return response()->json(['message' => 'ok'], 200);
});
});
Route::any('/{any}', function () { Route::any('/{any}', function () {
return response()->json(['message' => 'Not found.', 'docs' => 'https://coolify.io/docs'], 404); return response()->json(['message' => 'Not found.', 'docs' => 'https://coolify.io/docs'], 404);
})->where('any', '.*'); })->where('any', '.*');

View File

@@ -13,7 +13,7 @@ DOCKER_VERSION="26.0"
# TODO: Ask for a user # TODO: Ask for a user
CURRENT_USER=$USER CURRENT_USER=$USER
mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance,metrics,logs} mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance,sentinel}
mkdir -p /data/coolify/ssh/{keys,mux} mkdir -p /data/coolify/ssh/{keys,mux}
mkdir -p /data/coolify/proxy/dynamic mkdir -p /data/coolify/proxy/dynamic