Compare commits

...

14 Commits

Author SHA1 Message Date
Andras Bacsai
3535dbb98f Merge pull request #3583 from coollabsio/next
v4.0.0-beta.345
2024-09-26 13:21:16 +02:00
Andras Bacsai
84b2af53d8 refactor: Fix modal input closeOutside prop in configuration.blade.php 2024-09-26 13:20:06 +02:00
Andras Bacsai
ba70451765 refactor: Update install.sh script to remove redirection of upgrade output to /dev/null 2024-09-26 13:07:06 +02:00
Andras Bacsai
f3ec4ca4a3 refactor: Improve modal confirmation titles and button labels 2024-09-26 13:07:01 +02:00
Andras Bacsai
174923de98 refactor: Update ProductionSeeder to fix issue with coolify_key assignment 2024-09-26 13:06:56 +02:00
Andras Bacsai
68ab8dc14c refactor: Add localhost as Server if it doesn't exist and not in cloud environment 2024-09-26 12:31:39 +02:00
Andras Bacsai
b218356f2d chore: Update version numbers to 4.0.0-beta.345 2024-09-26 12:31:36 +02:00
Andras Bacsai
e83aecebc3 Merge pull request #3559 from coollabsio/next
v4.0.0-beta.344
2024-09-26 12:22:48 +02:00
Andras Bacsai
0bb1f57ea7 fix: deploy key based deployments 2024-09-26 12:19:49 +02:00
Andras Bacsai
d006edc485 refactor: Add localhost as Server if it doesn't exist and not in cloud environment 2024-09-26 10:37:02 +02:00
Andras Bacsai
aa28c99827 refactor: Update OS_TYPE for Asahi Linux in install.sh script 2024-09-26 10:36:59 +02:00
Andras Bacsai
567bbe9d0b chore: Update version numbers to 4.0.0-beta.344 2024-09-25 10:27:51 +02:00
Andras Bacsai
59d2c9748a fix: make sure to reload window if app status changes 2024-09-25 10:27:23 +02:00
Andras Bacsai
bd2e1ad9fe refactor: Fix typo in execute-container-command.blade.php 2024-09-25 10:25:35 +02:00
12 changed files with 118 additions and 148 deletions

View File

@@ -1442,14 +1442,24 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
if ($this->pull_request_id !== 0) { if ($this->pull_request_id !== 0) {
$local_branch = "pull/{$this->pull_request_id}/head"; $local_branch = "pull/{$this->pull_request_id}/head";
} }
$private_key = $this->application->privateKey?->getKeyLocation(); $private_key = data_get($this->application, 'private_key.private_key');
if ($private_key) { if ($private_key) {
$private_key = base64_encode($private_key);
$this->execute_remote_command( $this->execute_remote_command(
[ [
executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i {$private_key}\" git ls-remote {$this->fullRepoUrl} {$local_branch}"), executeInDocker($this->deployment_uuid, 'mkdir -p /root/.ssh'),
],
[
executeInDocker($this->deployment_uuid, "echo '{$private_key}' | base64 -d | tee /root/.ssh/id_rsa > /dev/null"),
],
[
executeInDocker($this->deployment_uuid, 'chmod 600 /root/.ssh/id_rsa'),
],
[
executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git ls-remote {$this->fullRepoUrl} {$local_branch}"),
'hidden' => true, 'hidden' => true,
'save' => 'git_commit_sha', 'save' => 'git_commit_sha',
], ]
); );
} else { } else {
$this->execute_remote_command( $this->execute_remote_command(

View File

@@ -9,6 +9,20 @@ use Livewire\Component;
class Terminal extends Component class Terminal extends Component
{ {
public function getListeners()
{
$teamId = auth()->user()->currentTeam()->id;
return [
"echo-private:team.{$teamId},ApplicationStatusChanged" => 'closeTerminal',
];
}
public function closeTerminal()
{
$this->dispatch('reloadWindow');
}
#[On('send-terminal-command')] #[On('send-terminal-command')]
public function sendTerminalCommand($isContainer, $identifier, $serverUuid) public function sendTerminalCommand($isContainer, $identifier, $serverUuid)
{ {

View File

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

View File

@@ -1,3 +1,3 @@
<?php <?php
return '4.0.0-beta.343'; return '4.0.0-beta.345';

View File

@@ -65,37 +65,39 @@ class ProductionSeeder extends Seeder
]); ]);
} }
// Add Coolify host (localhost) as Server if it doesn't exist // Add Coolify host (localhost) as Server if it doesn't exist
if (Server::find(0) == null) { if (! isCloud()) {
$server_details = [ if (Server::find(0) == null) {
'id' => 0, $server_details = [
'name' => 'localhost', 'id' => 0,
'description' => "This is the server where Coolify is running on. Don't delete this!", 'name' => 'localhost',
'user' => 'root', 'description' => "This is the server where Coolify is running on. Don't delete this!",
'ip' => 'host.docker.internal', 'user' => 'root',
'team_id' => 0, 'ip' => 'host.docker.internal',
'private_key_id' => 0, 'team_id' => 0,
]; 'private_key_id' => 0,
$server_details['proxy'] = ServerMetadata::from([ ];
'type' => ProxyTypes::TRAEFIK->value, $server_details['proxy'] = ServerMetadata::from([
'status' => ProxyStatus::EXITED->value, 'type' => ProxyTypes::TRAEFIK->value,
]); 'status' => ProxyStatus::EXITED->value,
$server = Server::create($server_details); ]);
$server->settings->is_reachable = true; $server = Server::create($server_details);
$server->settings->is_usable = true; $server->settings->is_reachable = true;
$server->settings->save(); $server->settings->is_usable = true;
} else { $server->settings->save();
$server = Server::find(0); } else {
$server->settings->is_reachable = true; $server = Server::find(0);
$server->settings->is_usable = true; $server->settings->is_reachable = true;
$server->settings->save(); $server->settings->is_usable = true;
} $server->settings->save();
if (StandaloneDocker::find(0) == null) { }
StandaloneDocker::create([ if (StandaloneDocker::find(0) == null) {
'id' => 0, StandaloneDocker::create([
'name' => 'localhost-coolify', 'id' => 0,
'network' => 'coolify', 'name' => 'localhost-coolify',
'server_id' => 0, 'network' => 'coolify',
]); 'server_id' => 0,
]);
}
} }
if (! isCloud() && config('coolify.is_windows_docker_desktop') == false) { if (! isCloud() && config('coolify.is_windows_docker_desktop') == false) {
@@ -112,8 +114,8 @@ class ProductionSeeder extends Seeder
} }
} else { } else {
if ($coolify_key) { if ($coolify_key) {
$coolify_key = Storage::disk('ssh-keys')->get($coolify_key);
$user = str($coolify_key)->before('@')->after('id.'); $user = str($coolify_key)->before('@')->after('id.');
$coolify_key = Storage::disk('ssh-keys')->get($coolify_key);
PrivateKey::create([ PrivateKey::create([
'id' => 0, 'id' => 0,
'team_id' => 0, 'team_id' => 0,

View File

@@ -8,7 +8,7 @@ set -o pipefail # Cause a pipeline to return the status of the last command that
CDN="https://cdn.coollabs.io/coolify-nightly" CDN="https://cdn.coollabs.io/coolify-nightly"
DATE=$(date +"%Y%m%d-%H%M%S") DATE=$(date +"%Y%m%d-%H%M%S")
VERSION="1.5" VERSION="1.6"
DOCKER_VERSION="26.0" DOCKER_VERSION="26.0"
# TODO: Ask for a user # TODO: Ask for a user
CURRENT_USER=$USER CURRENT_USER=$USER
@@ -39,6 +39,11 @@ if [ "$OS_TYPE" = "manjaro" ] || [ "$OS_TYPE" = "manjaro-arm" ]; then
OS_TYPE="arch" OS_TYPE="arch"
fi fi
# Check if the OS is Asahi Linux, if so, change it to fedora
if [ "$OS_TYPE" = "fedora-asahi-remix" ]; then
OS_TYPE="fedora"
fi
# Check if the OS is popOS, if so, change it to ubuntu # Check if the OS is popOS, if so, change it to ubuntu
if [ "$OS_TYPE" = "pop" ]; then if [ "$OS_TYPE" = "pop" ]; then
OS_TYPE="ubuntu" OS_TYPE="ubuntu"

View File

@@ -1,10 +1,10 @@
{ {
"coolify": { "coolify": {
"v4": { "v4": {
"version": "4.0.0-beta.343" "version": "4.0.0-beta.344"
}, },
"nightly": { "nightly": {
"version": "4.0.0-beta.344" "version": "4.0.0-beta.345"
}, },
"helper": { "helper": {
"version": "1.0.1" "version": "1.0.1"

View File

@@ -76,7 +76,7 @@
@endif @endif
@if ($application->fqdn) @if ($application->fqdn)
<span class="flex gap-1 text-xs">{{ Str::limit($application->fqdn, 60) }} <span class="flex gap-1 text-xs">{{ Str::limit($application->fqdn, 60) }}
<x-modal-input title="Edit Domains"> <x-modal-input title="Edit Domains" :closeOutside="false">
<x-slot:content> <x-slot:content>
<span class="cursor-pointer"> <span class="cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" <svg xmlns="http://www.w3.org/2000/svg"
@@ -107,15 +107,14 @@
Settings Settings
</a> </a>
@if (str($application->status)->contains('running')) @if (str($application->status)->contains('running'))
<x-modal-confirmation <x-modal-confirmation title="Confirm Service Application Restart?"
title="Confirm Service Application Restart?" buttonTitle="Restart"
buttonTitle="Restart" submitAction="restartApplication({{ $application->id }})" :actions="[
submitAction="restartApplication({{ $application->id }})" 'The selected service application will be unavailable during the restart.',
:actions="['The selected service application will be unavailable during the restart.', 'If the service application is currently in use data could be lost.']" 'If the service application is currently in use data could be lost.',
:confirmWithText="false" ]"
:confirmWithPassword="false" :confirmWithText="false" :confirmWithPassword="false"
step2ButtonText="Restart Service Container" step2ButtonText="Restart Service Container" />
/>
@endif @endif
</div> </div>
</div> </div>
@@ -155,15 +154,13 @@
Settings Settings
</a> </a>
@if (str($database->status)->contains('running')) @if (str($database->status)->contains('running'))
<x-modal-confirmation <x-modal-confirmation title="Confirm Service Database Restart?"
title="Confirm Service Database Restart?" buttonTitle="Restart" submitAction="restartDatabase({{ $database->id }})"
buttonTitle="Restart" :actions="[
submitAction="restartDatabase({{ $database->id }})" 'This service database will be unavailable during the restart.',
:actions="['This service database will be unavailable during the restart.', 'If the service database is currently in use data could be lost.']" 'If the service database is currently in use data could be lost.',
:confirmWithText="false" ]" :confirmWithText="false" :confirmWithPassword="false"
:confirmWithPassword="false" step2ButtonText="Restart Database" />
step2ButtonText="Restart Database"
/>
@endif @endif
</div> </div>
</div> </div>
@@ -183,7 +180,8 @@
lazy /> lazy />
@endforeach @endforeach
@foreach ($databases as $database) @foreach ($databases as $database)
<livewire:project.service.storage wire:key="database-{{ $database->id }}" :resource="$database" lazy /> <livewire:project.service.storage wire:key="database-{{ $database->id }}" :resource="$database"
lazy />
@endforeach @endforeach
</div> </div>
<div x-cloak x-show="activeTab === 'scheduled-tasks'"> <div x-cloak x-show="activeTab === 'scheduled-tasks'">

View File

@@ -32,7 +32,7 @@
<x-forms.button type="submit">Connect</x-forms.button> <x-forms.button type="submit">Connect</x-forms.button>
</form> </form>
@else @else
<div class="pt-4">No containers are not running.</div> <div class="pt-4">No containers are running.</div>
@endif @endif
</div> </div>
</div> </div>

View File

@@ -10,6 +10,8 @@ DATE=$(date +"%Y%m%d-%H%M%S")
VERSION="1.6" VERSION="1.6"
DOCKER_VERSION="26.0" 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,metrics,logs}
mkdir -p /data/coolify/ssh/{keys,mux} mkdir -p /data/coolify/ssh/{keys,mux}
@@ -401,88 +403,18 @@ if [ ! -f ~/.ssh/authorized_keys ]; then
chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
fi fi
checkSshKeyInAuthorizedKeys() { set +e
grep -qw "root@coolify" ~/.ssh/authorized_keys IS_COOLIFY_VOLUME_EXISTS=$(docker volume ls | grep coolify-db | wc -l)
return $? set -e
}
checkSshKeyInCoolifyData() { if [ "$IS_COOLIFY_VOLUME_EXISTS" -eq 0 ]; then
[ -s /data/coolify/ssh/keys/id.root@host.docker.internal ]
return $?
}
generateAuthorizedKeys() {
sed -i "/root@coolify/d" ~/.ssh/authorized_keys
cat /data/coolify/ssh/keys/id.root@host.docker.internal.pub >> ~/.ssh/authorized_keys
rm -f /data/coolify/ssh/keys/id.root@host.docker.internal.pub
}
generateSshKey() {
echo " - Generating SSH key." echo " - Generating SSH key."
ssh-keygen -t ed25519 -a 100 -f /data/coolify/ssh/keys/id.root@host.docker.internal -q -N "" -C root@coolify ssh-keygen -t ed25519 -a 100 -f /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal -q -N "" -C coolify
chown 9999 /data/coolify/ssh/keys/id.root@host.docker.internal chown 9999 /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal
generateAuthorizedKeys sed -i "/coolify/d" ~/.ssh/authorized_keys
} cat /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal.pub >> ~/.ssh/authorized_keys
rm -f /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal.pub
syncSshKeys() { fi
DB_RUNNING=$(docker inspect coolify-db --format '{{ .State.Status }}' 2>/dev/null)
# Check if SSH key exists in Coolify data but not in authorized_keys
if checkSshKeyInCoolifyData && ! checkSshKeyInAuthorizedKeys; then
# Add the existing Coolify SSH key to authorized_keys
cat /data/coolify/ssh/keys/id.root@host.docker.internal.pub >> ~/.ssh/authorized_keys
# Check if SSH key exists in authorized_keys but not in Coolify data
elif checkSshKeyInAuthorizedKeys && ! checkSshKeyInCoolifyData; then
# Ensure Coolify DB is running before proceeding
if [ "$DB_RUNNING" = "running" ]; then
# Retrieve DB user and SSH key from Coolify database
DB_USER=$(docker inspect coolify-db --format '{{ .Config.Env }}' | grep -oP 'POSTGRES_USER=\K[^ ]+')
DB_SSH_KEY=$(docker exec coolify-db psql -U $DB_USER -d coolify -t -c "SELECT \"private_key\" FROM \"private_keys\" WHERE id = 0 AND team_id = 0 LIMIT 1;" -A -t)
if [ -z "$DB_SSH_KEY" ]; then
# If no key found in DB, generate a new one
echo " - SSH key not found in database. Generating new key."
generateSshKey
else
# If key found in DB, save it and update authorized_keys
echo " - SSH key found in database. Saving to file."
echo "$DB_SSH_KEY" > /data/coolify/ssh/keys/id.root@host.docker.internal
chmod 600 /data/coolify/ssh/keys/id.root@host.docker.internal
chown 9999 /data/coolify/ssh/keys/id.root@host.docker.internal
# Generate public key from private key and update authorized_keys
ssh-keygen -y -f /data/coolify/ssh/keys/id.root@host.docker.internal -C root@coolify > /data/coolify/ssh/keys/id.root@host.docker.internal.pub
sed -i "/root@coolify/d" ~/.ssh/authorized_keys
cat /data/coolify/ssh/keys/id.root@host.docker.internal.pub >> ~/.ssh/authorized_keys
rm -f /data/coolify/ssh/keys/id.root@host.docker.internal.pub
chmod 600 ~/.ssh/authorized_keys
fi
fi
# If SSH key doesn't exist in either location
elif ! checkSshKeyInAuthorizedKeys && ! checkSshKeyInCoolifyData; then
# Ensure Coolify DB is running before proceeding
if [ "$DB_RUNNING" = "running" ]; then
# Retrieve DB user and SSH key from Coolify database
DB_USER=$(docker inspect coolify-db --format '{{ .Config.Env }}' | grep -oP 'POSTGRES_USER=\K[^ ]+')
DB_SSH_KEY=$(docker exec coolify-db psql -U $DB_USER -d coolify -t -c "SELECT \"private_key\" FROM \"private_keys\" WHERE id = 0 AND team_id = 0 LIMIT 1;" -A -t)
if [ -z "$DB_SSH_KEY" ]; then
# If no key found in DB, generate a new one
echo " - SSH key not found in database. Generating new key."
generateSshKey
else
# If key found in DB, save it and update authorized_keys
echo " - SSH key found in database. Saving to file."
echo "$DB_SSH_KEY" > /data/coolify/ssh/keys/id.root@host.docker.internal
chmod 600 /data/coolify/ssh/keys/id.root@host.docker.internal
ssh-keygen -y -f /data/coolify/ssh/keys/id.root@host.docker.internal -C root@coolify > /data/coolify/ssh/keys/id.root@host.docker.internal.pub
sed -i "/root@coolify/d" ~/.ssh/authorized_keys
cat /data/coolify/ssh/keys/id.root@host.docker.internal.pub >> ~/.ssh/authorized_keys
fi
else
generateSshKey
fi
fi
}
syncSshKeys || true
chown -R 9999:root /data/coolify chown -R 9999:root /data/coolify
chmod -R 700 /data/coolify chmod -R 700 /data/coolify
@@ -492,7 +424,7 @@ echo -e " - It could take a while based on your server's performance, network sp
echo -e " - Please wait." echo -e " - Please wait."
getAJoke getAJoke
bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}" >/dev/null 2>&1 bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}"
echo " - Coolify installed successfully." echo " - Coolify installed successfully."
rm -f $ENV_FILE-$DATE rm -f $ENV_FILE-$DATE

View File

@@ -3,21 +3,30 @@
# slogan: # slogan:
# tags: # tags:
# logo: # logo:
# port: 5000 # port: 4200
services: services:
postiz: postiz:
image: "ghcr.io/gitroomhq/postiz-app:latest" image: "ghcr.io/gitroomhq/postiz-app:latest"
environment: environment:
- SERVICE_FQDN_POSTIZ_5000 - SERVICE_FQDN_POSTIZ_4200
- MAIN_URL=${SERVICE_FQDN_POSTIZ} - MAIN_URL=${SERVICE_FQDN_POSTIZ}
- FRONTEND_URL=${SERVICE_FQDN_POSTIZ} - FRONTEND_URL=${SERVICE_FQDN_POSTIZ}
- NEXT_PUBLIC_BACKEND_URL=${SERVICE_FQDN_POSTIZ_3000} - NEXT_PUBLIC_BACKEND_URL=${SERVICE_FQDN_POSTIZAPI_3000}
- JWT_SECRET=${SERVICE_REALBASE64_JWTSECRET} - JWT_SECRET=${SERVICE_REALBASE64_JWTSECRET}
- DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-postiz}?schema=public - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-postiz}?schema=public
- REDIS_URL=redis://redis:6379 - REDIS_URL=redis://redis:6379
- BACKEND_INTERNAL_URL=${SERVICE_FQDN_POSTIZ} - BACKEND_INTERNAL_URL=http://localhost:3000/
- IS_GENERAL=true - IS_GENERAL=true
- CLOUDFLARE_ACCOUNT_ID=${CLOUDFLARE_ACCOUNT_ID}
- CLOUDFLARE_ACCESS_KEY=${CLOUDFLARE_ACCESS_KEY}
- CLOUDFLARE_SECRET_ACCESS_KEY=${CLOUDFLARE_SECRET_ACCESS_KEY}
- CLOUDFLARE_BUCKETNAME=${CLOUDFLARE_BUCKETNAME}
- CLOUDFLARE_BUCKET_URL=${CLOUDFLARE_BUCKET_URL}
- CLOUDFLARE_REGION=${CLOUDFLARE_REGION}
- RESEND_API_KEY=${RESEND_API_KEY}
- EMAIL_FROM_ADDRESS=${EMAIL_FROM_ADDRESS}
- EMAIL_FROM_NAME=${EMAIL_FROM_NAME}
depends_on: depends_on:
postgres: postgres:
condition: service_healthy condition: service_healthy

View File

@@ -1,10 +1,10 @@
{ {
"coolify": { "coolify": {
"v4": { "v4": {
"version": "4.0.0-beta.343" "version": "4.0.0-beta.345"
}, },
"nightly": { "nightly": {
"version": "4.0.0-beta.344" "version": "4.0.0-beta.346"
}, },
"helper": { "helper": {
"version": "1.0.1" "version": "1.0.1"