@if (!is_null(env('AUTOUPDATE', null)))
diff --git a/routes/api.php b/routes/api.php
index 57f45be5d..b63fde871 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -13,6 +13,8 @@ use App\Http\Controllers\Api\TeamController;
use App\Http\Middleware\ApiAllowed;
use App\Http\Middleware\IgnoreReadOnlyApiToken;
use App\Http\Middleware\OnlyRootApiToken;
+use App\Jobs\PushServerUpdateJob;
+use App\Models\Server;
use Illuminate\Support\Facades\Route;
Route::get('/health', [OtherController::class, 'healthcheck']);
@@ -129,6 +131,33 @@ Route::group([
});
+Route::group([
+ 'prefix' => 'v1',
+], function () {
+ Route::post('/sentinel/push', function () {
+ $token = request()->header('Authorization');
+ if (! $token) {
+ return response()->json(['message' => 'Unauthorized'], 401);
+ }
+ $naked_token = str_replace('Bearer ', '', $token);
+ $decrypted = decrypt($naked_token);
+ $decrypted_token = json_decode($decrypted, true);
+ $server_uuid = data_get($decrypted_token, 'server_uuid');
+ $server = Server::where('uuid', $server_uuid)->first();
+ if (! $server) {
+ return response()->json(['message' => 'Server not found'], 404);
+ }
+ if ($server->settings->sentinel_token !== $naked_token) {
+ return response()->json(['message' => 'Unauthorized'], 401);
+ }
+ $data = request()->all();
+
+ PushServerUpdateJob::dispatch($server, $data);
+
+ return response()->json(['message' => 'ok'], 200);
+ });
+});
+
Route::any('/{any}', function () {
return response()->json(['message' => 'Not found.', 'docs' => 'https://coolify.io/docs'], 404);
})->where('any', '.*');
diff --git a/scripts/install.sh b/scripts/install.sh
index 76a369e62..af3b4d464 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -13,7 +13,7 @@ DOCKER_VERSION="26.0"
# TODO: Ask for a user
CURRENT_USER=$USER
-mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance,metrics,logs}
+mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance,sentinel}
mkdir -p /data/coolify/ssh/{keys,mux}
mkdir -p /data/coolify/proxy/dynamic
diff --git a/storage/pail/.gitignore b/storage/pail/.gitignore
new file mode 100644
index 000000000..d6b7ef32c
--- /dev/null
+++ b/storage/pail/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/templates/compose/azimutt.yaml b/templates/compose/azimutt.yaml
index 314d4479a..4b498e423 100644
--- a/templates/compose/azimutt.yaml
+++ b/templates/compose/azimutt.yaml
@@ -9,9 +9,9 @@ services:
postgres:
image: postgres:15
environment:
- - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
- - POSTGRES_USER=$SERVICE_USER_POSTGRES
- - POSTGRES_DB=azimutt
+ - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
+ - POSTGRES_USER=${SERVICE_USER_POSTGRES}
+ - POSTGRES_DB=${POSTGRES_DB:-azimutt}
volumes:
- azimutt-postgres-data:/var/lib/postgresql/data
healthcheck:
@@ -80,8 +80,8 @@ services:
- PHX_SERVER=true
- PHX_HOST=$SERVICE_URL_AZIMUTT
- PORT=${PORT:-4000}
- - DATABASE_URL=ecto://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgres/azimutt
- - SECRET_KEY_BASE=$SERVICE_BASE64_64_AZIMUTT
+ - DATABASE_URL=ecto://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres/${POSTGRES_DB:-azimutt}
+ - SECRET_KEY_BASE=${SERVICE_BASE64_64_AZIMUTT}
- FILE_STORAGE_ADAPTER=${FILE_STORAGE_ADAPTER:-s3}
- AUTH_PASSWORD=${AUTH_PASSWORD:-true}
- SKIP_ONBOARDING_FUNNEL=${SKIP_ONBOARDING_FUNNEL:-true}
diff --git a/templates/compose/calcom.yaml b/templates/compose/calcom.yaml
new file mode 100644
index 000000000..89f3376ee
--- /dev/null
+++ b/templates/compose/calcom.yaml
@@ -0,0 +1,65 @@
+# documentation: https://cal.com/docs
+# slogan: Scheduling infrastructure for everyone.
+# tags: calcom,calendso,scheduling,open,source
+# logo: svgs/calcom.svg
+# port: 3000
+
+services:
+ calcom:
+ image: calcom.docker.scarf.sh/calcom/cal.com
+ platform: linux/amd64
+ environment:
+ # Some variables still uses Calcom previous name, Calendso
+ #
+ # Full list https://github.com/calcom/cal.com/blob/main/.env.example
+ - SERVICE_FQDN_CALCOM_3000
+ - NEXT_PUBLIC_LICENSE_CONSENT=agree
+ - NODE_ENV=production
+ - NEXT_PUBLIC_WEBAPP_URL=${SERVICE_FQDN_CALCOM}
+ - NEXT_PUBLIC_API_V2_URL=${SERVICE_FQDN_CALCOM}/api/v2
+ # https://next-auth.js.org/configuration/options#nextauth_url
+ # From https://github.com/calcom/docker?tab=readme-ov-file#important-run-time-variables, it should be ${NEXT_PUBLIC_WEBAPP_URL}/api/auth
+ - NEXTAUTH_URL=${SERVICE_FQDN_CALCOM}/api/auth
+ # It is highly recommended that the NEXTAUTH_SECRET must be overridden and very unique
+ # Use `openssl rand -base64 32` to generate a key
+ - NEXTAUTH_SECRET=${SERVICE_BASE64_CALCOMSECRET}
+ # Encryption key that will be used to encrypt CalDAV credentials, choose a random string, for example with `dd if=/dev/urandom bs=1K count=1 | md5sum`
+ - CALENDSO_ENCRYPTION_KEY=${SERVICE_BASE64_CALCOMKEY}
+ - POSTGRES_USER=${SERVICE_USER_POSTGRES}
+ - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
+ - POSTGRES_DB=${POSTGRES_DB:-calendso}
+ - DATABASE_HOST=postgresql
+ - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@${DATABASE_HOST:-postgresql}/${POSTGRES_DB:-calendso}
+ # Needed to run migrations while using a connection pooler like PgBouncer
+ # Use the same one as DATABASE_URL if you are not using a connection pooler
+ - DATABASE_DIRECT_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@${DATABASE_HOST:-postgresql}/${POSTGRES_DB:-calendso}
+ # GOOGLE_API_CREDENTIALS={}
+ # Set this to 1 if you don't want Cal to collect anonymous usage
+ - CALCOM_TELEMETRY_DISABLED=1
+ # E-mail settings
+ # Configures the global From: header whilst sending emails.
+ - EMAIL_FROM=${EMAIL_FROM}
+ - EMAIL_FROM_NAME=${EMAIL_FROM_NAME}
+ # Configure SMTP settings (@see https://nodemailer.com/smtp/).
+ - EMAIL_SERVER_HOST=${EMAIL_SERVER_HOST}
+ - EMAIL_SERVER_PORT=${EMAIL_SERVER_PORT}
+ - EMAIL_SERVER_USER=${EMAIL_SERVER_USER}
+ - EMAIL_SERVER_PASSWORD=${EMAIL_SERVER_PASSWORD}
+ - NEXT_PUBLIC_APP_NAME="Cal.com"
+ # More info on ALLOWED_HOSTNAMES https://github.com/calcom/cal.com/issues/12201
+ - ALLOWED_HOSTNAMES=["${SERVICE_FQDN_CALCOM}"]
+ depends_on:
+ - postgresql
+ postgresql:
+ image: postgres:16-alpine
+ environment:
+ - POSTGRES_USER=${SERVICE_USER_POSTGRES}
+ - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
+ - POSTGRES_DB=${POSTGRES_DB:-calendso}
+ volumes:
+ - calcom-postgresql-data:/var/lib/postgresql/data
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 5s
+ timeout: 20s
+ retries: 10
diff --git a/templates/compose/edgedb.yaml b/templates/compose/edgedb.yaml
new file mode 100644
index 000000000..c305895ee
--- /dev/null
+++ b/templates/compose/edgedb.yaml
@@ -0,0 +1,41 @@
+# ignore: true
+# documentation: https://www.edgedb.com
+# slogan: An open-source database designed as a spiritual successor to SQL and the relational paradigm. Powered by the Postgres query engine under the hood.
+# tags: db database sql
+# logo: svgs/edgedb.svg
+# port: 5656
+
+services:
+ edgedb:
+ image: edgedb/edgedb
+ environment:
+ - SERVICE_FQDN_EDGEDB_5656
+ - EDGEDB_SERVER_ADMIN_UI=${EDGEDB_SERVER_ADMIN_UI:-enabled}
+ - EDGEDB_SERVER_BACKEND_DSN=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql:5432/${POSTGRES_DB:-edgedb}
+ - EDGEDB_SERVER_SECURITY=${EDGEDB_SERVER_SECURITY:-strict}
+ - EDGEDB_SERVER_PASSWORD=${SERVICE_PASSWORD_EDGEDB}
+ - POSTGRES_DB=${POSTGRES_DB:-edgedb}
+ depends_on:
+ postgresql:
+ condition: service_healthy
+ volumes:
+ - edgedb-data:/dbschema
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:5656/server/status/alive"]
+ interval: 5s
+ timeout: 20s
+ retries: 10
+
+ postgresql:
+ image: postgres:16-alpine
+ volumes:
+ - edgedb-postgresql-data:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_USER=${SERVICE_USER_POSTGRES}
+ - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
+ - POSTGRES_DB=${POSTGRES_DB:-edgedb}
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 5s
+ timeout: 20s
+ retries: 10
diff --git a/templates/compose/grafana-with-postgresql.yaml b/templates/compose/grafana-with-postgresql.yaml
index 25276468e..0ccdd235d 100644
--- a/templates/compose/grafana-with-postgresql.yaml
+++ b/templates/compose/grafana-with-postgresql.yaml
@@ -39,4 +39,3 @@ services:
interval: 5s
timeout: 20s
retries: 10
-
diff --git a/templates/compose/mindsdb.yaml b/templates/compose/mindsdb.yaml
new file mode 100644
index 000000000..72dc5a2d0
--- /dev/null
+++ b/templates/compose/mindsdb.yaml
@@ -0,0 +1,48 @@
+# documentation: https://docs.mindsdb.com/what-is-mindsdb
+# slogan: MindsDB is the platform for building AI from enterprise data, enabling smarter organizations.
+# tags: mysql, postgresdb, machine-learning, ai
+# logo: svgs/mindsdb.svg
+# port: 47334
+
+services:
+ mindsdb:
+ image: mindsdb/mindsdb:latest
+ environment:
+ - SERVICE_FQDN_MINDSDB_47334
+ - SERVICE_FQDN_API_47335=/api
+ - MINDSDB_DOCKER_ENV=true
+ - MINDSDB_STORAGE_DIR=/mindsdb/var
+ - FLASK_DEBUG=${FLASK_DEBUG:-1} # This will make sure http requests are logged regardless of log level
+ - OPENAI_API_KEY=${OPENAI_API_KEY}
+ - LANGFUSE_HOST=${LANGFUSE_HOST}
+ - LANGFUSE_PUBLIC_KEY=${LANGFUSE_PUBLIC_KEY}
+ - LANGFUSE_SECRET_KEY=${LANGFUSE_SECRET_KEY}
+ - LANGFUSE_RELEASE=${LANGFUSE_RELEASE:-local}
+ - LANGFUSE_DEBUG=${LANGFUSE_DEBUG:-False}
+ - LANGFUSE_TIMEOUT=${LANGFUSE_TIMEOUT:-10}
+ - LANGFUSE_SAMPLE_RATE=${LANGFUSE_SAMPLE_RATE:-1.0}
+ - MINDSDB_DB_CON=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql/${POSTGRES_DB:-mindsdb-db}
+ volumes:
+ - mindsdb-data:/mindsdb/var
+ depends_on:
+ postgresql:
+ condition: service_healthy
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:47334/api/util/ping"]
+ interval: 30s
+ timeout: 5s
+ retries: 15
+
+ postgresql:
+ image: postgres:16-alpine
+ volumes:
+ - mindsdb-postgresql-data:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_USER=${SERVICE_USER_POSTGRES}
+ - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
+ - POSTGRES_DB=${POSTGRES_DB:-mindsdb-db}
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 10s
+ timeout: 5s
+ retries: 15
diff --git a/templates/compose/mosquitto.yaml b/templates/compose/mosquitto.yaml
new file mode 100644
index 000000000..1ec6f0cdc
--- /dev/null
+++ b/templates/compose/mosquitto.yaml
@@ -0,0 +1,48 @@
+# documentation: https://mosquitto.org/documentation/
+# slogan: Mosquitto is lightweight and suitable for use on all devices, from low-power single-board computers to full servers.
+# tags: mosquitto, mqtt, open-source
+# logo: svgs/mosquitto.svg
+# port: 1883
+
+services:
+ mosquitto:
+ image: eclipse-mosquitto
+ environment:
+ - SERVICE_FQDN_MOSQUITTO_1883
+ - MQTT_USERNAME=${SERVICE_USER_MOSQUITTO}
+ - MQTT_PASSWORD=${SERVICE_PASSWORD_MOSQUITTO}
+ - REQUIRE_CERTIFICATE=${REQUIRE_CERTIFICATE:-false}
+ - ALLOW_ANONYMOUS=${ALLOW_ANONYMOUS:-true}
+ volumes:
+ - mosquitto-config:/mosquitto/config
+ - mosquitto-certs:/certs
+ healthcheck:
+ test: ["CMD-SHELL", "exit 0"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+
+ entrypoint: 'sh -c "
+ if [ ''$REQUIRE_CERTIFICATE'' = ''true'' ]; then
+ echo ''listener 8883'' > /mosquitto/config/mosquitto.conf &&
+ echo ''cafile /certs/ca.crt'' >> /mosquitto/config/mosquitto.conf &&
+ echo ''certfile /certs/server.crt'' >> /mosquitto/config/mosquitto.conf &&
+ echo ''keyfile /certs/server.key'' >> /mosquitto/config/mosquitto.conf;
+ else
+ echo ''listener 1883'' > /mosquitto/config/mosquitto.conf;
+ fi &&
+ echo ''require_certificate ''$REQUIRE_CERTIFICATE >> /mosquitto/config/mosquitto.conf &&
+ echo ''allow_anonymous ''$ALLOW_ANONYMOUS >> /mosquitto/config/mosquitto.conf &&
+ if [ -n ''$SERVICE_USER_MOSQUITTO''] && [ -n ''$SERVICE_PASSWORD_MOSQUITTO'' ]; then
+ echo ''password_file /mosquitto/config/passwords'' >> /mosquitto/config/mosquitto.conf &&
+ touch /mosquitto/config/passwords &&
+ chmod 0700 /mosquitto/config/passwords &&
+ chown root:root /mosquitto/config/passwords &&
+ mosquitto_passwd -b -c /mosquitto/config/passwords $SERVICE_USER_MOSQUITTO $SERVICE_PASSWORD_MOSQUITTO &&
+ chown mosquitto:mosquitto /mosquitto/config/passwords;
+ fi &&
+ exec mosquitto -c /mosquitto/config/mosquitto.conf
+ "'
+ labels:
+ - traefik.tcp.routers.mqtt.entrypoints=mqtt
+ - traefik.tcp.routers.mqtts.entrypoints=mqtts
diff --git a/templates/compose/plausible.yaml b/templates/compose/plausible.yaml
index e02e92d38..a37dcaf6e 100644
--- a/templates/compose/plausible.yaml
+++ b/templates/compose/plausible.yaml
@@ -10,31 +10,60 @@ services:
command: 'sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run"'
environment:
- SERVICE_FQDN_PLAUSIBLE
- - "DATABASE_URL=postgres://postgres:$SERVICE_PASSWORD_POSTGRES@plausible_db/plausible"
- - BASE_URL=$SERVICE_FQDN_PLAUSIBLE
- - SECRET_KEY_BASE=$SERVICE_BASE64_64_PLAUSIBLE
- - TOTP_VAULT_KEY=$SERVICE_REALBASE64_32_TOTP
+ - DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@plausible-db:5432/${POSTGRES_DB:-plausible-db}
+ - CLICKHOUSE_DATABASE_URL=http://plausible-events-db:8123/plausible_events_db
+ - BASE_URL=${SERVICE_FQDN_PLAUSIBLE}
+ - SECRET_KEY_BASE=${SERVICE_BASE64_64_PLAUSIBLE}
+ - TOTP_VAULT_KEY=${SERVICE_REALBASE64_32_TOTP}
depends_on:
- - plausible_db
- - plausible_events_db
- - mail
+ plausible-db:
+ condition: service_healthy
+ plausible-events-db:
+ condition: service_healthy
+ mail:
+ condition: service_healthy
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "wget",
+ "--no-verbose",
+ "--tries=1",
+ "--spider",
+ "http://127.0.0.1:8000/api/health",
+ ]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ start_period: 45s
+
mail:
image: bytemark/smtp
+ platform: linux/amd64
+ healthcheck:
+ test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/25' || exit 1"]
+ interval: 5s
+ timeout: 10s
+ retries: 20
- plausible_db:
+ plausible-db:
image: "postgres:16-alpine"
volumes:
- - "db-data:/var/lib/postgresql/data"
+ - plausible-postgres-data:/var/lib/postgresql/data
environment:
- - POSTGRES_DB=plausible
- - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
+ - POSTGRES_DB=${POSTGRES_DB:-plausible-db}
+ - POSTGRES_USER=${SERVICE_USER_POSTGRES}
+ - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 5s
+ timeout: 20s
+ retries: 10
- plausible_events_db:
+ plausible-events-db:
image: "clickhouse/clickhouse-server:24.3.3.102-alpine"
volumes:
- - type: volume
- source: event-data
- target: /var/lib/clickhouse
+ - plausible-events-data:/var/lib/clickhouse
- type: bind
source: ./clickhouse/clickhouse-config.xml
target: /etc/clickhouse-server/config.d/logging.xml
@@ -49,3 +78,10 @@ services:
nofile:
soft: 262144
hard: 262144
+ healthcheck:
+ test:
+ [
+ "CMD-SHELL",
+ "wget --no-verbose --tries=1 -O - http://127.0.0.1:8123/ping || exit 1",
+ ]
+ start_period: 30s
diff --git a/templates/compose/windmill.yaml b/templates/compose/windmill.yaml
index a14854ba0..1ce3a4652 100644
--- a/templates/compose/windmill.yaml
+++ b/templates/compose/windmill.yaml
@@ -11,10 +11,11 @@ services:
volumes:
- db-data:/var/lib/postgresql/data
environment:
- - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
- - POSTGRES_DB=${POSTGRES_DB:-windmill}
+ - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
+ - POSTGRES_USER=${SERVICE_USER_POSTGRES}
+ - POSTGRES_DB=${POSTGRES_DB:-windmill-db}
healthcheck:
- test: ["CMD-SHELL", "pg_isready -U postgres"]
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
@@ -23,16 +24,16 @@ services:
image: ghcr.io/windmill-labs/windmill:main
environment:
- SERVICE_FQDN_WINDMILL_8000
- - DATABASE_URL=postgres://postgres:$SERVICE_PASSWORD_POSTGRES@db/windmill
- - MODE=${MODE:-server}
- - BASE_URL=$SERVICE_FQDN_WINDMILL
+ - DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@db/${POSTGRES_DB:-windmill-db}
+ - MODE=server
+ - BASE_URL=${SERVICE_FQDN_WINDMILL}
depends_on:
db:
condition: service_healthy
volumes:
- worker-logs:/tmp/windmill/logs
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"]
+ test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
@@ -40,9 +41,9 @@ services:
windmill-worker-1:
image: ghcr.io/windmill-labs/windmill:main
environment:
- - DATABASE_URL=postgres://postgres:$SERVICE_PASSWORD_POSTGRES@db/windmill
- - MODE=${MODE:-worker}
- - WORKER_GROUP=${WORKER_GROUP:-default}
+ - DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@db/${POSTGRES_DB:-windmill-db}
+ - MODE=worker
+ - WORKER_GROUP=default
depends_on:
db:
condition: service_healthy
@@ -51,7 +52,7 @@ services:
- worker-dependency-cache:/tmp/windmill/cache
- worker-logs:/tmp/windmill/logs
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"]
+ test: ["CMD-SHELL", "exit 0"]
interval: 30s
timeout: 10s
retries: 3
@@ -59,9 +60,9 @@ services:
windmill-worker-2:
image: ghcr.io/windmill-labs/windmill:main
environment:
- - DATABASE_URL=postgres://postgres:$SERVICE_PASSWORD_POSTGRES@db/windmill
- - MODE=${MODE:-worker}
- - WORKER_GROUP=${WORKER_GROUP:-default}
+ - DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@db/${POSTGRES_DB:-windmill-db}
+ - MODE=worker
+ - WORKER_GROUP=default
depends_on:
db:
condition: service_healthy
@@ -70,7 +71,7 @@ services:
- worker-dependency-cache:/tmp/windmill/cache
- worker-logs:/tmp/windmill/logs
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"]
+ test: ["CMD-SHELL", "exit 0"]
interval: 30s
timeout: 10s
retries: 3
@@ -78,9 +79,9 @@ services:
windmill-worker-3:
image: ghcr.io/windmill-labs/windmill:main
environment:
- - DATABASE_URL=postgres://postgres:$SERVICE_PASSWORD_POSTGRES@db/windmill
- - MODE=${MODE:-worker}
- - WORKER_GROUP=${WORKER_GROUP:-default}
+ - DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@db/${POSTGRES_DB:-windmill-db}
+ - MODE=worker
+ - WORKER_GROUP=default
depends_on:
db:
condition: service_healthy
@@ -89,7 +90,7 @@ services:
- worker-dependency-cache:/tmp/windmill/cache
- worker-logs:/tmp/windmill/logs
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"]
+ test: ["CMD-SHELL", "exit 0"]
interval: 30s
timeout: 10s
retries: 3
@@ -97,18 +98,18 @@ services:
windmill-worker-native:
image: ghcr.io/windmill-labs/windmill:main
environment:
- - DATABASE_URL=postgres://postgres:$SERVICE_PASSWORD_POSTGRES@db/windmill
- - MODE=${MODE:-worker}
- - WORKER_GROUP=${WORKER_GROUP:-native}
- - NUM_WORKERS=${NUM_WORKERS:-8}
- - SLEEP_QUEUE=${SLEEP_QUEUE:-200}
+ - DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@db/${POSTGRES_DB:-windmill-db}
+ - MODE=worker
+ - WORKER_GROUP=native
+ - NUM_WORKERS=8
+ - SLEEP_QUEUE=200
depends_on:
db:
condition: service_healthy
volumes:
- worker-logs:/tmp/windmill/logs
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"]
+ test: ["CMD-SHELL", "exit 0"]
interval: 30s
timeout: 10s
retries: 3
@@ -122,3 +123,4 @@ services:
interval: 30s
timeout: 10s
retries: 3
+ start_period: 20s
\ No newline at end of file
diff --git a/templates/service-templates.json b/templates/service-templates.json
index 664eb1ade..644864ade 100644
--- a/templates/service-templates.json
+++ b/templates/service-templates.json
@@ -224,6 +224,21 @@
"minversion": "0.0.0",
"port": "10000"
},
+ "calcom": {
+ "documentation": "https://cal.com/docs?utm_source=coolify.io",
+ "slogan": "Scheduling infrastructure for everyone.",
+ "compose": "c2VydmljZXM6CiAgY2FsY29tOgogICAgaW1hZ2U6IGNhbGNvbS5kb2NrZXIuc2NhcmYuc2gvY2FsY29tL2NhbC5jb20KICAgIHBsYXRmb3JtOiBsaW51eC9hbWQ2NAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0NBTENPTV8zMDAwCiAgICAgIC0gTkVYVF9QVUJMSUNfTElDRU5TRV9DT05TRU5UPWFncmVlCiAgICAgIC0gTk9ERV9FTlY9cHJvZHVjdGlvbgogICAgICAtICdORVhUX1BVQkxJQ19XRUJBUFBfVVJMPSR7U0VSVklDRV9GUUROX0NBTENPTX0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQSV9WMl9VUkw9JHtTRVJWSUNFX0ZRRE5fQ0FMQ09NfS9hcGkvdjInCiAgICAgIC0gJ05FWFRBVVRIX1VSTD0ke1NFUlZJQ0VfRlFETl9DQUxDT019L2FwaS9hdXRoJwogICAgICAtICdORVhUQVVUSF9TRUNSRVQ9JHtTRVJWSUNFX0JBU0U2NF9DQUxDT01TRUNSRVR9JwogICAgICAtICdDQUxFTkRTT19FTkNSWVBUSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0X0NBTENPTUtFWX0nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIC0gREFUQUJBU0VfSE9TVD1wb3N0Z3Jlc3FsCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtEQVRBQkFTRV9IT1NUOi1wb3N0Z3Jlc3FsfS8ke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIC0gJ0RBVEFCQVNFX0RJUkVDVF9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7REFUQUJBU0VfSE9TVDotcG9zdGdyZXNxbH0vJHtQT1NUR1JFU19EQjotY2FsZW5kc299JwogICAgICAtIENBTENPTV9URUxFTUVUUllfRElTQUJMRUQ9MQogICAgICAtICdFTUFJTF9GUk9NPSR7RU1BSUxfRlJPTX0nCiAgICAgIC0gJ0VNQUlMX0ZST01fTkFNRT0ke0VNQUlMX0ZST01fTkFNRX0nCiAgICAgIC0gJ0VNQUlMX1NFUlZFUl9IT1NUPSR7RU1BSUxfU0VSVkVSX0hPU1R9JwogICAgICAtICdFTUFJTF9TRVJWRVJfUE9SVD0ke0VNQUlMX1NFUlZFUl9QT1JUfScKICAgICAgLSAnRU1BSUxfU0VSVkVSX1VTRVI9JHtFTUFJTF9TRVJWRVJfVVNFUn0nCiAgICAgIC0gJ0VNQUlMX1NFUlZFUl9QQVNTV09SRD0ke0VNQUlMX1NFUlZFUl9QQVNTV09SRH0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQUF9OQU1FPSJDYWwuY29tIicKICAgICAgLSAnQUxMT1dFRF9IT1NUTkFNRVM9WyIke1NFUlZJQ0VfRlFETl9DQUxDT019Il0nCiAgICBkZXBlbmRzX29uOgogICAgICAtIHBvc3RncmVzcWwKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LWNhbGVuZHNvfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2NhbGNvbS1wb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=",
+ "tags": [
+ "calcom",
+ "calendso",
+ "scheduling",
+ "open",
+ "source"
+ ],
+ "logo": "svgs/calcom.svg",
+ "minversion": "0.0.0",
+ "port": "3000"
+ },
"castopod": {
"documentation": "https://docs.castopod.org/main/en/?utm_source=coolify.io",
"slogan": "Castopod is a free & open-source hosting platform made for podcasters who want engage and interact with their audience.",
@@ -1523,6 +1538,20 @@
"minversion": "0.0.0",
"port": "8081"
},
+ "mindsdb": {
+ "documentation": "https://docs.mindsdb.com/what-is-mindsdb?utm_source=coolify.io",
+ "slogan": "MindsDB is the platform for building AI from enterprise data, enabling smarter organizations.",
+ "compose": "c2VydmljZXM6CiAgbWluZHNkYjoKICAgIGltYWdlOiAnbWluZHNkYi9taW5kc2RiOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9NSU5EU0RCXzQ3MzM0CiAgICAgIC0gU0VSVklDRV9GUUROX0FQSV80NzMzNT0vYXBpCiAgICAgIC0gTUlORFNEQl9ET0NLRVJfRU5WPXRydWUKICAgICAgLSBNSU5EU0RCX1NUT1JBR0VfRElSPS9taW5kc2RiL3ZhcgogICAgICAtICdGTEFTS19ERUJVRz0ke0ZMQVNLX0RFQlVHOi0xfScKICAgICAgLSAnT1BFTkFJX0FQSV9LRVk9JHtPUEVOQUlfQVBJX0tFWX0nCiAgICAgIC0gJ0xBTkdGVVNFX0hPU1Q9JHtMQU5HRlVTRV9IT1NUfScKICAgICAgLSAnTEFOR0ZVU0VfUFVCTElDX0tFWT0ke0xBTkdGVVNFX1BVQkxJQ19LRVl9JwogICAgICAtICdMQU5HRlVTRV9TRUNSRVRfS0VZPSR7TEFOR0ZVU0VfU0VDUkVUX0tFWX0nCiAgICAgIC0gJ0xBTkdGVVNFX1JFTEVBU0U9JHtMQU5HRlVTRV9SRUxFQVNFOi1sb2NhbH0nCiAgICAgIC0gJ0xBTkdGVVNFX0RFQlVHPSR7TEFOR0ZVU0VfREVCVUc6LUZhbHNlfScKICAgICAgLSAnTEFOR0ZVU0VfVElNRU9VVD0ke0xBTkdGVVNFX1RJTUVPVVQ6LTEwfScKICAgICAgLSAnTEFOR0ZVU0VfU0FNUExFX1JBVEU9JHtMQU5HRlVTRV9TQU1QTEVfUkFURTotMS4wfScKICAgICAgLSAnTUlORFNEQl9EQl9DT049cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QHBvc3RncmVzcWwvJHtQT1NUR1JFU19EQjotbWluZHNkYi1kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdtaW5kc2RiLWRhdGE6L21pbmRzZGIvdmFyJwogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXNxbDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjQ3MzM0L2FwaS91dGlsL3BpbmcnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTUKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICB2b2x1bWVzOgogICAgICAtICdtaW5kc2RiLXBvc3RncmVzcWwtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LW1pbmRzZGItZGJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAxNQo=",
+ "tags": [
+ "mysql",
+ "postgresdb",
+ "machine-learning",
+ "ai"
+ ],
+ "logo": "svgs/mindsdb.svg",
+ "minversion": "0.0.0",
+ "port": "47334"
+ },
"minecraft": {
"documentation": "https://github.com/itzg/docker-minecraft-server?utm_source=coolify.io",
"slogan": "Minecraft Server that will automatically download selected version at startup.",
@@ -1583,6 +1612,19 @@
"minversion": "0.0.0",
"port": "8080"
},
+ "mosquitto": {
+ "documentation": "https://mosquitto.org/documentation/?utm_source=coolify.io",
+ "slogan": "Mosquitto is lightweight and suitable for use on all devices, from low-power single-board computers to full servers.",
+ "compose": "c2VydmljZXM6CiAgbW9zcXVpdHRvOgogICAgaW1hZ2U6IGVjbGlwc2UtbW9zcXVpdHRvCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTU9TUVVJVFRPXzE4ODMKICAgICAgLSAnTVFUVF9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9NT1NRVUlUVE99JwogICAgICAtICdNUVRUX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE99JwogICAgICAtICdSRVFVSVJFX0NFUlRJRklDQVRFPSR7UkVRVUlSRV9DRVJUSUZJQ0FURTotZmFsc2V9JwogICAgICAtICdBTExPV19BTk9OWU1PVVM9JHtBTExPV19BTk9OWU1PVVM6LXRydWV9JwogICAgdm9sdW1lczoKICAgICAgLSAnbW9zcXVpdHRvLWNvbmZpZzovbW9zcXVpdHRvL2NvbmZpZycKICAgICAgLSAnbW9zcXVpdHRvLWNlcnRzOi9jZXJ0cycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICBlbnRyeXBvaW50OiAic2ggLWMgXCIgaWYgWyAnJFJFUVVJUkVfQ0VSVElGSUNBVEUnID0gJ3RydWUnIF07IHRoZW4gZWNobyAnbGlzdGVuZXIgODg4MycgPiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdjYWZpbGUgL2NlcnRzL2NhLmNydCcgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgZWNobyAnY2VydGZpbGUgL2NlcnRzL3NlcnZlci5jcnQnID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIGVjaG8gJ2tleWZpbGUgIC9jZXJ0cy9zZXJ2ZXIua2V5JyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZjsgZWxzZSBlY2hvICdsaXN0ZW5lciAxODgzJyA+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mOyBmaSAmJiBlY2hvICdyZXF1aXJlX2NlcnRpZmljYXRlICckUkVRVUlSRV9DRVJUSUZJQ0FURSA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdhbGxvd19hbm9ueW1vdXMgJyRBTExPV19BTk9OWU1PVVMgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgaWYgWyAtbiAnJFNFUlZJQ0VfVVNFUl9NT1NRVUlUVE8nXSAmJiBbIC1uICckU0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE8nIF07IHRoZW4gZWNobyAncGFzc3dvcmRfZmlsZSAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMnID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIHRvdWNoIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAmJiBjaG1vZCAwNzAwIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAmJiBjaG93biByb290OnJvb3QgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICYmIG1vc3F1aXR0b19wYXNzd2QgLWIgLWMgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICRTRVJWSUNFX1VTRVJfTU9TUVVJVFRPICRTRVJWSUNFX1BBU1NXT1JEX01PU1FVSVRUTyAmJiBjaG93biBtb3NxdWl0dG86bW9zcXVpdHRvIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkczsgZmkgJiYgZXhlYyBtb3NxdWl0dG8gLWMgL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgXCIiCiAgICBsYWJlbHM6CiAgICAgIC0gdHJhZWZpay50Y3Aucm91dGVycy5tcXR0LmVudHJ5cG9pbnRzPW1xdHQKICAgICAgLSB0cmFlZmlrLnRjcC5yb3V0ZXJzLm1xdHRzLmVudHJ5cG9pbnRzPW1xdHRzCg==",
+ "tags": [
+ "mosquitto",
+ "mqtt",
+ "open-source"
+ ],
+ "logo": "svgs/mosquitto.svg",
+ "minversion": "0.0.0",
+ "port": "1883"
+ },
"n8n-with-postgresql": {
"documentation": "https://n8n.io?utm_source=coolify.io",
"slogan": "n8n is an extendable workflow automation tool.",
@@ -2624,7 +2666,7 @@
"windmill": {
"documentation": "https://www.windmill.dev/docs/?utm_source=coolify.io",
"slogan": "Windmill is a developer platform to build production-grade multi-steps automations and internal apps.",
- "compose": "c2VydmljZXM6CiAgZGI6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2JwogICAgc2htX3NpemU6IDFnCiAgICB2b2x1bWVzOgogICAgICAtICdkYi1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LXdpbmRtaWxsfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSBwb3N0Z3JlcycKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgd2luZG1pbGwtc2VydmVyOgogICAgaW1hZ2U6ICdnaGNyLmlvL3dpbmRtaWxsLWxhYnMvd2luZG1pbGw6bWFpbicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9XSU5ETUlMTF84MDAwCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotc2VydmVyfScKICAgICAgLSBCQVNFX1VSTD0kU0VSVklDRV9GUUROX1dJTkRNSUxMCiAgICBkZXBlbmRzX29uOgogICAgICBkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgdm9sdW1lczoKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3ZlcnNpb24gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTE6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotd29ya2VyfScKICAgICAgLSAnV09SS0VSX0dST1VQPSR7V09SS0VSX0dST1VQOi1kZWZhdWx0fScKICAgIGRlcGVuZHNfb246CiAgICAgIGRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnd29ya2VyLWRlcGVuZGVuY3ktY2FjaGU6L3RtcC93aW5kbWlsbC9jYWNoZScKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3ZlcnNpb24gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTI6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotd29ya2VyfScKICAgICAgLSAnV09SS0VSX0dST1VQPSR7V09SS0VSX0dST1VQOi1kZWZhdWx0fScKICAgIGRlcGVuZHNfb246CiAgICAgIGRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnd29ya2VyLWRlcGVuZGVuY3ktY2FjaGU6L3RtcC93aW5kbWlsbC9jYWNoZScKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3ZlcnNpb24gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTM6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotd29ya2VyfScKICAgICAgLSAnV09SS0VSX0dST1VQPSR7V09SS0VSX0dST1VQOi1kZWZhdWx0fScKICAgIGRlcGVuZHNfb246CiAgICAgIGRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnd29ya2VyLWRlcGVuZGVuY3ktY2FjaGU6L3RtcC93aW5kbWlsbC9jYWNoZScKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3ZlcnNpb24gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLW5hdGl2ZToKICAgIGltYWdlOiAnZ2hjci5pby93aW5kbWlsbC1sYWJzL3dpbmRtaWxsOm1haW4nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vcG9zdGdyZXM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAZGIvd2luZG1pbGwnCiAgICAgIC0gJ01PREU9JHtNT0RFOi13b3JrZXJ9JwogICAgICAtICdXT1JLRVJfR1JPVVA9JHtXT1JLRVJfR1JPVVA6LW5hdGl2ZX0nCiAgICAgIC0gJ05VTV9XT1JLRVJTPSR7TlVNX1dPUktFUlM6LTh9JwogICAgICAtICdTTEVFUF9RVUVVRT0ke1NMRUVQX1FVRVVFOi0yMDB9JwogICAgZGVwZW5kc19vbjoKICAgICAgZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3dvcmtlci1sb2dzOi90bXAvd2luZG1pbGwvbG9ncycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo4MDAwL2FwaS92ZXJzaW9uIHx8IGV4aXQgMScKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogIGxzcDoKICAgIGltYWdlOiAnZ2hjci5pby93aW5kbWlsbC1sYWJzL3dpbmRtaWxsLWxzcDpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdsc3AtY2FjaGU6L3Jvb3QvLmNhY2hlJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdleGl0IDAnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMK",
+ "compose": "c2VydmljZXM6CiAgZGI6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2JwogICAgc2htX3NpemU6IDFnCiAgICB2b2x1bWVzOgogICAgICAtICdkYi1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotd2luZG1pbGwtZGJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgd2luZG1pbGwtc2VydmVyOgogICAgaW1hZ2U6ICdnaGNyLmlvL3dpbmRtaWxsLWxhYnMvd2luZG1pbGw6bWFpbicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9XSU5ETUlMTF84MDAwCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QGRiLyR7UE9TVEdSRVNfREI6LXdpbmRtaWxsLWRifScKICAgICAgLSBNT0RFPXNlcnZlcgogICAgICAtICdCQVNFX1VSTD0ke1NFUlZJQ0VfRlFETl9XSU5ETUlMTH0nCiAgICBkZXBlbmRzX29uOgogICAgICBkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgdm9sdW1lczoKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvaGVhbHRoJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTE6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QGRiLyR7UE9TVEdSRVNfREI6LXdpbmRtaWxsLWRifScKICAgICAgLSBNT0RFPXdvcmtlcgogICAgICAtIFdPUktFUl9HUk9VUD1kZWZhdWx0CiAgICBkZXBlbmRzX29uOgogICAgICBkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgdm9sdW1lczoKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICAgIC0gJ3dvcmtlci1kZXBlbmRlbmN5LWNhY2hlOi90bXAvd2luZG1pbGwvY2FjaGUnCiAgICAgIC0gJ3dvcmtlci1sb2dzOi90bXAvd2luZG1pbGwvbG9ncycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTI6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QGRiLyR7UE9TVEdSRVNfREI6LXdpbmRtaWxsLWRifScKICAgICAgLSBNT0RFPXdvcmtlcgogICAgICAtIFdPUktFUl9HUk9VUD1kZWZhdWx0CiAgICBkZXBlbmRzX29uOgogICAgICBkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgdm9sdW1lczoKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICAgIC0gJ3dvcmtlci1kZXBlbmRlbmN5LWNhY2hlOi90bXAvd2luZG1pbGwvY2FjaGUnCiAgICAgIC0gJ3dvcmtlci1sb2dzOi90bXAvd2luZG1pbGwvbG9ncycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTM6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QGRiLyR7UE9TVEdSRVNfREI6LXdpbmRtaWxsLWRifScKICAgICAgLSBNT0RFPXdvcmtlcgogICAgICAtIFdPUktFUl9HUk9VUD1kZWZhdWx0CiAgICBkZXBlbmRzX29uOgogICAgICBkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgdm9sdW1lczoKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICAgIC0gJ3dvcmtlci1kZXBlbmRlbmN5LWNhY2hlOi90bXAvd2luZG1pbGwvY2FjaGUnCiAgICAgIC0gJ3dvcmtlci1sb2dzOi90bXAvd2luZG1pbGwvbG9ncycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLW5hdGl2ZToKICAgIGltYWdlOiAnZ2hjci5pby93aW5kbWlsbC1sYWJzL3dpbmRtaWxsOm1haW4nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AZGIvJHtQT1NUR1JFU19EQjotd2luZG1pbGwtZGJ9JwogICAgICAtIE1PREU9d29ya2VyCiAgICAgIC0gV09SS0VSX0dST1VQPW5hdGl2ZQogICAgICAtIE5VTV9XT1JLRVJTPTgKICAgICAgLSBTTEVFUF9RVUVVRT0yMDAKICAgIGRlcGVuZHNfb246CiAgICAgIGRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICB2b2x1bWVzOgogICAgICAtICd3b3JrZXItbG9nczovdG1wL3dpbmRtaWxsL2xvZ3MnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ2V4aXQgMCcKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogIGxzcDoKICAgIGltYWdlOiAnZ2hjci5pby93aW5kbWlsbC1sYWJzL3dpbmRtaWxsLWxzcDpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdsc3AtY2FjaGU6L3Jvb3QvLmNhY2hlJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdleGl0IDAnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICAgICAgc3RhcnRfcGVyaW9kOiAyMHMK",
"tags": [
"windmill",
"workflow",
diff --git a/tests/Browser/ExampleTest.php b/tests/Browser/ExampleTest.php
deleted file mode 100644
index 15dc8f5f1..000000000
--- a/tests/Browser/ExampleTest.php
+++ /dev/null
@@ -1,20 +0,0 @@
-browse(function (Browser $browser) {
- $browser->visit('/')
- ->assertSee('Laravel');
- });
- }
-}
diff --git a/tests/Browser/LoginTest.php b/tests/Browser/LoginTest.php
new file mode 100644
index 000000000..cac9a65fe
--- /dev/null
+++ b/tests/Browser/LoginTest.php
@@ -0,0 +1,32 @@
+browse(function (Browser $browser) use ($password, $email) {
+ $browser->visit('/login')
+ ->type('email', $email)
+ ->type('password', $password)
+ ->press('Login')
+ ->assertPathIs('/')
+ ->screenshot('login');
+ });
+ }
+}
diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php
index 8628871a1..98e90fa79 100644
--- a/tests/DuskTestCase.php
+++ b/tests/DuskTestCase.php
@@ -39,7 +39,7 @@ abstract class DuskTestCase extends BaseTestCase
})->all());
return RemoteWebDriver::create(
- $_ENV['DUSK_DRIVER_URL'] ?? 'http://localhost:9515',
+ 'http://localhost:4444',
DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY,
$options
@@ -50,23 +50,8 @@ abstract class DuskTestCase extends BaseTestCase
/**
* Determine if the browser window should start maximized.
*/
- protected function shouldStartMaximized(): bool
- {
- return isset($_SERVER['DUSK_START_MAXIMIZED']) ||
- isset($_ENV['DUSK_START_MAXIMIZED']);
- }
-
- /**
- * Determine whether the Dusk command has disabled headless mode.
- */
- protected function hasHeadlessDisabled(): bool
- {
- return isset($_SERVER['DUSK_HEADLESS_DISABLED']) ||
- isset($_ENV['DUSK_HEADLESS_DISABLED']);
- }
-
protected function baseUrl()
{
- return rtrim(config('app.url'), '/');
+ return 'http://localhost:8000';
}
}
diff --git a/versions.json b/versions.json
index 7d8a9b2d1..e24038001 100644
--- a/versions.json
+++ b/versions.json
@@ -1,7 +1,7 @@
{
"coolify": {
"v4": {
- "version": "4.0.0-beta.361"
+ "version": "4.0.0-beta.360"
},
"nightly": {
"version": "4.0.0-beta.362"
@@ -11,6 +11,9 @@
},
"realtime": {
"version": "1.0.3"
+ },
+ "sentinel": {
+ "version": "next"
}
}
}