commit
58af09114b
10
.github/workflows/pocketbase-release.yml
vendored
10
.github/workflows/pocketbase-release.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
|||||||
context: others/pocketbase/
|
context: others/pocketbase/
|
||||||
platforms: linux/arm64
|
platforms: linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: coollabsio/pocketbase:0.10.2-arm64
|
tags: coollabsio/pocketbase:0.11.0-arm64
|
||||||
amd64:
|
amd64:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@ -48,7 +48,7 @@ jobs:
|
|||||||
context: others/pocketbase/
|
context: others/pocketbase/
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
push: true
|
push: true
|
||||||
tags: coollabsio/pocketbase:0.10.2-amd64
|
tags: coollabsio/pocketbase:0.11.0-amd64
|
||||||
aarch64:
|
aarch64:
|
||||||
runs-on: [self-hosted, arm64]
|
runs-on: [self-hosted, arm64]
|
||||||
steps:
|
steps:
|
||||||
@ -69,7 +69,7 @@ jobs:
|
|||||||
context: others/pocketbase/
|
context: others/pocketbase/
|
||||||
platforms: linux/aarch64
|
platforms: linux/aarch64
|
||||||
push: true
|
push: true
|
||||||
tags: coollabsio/pocketbase:0.10.2-aarch64
|
tags: coollabsio/pocketbase:0.11.0-aarch64
|
||||||
merge-manifest:
|
merge-manifest:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [amd64, arm64, aarch64]
|
needs: [amd64, arm64, aarch64]
|
||||||
@ -87,5 +87,5 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
- name: Create & publish manifest
|
- name: Create & publish manifest
|
||||||
run: |
|
run: |
|
||||||
docker manifest create coollabsio/pocketbase:0.10.2 --amend coollabsio/pocketbase:0.10.2-amd64 --amend coollabsio/pocketbase:0.10.2-arm64 --amend coollabsio/pocketbase:0.10.2-aarch64
|
docker manifest create coollabsio/pocketbase:0.11.0 --amend coollabsio/pocketbase:0.11.0-amd64 --amend coollabsio/pocketbase:0.11.0-arm64 --amend coollabsio/pocketbase:0.11.0-aarch64
|
||||||
docker manifest push coollabsio/pocketbase:0.10.2
|
docker manifest push coollabsio/pocketbase:0.11.0
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,6 +12,7 @@ dist
|
|||||||
apps/api/db/*.db
|
apps/api/db/*.db
|
||||||
apps/api/db/migration.db-journal
|
apps/api/db/migration.db-journal
|
||||||
apps/api/core*
|
apps/api/core*
|
||||||
|
apps/server/build
|
||||||
apps/backup/backups/*
|
apps/backup/backups/*
|
||||||
!apps/backup/backups/.gitkeep
|
!apps/backup/backups/.gitkeep
|
||||||
/logs
|
/logs
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,3 +1,227 @@
|
|||||||
|
- templateVersion: 1.0.0
|
||||||
|
defaultVersion: "9.22"
|
||||||
|
documentation: https://docs.directus.io/getting-started/introduction.html
|
||||||
|
type: directus-postgresql
|
||||||
|
name: Directus
|
||||||
|
subname: (PostgreSQL)
|
||||||
|
description: >-
|
||||||
|
Directus is a free and open-source headless CMS framework for managing custom SQL-based databases.
|
||||||
|
labels:
|
||||||
|
- CMS
|
||||||
|
- headless
|
||||||
|
services:
|
||||||
|
$$id:
|
||||||
|
name: Directus
|
||||||
|
depends_on:
|
||||||
|
- $$id-postgresql
|
||||||
|
- $$id-redis
|
||||||
|
image: directus/directus:$$core_version
|
||||||
|
volumes:
|
||||||
|
- $$id-uploads:/directus/uploads
|
||||||
|
- $$id-database:/directus/database
|
||||||
|
- $$id-extensions:/directus/extensions
|
||||||
|
environment:
|
||||||
|
- KEY=$$secret_key
|
||||||
|
- SECRET=$$secret_secret
|
||||||
|
- DB_CLIENT=pg
|
||||||
|
- DB_CONNECTION_STRING=$$secret_db_connection_string
|
||||||
|
- CACHE_ENABLED=true
|
||||||
|
- CACHE_STORE=redis
|
||||||
|
- CACHE_REDIS=$$secret_cache_redis
|
||||||
|
- ADMIN_EMAIL=$$config_admin_email
|
||||||
|
- ADMIN_PASSWORD=$$secret_admin_password
|
||||||
|
- CACHE_AUTO_PURGE=true
|
||||||
|
- PUBLIC_URL=$$config_public_url
|
||||||
|
ports:
|
||||||
|
- "8055"
|
||||||
|
$$id-postgresql:
|
||||||
|
name: Directus PostgreSQL
|
||||||
|
depends_on: []
|
||||||
|
image: postgres:14-alpine
|
||||||
|
volumes:
|
||||||
|
- $$id-postgresql-data:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=$$config_postgres_user
|
||||||
|
- POSTGRES_PASSWORD=$$secret_postgres_password
|
||||||
|
- POSTGRES_DB=$$config_postgres_db
|
||||||
|
ports: []
|
||||||
|
$$id-redis:
|
||||||
|
name: Directus Redis
|
||||||
|
depends_on: []
|
||||||
|
image: redis:7.0.4-alpine
|
||||||
|
command: "--maxmemory 512mb --maxmemory-policy allkeys-lru --maxmemory-samples 5"
|
||||||
|
volumes:
|
||||||
|
- "$$id-redis:/data"
|
||||||
|
environment: []
|
||||||
|
variables:
|
||||||
|
- id: $$config_public_url
|
||||||
|
name: PUBLIC_URL
|
||||||
|
label: Public URL
|
||||||
|
defaultValue: $$generate_fqdn
|
||||||
|
description: ""
|
||||||
|
- id: $$secret_db_connection_string
|
||||||
|
name: DB_CONNECTION_STRING
|
||||||
|
label: Directus Database Url
|
||||||
|
defaultValue: postgresql://$$config_postgres_user:$$secret_postgres_password@$$id-postgresql:5432/$$config_postgres_db
|
||||||
|
description: ""
|
||||||
|
- id: $$config_postgres_db
|
||||||
|
main: $$id-postgresql
|
||||||
|
name: POSTGRES_DB
|
||||||
|
label: Database
|
||||||
|
defaultValue: directus
|
||||||
|
description: ""
|
||||||
|
- id: $$config_postgres_user
|
||||||
|
main: $$id-postgresql
|
||||||
|
name: POSTGRES_USER
|
||||||
|
label: User
|
||||||
|
defaultValue: $$generate_username
|
||||||
|
description: ""
|
||||||
|
- id: $$secret_postgres_password
|
||||||
|
main: $$id-postgresql
|
||||||
|
name: POSTGRES_PASSWORD
|
||||||
|
label: Password
|
||||||
|
defaultValue: $$generate_password
|
||||||
|
description: ""
|
||||||
|
showOnConfiguration: true
|
||||||
|
- id: $$secret_cache_redis
|
||||||
|
name: CACHE_REDIS
|
||||||
|
label: Redis Url
|
||||||
|
defaultValue: redis://$$id-redis:6379
|
||||||
|
description: ""
|
||||||
|
- id: $$config_admin_email
|
||||||
|
name: ADMIN_EMAIL
|
||||||
|
label: Initial Admin Email
|
||||||
|
defaultValue: "admin@example.com"
|
||||||
|
description: "The email address of the first user that is automatically created. You can change it later in Directus."
|
||||||
|
- id: $$secret_admin_password
|
||||||
|
name: ADMIN_PASSWORD
|
||||||
|
label: Initial Admin Password
|
||||||
|
defaultValue: $$generate_password
|
||||||
|
description: "The password of the first user that is automatically created."
|
||||||
|
showOnConfiguration: true
|
||||||
|
- id: $$secret_key
|
||||||
|
name: KEY
|
||||||
|
label: Key
|
||||||
|
defaultValue: $$generate_password
|
||||||
|
description: "Unique identifier for the project."
|
||||||
|
showOnConfiguration: true
|
||||||
|
- id: $$secret_secret
|
||||||
|
name: SECRET
|
||||||
|
label: Secret
|
||||||
|
defaultValue: $$generate_password
|
||||||
|
description: "Secret string for the project."
|
||||||
|
showOnConfiguration: true
|
||||||
|
|
||||||
|
- templateVersion: 1.0.0
|
||||||
|
defaultVersion: v1.3.8
|
||||||
|
documentation: https://github.com/LibreTranslate/LibreTranslate
|
||||||
|
description: Free and Open Source Machine Translation API. 100% self-hosted, offline capable and easy to setup.
|
||||||
|
type: libretranslate
|
||||||
|
name: Libretranslate
|
||||||
|
labels:
|
||||||
|
- translator
|
||||||
|
- argos
|
||||||
|
- python
|
||||||
|
- libretranslate
|
||||||
|
services:
|
||||||
|
$$id:
|
||||||
|
name: Libretranslate
|
||||||
|
image: libretranslate/libretranslate:$$core_version
|
||||||
|
environment:
|
||||||
|
- LT_HOST=0.0.0.0
|
||||||
|
- LT_SUGGESTIONS=true
|
||||||
|
- LT_CHAR_LIMIT=$$config_lt_char_limit
|
||||||
|
- LT_REQ_LIMIT=$$config_lt_req_limit
|
||||||
|
- LT_BATCH_LIMIT=$$config_lt_batch_limit
|
||||||
|
- LT_GA_ID=$$config_lt_ga_id
|
||||||
|
- LT_DISABLE_WEB_UI=$$config_lt_web_ui
|
||||||
|
volumes:
|
||||||
|
- $$id-libretranslate:/libretranslate
|
||||||
|
ports:
|
||||||
|
- "5000"
|
||||||
|
variables:
|
||||||
|
- id: $$config_lt_char_limit
|
||||||
|
name: LT_CHAR_LIMIT
|
||||||
|
label: Char limit
|
||||||
|
defaultValue: "5000"
|
||||||
|
description: "Set character limit."
|
||||||
|
- id: $$config_lt_req_limit
|
||||||
|
name: LT_REQ_LIMIT
|
||||||
|
label: Request limit
|
||||||
|
defaultValue: "5000"
|
||||||
|
description: "Set maximum number of requests per minute per client."
|
||||||
|
- id: $$config_lt_batch_limit
|
||||||
|
name: LT_BATCH_LIMIT
|
||||||
|
label: Batch Limit
|
||||||
|
defaultValue: "5000"
|
||||||
|
description: "Set maximum number of texts to translate in a batch request."
|
||||||
|
- id: $$config_lt_ga_id
|
||||||
|
name: LT_GA_ID
|
||||||
|
label: Google Analytics ID
|
||||||
|
defaultValue: ""
|
||||||
|
description: "Enable Google Analytics on the API client page by providing an ID"
|
||||||
|
- id: $$config_lt_web_ui
|
||||||
|
name: LT_DISABLE_WEB_UI
|
||||||
|
label: Web UI
|
||||||
|
defaultValue: "false"
|
||||||
|
description: "Disable or enable web ui. True or false."
|
||||||
|
- templateVersion: 1.0.0
|
||||||
|
defaultVersion: 0.8.1
|
||||||
|
documentation: https://github.com/benbusby/whoogle-search
|
||||||
|
type: whoogle
|
||||||
|
name: Whoogle Search
|
||||||
|
description: A self-hosted, ad-free, privacy-respecting metasearch engine
|
||||||
|
labels:
|
||||||
|
- search
|
||||||
|
- google
|
||||||
|
services:
|
||||||
|
$$id:
|
||||||
|
name: Whoogle Search
|
||||||
|
documentation: https://github.com/benbusby/whoogle-search
|
||||||
|
depends_on: []
|
||||||
|
image: benbusby/whoogle-search:$$core_version
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
environment:
|
||||||
|
- WHOOGLE_USER=$$config_whoogle_username
|
||||||
|
- WHOOGLE_PASS=$$secret_whoogle_password
|
||||||
|
- WHOOGLE_CONFIG_PREFERENCES_KEY=$$secret_whoogle_preferences_key
|
||||||
|
ulimits:
|
||||||
|
nofile:
|
||||||
|
soft: 262144
|
||||||
|
hard: 262144
|
||||||
|
ports:
|
||||||
|
- "5000"
|
||||||
|
variables:
|
||||||
|
- id: $$config_whoogle_username
|
||||||
|
name: WHOOGLE_USER
|
||||||
|
label: Whoogle User
|
||||||
|
defaultValue: $$generate_username
|
||||||
|
description: "Username to log into Whoogle"
|
||||||
|
- id: $$secret_whoogle_password
|
||||||
|
name: WHOOGLE_PASSWORD
|
||||||
|
label: Whoogle Password
|
||||||
|
defaultValue: $$generate_password
|
||||||
|
description: "Password to log into Whoogle"
|
||||||
|
showOnConfiguration: true
|
||||||
|
- id: $$secret_whoogle_preferences_key
|
||||||
|
name: WHOOGLE_CONFIG_PREFERENCES_KEY
|
||||||
|
label: Whoogle preferences key
|
||||||
|
defaultValue: $$generate_password
|
||||||
|
description: "password to encrypt preferences"
|
||||||
|
- templateVersion: 1.0.0
|
||||||
|
defaultVersion: 1.1.3
|
||||||
|
documentation: https://docs.openblocks.dev/
|
||||||
|
type: openblocks
|
||||||
|
name: Openblocks
|
||||||
|
description: The Open Source Retool Alternative
|
||||||
|
services:
|
||||||
|
$$id:
|
||||||
|
image: openblocksdev/openblocks-ce:$$core_version
|
||||||
|
volumes:
|
||||||
|
- $$id-stacks-data:/openblocks-stacks
|
||||||
|
ports:
|
||||||
|
- "3000"
|
||||||
- templateVersion: 1.0.0
|
- templateVersion: 1.0.0
|
||||||
defaultVersion: "0.10.2"
|
defaultVersion: "0.10.2"
|
||||||
documentation: https://pocketbase.io/docs/
|
documentation: https://pocketbase.io/docs/
|
||||||
@ -124,12 +348,12 @@
|
|||||||
description: ""
|
description: ""
|
||||||
- id: $$config_disable_auth
|
- id: $$config_disable_auth
|
||||||
name: DISABLE_AUTH
|
name: DISABLE_AUTH
|
||||||
label: Disable Authentication
|
label: Authentication
|
||||||
defaultValue: "false"
|
defaultValue: "false"
|
||||||
description: ""
|
description: ""
|
||||||
- id: $$config_disable_registration
|
- id: $$config_disable_registration
|
||||||
name: DISABLE_REGISTRATION
|
name: DISABLE_REGISTRATION
|
||||||
label: Disable Registration
|
label: Registration
|
||||||
defaultValue: "true"
|
defaultValue: "true"
|
||||||
description: ""
|
description: ""
|
||||||
- id: $$config_postgres_user
|
- id: $$config_postgres_user
|
||||||
@ -332,12 +556,12 @@
|
|||||||
volumes:
|
volumes:
|
||||||
- $$id-lavalink:/lavalink
|
- $$id-lavalink:/lavalink
|
||||||
ports:
|
ports:
|
||||||
- "2333"
|
- $$config_port
|
||||||
files:
|
files:
|
||||||
- location: /opt/Lavalink/application.yml
|
- location: /opt/Lavalink/application.yml
|
||||||
content: >-
|
content: >-
|
||||||
server:
|
server:
|
||||||
port: $$config_port
|
port: 2333
|
||||||
address: 0.0.0.0
|
address: 0.0.0.0
|
||||||
lavalink:
|
lavalink:
|
||||||
server:
|
server:
|
||||||
@ -364,11 +588,6 @@
|
|||||||
max-file-size: 1GB
|
max-file-size: 1GB
|
||||||
max-history: 30
|
max-history: 30
|
||||||
variables:
|
variables:
|
||||||
- id: $$config_port
|
|
||||||
name: PORT
|
|
||||||
label: Port
|
|
||||||
defaultValue: "2333"
|
|
||||||
required: true
|
|
||||||
- id: $$secret_password
|
- id: $$secret_password
|
||||||
name: PASSWORD
|
name: PASSWORD
|
||||||
label: Password
|
label: Password
|
||||||
@ -3250,12 +3469,12 @@
|
|||||||
description: ""
|
description: ""
|
||||||
- id: $$config_disable_auth
|
- id: $$config_disable_auth
|
||||||
name: DISABLE_AUTH
|
name: DISABLE_AUTH
|
||||||
label: Disable Authentication
|
label: Authentication
|
||||||
defaultValue: "false"
|
defaultValue: "false"
|
||||||
description: ""
|
description: ""
|
||||||
- id: $$config_disable_registration
|
- id: $$config_disable_registration
|
||||||
name: DISABLE_REGISTRATION
|
name: DISABLE_REGISTRATION
|
||||||
label: Disable Registration
|
label: Registration
|
||||||
defaultValue: "true"
|
defaultValue: "true"
|
||||||
description: ""
|
description: ""
|
||||||
- id: $$config_postgresql_username
|
- id: $$config_postgresql_username
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
"is-ip": "5.0.0",
|
"is-ip": "5.0.0",
|
||||||
"is-port-reachable": "4.0.0",
|
"is-port-reachable": "4.0.0",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"jsonwebtoken": "8.5.1",
|
"jsonwebtoken": "9.0.0",
|
||||||
"minimist": "^1.2.7",
|
"minimist": "^1.2.7",
|
||||||
"node-forge": "1.3.1",
|
"node-forge": "1.3.1",
|
||||||
"node-os-utils": "1.3.7",
|
"node-os-utils": "1.3.7",
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
-- RedefineTables
|
||||||
|
PRAGMA foreign_keys=OFF;
|
||||||
|
CREATE TABLE "new_GitSource" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"forPublic" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"type" TEXT,
|
||||||
|
"apiUrl" TEXT,
|
||||||
|
"htmlUrl" TEXT,
|
||||||
|
"customPort" INTEGER NOT NULL DEFAULT 22,
|
||||||
|
"customUser" TEXT NOT NULL DEFAULT 'git',
|
||||||
|
"organization" TEXT,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" DATETIME NOT NULL,
|
||||||
|
"githubAppId" TEXT,
|
||||||
|
"gitlabAppId" TEXT,
|
||||||
|
"isSystemWide" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
CONSTRAINT "GitSource_gitlabAppId_fkey" FOREIGN KEY ("gitlabAppId") REFERENCES "GitlabApp" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT "GitSource_githubAppId_fkey" FOREIGN KEY ("githubAppId") REFERENCES "GithubApp" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
INSERT INTO "new_GitSource" ("apiUrl", "createdAt", "customPort", "forPublic", "githubAppId", "gitlabAppId", "htmlUrl", "id", "isSystemWide", "name", "organization", "type", "updatedAt") SELECT "apiUrl", "createdAt", "customPort", "forPublic", "githubAppId", "gitlabAppId", "htmlUrl", "id", "isSystemWide", "name", "organization", "type", "updatedAt" FROM "GitSource";
|
||||||
|
DROP TABLE "GitSource";
|
||||||
|
ALTER TABLE "new_GitSource" RENAME TO "GitSource";
|
||||||
|
CREATE UNIQUE INDEX "GitSource_githubAppId_key" ON "GitSource"("githubAppId");
|
||||||
|
CREATE UNIQUE INDEX "GitSource_gitlabAppId_key" ON "GitSource"("gitlabAppId");
|
||||||
|
PRAGMA foreign_key_check;
|
||||||
|
PRAGMA foreign_keys=ON;
|
@ -325,6 +325,7 @@ model GitSource {
|
|||||||
apiUrl String?
|
apiUrl String?
|
||||||
htmlUrl String?
|
htmlUrl String?
|
||||||
customPort Int @default(22)
|
customPort Int @default(22)
|
||||||
|
customUser String @default("git")
|
||||||
organization String?
|
organization String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
@ -419,6 +419,7 @@ import * as buildpacks from '../lib/buildPacks';
|
|||||||
githubAppId: gitSource.githubApp?.id,
|
githubAppId: gitSource.githubApp?.id,
|
||||||
gitlabAppId: gitSource.gitlabApp?.id,
|
gitlabAppId: gitSource.gitlabApp?.id,
|
||||||
customPort: gitSource.customPort,
|
customPort: gitSource.customPort,
|
||||||
|
customUser: gitSource.customUser,
|
||||||
gitCommitHash,
|
gitCommitHash,
|
||||||
configuration,
|
configuration,
|
||||||
repository,
|
repository,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
|
import { generateSecrets } from '../common';
|
||||||
import { buildCacheImageForLaravel, buildImage } from './common';
|
import { buildCacheImageForLaravel, buildImage } from './common';
|
||||||
|
|
||||||
const createDockerfile = async (data, image): Promise<void> => {
|
const createDockerfile = async (data, image): Promise<void> => {
|
||||||
@ -7,6 +8,11 @@ const createDockerfile = async (data, image): Promise<void> => {
|
|||||||
|
|
||||||
Dockerfile.push(`FROM ${image}`);
|
Dockerfile.push(`FROM ${image}`);
|
||||||
Dockerfile.push(`LABEL coolify.buildId=${buildId}`);
|
Dockerfile.push(`LABEL coolify.buildId=${buildId}`);
|
||||||
|
if (secrets.length > 0) {
|
||||||
|
generateSecrets(secrets, pullmergeRequestId, true).forEach((env) => {
|
||||||
|
Dockerfile.push(env);
|
||||||
|
});
|
||||||
|
}
|
||||||
Dockerfile.push('WORKDIR /app');
|
Dockerfile.push('WORKDIR /app');
|
||||||
Dockerfile.push(`ENV WEB_DOCUMENT_ROOT /app/public`);
|
Dockerfile.push(`ENV WEB_DOCUMENT_ROOT /app/public`);
|
||||||
Dockerfile.push(`COPY --chown=application:application composer.* ./`);
|
Dockerfile.push(`COPY --chown=application:application composer.* ./`);
|
||||||
|
@ -19,7 +19,7 @@ import { saveBuildLog, saveDockerRegistryCredentials } from './buildPacks/common
|
|||||||
import { scheduler } from './scheduler';
|
import { scheduler } from './scheduler';
|
||||||
import type { ExecaChildProcess } from 'execa';
|
import type { ExecaChildProcess } from 'execa';
|
||||||
|
|
||||||
export const version = '3.12.8';
|
export const version = '3.12.9';
|
||||||
export const isDev = process.env.NODE_ENV === 'development';
|
export const isDev = process.env.NODE_ENV === 'development';
|
||||||
export const sentryDSN =
|
export const sentryDSN =
|
||||||
'https://409f09bcb7af47928d3e0f46b78987f3@o1082494.ingest.sentry.io/4504236622217216';
|
'https://409f09bcb7af47928d3e0f46b78987f3@o1082494.ingest.sentry.io/4504236622217216';
|
||||||
@ -1884,6 +1884,30 @@ export async function pushToRegistry(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseSecret(secret, isBuild) {
|
||||||
|
if (secret.value.includes('$')) {
|
||||||
|
secret.value = secret.value.replaceAll('$', '$$$$');
|
||||||
|
}
|
||||||
|
if (secret.value.includes('\\n')) {
|
||||||
|
if (isBuild) {
|
||||||
|
return `ARG ${secret.name}=${secret.value}`;
|
||||||
|
} else {
|
||||||
|
return `${secret.name}=${secret.value}`;
|
||||||
|
}
|
||||||
|
} else if (secret.value.includes(' ')) {
|
||||||
|
if (isBuild) {
|
||||||
|
return `ARG ${secret.name}='${secret.value}'`;
|
||||||
|
} else {
|
||||||
|
return `${secret.name}='${secret.value}'`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isBuild) {
|
||||||
|
return `ARG ${secret.name}=${secret.value}`;
|
||||||
|
} else {
|
||||||
|
return `${secret.name}=${secret.value}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
export function generateSecrets(
|
export function generateSecrets(
|
||||||
secrets: Array<any>,
|
secrets: Array<any>,
|
||||||
pullmergeRequestId: string,
|
pullmergeRequestId: string,
|
||||||
@ -1899,15 +1923,7 @@ export function generateSecrets(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const build = isBuild && secret.isBuildSecret;
|
const build = isBuild && secret.isBuildSecret;
|
||||||
if (build) {
|
envs.push(parseSecret(secret, build));
|
||||||
if (secret.value.includes(' ') || secret.value.includes('\\n')) {
|
|
||||||
envs.push(`ARG ${secret.name}='${secret.value}'`);
|
|
||||||
} else {
|
|
||||||
envs.push(`ARG ${secret.name}=${secret.value}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
envs.push(`${secret.name}=${secret.value}`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!pullmergeRequestId && normalSecrets.length > 0) {
|
if (!pullmergeRequestId && normalSecrets.length > 0) {
|
||||||
@ -1916,15 +1932,7 @@ export function generateSecrets(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const build = isBuild && secret.isBuildSecret;
|
const build = isBuild && secret.isBuildSecret;
|
||||||
if (build) {
|
envs.push(parseSecret(secret, build));
|
||||||
if (secret.value.includes(' ') || secret.value.includes('\\n')) {
|
|
||||||
envs.push(`ARG ${secret.name}='${secret.value}'`);
|
|
||||||
} else {
|
|
||||||
envs.push(`ARG ${secret.name}=${secret.value}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
envs.push(`${secret.name}=${secret.value}`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const portFound = envs.filter((env) => env.startsWith('PORT'));
|
const portFound = envs.filter((env) => env.startsWith('PORT'));
|
||||||
|
@ -12,7 +12,8 @@ export default async function ({
|
|||||||
buildId,
|
buildId,
|
||||||
privateSshKey,
|
privateSshKey,
|
||||||
customPort,
|
customPort,
|
||||||
forPublic
|
forPublic,
|
||||||
|
customUser,
|
||||||
}: {
|
}: {
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
workdir: string;
|
workdir: string;
|
||||||
@ -25,6 +26,7 @@ export default async function ({
|
|||||||
privateSshKey: string;
|
privateSshKey: string;
|
||||||
customPort: number;
|
customPort: number;
|
||||||
forPublic: boolean;
|
forPublic: boolean;
|
||||||
|
customUser: string;
|
||||||
}): Promise<string> {
|
}): Promise<string> {
|
||||||
const url = htmlUrl.replace('https://', '').replace('http://', '').replace(/\/$/, '');
|
const url = htmlUrl.replace('https://', '').replace('http://', '').replace(/\/$/, '');
|
||||||
if (!forPublic) {
|
if (!forPublic) {
|
||||||
@ -53,7 +55,7 @@ export default async function ({
|
|||||||
} else {
|
} else {
|
||||||
await executeCommand({
|
await executeCommand({
|
||||||
command:
|
command:
|
||||||
`git clone -q -b ${branch} git@${url}:${repository}.git --config core.sshCommand="ssh -p ${customPort} -q -i ${repodir}id.rsa -o StrictHostKeyChecking=no" ${workdir}/ && cd ${workdir}/ && git checkout ${gitCommitHash || ""} && git submodule update --init --recursive && git lfs pull && cd .. `, shell: true
|
`git clone -q -b ${branch} ${customUser}@${url}:${repository}.git --config core.sshCommand="ssh -p ${customPort} -q -i ${repodir}id.rsa -o StrictHostKeyChecking=no" ${workdir}/ && cd ${workdir}/ && git checkout ${gitCommitHash || ""} && git submodule update --init --recursive && git lfs pull && cd .. `, shell: true
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -764,7 +764,9 @@ export async function checkDomain(request: FastifyRequest<CheckDomain>) {
|
|||||||
fqdn,
|
fqdn,
|
||||||
settings: { dualCerts }
|
settings: { dualCerts }
|
||||||
} = await prisma.application.findUnique({ where: { id }, include: { settings: true } });
|
} = await prisma.application.findUnique({ where: { id }, include: { settings: true } });
|
||||||
return await checkDomainsIsValidInDNS({ hostname: domain, fqdn, dualCerts });
|
// TODO: Disabled this because it is having problems with remote docker engines.
|
||||||
|
// return await checkDomainsIsValidInDNS({ hostname: domain, fqdn, dualCerts });
|
||||||
|
return {};
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message });
|
return errorHandler({ status, message });
|
||||||
}
|
}
|
||||||
@ -805,11 +807,12 @@ export async function checkDNS(request: FastifyRequest<CheckDNS>) {
|
|||||||
remoteEngine,
|
remoteEngine,
|
||||||
remoteIpAddress
|
remoteIpAddress
|
||||||
});
|
});
|
||||||
if (isDNSCheckEnabled && !isDev && !forceSave) {
|
// TODO: Disabled this because it is having problems with remote docker engines.
|
||||||
let hostname = request.hostname.split(':')[0];
|
// if (isDNSCheckEnabled && !isDev && !forceSave) {
|
||||||
if (remoteEngine) hostname = remoteIpAddress;
|
// let hostname = request.hostname.split(':')[0];
|
||||||
return await checkDomainsIsValidInDNS({ hostname, fqdn, dualCerts });
|
// if (remoteEngine) hostname = remoteIpAddress;
|
||||||
}
|
// return await checkDomainsIsValidInDNS({ hostname, fqdn, dualCerts });
|
||||||
|
// }
|
||||||
return {};
|
return {};
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message });
|
return errorHandler({ status, message });
|
||||||
@ -842,15 +845,16 @@ export async function getDockerImages(request) {
|
|||||||
try {
|
try {
|
||||||
const { stdout } = await executeCommand({
|
const { stdout } = await executeCommand({
|
||||||
dockerId: application.destinationDocker.id,
|
dockerId: application.destinationDocker.id,
|
||||||
command: `docker images --format '{{.Repository}}#{{.Tag}}#{{.CreatedAt}}' | grep -i ${id} | grep -v cache`,
|
command: `docker images --format '{{.Repository}}#{{.Tag}}#{{.CreatedAt}}'`
|
||||||
shell: true
|
|
||||||
});
|
});
|
||||||
const { stdout: runningImage } = await executeCommand({
|
const { stdout: runningImage } = await executeCommand({
|
||||||
dockerId: application.destinationDocker.id,
|
dockerId: application.destinationDocker.id,
|
||||||
command: `docker ps -a --filter 'label=com.docker.compose.service=${id}' --format {{.Image}}`
|
command: `docker ps -a --filter 'label=com.docker.compose.service=${id}' --format {{.Image}}`
|
||||||
});
|
});
|
||||||
const images = stdout.trim().split('\n');
|
const images = stdout
|
||||||
|
.trim()
|
||||||
|
.split('\n')
|
||||||
|
.filter((image) => image.includes(id) && !image.includes('-cache'));
|
||||||
for (const image of images) {
|
for (const image of images) {
|
||||||
const [repository, tag, createdAt] = image.split('#');
|
const [repository, tag, createdAt] = image.split('#');
|
||||||
if (tag.includes('-')) {
|
if (tag.includes('-')) {
|
||||||
@ -871,6 +875,7 @@ export async function getDockerImages(request) {
|
|||||||
runningImage
|
runningImage
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
return {
|
return {
|
||||||
imagesAvailables
|
imagesAvailables
|
||||||
};
|
};
|
||||||
|
@ -263,14 +263,14 @@ export async function parseAndFindServiceTemplates(service: any, workdir?: strin
|
|||||||
for (const secret of service.serviceSecret) {
|
for (const secret of service.serviceSecret) {
|
||||||
let { name, value } = secret
|
let { name, value } = secret
|
||||||
name = name.toLowerCase()
|
name = name.toLowerCase()
|
||||||
const regexHashed = new RegExp(`\\$\\$hashed\\$\\$secret_${name}\"`, 'gi')
|
const regexHashed = new RegExp(`\\$\\$hashed\\$\\$secret_${name}`, 'gi')
|
||||||
const regex = new RegExp(`\\$\\$secret_${name}\"`, 'gi')
|
const regex = new RegExp(`\\$\\$secret_${name}`, 'gi')
|
||||||
if (value) {
|
if (value) {
|
||||||
strParsedTemplate = strParsedTemplate.replaceAll(regexHashed, bcrypt.hashSync(value.replaceAll("\"", "\\\""), 10) + '"')
|
strParsedTemplate = strParsedTemplate.replaceAll(regexHashed, bcrypt.hashSync(value.replaceAll("\"", "\\\""), 10))
|
||||||
strParsedTemplate = strParsedTemplate.replaceAll(regex, value.replaceAll("\"", "\\\"") + '"')
|
strParsedTemplate = strParsedTemplate.replaceAll(regex, value.replaceAll("\"", "\\\""))
|
||||||
} else {
|
} else {
|
||||||
strParsedTemplate = strParsedTemplate.replaceAll(regexHashed, '' + '"')
|
strParsedTemplate = strParsedTemplate.replaceAll(regexHashed, '')
|
||||||
strParsedTemplate = strParsedTemplate.replaceAll(regex, '' + '"')
|
strParsedTemplate = strParsedTemplate.replaceAll(regex, '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,7 +504,9 @@ export async function checkServiceDomain(request: FastifyRequest<CheckServiceDom
|
|||||||
const { id } = request.params
|
const { id } = request.params
|
||||||
const { domain } = request.query
|
const { domain } = request.query
|
||||||
const { fqdn, dualCerts } = await prisma.service.findUnique({ where: { id } })
|
const { fqdn, dualCerts } = await prisma.service.findUnique({ where: { id } })
|
||||||
return await checkDomainsIsValidInDNS({ hostname: domain, fqdn, dualCerts });
|
// TODO: Disabled this because it is having problems with remote docker engines.
|
||||||
|
// return await checkDomainsIsValidInDNS({ hostname: domain, fqdn, dualCerts });
|
||||||
|
return {}
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message })
|
||||||
}
|
}
|
||||||
@ -530,11 +532,12 @@ export async function checkService(request: FastifyRequest<CheckService>) {
|
|||||||
throw { status: 500, message: `Domain ${getDomain(fqdn).replace('www.', '')} is already in use!` }
|
throw { status: 500, message: `Domain ${getDomain(fqdn).replace('www.', '')} is already in use!` }
|
||||||
}
|
}
|
||||||
if (exposePort) await checkExposedPort({ id, configuredPort, exposePort, engine, remoteEngine, remoteIpAddress })
|
if (exposePort) await checkExposedPort({ id, configuredPort, exposePort, engine, remoteEngine, remoteIpAddress })
|
||||||
if (isDNSCheckEnabled && !isDev && !forceSave) {
|
// TODO: Disabled this because it is having problems with remote docker engines.
|
||||||
let hostname = request.hostname.split(':')[0];
|
// if (isDNSCheckEnabled && !isDev && !forceSave) {
|
||||||
if (remoteEngine) hostname = remoteIpAddress;
|
// let hostname = request.hostname.split(':')[0];
|
||||||
return await checkDomainsIsValidInDNS({ hostname, fqdn, dualCerts });
|
// if (remoteEngine) hostname = remoteIpAddress;
|
||||||
}
|
// return await checkDomainsIsValidInDNS({ hostname, fqdn, dualCerts });
|
||||||
|
// }
|
||||||
return {}
|
return {}
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message })
|
||||||
|
@ -22,11 +22,11 @@ export async function listSources(request: FastifyRequest) {
|
|||||||
export async function saveSource(request, reply) {
|
export async function saveSource(request, reply) {
|
||||||
try {
|
try {
|
||||||
const { id } = request.params
|
const { id } = request.params
|
||||||
let { name, htmlUrl, apiUrl, customPort, isSystemWide } = request.body
|
let { name, htmlUrl, apiUrl, customPort, customUser, isSystemWide } = request.body
|
||||||
if (customPort) customPort = Number(customPort)
|
if (customPort) customPort = Number(customPort)
|
||||||
await prisma.gitSource.update({
|
await prisma.gitSource.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: { name, htmlUrl, apiUrl, customPort, isSystemWide }
|
data: { name, htmlUrl, apiUrl, customPort, customUser, isSystemWide }
|
||||||
});
|
});
|
||||||
return reply.code(201).send()
|
return reply.code(201).send()
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
@ -48,6 +48,7 @@ export async function getSource(request: FastifyRequest<OnlyId>) {
|
|||||||
apiUrl: null,
|
apiUrl: null,
|
||||||
organization: null,
|
organization: null,
|
||||||
customPort: 22,
|
customPort: 22,
|
||||||
|
customUser: 'git',
|
||||||
},
|
},
|
||||||
settings
|
settings
|
||||||
}
|
}
|
||||||
@ -133,7 +134,7 @@ export async function saveGitLabSource(request: FastifyRequest<SaveGitLabSource>
|
|||||||
try {
|
try {
|
||||||
const { id } = request.params
|
const { id } = request.params
|
||||||
const { teamId } = request.user
|
const { teamId } = request.user
|
||||||
let { type, name, htmlUrl, apiUrl, oauthId, appId, appSecret, groupName, customPort } =
|
let { type, name, htmlUrl, apiUrl, oauthId, appId, appSecret, groupName, customPort, customUser } =
|
||||||
request.body
|
request.body
|
||||||
|
|
||||||
if (oauthId) oauthId = Number(oauthId);
|
if (oauthId) oauthId = Number(oauthId);
|
||||||
@ -142,7 +143,7 @@ export async function saveGitLabSource(request: FastifyRequest<SaveGitLabSource>
|
|||||||
|
|
||||||
if (id === 'new') {
|
if (id === 'new') {
|
||||||
const newId = cuid()
|
const newId = cuid()
|
||||||
await prisma.gitSource.create({ data: { id: newId, type, apiUrl, htmlUrl, name, customPort, teams: { connect: { id: teamId } } } });
|
await prisma.gitSource.create({ data: { id: newId, type, apiUrl, htmlUrl, name, customPort, customUser, teams: { connect: { id: teamId } } } });
|
||||||
await prisma.gitlabApp.create({
|
await prisma.gitlabApp.create({
|
||||||
data: {
|
data: {
|
||||||
teams: { connect: { id: teamId } },
|
teams: { connect: { id: teamId } },
|
||||||
@ -158,7 +159,7 @@ export async function saveGitLabSource(request: FastifyRequest<SaveGitLabSource>
|
|||||||
id: newId
|
id: newId
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await prisma.gitSource.update({ where: { id }, data: { type, apiUrl, htmlUrl, name, customPort } });
|
await prisma.gitSource.update({ where: { id }, data: { type, apiUrl, htmlUrl, name, customPort, customUser } });
|
||||||
await prisma.gitlabApp.update({
|
await prisma.gitlabApp.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: {
|
data: {
|
||||||
|
@ -21,6 +21,7 @@ export interface SaveGitLabSource extends OnlyId {
|
|||||||
appSecret: string,
|
appSecret: string,
|
||||||
groupName: string,
|
groupName: string,
|
||||||
customPort: number,
|
customPort: number,
|
||||||
|
customUser: string,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export interface CheckGitLabOAuthId extends OnlyId {
|
export interface CheckGitLabOAuthId extends OnlyId {
|
||||||
|
1014
apps/api/tags.json
1014
apps/api/tags.json
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -352,11 +352,12 @@
|
|||||||
async function reloadCompose() {
|
async function reloadCompose() {
|
||||||
if (loading.reloadCompose) return;
|
if (loading.reloadCompose) return;
|
||||||
loading.reloadCompose = true;
|
loading.reloadCompose = true;
|
||||||
|
try {
|
||||||
|
if (application.gitSource.type === 'github') {
|
||||||
const composeLocation = application.dockerComposeFileLocation.startsWith('/')
|
const composeLocation = application.dockerComposeFileLocation.startsWith('/')
|
||||||
? application.dockerComposeFileLocation
|
? application.dockerComposeFileLocation
|
||||||
: `/${application.dockerComposeFileLocation}`;
|
: `/${application.dockerComposeFileLocation}`;
|
||||||
try {
|
|
||||||
if (application.gitSource.type === 'github') {
|
|
||||||
const headers = isPublicRepository
|
const headers = isPublicRepository
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
@ -383,6 +384,17 @@
|
|||||||
if (!$appSession.tokens.gitlab) {
|
if (!$appSession.tokens.gitlab) {
|
||||||
await getGitlabToken();
|
await getGitlabToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const composeLocation = application.dockerComposeFileLocation.startsWith('/')
|
||||||
|
? application.dockerComposeFileLocation.substring(1) // Remove the '/' from the start
|
||||||
|
: application.dockerComposeFileLocation;
|
||||||
|
|
||||||
|
// If the file is in a subdirectory, lastIndex will be > 0
|
||||||
|
// Otherwise it will be -1 and path will be an empty string
|
||||||
|
const lastIndex = composeLocation.lastIndexOf('/') + 1
|
||||||
|
const path = composeLocation.substring(0, lastIndex)
|
||||||
|
const fileName = composeLocation.substring(lastIndex)
|
||||||
|
|
||||||
const headers = isPublicRepository
|
const headers = isPublicRepository
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
@ -390,13 +402,13 @@
|
|||||||
};
|
};
|
||||||
const url = isPublicRepository
|
const url = isPublicRepository
|
||||||
? ``
|
? ``
|
||||||
: `/v4/projects/${application.projectId}/repository/tree`;
|
: `/v4/projects/${application.projectId}/repository/tree?path=${path}`; // Use path param to find file in a subdirectory
|
||||||
const files = await get(`${apiUrl}${url}`, {
|
const files = await get(`${apiUrl}${url}`, {
|
||||||
...headers
|
...headers
|
||||||
});
|
});
|
||||||
const dockerComposeFileYml = files.find(
|
const dockerComposeFileYml = files.find(
|
||||||
(file: { name: string; type: string }) =>
|
(file: { name: string; type: string }) =>
|
||||||
file.name === composeLocation && file.type === 'blob'
|
file.name === fileName && file.type === 'blob'
|
||||||
);
|
);
|
||||||
const id = dockerComposeFileYml.id;
|
const id = dockerComposeFileYml.id;
|
||||||
|
|
||||||
|
7
apps/server/nodemon.json
Normal file
7
apps/server/nodemon.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"watch": ["src"],
|
||||||
|
"ignore": ["src/**/*.test.ts"],
|
||||||
|
"ext": "ts,mjs,json,graphql",
|
||||||
|
"exec": "rimraf build && esbuild `find src \\( -name '*.ts' -o -name '*.js' \\)` --platform=node --outdir=build --format=cjs && node build",
|
||||||
|
"legacyWatch": true
|
||||||
|
}
|
@ -4,7 +4,8 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rimraf ../../build && tsc --outDir ../../build",
|
"build": "rimraf ../../build && tsc --outDir ../../build",
|
||||||
"dev": "tsx watch --clear-screen=false src",
|
"dev-old": "tsx watch --clear-screen=false src",
|
||||||
|
"dev": "nodemon",
|
||||||
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
||||||
"format": "prettier --plugin-search-dir . --write .",
|
"format": "prettier --plugin-search-dir . --write .",
|
||||||
"test-dev": "start-server-and-test 'tsx src/server' http-get://localhost:2022 'tsx src/client'",
|
"test-dev": "start-server-and-test 'tsx src/server' http-get://localhost:2022 'tsx src/client'",
|
||||||
@ -43,7 +44,7 @@
|
|||||||
"is-ip": "5.0.0",
|
"is-ip": "5.0.0",
|
||||||
"is-port-reachable": "4.0.0",
|
"is-port-reachable": "4.0.0",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"jsonwebtoken": "8.5.1",
|
"jsonwebtoken": "9.0.0",
|
||||||
"node-fetch": "3.3.0",
|
"node-fetch": "3.3.0",
|
||||||
"p-all": "4.0.0",
|
"p-all": "4.0.0",
|
||||||
"p-throttle": "5.0.0",
|
"p-throttle": "5.0.0",
|
||||||
@ -65,6 +66,8 @@
|
|||||||
"@types/node-fetch": "2.6.2",
|
"@types/node-fetch": "2.6.2",
|
||||||
"@types/shell-quote": "^1.7.1",
|
"@types/shell-quote": "^1.7.1",
|
||||||
"@types/ws": "8.5.3",
|
"@types/ws": "8.5.3",
|
||||||
|
"esbuild": "0.15.15",
|
||||||
|
"nodemon": "2.0.20",
|
||||||
"npm-run-all": "4.1.5",
|
"npm-run-all": "4.1.5",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
"start-server-and-test": "1.14.0",
|
"start-server-and-test": "1.14.0",
|
||||||
|
@ -325,6 +325,7 @@ model GitSource {
|
|||||||
apiUrl String?
|
apiUrl String?
|
||||||
htmlUrl String?
|
htmlUrl String?
|
||||||
customPort Int @default(22)
|
customPort Int @default(22)
|
||||||
|
customUser String @default("git")
|
||||||
organization String?
|
organization String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import Bree from 'bree';
|
import Bree from 'bree';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import Cabin from 'cabin';
|
// import Cabin from 'cabin';
|
||||||
import TSBree from '@breejs/ts-worker';
|
import TSBree from '@breejs/ts-worker';
|
||||||
|
|
||||||
export const isDev = process.env['NODE_ENV'] === 'development';
|
export const isDev = process.env['NODE_ENV'] === 'development';
|
||||||
@ -9,7 +9,7 @@ Bree.extend(TSBree);
|
|||||||
|
|
||||||
const options: any = {
|
const options: any = {
|
||||||
defaultExtension: 'js',
|
defaultExtension: 'js',
|
||||||
logger: new Cabin(),
|
logger: false,
|
||||||
// logger: false,
|
// logger: false,
|
||||||
// workerMessageHandler: async ({ name, message }) => {
|
// workerMessageHandler: async ({ name, message }) => {
|
||||||
// if (name === 'deployApplication' && message?.deploying) {
|
// if (name === 'deployApplication' && message?.deploying) {
|
||||||
@ -18,9 +18,8 @@ const options: any = {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
// jobs: [{ name: 'deployApplication' }]
|
jobs: [{ name: 'deployApplication' }, { name: 'worker' }]
|
||||||
jobs: [{ name: 'worker' }]
|
|
||||||
};
|
};
|
||||||
if (isDev) options.root = path.join(__dirname, '../jobs');
|
if (isDev) options.root = path.join(__dirname, './jobs');
|
||||||
|
|
||||||
export const scheduler = new Bree(options);
|
export const scheduler = new Bree(options);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
const handleError = (ev: { target: { src: string } }) => (ev.target.src = fallback);
|
const handleError = (ev: { target: { src: string } }) => (ev.target.src = fallback);
|
||||||
let extension = 'png';
|
let extension = 'png';
|
||||||
let svgs = [
|
let svgs = [
|
||||||
|
'directus',
|
||||||
'pocketbase',
|
'pocketbase',
|
||||||
'gitea',
|
'gitea',
|
||||||
'languagetool',
|
'languagetool',
|
||||||
|
@ -58,11 +58,10 @@ export const appSession: Writable<AppSession> = writable({
|
|||||||
});
|
});
|
||||||
export const disabledButton: Writable<boolean> = writable(false);
|
export const disabledButton: Writable<boolean> = writable(false);
|
||||||
export const isDeploymentEnabled: Writable<boolean> = writable(false);
|
export const isDeploymentEnabled: Writable<boolean> = writable(false);
|
||||||
export function checkIfDeploymentEnabledApplications(isAdmin: boolean, application: any) {
|
export function checkIfDeploymentEnabledApplications(application: any) {
|
||||||
return !!(
|
return !!(
|
||||||
isAdmin &&
|
|
||||||
(application.buildPack === 'compose') ||
|
(application.buildPack === 'compose') ||
|
||||||
(application.fqdn || application.settings.isBot) &&
|
(application.fqdn || application.settings?.isBot) &&
|
||||||
((application.gitSource &&
|
((application.gitSource &&
|
||||||
application.repository &&
|
application.repository &&
|
||||||
application.buildPack) || application.simpleDockerfile) &&
|
application.buildPack) || application.simpleDockerfile) &&
|
||||||
@ -70,9 +69,8 @@ export function checkIfDeploymentEnabledApplications(isAdmin: boolean, applicati
|
|||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
export function checkIfDeploymentEnabledServices(isAdmin: boolean, service: any) {
|
export function checkIfDeploymentEnabledServices( service: any) {
|
||||||
return (
|
return (
|
||||||
isAdmin &&
|
|
||||||
service.fqdn &&
|
service.fqdn &&
|
||||||
service.destinationDocker &&
|
service.destinationDocker &&
|
||||||
service.version &&
|
service.version &&
|
||||||
|
@ -162,12 +162,12 @@
|
|||||||
<input id="main-drawer" type="checkbox" class="drawer-toggle" bind:this={sidedrawerToggler} />
|
<input id="main-drawer" type="checkbox" class="drawer-toggle" bind:this={sidedrawerToggler} />
|
||||||
<div class="drawer-content">
|
<div class="drawer-content">
|
||||||
{#if $appSession.userId}
|
{#if $appSession.userId}
|
||||||
|
<Tooltip triggeredBy="#dashboard" placement="right" color="bg-pink-500">Dashboard</Tooltip>
|
||||||
|
<Tooltip triggeredBy="#servers" placement="right" color="bg-sky-500">Servers</Tooltip>
|
||||||
<Tooltip triggeredBy="#iam" placement="right" color="bg-iam">IAM</Tooltip>
|
<Tooltip triggeredBy="#iam" placement="right" color="bg-iam">IAM</Tooltip>
|
||||||
<Tooltip triggeredBy="#settings" placement="right" color="bg-settings text-black"
|
<Tooltip triggeredBy="#settings" placement="right" color="bg-settings text-black"
|
||||||
>Settings</Tooltip
|
>Settings</Tooltip
|
||||||
>
|
>
|
||||||
<Tooltip triggeredBy="#documentation" placement="right" color="bg-info">Documentation</Tooltip
|
|
||||||
>
|
|
||||||
<Tooltip triggeredBy="#logout" placement="right" color="bg-red-600">Logout</Tooltip>
|
<Tooltip triggeredBy="#logout" placement="right" color="bg-red-600">Logout</Tooltip>
|
||||||
<nav class="nav-main hidden lg:block z-20">
|
<nav class="nav-main hidden lg:block z-20">
|
||||||
<div class="flex h-screen w-full flex-col items-center transition-all duration-100">
|
<div class="flex h-screen w-full flex-col items-center transition-all duration-100">
|
||||||
@ -183,7 +183,6 @@
|
|||||||
<div class="flex flex-col space-y-2 py-2" class:mt-2={$appSession.whiteLabeled}>
|
<div class="flex flex-col space-y-2 py-2" class:mt-2={$appSession.whiteLabeled}>
|
||||||
<a
|
<a
|
||||||
id="dashboard"
|
id="dashboard"
|
||||||
sveltekit:prefetch
|
|
||||||
href="/"
|
href="/"
|
||||||
class="icons hover:text-pink-500"
|
class="icons hover:text-pink-500"
|
||||||
class:text-pink-500={$page.url.pathname === '/'}
|
class:text-pink-500={$page.url.pathname === '/'}
|
||||||
@ -210,7 +209,6 @@
|
|||||||
{#if $appSession.teamId === '0'}
|
{#if $appSession.teamId === '0'}
|
||||||
<a
|
<a
|
||||||
id="servers"
|
id="servers"
|
||||||
sveltekit:prefetch
|
|
||||||
href="/servers"
|
href="/servers"
|
||||||
class="icons hover:text-sky-500"
|
class="icons hover:text-sky-500"
|
||||||
class:text-sky-500={$page.url.pathname === '/servers'}
|
class:text-sky-500={$page.url.pathname === '/servers'}
|
||||||
@ -236,8 +234,6 @@
|
|||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<Tooltip triggeredBy="#dashboard" placement="right">Dashboard</Tooltip>
|
|
||||||
<Tooltip triggeredBy="#servers" placement="right">Servers</Tooltip>
|
|
||||||
<div class="flex-1" />
|
<div class="flex-1" />
|
||||||
<div class="lg:block hidden">
|
<div class="lg:block hidden">
|
||||||
<UpdateAvailable />
|
<UpdateAvailable />
|
||||||
@ -245,7 +241,6 @@
|
|||||||
<div class="flex flex-col space-y-2 py-2">
|
<div class="flex flex-col space-y-2 py-2">
|
||||||
<a
|
<a
|
||||||
id="iam"
|
id="iam"
|
||||||
sveltekit:prefetch
|
|
||||||
href={$appSession.pendingInvitations.length > 0 ? '/iam/pending' : '/iam'}
|
href={$appSession.pendingInvitations.length > 0 ? '/iam/pending' : '/iam'}
|
||||||
class="icons hover:text-iam indicator"
|
class="icons hover:text-iam indicator"
|
||||||
class:text-iam={$page.url.pathname.startsWith('/iam')}
|
class:text-iam={$page.url.pathname.startsWith('/iam')}
|
||||||
@ -274,7 +269,6 @@
|
|||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
id="settings"
|
id="settings"
|
||||||
sveltekit:prefetch
|
|
||||||
href={$appSession.teamId === '0' ? '/settings/coolify' : '/settings/docker'}
|
href={$appSession.teamId === '0' ? '/settings/coolify' : '/settings/docker'}
|
||||||
class="icons hover:text-settings"
|
class="icons hover:text-settings"
|
||||||
class:text-settings={$page.url.pathname.startsWith('/settings')}
|
class:text-settings={$page.url.pathname.startsWith('/settings')}
|
||||||
@ -299,10 +293,9 @@
|
|||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
id="documentation"
|
id="documentation"
|
||||||
sveltekit:prefetch
|
|
||||||
href="https://docs.coollabs.io/coolify/"
|
href="https://docs.coollabs.io/coolify/"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noreferrer external"
|
||||||
class="icons hover:text-info"
|
class="icons hover:text-info"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@ -395,7 +388,6 @@
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
class="no-underline icons hover:text-white hover:bg-pink-500"
|
class="no-underline icons hover:text-white hover:bg-pink-500"
|
||||||
sveltekit:prefetch
|
|
||||||
href="/"
|
href="/"
|
||||||
class:bg-pink-500={$page.url.pathname === '/'}
|
class:bg-pink-500={$page.url.pathname === '/'}
|
||||||
on:click={closeDrawer}
|
on:click={closeDrawer}
|
||||||
@ -424,7 +416,6 @@
|
|||||||
<a
|
<a
|
||||||
id="servers"
|
id="servers"
|
||||||
class="no-underline icons hover:text-white hover:bg-sky-500"
|
class="no-underline icons hover:text-white hover:bg-sky-500"
|
||||||
sveltekit:prefetch
|
|
||||||
href="/servers"
|
href="/servers"
|
||||||
class:bg-sky-500={$page.url.pathname.startsWith('/servers')}
|
class:bg-sky-500={$page.url.pathname.startsWith('/servers')}
|
||||||
on:click={closeDrawer}
|
on:click={closeDrawer}
|
||||||
@ -504,6 +495,30 @@
|
|||||||
Settings
|
Settings
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
class="no-underline icons hover:text-white hover:bg-info"
|
||||||
|
href="https://docs.coollabs.io/coolify/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer external"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="w-8 h-8"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
Documentation
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li class="flex-1 bg-transparent" />
|
<li class="flex-1 bg-transparent" />
|
||||||
<div class="block lg:hidden">
|
<div class="block lg:hidden">
|
||||||
<UpdateAvailable />
|
<UpdateAvailable />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let application: any;
|
export let application: any;
|
||||||
import { status } from '$lib/store';
|
import { appSession, status } from '$lib/store';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -220,7 +220,7 @@
|
|||||||
<li class="menu-title">
|
<li class="menu-title">
|
||||||
<span>Advanced</span>
|
<span>Advanced</span>
|
||||||
</li>
|
</li>
|
||||||
{#if application.gitSourceId}
|
{#if application.gitSourceId && $appSession.isAdmin}
|
||||||
<li
|
<li
|
||||||
class="rounded"
|
class="rounded"
|
||||||
class:bg-coollabs={$page.url.pathname === `/applications/${$page.params.id}/revert`}
|
class:bg-coollabs={$page.url.pathname === `/applications/${$page.params.id}/revert`}
|
||||||
@ -295,6 +295,7 @@
|
|||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<li
|
<li
|
||||||
class="rounded"
|
class="rounded"
|
||||||
class:bg-coollabs={$page.url.pathname === `/applications/${$page.params.id}/danger`}
|
class:bg-coollabs={$page.url.pathname === `/applications/${$page.params.id}/danger`}
|
||||||
@ -318,4 +319,5 @@
|
|||||||
</svg>Danger Zone</a
|
</svg>Danger Zone</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
|
{/if}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
import { del, post, put } from '$lib/api';
|
import { del, post, put } from '$lib/api';
|
||||||
import { errorNotification } from '$lib/common';
|
import { errorNotification } from '$lib/common';
|
||||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||||
import { addToast } from '$lib/store';
|
import { addToast, appSession } from '$lib/store';
|
||||||
import { t } from '$lib/translations';
|
import { t } from '$lib/translations';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
@ -120,6 +120,7 @@
|
|||||||
<label for="name" class="pb-5 uppercase lg:block hidden font-bold" />
|
<label for="name" class="pb-5 uppercase lg:block hidden font-bold" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<div class="flex justify-center h-full items-center pt-3">
|
<div class="flex justify-center h-full items-center pt-3">
|
||||||
<div class="flex flex-row justify-center space-x-2">
|
<div class="flex flex-row justify-center space-x-2">
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
@ -127,5 +128,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
import { del, post, put } from '$lib/api';
|
import { del, post, put } from '$lib/api';
|
||||||
import { errorNotification } from '$lib/common';
|
import { errorNotification } from '$lib/common';
|
||||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||||
import { addToast } from '$lib/store';
|
import { addToast, appSession } from '$lib/store';
|
||||||
import { t } from '$lib/translations';
|
import { t } from '$lib/translations';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
@ -124,6 +124,7 @@
|
|||||||
<div class="flex justify-center h-full items-center pt-0 lg:pt-0 pl-4 lg:pl-0">
|
<div class="flex justify-center h-full items-center pt-0 lg:pt-0 pl-4 lg:pl-0">
|
||||||
<button
|
<button
|
||||||
on:click={() => updateSecret({ changeIsBuildSecret: true })}
|
on:click={() => updateSecret({ changeIsBuildSecret: true })}
|
||||||
|
disabled={!$appSession.isAdmin}
|
||||||
aria-pressed="false"
|
aria-pressed="false"
|
||||||
class="relative inline-flex h-6 w-11 flex-shrink-0 rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out"
|
class="relative inline-flex h-6 w-11 flex-shrink-0 rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out"
|
||||||
class:bg-green-600={isBuildSecret}
|
class:bg-green-600={isBuildSecret}
|
||||||
@ -177,7 +178,7 @@
|
|||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
<button class="btn btn-sm btn-primary" on:click={addNewSecret}>Add</button>
|
<button class="btn btn-sm btn-primary" on:click={addNewSecret}>Add</button>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else if $appSession.isAdmin}
|
||||||
<div class="flex flex-row justify-center space-x-2">
|
<div class="flex flex-row justify-center space-x-2">
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
<button class="btn btn-sm btn-primary" on:click={() => updateSecret()}>Set</button>
|
<button class="btn btn-sm btn-primary" on:click={() => updateSecret()}>Set</button>
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
let forceDelete = false;
|
let forceDelete = false;
|
||||||
let stopping = false;
|
let stopping = false;
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
$isDeploymentEnabled = checkIfDeploymentEnabledApplications($appSession.isAdmin, application);
|
$isDeploymentEnabled = checkIfDeploymentEnabledApplications(application);
|
||||||
|
|
||||||
async function deleteApplication(name: string, force: boolean) {
|
async function deleteApplication(name: string, force: boolean) {
|
||||||
const sure = confirm($t('application.confirm_to_delete', { name }));
|
const sure = confirm($t('application.confirm_to_delete', { name }));
|
||||||
@ -292,7 +292,6 @@
|
|||||||
<a
|
<a
|
||||||
href={$isDeploymentEnabled ? `/applications/${id}/logs` : null}
|
href={$isDeploymentEnabled ? `/applications/${id}/logs` : null}
|
||||||
class="btn btn-sm text-sm gap-2"
|
class="btn btn-sm text-sm gap-2"
|
||||||
sveltekit:prefetch
|
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -363,7 +362,7 @@
|
|||||||
<button
|
<button
|
||||||
on:click={restartApplication}
|
on:click={restartApplication}
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@ -383,7 +382,7 @@
|
|||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
<button
|
<button
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
on:click={() => handleDeploySubmit(true)}
|
on:click={() => handleDeploySubmit(true)}
|
||||||
>
|
>
|
||||||
@ -409,7 +408,7 @@
|
|||||||
<button
|
<button
|
||||||
on:click={stopApplication}
|
on:click={stopApplication}
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@ -432,7 +431,7 @@
|
|||||||
<button
|
<button
|
||||||
on:click={stopApplication}
|
on:click={stopApplication}
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@ -453,7 +452,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
on:click={() => handleDeploySubmit(true)}
|
on:click={() => handleDeploySubmit(true)}
|
||||||
>
|
>
|
||||||
{#if $status.application.overallStatus !== 'degraded'}
|
{#if $status.application.overallStatus !== 'degraded'}
|
||||||
|
@ -72,7 +72,6 @@
|
|||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<a
|
<a
|
||||||
href={`/destinations/new?from=/applications/${id}/configuration/destination`}
|
href={`/destinations/new?from=/applications/${id}/configuration/destination`}
|
||||||
sveltekit:prefetch
|
|
||||||
class="add-icon bg-sky-600 hover:bg-sky-500"
|
class="add-icon bg-sky-600 hover:bg-sky-500"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
@ -255,7 +255,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<div class="flex flex-row items-center">
|
<div class="flex flex-row items-center">
|
||||||
<div class="title py-4 pr-4">Public Repository from Git</div>
|
<div class="title py-4 pr-4">Public Repository from Git</div>
|
||||||
<DocLink url="https://docs.coollabs.io/coolify/applications/#public-repository" />
|
<DocLink url="https://docs.coollabs.io/coolify/applications/#public-repository-from-git" />
|
||||||
</div>
|
</div>
|
||||||
<PublicRepository />
|
<PublicRepository />
|
||||||
<div class="flex flex-row items-center pt-10">
|
<div class="flex flex-row items-center pt-10">
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
let isDBBranching = application.settings.isDBBranching;
|
let isDBBranching = application.settings.isDBBranching;
|
||||||
|
|
||||||
async function changeSettings(name: any) {
|
async function changeSettings(name: any) {
|
||||||
|
if (!$appSession.isAdmin) return
|
||||||
if (name === 'previews') {
|
if (name === 'previews') {
|
||||||
previews = !previews;
|
previews = !previews;
|
||||||
}
|
}
|
||||||
@ -102,7 +103,7 @@
|
|||||||
}
|
}
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
} finally {
|
} finally {
|
||||||
$isDeploymentEnabled = checkIfDeploymentEnabledApplications($appSession.isAdmin, application);
|
$isDeploymentEnabled = checkIfDeploymentEnabledApplications(application);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -119,6 +120,7 @@
|
|||||||
id="autodeploy"
|
id="autodeploy"
|
||||||
isCenter={false}
|
isCenter={false}
|
||||||
bind:setting={autodeploy}
|
bind:setting={autodeploy}
|
||||||
|
disabled={!$appSession.isAdmin}
|
||||||
on:click={() => changeSettings('autodeploy')}
|
on:click={() => changeSettings('autodeploy')}
|
||||||
title={$t('application.enable_automatic_deployment')}
|
title={$t('application.enable_automatic_deployment')}
|
||||||
description={$t('application.enable_auto_deploy_webhooks')}
|
description={$t('application.enable_auto_deploy_webhooks')}
|
||||||
@ -130,6 +132,7 @@
|
|||||||
id="previews"
|
id="previews"
|
||||||
isCenter={false}
|
isCenter={false}
|
||||||
bind:setting={previews}
|
bind:setting={previews}
|
||||||
|
disabled={!$appSession.isAdmin}
|
||||||
on:click={() => changeSettings('previews')}
|
on:click={() => changeSettings('previews')}
|
||||||
title={$t('application.enable_mr_pr_previews')}
|
title={$t('application.enable_mr_pr_previews')}
|
||||||
description={$t('application.enable_preview_deploy_mr_pr_requests')}
|
description={$t('application.enable_preview_deploy_mr_pr_requests')}
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
$status.application.overallStatus === 'degraded' ||
|
$status.application.overallStatus === 'degraded' ||
|
||||||
$status.application.overallStatus === 'healthy' ||
|
$status.application.overallStatus === 'healthy' ||
|
||||||
$status.application.initialLoading;
|
$status.application.initialLoading;
|
||||||
$isDeploymentEnabled = checkIfDeploymentEnabledApplications($appSession.isAdmin, application);
|
$isDeploymentEnabled = checkIfDeploymentEnabledApplications(application);
|
||||||
let statues: any = {};
|
let statues: any = {};
|
||||||
let loading = {
|
let loading = {
|
||||||
save: false,
|
save: false,
|
||||||
@ -235,7 +235,7 @@
|
|||||||
}
|
}
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
} finally {
|
} finally {
|
||||||
$isDeploymentEnabled = checkIfDeploymentEnabledApplications($appSession.isAdmin, application);
|
$isDeploymentEnabled = checkIfDeploymentEnabledApplications(application);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function handleSubmit(toast: boolean = true) {
|
async function handleSubmit(toast: boolean = true) {
|
||||||
@ -269,7 +269,7 @@
|
|||||||
}
|
}
|
||||||
await saveForm(id, application, baseDatabaseBranch, dockerComposeConfiguration);
|
await saveForm(id, application, baseDatabaseBranch, dockerComposeConfiguration);
|
||||||
setLocation(application, settings);
|
setLocation(application, settings);
|
||||||
$isDeploymentEnabled = checkIfDeploymentEnabledApplications($appSession.isAdmin, application);
|
$isDeploymentEnabled = checkIfDeploymentEnabledApplications(application);
|
||||||
|
|
||||||
forceSave = false;
|
forceSave = false;
|
||||||
if (toast) {
|
if (toast) {
|
||||||
@ -366,11 +366,12 @@
|
|||||||
async function reloadCompose() {
|
async function reloadCompose() {
|
||||||
if (loading.reloadCompose) return;
|
if (loading.reloadCompose) return;
|
||||||
loading.reloadCompose = true;
|
loading.reloadCompose = true;
|
||||||
|
try {
|
||||||
|
if (application.gitSource.type === 'github') {
|
||||||
const composeLocation = application.dockerComposeFileLocation.startsWith('/')
|
const composeLocation = application.dockerComposeFileLocation.startsWith('/')
|
||||||
? application.dockerComposeFileLocation
|
? application.dockerComposeFileLocation
|
||||||
: `/${application.dockerComposeFileLocation}`;
|
: `/${application.dockerComposeFileLocation}`;
|
||||||
try {
|
|
||||||
if (application.gitSource.type === 'github') {
|
|
||||||
const headers = isPublicRepository
|
const headers = isPublicRepository
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
@ -397,6 +398,17 @@
|
|||||||
if (!$appSession.tokens.gitlab) {
|
if (!$appSession.tokens.gitlab) {
|
||||||
await getGitlabToken();
|
await getGitlabToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const composeLocation = application.dockerComposeFileLocation.startsWith('/')
|
||||||
|
? application.dockerComposeFileLocation.substring(1) // Remove the '/' from the start
|
||||||
|
: application.dockerComposeFileLocation;
|
||||||
|
|
||||||
|
// If the file is in a subdirectory, lastIndex will be > 0
|
||||||
|
// Otherwise it will be -1 and path will be an empty string
|
||||||
|
const lastIndex = composeLocation.lastIndexOf('/') + 1
|
||||||
|
const path = composeLocation.substring(0, lastIndex)
|
||||||
|
const fileName = composeLocation.substring(lastIndex)
|
||||||
|
|
||||||
const headers = isPublicRepository
|
const headers = isPublicRepository
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
@ -404,13 +416,13 @@
|
|||||||
};
|
};
|
||||||
const url = isPublicRepository
|
const url = isPublicRepository
|
||||||
? ``
|
? ``
|
||||||
: `/v4/projects/${application.projectId}/repository/tree`;
|
: `/v4/projects/${application.projectId}/repository/tree?path=${path}`;
|
||||||
const files = await get(`${apiUrl}${url}`, {
|
const files = await get(`${apiUrl}${url}`, {
|
||||||
...headers
|
...headers
|
||||||
});
|
});
|
||||||
const dockerComposeFileYml = files.find(
|
const dockerComposeFileYml = files.find(
|
||||||
(file: { name: string; type: string }) =>
|
(file: { name: string; type: string }) =>
|
||||||
file.name === composeLocation && file.type === 'blob'
|
file.name === fileName && file.type === 'blob'
|
||||||
);
|
);
|
||||||
const id = dockerComposeFileYml.id;
|
const id = dockerComposeFileYml.id;
|
||||||
|
|
||||||
@ -490,7 +502,7 @@
|
|||||||
<div class="grid grid-flow-row gap-2 px-4">
|
<div class="grid grid-flow-row gap-2 px-4">
|
||||||
<div class="mt-2 grid grid-cols-2 items-center">
|
<div class="mt-2 grid grid-cols-2 items-center">
|
||||||
<label for="name">{$t('forms.name')}</label>
|
<label for="name">{$t('forms.name')}</label>
|
||||||
<input name="name" id="name" class="w-full" bind:value={application.name} required />
|
<input name="name" id="name" class="w-full" bind:value={application.name} disabled={!$appSession.isAdmin} required />
|
||||||
</div>
|
</div>
|
||||||
{#if !isSimpleDockerfile}
|
{#if !isSimpleDockerfile}
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { asyncSleep, errorNotification, getRndInteger } from '$lib/common';
|
import { asyncSleep, errorNotification, getRndInteger } from '$lib/common';
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy, onMount } from 'svelte';
|
||||||
import { addToast } from '$lib/store';
|
import { addToast, appSession } from '$lib/store';
|
||||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||||
import DeleteIcon from '$lib/components/DeleteIcon.svelte';
|
import DeleteIcon from '$lib/components/DeleteIcon.svelte';
|
||||||
|
|
||||||
@ -264,6 +264,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<button
|
<button
|
||||||
id="restart"
|
id="restart"
|
||||||
|
disabled={!$appSession.isAdmin}
|
||||||
on:click={() => restartPreview(preview)}
|
on:click={() => restartPreview(preview)}
|
||||||
type="submit"
|
type="submit"
|
||||||
class="icons bg-transparent text-sm flex items-center space-x-2"
|
class="icons bg-transparent text-sm flex items-center space-x-2"
|
||||||
@ -286,7 +287,12 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<Tooltip triggeredBy="#restart">Restart (useful to change secrets)</Tooltip>
|
<Tooltip triggeredBy="#restart">Restart (useful to change secrets)</Tooltip>
|
||||||
<button id="forceredeploypreview" class="icons" on:click={() => redeploy(preview)}>
|
<button
|
||||||
|
id="forceredeploypreview"
|
||||||
|
class="icons"
|
||||||
|
disabled={!$appSession.isAdmin}
|
||||||
|
on:click={() => redeploy(preview)}
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="w-6 h-6"
|
class="w-6 h-6"
|
||||||
@ -310,7 +316,7 @@
|
|||||||
id="deletepreview"
|
id="deletepreview"
|
||||||
class="icons"
|
class="icons"
|
||||||
class:hover:text-error={!loading.removing}
|
class:hover:text-error={!loading.removing}
|
||||||
disabled={loading.removing}
|
disabled={loading.removing || !$appSession.isAdmin}
|
||||||
on:click={() => removeApplication(preview)}
|
on:click={() => removeApplication(preview)}
|
||||||
><DeleteIcon />
|
><DeleteIcon />
|
||||||
</button>
|
</button>
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
import pLimit from 'p-limit';
|
import pLimit from 'p-limit';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { get, post, put } from '$lib/api';
|
import { get, post, put } from '$lib/api';
|
||||||
import { addToast } from '$lib/store';
|
import { addToast, appSession } from '$lib/store';
|
||||||
import Secret from './_Secret.svelte';
|
import Secret from './_Secret.svelte';
|
||||||
import PreviewSecret from './_PreviewSecret.svelte';
|
import PreviewSecret from './_PreviewSecret.svelte';
|
||||||
import { errorNotification } from '$lib/common';
|
import { errorNotification } from '$lib/common';
|
||||||
@ -106,9 +106,11 @@
|
|||||||
/>
|
/>
|
||||||
{/key}
|
{/key}
|
||||||
{/each}
|
{/each}
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<div class="lg:pt-0 pt-10">
|
<div class="lg:pt-0 pt-10">
|
||||||
<Secret on:refresh={refreshSecrets} length={secrets.length} isNewSecret />
|
<Secret on:refresh={refreshSecrets} length={secrets.length} isNewSecret />
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
{#if !application.settings.isBot && !application.simpleDockerfile}
|
{#if !application.settings.isBot && !application.simpleDockerfile}
|
||||||
<div class="flex flex-row border-b border-coolgray-500 mb-6 space-x-2">
|
<div class="flex flex-row border-b border-coolgray-500 mb-6 space-x-2">
|
||||||
<div class="title font-bold pb-3 pt-8">
|
<div class="title font-bold pb-3 pt-8">
|
||||||
@ -135,6 +137,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<form on:submit|preventDefault={getValues} class="mb-12 w-full">
|
<form on:submit|preventDefault={getValues} class="mb-12 w-full">
|
||||||
<div class="flex flex-row border-b border-coolgray-500 mb-6 space-x-2 pt-10">
|
<div class="flex flex-row border-b border-coolgray-500 mb-6 space-x-2 pt-10">
|
||||||
<div class="flex flex-row space-x-2">
|
<div class="flex flex-row space-x-2">
|
||||||
@ -149,3 +152,4 @@
|
|||||||
class="mb-2 min-h-[200px] w-full"
|
class="mb-2 min-h-[200px] w-full"
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
{/if}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
import { get } from '$lib/api';
|
import { get } from '$lib/api';
|
||||||
import { t } from '$lib/translations';
|
import { t } from '$lib/translations';
|
||||||
import Explainer from '$lib/components/Explainer.svelte';
|
import Explainer from '$lib/components/Explainer.svelte';
|
||||||
|
import { appSession } from '$lib/store';
|
||||||
|
|
||||||
let composeJson = JSON.parse(application?.dockerComposeFile || '{}');
|
let composeJson = JSON.parse(application?.dockerComposeFile || '{}');
|
||||||
let predefinedVolumes: any[] = [];
|
let predefinedVolumes: any[] = [];
|
||||||
@ -86,12 +87,15 @@
|
|||||||
<Storage on:refresh={refreshStorage} {storage} />
|
<Storage on:refresh={refreshStorage} {storage} />
|
||||||
{/key}
|
{/key}
|
||||||
{/each}
|
{/each}
|
||||||
<div class="Preview Secrets" class:pt-10={predefinedVolumes.length > 0}>
|
{#if $appSession.isAdmin}
|
||||||
|
<div class:pt-10={predefinedVolumes.length > 0}>
|
||||||
Add New Volume <Explainer
|
Add New Volume <Explainer
|
||||||
position="dropdown-bottom"
|
position="dropdown-bottom"
|
||||||
explanation={$t('application.storage.persistent_storage_explainer')}
|
explanation={$t('application.storage.persistent_storage_explainer')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Storage on:refresh={refreshStorage} isNew />
|
<Storage on:refresh={refreshStorage} isNew />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -176,7 +176,6 @@
|
|||||||
id="exited"
|
id="exited"
|
||||||
href={!$status.database.isRunning ? `/databases/${id}/logs` : null}
|
href={!$status.database.isRunning ? `/databases/${id}/logs` : null}
|
||||||
class="icons bg-transparent text-red-500 tooltip-error"
|
class="icons bg-transparent text-red-500 tooltip-error"
|
||||||
sveltekit:prefetch
|
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -271,7 +270,6 @@
|
|||||||
<a
|
<a
|
||||||
id="configuration"
|
id="configuration"
|
||||||
href="/databases/{id}"
|
href="/databases/{id}"
|
||||||
sveltekit:prefetch
|
|
||||||
class="hover:text-yellow-500 rounded"
|
class="hover:text-yellow-500 rounded"
|
||||||
class:text-yellow-500={$page.url.pathname === `/databases/${id}`}
|
class:text-yellow-500={$page.url.pathname === `/databases/${id}`}
|
||||||
class:bg-coolgray-500={$page.url.pathname === `/databases/${id}`}
|
class:bg-coolgray-500={$page.url.pathname === `/databases/${id}`}
|
||||||
@ -305,7 +303,6 @@
|
|||||||
<a
|
<a
|
||||||
id="databaselogs"
|
id="databaselogs"
|
||||||
href={$status.database.isRunning ? `/databases/${id}/logs` : null}
|
href={$status.database.isRunning ? `/databases/${id}/logs` : null}
|
||||||
sveltekit:prefetch
|
|
||||||
class="hover:text-pink-500 rounded"
|
class="hover:text-pink-500 rounded"
|
||||||
class:text-pink-500={$page.url.pathname === `/databases/${id}/logs`}
|
class:text-pink-500={$page.url.pathname === `/databases/${id}/logs`}
|
||||||
class:bg-coolgray-500={$page.url.pathname === `/databases/${id}/logs`}
|
class:bg-coolgray-500={$page.url.pathname === `/databases/${id}/logs`}
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
{$t('application.configuration.no_configurable_destination')}
|
{$t('application.configuration.no_configurable_destination')}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<a href="/destinations/new" sveltekit:prefetch class="add-icon bg-sky-600 hover:bg-sky-500">
|
<a href="/destinations/new" class="add-icon bg-sky-600 hover:bg-sky-500">
|
||||||
<svg
|
<svg
|
||||||
class="w-6"
|
class="w-6"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -57,11 +57,7 @@
|
|||||||
<div class="flex-col">
|
<div class="flex-col">
|
||||||
<div class="pb-2 text-center font-bold">No SSH key found</div>
|
<div class="pb-2 text-center font-bold">No SSH key found</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<a
|
<a href="/settings/ssh" class="add-icon bg-sky-600 hover:bg-sky-500">
|
||||||
href="/settings/ssh"
|
|
||||||
sveltekit:prefetch
|
|
||||||
class="add-icon bg-sky-600 hover:bg-sky-500"
|
|
||||||
>
|
|
||||||
<svg
|
<svg
|
||||||
class="w-6"
|
class="w-6"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -669,7 +669,7 @@
|
|||||||
<button class="btn btn-sm btn-primary" on:click={refreshStatusApplications}
|
<button class="btn btn-sm btn-primary" on:click={refreshStatusApplications}
|
||||||
>{noInitialStatus.applications ? 'Load Status' : 'Refresh Status'}</button
|
>{noInitialStatus.applications ? 'Load Status' : 'Refresh Status'}</button
|
||||||
>
|
>
|
||||||
{#if foundUnconfiguredApplication}
|
{#if foundUnconfiguredApplication && $appSession.isAdmin}
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm"
|
class="btn btn-sm"
|
||||||
class:loading={loading.applications}
|
class:loading={loading.applications}
|
||||||
@ -783,11 +783,13 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<button
|
<button
|
||||||
class="icons hover:bg-green-500"
|
class="icons hover:bg-green-500"
|
||||||
on:click|stopPropagation|preventDefault={() =>
|
on:click|stopPropagation|preventDefault={() =>
|
||||||
deleteApplication(application.id)}><DeleteIcon /></button
|
deleteApplication(application.id)}><DeleteIcon /></button
|
||||||
>
|
>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -896,11 +898,13 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<button
|
<button
|
||||||
class="icons hover:bg-green-500"
|
class="icons hover:bg-green-500"
|
||||||
on:click|stopPropagation|preventDefault={() =>
|
on:click|stopPropagation|preventDefault={() =>
|
||||||
deleteApplication(application.id)}><DeleteIcon /></button
|
deleteApplication(application.id)}><DeleteIcon /></button
|
||||||
>
|
>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -991,11 +995,13 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<button
|
<button
|
||||||
class="icons hover:bg-pink-500"
|
class="icons hover:bg-pink-500"
|
||||||
on:click|stopPropagation|preventDefault={() => deleteService(service.id)}
|
on:click|stopPropagation|preventDefault={() => deleteService(service.id)}
|
||||||
><DeleteIcon /></button
|
><DeleteIcon /></button
|
||||||
>
|
>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1077,11 +1083,13 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<button
|
<button
|
||||||
class="icons hover:bg-pink-500"
|
class="icons hover:bg-pink-500"
|
||||||
on:click|stopPropagation|preventDefault={() => deleteService(service.id)}
|
on:click|stopPropagation|preventDefault={() => deleteService(service.id)}
|
||||||
><DeleteIcon /></button
|
><DeleteIcon /></button
|
||||||
>
|
>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1173,11 +1181,13 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<button
|
<button
|
||||||
class="icons hover:bg-databases-100"
|
class="icons hover:bg-databases-100"
|
||||||
on:click|stopPropagation|preventDefault={() => deleteDatabase(database.id)}
|
on:click|stopPropagation|preventDefault={() => deleteDatabase(database.id)}
|
||||||
><DeleteIcon /></button
|
><DeleteIcon /></button
|
||||||
>
|
>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1259,11 +1269,13 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<button
|
<button
|
||||||
class="icons hover:bg-databases"
|
class="icons hover:bg-databases"
|
||||||
on:click|stopPropagation|preventDefault={() => deleteDatabase(database.id)}
|
on:click|stopPropagation|preventDefault={() => deleteDatabase(database.id)}
|
||||||
><DeleteIcon /></button
|
><DeleteIcon /></button
|
||||||
>
|
>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
export let service: any;
|
export let service: any;
|
||||||
export let template: any;
|
export let template: any;
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
|
import { appSession } from '$lib/store';
|
||||||
import ServiceLinks from './_ServiceLinks.svelte';
|
import ServiceLinks from './_ServiceLinks.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -106,6 +107,7 @@
|
|||||||
</svg>Service</a
|
</svg>Service</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<li class="menu-title">
|
<li class="menu-title">
|
||||||
<span>Advanced</span>
|
<span>Advanced</span>
|
||||||
</li>
|
</li>
|
||||||
@ -132,4 +134,5 @@
|
|||||||
</svg>Danger Zone</a
|
</svg>Danger Zone</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
|
{/if}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
import { del, post } from '$lib/api';
|
import { del, post } from '$lib/api';
|
||||||
import { errorNotification } from '$lib/common';
|
import { errorNotification } from '$lib/common';
|
||||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||||
import { addToast } from '$lib/store';
|
import { addToast, appSession } from '$lib/store';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
@ -77,6 +77,7 @@
|
|||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<td>
|
<td>
|
||||||
{#if isNewSecret}
|
{#if isNewSecret}
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
@ -93,3 +94,4 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
|
{/if}
|
||||||
|
@ -76,11 +76,10 @@
|
|||||||
import { dev } from '$app/env';
|
import { dev } from '$app/env';
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
|
|
||||||
$isDeploymentEnabled = checkIfDeploymentEnabledServices($appSession.isAdmin, service);
|
$isDeploymentEnabled = checkIfDeploymentEnabledServices(service);
|
||||||
|
|
||||||
let statusInterval: any;
|
let statusInterval: any;
|
||||||
|
|
||||||
|
|
||||||
async function deleteService() {
|
async function deleteService() {
|
||||||
const sure = confirm($t('application.confirm_to_delete', { name: service.name }));
|
const sure = confirm($t('application.confirm_to_delete', { name: service.name }));
|
||||||
if (sure) {
|
if (sure) {
|
||||||
@ -291,7 +290,7 @@
|
|||||||
</button>
|
</button>
|
||||||
{:else if $status.service.overallStatus === 'healthy'}
|
{:else if $status.service.overallStatus === 'healthy'}
|
||||||
<button
|
<button
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
on:click={() => restartService()}
|
on:click={() => restartService()}
|
||||||
>
|
>
|
||||||
@ -317,7 +316,7 @@
|
|||||||
<button
|
<button
|
||||||
on:click={() => stopService(false)}
|
on:click={() => stopService(false)}
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@ -338,9 +337,9 @@
|
|||||||
</button>
|
</button>
|
||||||
{:else if $status.service.overallStatus === 'degraded'}
|
{:else if $status.service.overallStatus === 'degraded'}
|
||||||
<button
|
<button
|
||||||
on:click={stopService}
|
on:click={() => stopService()}
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@ -362,7 +361,7 @@
|
|||||||
{#if $status.service.overallStatus === 'degraded'}
|
{#if $status.service.overallStatus === 'degraded'}
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
on:click={() => restartService()}
|
on:click={() => restartService()}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@ -386,7 +385,7 @@
|
|||||||
{:else if $status.service.overallStatus === 'stopped'}
|
{:else if $status.service.overallStatus === 'stopped'}
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm gap-2"
|
class="btn btn-sm gap-2"
|
||||||
disabled={!$isDeploymentEnabled}
|
disabled={!$isDeploymentEnabled || !$appSession.isAdmin}
|
||||||
on:click={() => startService()}
|
on:click={() => startService()}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
{$t('application.configuration.no_configurable_destination')}
|
{$t('application.configuration.no_configurable_destination')}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<a href="/new/destination" sveltekit:prefetch class="add-icon bg-sky-600 hover:bg-sky-500">
|
<a href="/new/destination" class="add-icon bg-sky-600 hover:bg-sky-500">
|
||||||
<svg
|
<svg
|
||||||
class="w-6"
|
class="w-6"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
if (formData) service = await saveForm(formData, service);
|
if (formData) service = await saveForm(formData, service);
|
||||||
setLocation(service);
|
setLocation(service);
|
||||||
forceSave = false;
|
forceSave = false;
|
||||||
$isDeploymentEnabled = checkIfDeploymentEnabledServices($appSession.isAdmin, service);
|
$isDeploymentEnabled = checkIfDeploymentEnabledServices(service);
|
||||||
return addToast({
|
return addToast({
|
||||||
message: 'Configuration saved.',
|
message: 'Configuration saved.',
|
||||||
type: 'success'
|
type: 'success'
|
||||||
@ -165,6 +165,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function changeSettings(name: any) {
|
async function changeSettings(name: any) {
|
||||||
|
if (!$appSession.isAdmin) return;
|
||||||
try {
|
try {
|
||||||
if (name === 'dualCerts') {
|
if (name === 'dualCerts') {
|
||||||
dualCerts = !dualCerts;
|
dualCerts = !dualCerts;
|
||||||
@ -277,7 +278,14 @@
|
|||||||
<div class="grid grid-flow-row gap-2 px-4">
|
<div class="grid grid-flow-row gap-2 px-4">
|
||||||
<div class="mt-2 grid grid-cols-2 items-center">
|
<div class="mt-2 grid grid-cols-2 items-center">
|
||||||
<label for="name">{$t('forms.name')}</label>
|
<label for="name">{$t('forms.name')}</label>
|
||||||
<input name="name" id="name" class="w-full" bind:value={service.name} required />
|
<input
|
||||||
|
name="name"
|
||||||
|
id="name"
|
||||||
|
class="w-full"
|
||||||
|
disabled={!$appSession.isAdmin}
|
||||||
|
bind:value={service.name}
|
||||||
|
required
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="version">Version / Tag</label>
|
<label for="version">Version / Tag</label>
|
||||||
@ -386,7 +394,7 @@
|
|||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<Setting
|
<Setting
|
||||||
id="dualCerts"
|
id="dualCerts"
|
||||||
disabled={$status.service.isRunning}
|
disabled={$status.service.isRunning || !$appSession.isAdmin}
|
||||||
dataTooltip={$t('forms.must_be_stopped_to_modify')}
|
dataTooltip={$t('forms.must_be_stopped_to_modify')}
|
||||||
bind:setting={dualCerts}
|
bind:setting={dualCerts}
|
||||||
title={$t('application.ssl_www_and_non_www')}
|
title={$t('application.ssl_www_and_non_www')}
|
||||||
@ -482,7 +490,7 @@
|
|||||||
required={variable?.required}
|
required={variable?.required}
|
||||||
/>
|
/>
|
||||||
{:else if variable.defaultValue === 'true' || variable.defaultValue === 'false'}
|
{:else if variable.defaultValue === 'true' || variable.defaultValue === 'false'}
|
||||||
{#if variable.value === 'true' || variable.value === 'false'}
|
{#if variable.value === 'true' || variable.value === 'false' || variable.value === 'invite_only'}
|
||||||
<select
|
<select
|
||||||
class="w-full font-normal"
|
class="w-full font-normal"
|
||||||
readonly={isDisabled}
|
readonly={isDisabled}
|
||||||
@ -496,6 +504,9 @@
|
|||||||
>
|
>
|
||||||
<option value="true">enabled</option>
|
<option value="true">enabled</option>
|
||||||
<option value="false">disabled</option>
|
<option value="false">disabled</option>
|
||||||
|
{#if service.type.startsWith('plausibleanalytics') && variable.id == 'config_disable_registration'}
|
||||||
|
<option value="invite_only">invite_only</option>
|
||||||
|
{/if}
|
||||||
</select>
|
</select>
|
||||||
{:else}
|
{:else}
|
||||||
<select
|
<select
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
import { get } from '$lib/api';
|
import { get } from '$lib/api';
|
||||||
import { t } from '$lib/translations';
|
import { t } from '$lib/translations';
|
||||||
import pLimit from 'p-limit';
|
import pLimit from 'p-limit';
|
||||||
import { addToast } from '$lib/store';
|
import { addToast, appSession } from '$lib/store';
|
||||||
import { saveSecret } from './utils';
|
import { saveSecret } from './utils';
|
||||||
const limit = pLimit(1);
|
const limit = pLimit(1);
|
||||||
|
|
||||||
@ -83,7 +83,12 @@
|
|||||||
{#each secrets as secret}
|
{#each secrets as secret}
|
||||||
{#key secret.id}
|
{#key secret.id}
|
||||||
<tr>
|
<tr>
|
||||||
<Secret name={secret.name} value={secret.value} readonly={secret.readOnly} on:refresh={refreshSecrets} />
|
<Secret
|
||||||
|
name={secret.name}
|
||||||
|
value={secret.value}
|
||||||
|
readonly={secret.readOnly}
|
||||||
|
on:refresh={refreshSecrets}
|
||||||
|
/>
|
||||||
</tr>
|
</tr>
|
||||||
{/key}
|
{/key}
|
||||||
{/each}
|
{/each}
|
||||||
@ -93,6 +98,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<form on:submit|preventDefault={getValues} class="mb-12 w-full">
|
<form on:submit|preventDefault={getValues} class="mb-12 w-full">
|
||||||
<div class="flex flex-row border-b border-coolgray-500 mb-6 space-x-2 pt-10">
|
<div class="flex flex-row border-b border-coolgray-500 mb-6 space-x-2 pt-10">
|
||||||
<div class="flex flex-row space-x-2">
|
<div class="flex flex-row space-x-2">
|
||||||
@ -107,4 +113,5 @@
|
|||||||
class="mb-2 min-h-[200px] w-full"
|
class="mb-2 min-h-[200px] w-full"
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
import { get } from '$lib/api';
|
import { get } from '$lib/api';
|
||||||
import { t } from '$lib/translations';
|
import { t } from '$lib/translations';
|
||||||
import Explainer from '$lib/components/Explainer.svelte';
|
import Explainer from '$lib/components/Explainer.svelte';
|
||||||
|
import { appSession } from '$lib/store';
|
||||||
|
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
async function refreshStorage() {
|
async function refreshStorage() {
|
||||||
@ -81,10 +82,11 @@
|
|||||||
{/key}
|
{/key}
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<div class="title" class:pt-10={persistentStorages.filter((s) => s.predefined).length > 0}>
|
<div class="title" class:pt-10={persistentStorages.filter((s) => s.predefined).length > 0}>
|
||||||
Add New Volume
|
Add New Volume
|
||||||
</div>
|
</div>
|
||||||
<Storage on:refresh={refreshStorage} isNew {services} />
|
<Storage on:refresh={refreshStorage} isNew {services} />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -190,7 +190,7 @@
|
|||||||
id="name"
|
id="name"
|
||||||
required
|
required
|
||||||
bind:value={source.name}
|
bind:value={source.name}
|
||||||
disabled={$appSession.teamId !== '0'}
|
disabled={!$appSession.isAdmin}
|
||||||
/>
|
/>
|
||||||
<label for="htmlUrl">HTML URL</label>
|
<label for="htmlUrl">HTML URL</label>
|
||||||
<input
|
<input
|
||||||
@ -236,6 +236,7 @@
|
|||||||
placeholder="eg: coollabsio"
|
placeholder="eg: coollabsio"
|
||||||
bind:value={source.organization}
|
bind:value={source.organization}
|
||||||
/>
|
/>
|
||||||
|
{#if $appSession.isAdmin}
|
||||||
<Setting
|
<Setting
|
||||||
customClass="pt-4"
|
customClass="pt-4"
|
||||||
id="autodeploy"
|
id="autodeploy"
|
||||||
@ -246,6 +247,7 @@
|
|||||||
title="System Wide Git Source"
|
title="System Wide Git Source"
|
||||||
description="System Wide Git Sources are available to all the users in your Coolify instance. <br><br> <span class='font-bold text-warning'>Use with caution, as it can be a security risk.</span>"
|
description="System Wide Git Sources are available to all the users in your Coolify instance. <br><br> <span class='font-bold text-warning'>Use with caution, as it can be a security risk.</span>"
|
||||||
/>
|
/>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{:else}
|
{:else}
|
||||||
|
@ -51,7 +51,8 @@
|
|||||||
appId: source.gitlabApp.appId,
|
appId: source.gitlabApp.appId,
|
||||||
appSecret: source.gitlabApp.appSecret,
|
appSecret: source.gitlabApp.appSecret,
|
||||||
groupName: source.gitlabApp.groupName,
|
groupName: source.gitlabApp.groupName,
|
||||||
customPort: source.customPort
|
customPort: source.customPort,
|
||||||
|
customUser: source.customUser,
|
||||||
});
|
});
|
||||||
const from = $page.url.searchParams.get('from');
|
const from = $page.url.searchParams.get('from');
|
||||||
if (from) {
|
if (from) {
|
||||||
@ -70,7 +71,8 @@
|
|||||||
name: source.name,
|
name: source.name,
|
||||||
htmlUrl: source.htmlUrl.replace(/\/$/, ''),
|
htmlUrl: source.htmlUrl.replace(/\/$/, ''),
|
||||||
apiUrl: source.apiUrl.replace(/\/$/, ''),
|
apiUrl: source.apiUrl.replace(/\/$/, ''),
|
||||||
customPort: source.customPort
|
customPort: source.customPort,
|
||||||
|
customUser: source.customUser
|
||||||
});
|
});
|
||||||
return addToast({
|
return addToast({
|
||||||
message: 'Configuration saved.',
|
message: 'Configuration saved.',
|
||||||
@ -244,6 +246,22 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{#if selfHosted}
|
{#if selfHosted}
|
||||||
|
<div class="grid grid-cols-2 items-center">
|
||||||
|
<label for="customPort" class="text-base font-bold text-stone-100"
|
||||||
|
>Custom SSH User <Explainer
|
||||||
|
explanation={'If you use a self-hosted version of Git, you can provide a custom SSH user for all the Git related actions.'}
|
||||||
|
/></label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="w-full"
|
||||||
|
name="customUser"
|
||||||
|
id="customUser"
|
||||||
|
disabled={!selfHosted}
|
||||||
|
readonly={!selfHosted}
|
||||||
|
required
|
||||||
|
bind:value={source.customUser}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="customPort" class="text-base font-bold text-stone-100"
|
<label for="customPort" class="text-base font-bold text-stone-100"
|
||||||
>Custom SSH Port <Explainer
|
>Custom SSH Port <Explainer
|
||||||
|
4
apps/ui/static/icons/directus.svg
Normal file
4
apps/ui/static/icons/directus.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200" fill="none">
|
||||||
|
<rect width="200" height="200" rx="30" fill="#4422dd" />
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M148.883 112.106C148.124 111.916 147.491 111.726 146.921 111.473C146.5 111.286 146.148 111.064 145.839 110.807C145.635 110.637 145.547 110.369 145.572 110.104C145.877 106.923 145.541 104.118 145.845 100.964C147.111 88.1771 155.15 92.2285 162.367 90.1395C166.511 88.9722 170.655 86.6747 172.169 82.1555C172.417 81.4157 172.199 80.6114 171.684 80.0255C166.956 74.6505 161.723 69.9012 156.037 65.831C136.973 52.2582 112.197 46.6221 89.4444 49.9189C88.5825 50.0438 88.1307 50.9987 88.6016 51.7314C91.4833 56.2156 95.2849 59.8853 99.6447 62.5864C100.437 63.0773 100.119 64.1376 99.2092 63.9337C97.0711 63.4543 94.3238 62.5194 91.7401 60.6961C91.4911 60.5204 91.1704 60.4762 90.8873 60.5891C89.7323 61.0497 88.0643 61.7139 86.6859 62.3089C85.8925 62.6514 85.731 63.6747 86.3841 64.2407C97.8122 74.1467 114.437 75.6526 127.455 67.7254C128.248 67.2425 129.518 68.2348 129.262 69.1275C128.853 70.5574 128.375 72.523 127.867 75.1999C124.638 91.5322 115.332 90.2661 103.811 86.1514C80.7898 77.8076 67.7294 84.9328 56.1177 70.8281C55.3109 69.8481 53.8925 69.5083 52.9328 70.3392C50.5358 72.4145 49.1172 75.4437 49.1172 78.6816C49.1172 82.5166 51.0968 85.8018 54.0311 87.7682C54.3981 88.0142 54.8858 87.9102 55.1598 87.5636C55.8748 86.6586 56.4597 86.0587 57.1881 85.6794C57.9852 85.2641 58.374 86.4045 57.701 87.0003C55.2349 89.1839 54.527 91.7851 52.9154 96.913C50.3832 104.952 51.4594 113.182 39.6217 115.334C33.3546 115.651 33.4812 119.892 31.2023 126.222C28.5575 133.863 25.0942 137.247 18.6844 143.924C17.8078 144.837 17.7326 146.297 18.696 147.118C21.2564 149.301 23.8969 149.421 26.5812 148.315C33.228 145.53 38.3556 136.921 43.1666 131.35C48.5474 125.146 61.4613 127.805 71.21 121.728C76.4677 118.504 79.6266 114.386 78.6164 108.217C78.4537 107.224 79.5906 106.626 80.0029 107.545C80.7856 109.289 81.2988 111.149 81.5121 113.071C81.5681 113.575 82.0184 113.947 82.5245 113.919C93.0718 113.326 106.711 124.959 119.458 128.107C120.233 128.299 120.784 127.403 120.346 126.736C119.539 125.507 118.854 124.233 118.308 122.931C117.744 121.578 117.317 120.265 117.015 118.998C116.778 118.007 118.226 117.741 118.721 118.632C121.99 124.524 128.523 130.057 137.615 130.717C140.717 130.97 144.136 130.59 147.681 129.514C151.922 128.248 155.847 126.602 160.531 127.488C164.013 128.122 167.241 129.894 169.267 132.869C172.11 137.015 178.11 138.113 181.308 133.781C181.743 133.191 181.78 132.403 181.492 131.729C174.45 115.223 156.569 114.089 148.883 112.106Z" fill="white" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
BIN
apps/ui/static/icons/libretranslate.png
Normal file
BIN
apps/ui/static/icons/libretranslate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
apps/ui/static/icons/openblocks.png
Normal file
BIN
apps/ui/static/icons/openblocks.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
BIN
apps/ui/static/icons/whoogle.png
Normal file
BIN
apps/ui/static/icons/whoogle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@ -1,6 +1,6 @@
|
|||||||
FROM alpine:3.17
|
FROM alpine:3.17
|
||||||
ARG BUILDARCH
|
ARG BUILDARCH
|
||||||
ARG PB_VERSION=0.10.2
|
ARG PB_VERSION=0.11.0
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
unzip \
|
unzip \
|
||||||
ca-certificates
|
ca-certificates
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "coolify",
|
"name": "coolify",
|
||||||
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
|
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
|
||||||
"version": "3.12.8",
|
"version": "3.12.9",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": "github:coollabsio/coolify",
|
"repository": "github:coollabsio/coolify",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -55,7 +55,7 @@ importers:
|
|||||||
is-ip: 5.0.0
|
is-ip: 5.0.0
|
||||||
is-port-reachable: 4.0.0
|
is-port-reachable: 4.0.0
|
||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
jsonwebtoken: 8.5.1
|
jsonwebtoken: 9.0.0
|
||||||
minimist: ^1.2.7
|
minimist: ^1.2.7
|
||||||
node-forge: 1.3.1
|
node-forge: 1.3.1
|
||||||
node-os-utils: 1.3.7
|
node-os-utils: 1.3.7
|
||||||
@ -109,7 +109,7 @@ importers:
|
|||||||
is-ip: 5.0.0
|
is-ip: 5.0.0
|
||||||
is-port-reachable: 4.0.0
|
is-port-reachable: 4.0.0
|
||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
jsonwebtoken: 8.5.1
|
jsonwebtoken: 9.0.0
|
||||||
minimist: 1.2.7
|
minimist: 1.2.7
|
||||||
node-forge: 1.3.1
|
node-forge: 1.3.1
|
||||||
node-os-utils: 1.3.7
|
node-os-utils: 1.3.7
|
||||||
@ -265,6 +265,7 @@ importers:
|
|||||||
cuid: 2.1.8
|
cuid: 2.1.8
|
||||||
dayjs: 1.11.6
|
dayjs: 1.11.6
|
||||||
dotenv: ^16.0.3
|
dotenv: ^16.0.3
|
||||||
|
esbuild: 0.15.15
|
||||||
execa: 6.1.0
|
execa: 6.1.0
|
||||||
fastify: 4.10.2
|
fastify: 4.10.2
|
||||||
fastify-plugin: 4.4.0
|
fastify-plugin: 4.4.0
|
||||||
@ -272,8 +273,9 @@ importers:
|
|||||||
is-ip: 5.0.0
|
is-ip: 5.0.0
|
||||||
is-port-reachable: 4.0.0
|
is-port-reachable: 4.0.0
|
||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
jsonwebtoken: 8.5.1
|
jsonwebtoken: 9.0.0
|
||||||
node-fetch: 3.3.0
|
node-fetch: 3.3.0
|
||||||
|
nodemon: 2.0.20
|
||||||
npm-run-all: 4.1.5
|
npm-run-all: 4.1.5
|
||||||
p-all: 4.0.0
|
p-all: 4.0.0
|
||||||
p-throttle: 5.0.0
|
p-throttle: 5.0.0
|
||||||
@ -319,7 +321,7 @@ importers:
|
|||||||
is-ip: 5.0.0
|
is-ip: 5.0.0
|
||||||
is-port-reachable: 4.0.0
|
is-port-reachable: 4.0.0
|
||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
jsonwebtoken: 8.5.1
|
jsonwebtoken: 9.0.0
|
||||||
node-fetch: 3.3.0
|
node-fetch: 3.3.0
|
||||||
p-all: 4.0.0
|
p-all: 4.0.0
|
||||||
p-throttle: 5.0.0
|
p-throttle: 5.0.0
|
||||||
@ -340,6 +342,8 @@ importers:
|
|||||||
'@types/node-fetch': 2.6.2
|
'@types/node-fetch': 2.6.2
|
||||||
'@types/shell-quote': 1.7.1
|
'@types/shell-quote': 1.7.1
|
||||||
'@types/ws': 8.5.3
|
'@types/ws': 8.5.3
|
||||||
|
esbuild: 0.15.15
|
||||||
|
nodemon: 2.0.20
|
||||||
npm-run-all: 4.1.5
|
npm-run-all: 4.1.5
|
||||||
rimraf: 3.0.2
|
rimraf: 3.0.2
|
||||||
start-server-and-test: 1.14.0
|
start-server-and-test: 1.14.0
|
||||||
@ -1449,6 +1453,7 @@ packages:
|
|||||||
engines: {node: '>= 12.11'}
|
engines: {node: '>= 12.11'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
bree: '>=9.0.0'
|
bree: '>=9.0.0'
|
||||||
|
tsconfig-paths: '>= 4'
|
||||||
dependencies:
|
dependencies:
|
||||||
bree: 9.1.2
|
bree: 9.1.2
|
||||||
ts-node: 10.8.2_wup25etrarvlqkprac7h35hj7u
|
ts-node: 10.8.2_wup25etrarvlqkprac7h35hj7u
|
||||||
@ -5733,20 +5738,14 @@ packages:
|
|||||||
graceful-fs: 4.2.10
|
graceful-fs: 4.2.10
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/jsonwebtoken/8.5.1:
|
/jsonwebtoken/9.0.0:
|
||||||
resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==}
|
resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==}
|
||||||
engines: {node: '>=4', npm: '>=1.4.28'}
|
engines: {node: '>=12', npm: '>=6'}
|
||||||
dependencies:
|
dependencies:
|
||||||
jws: 3.2.2
|
jws: 3.2.2
|
||||||
lodash.includes: 4.3.0
|
lodash: 4.17.21
|
||||||
lodash.isboolean: 3.0.3
|
|
||||||
lodash.isinteger: 4.0.4
|
|
||||||
lodash.isnumber: 3.0.3
|
|
||||||
lodash.isplainobject: 4.0.6
|
|
||||||
lodash.isstring: 4.0.1
|
|
||||||
lodash.once: 4.1.1
|
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
semver: 5.7.1
|
semver: 7.3.8
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/jwa/1.4.1:
|
/jwa/1.4.1:
|
||||||
@ -5902,37 +5901,13 @@ packages:
|
|||||||
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/lodash.includes/4.3.0:
|
|
||||||
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/lodash.isboolean/3.0.3:
|
|
||||||
resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/lodash.isinteger/4.0.4:
|
|
||||||
resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/lodash.isnumber/3.0.3:
|
|
||||||
resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/lodash.isplainobject/4.0.6:
|
/lodash.isplainobject/4.0.6:
|
||||||
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
|
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/lodash.isstring/4.0.1:
|
|
||||||
resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/lodash.merge/4.6.2:
|
/lodash.merge/4.6.2:
|
||||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||||
|
|
||||||
/lodash.once/4.1.1:
|
|
||||||
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/lodash.uniqby/4.5.0:
|
/lodash.uniqby/4.5.0:
|
||||||
resolution: {integrity: sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ==}
|
resolution: {integrity: sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
Reference in New Issue
Block a user