Compare commits
58 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d1bd5d45e7 | ||
|
1fdd357278 | ||
|
c870cd8ced | ||
|
dc2b15ba2a | ||
|
5dd9c998f0 | ||
|
b214a1dc79 | ||
|
c82aba4634 | ||
|
7a5257739d | ||
|
581c71305e | ||
|
091c8c1227 | ||
|
c5f86f291c | ||
|
a8c2d136e2 | ||
|
643e47c744 | ||
|
794e9b53b8 | ||
|
2a1f80dcdf | ||
|
e83d377bda | ||
|
0c14c1652b | ||
|
78283f5902 | ||
|
04e3709170 | ||
|
79b0eef089 | ||
|
45f1c22611 | ||
|
2cfb438937 | ||
|
767a98e88c | ||
|
4e89beaf14 | ||
|
b7a408eac2 | ||
|
35700ec24a | ||
|
e1380db565 | ||
|
14160c7f6f | ||
|
698a5efaf4 | ||
|
c597ac77f8 | ||
|
d388b59973 | ||
|
f9b72e3e3b | ||
|
a831309c56 | ||
|
01eab4911d | ||
|
ef291845b5 | ||
|
3c8d87f783 | ||
|
b2290d7c39 | ||
|
4dad6e48d0 | ||
|
ddcfb1932e | ||
|
ae998af026 | ||
|
db04817371 | ||
|
24f0ee75dd | ||
|
6ad77e4092 | ||
|
5c00aaf026 | ||
|
edc7d6f04c | ||
|
369acd7617 | ||
|
2fdec85d7b | ||
|
2ee48866f3 | ||
|
d2f0f8cb11 | ||
|
11aa993e37 | ||
|
15aa11cbea | ||
|
f028fd6e52 | ||
|
bf5383193a | ||
|
10c91b9bc3 | ||
|
fc6b27e70a | ||
|
95e3f7e6fb | ||
|
f4ca4424dd | ||
|
dfc88144bf |
@ -1,8 +0,0 @@
|
||||
_____ _ _ __
|
||||
/ ____| | (_)/ _|
|
||||
| | ___ ___ | |_| |_ _ _
|
||||
| | / _ \ / _ \| | | _| | | |
|
||||
| |___| (_) | (_) | | | | | |_| |
|
||||
\_____\___/ \___/|_|_|_| \__, |
|
||||
__/ |
|
||||
|___/
|
@ -12,7 +12,7 @@ tasks:
|
||||
./vendor/bin/spin exec -u webuser coolify php artisan key:generate
|
||||
./vendor/bin/spin exec -u webuser coolify php artisan storage:link
|
||||
./vendor/bin/spin exec -u webuser coolify php artisan migrate:fresh --seed
|
||||
cat .coolify-logo
|
||||
cat .jesus-is-king
|
||||
gp sync-done spin-is-ready
|
||||
|
||||
- name: Install Node dependencies and run Vite
|
||||
|
6
.jesus-is-king
Normal file
@ -0,0 +1,6 @@
|
||||
__ _ __ __ _
|
||||
/ /__ _______ _______ (_)____ / //_/(_)___ ____ _
|
||||
__ / / _ \/ ___/ / / / ___/ / / ___/ / ,< / / __ \/ __ `/
|
||||
/ /_/ / __(__ ) /_/ (__ ) / (__ ) / /| |/ / / / / /_/ /
|
||||
\____/\___/____/\__,_/____/ /_/____/ /_/ |_/_/_/ /_/\__, /
|
||||
/____/
|
@ -19,7 +19,7 @@
|
||||
<<<EOF
|
||||
Hello,
|
||||
|
||||
Welcome to Coolify Cloud.
|
||||
Welcome to Last Hour Cloud.
|
||||
Here is your user id: $user->id
|
||||
|
||||
EOF
|
||||
|
@ -1,94 +0,0 @@
|
||||
# Citizen Code of Conduct
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
A primary goal of Coolify is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof).
|
||||
|
||||
This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior.
|
||||
|
||||
We invite all those who participate in Coolify to help us create safe and positive experiences for everyone.
|
||||
|
||||
## 2. Open [Source/Culture/Tech] Citizenship
|
||||
|
||||
A supplemental goal of this Code of Conduct is to increase open [source/culture/tech] citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community.
|
||||
|
||||
Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society.
|
||||
|
||||
If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know.
|
||||
|
||||
## 3. Expected Behavior
|
||||
|
||||
The following behaviors are expected and requested of all community members:
|
||||
|
||||
* Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community.
|
||||
* Exercise consideration and respect in your speech and actions.
|
||||
* Attempt collaboration before conflict.
|
||||
* Refrain from demeaning, discriminatory, or harassing behavior and speech.
|
||||
* Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential.
|
||||
* Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations.
|
||||
|
||||
## 4. Unacceptable Behavior
|
||||
|
||||
The following behaviors are considered harassment and are unacceptable within our community:
|
||||
|
||||
* Violence, threats of violence or violent language directed against another person.
|
||||
* Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language.
|
||||
* Posting or displaying sexually explicit or violent material.
|
||||
* Posting or threatening to post other people's personally identifying information ("doxing").
|
||||
* Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability.
|
||||
* Inappropriate photography or recording.
|
||||
* Inappropriate physical contact. You should have someone's consent before touching them.
|
||||
* Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances.
|
||||
* Deliberate intimidation, stalking or following (online or in person).
|
||||
* Advocating for, or encouraging, any of the above behavior.
|
||||
* Sustained disruption of community events, including talks and presentations.
|
||||
|
||||
## 5. Weapons Policy
|
||||
|
||||
No weapons will be allowed at Coolify events, community spaces, or in other spaces covered by the scope of this Code of Conduct. Weapons include but are not limited to guns, explosives (including fireworks), and large knives such as those used for hunting or display, as well as any other item used for the purpose of causing injury or harm to others. Anyone seen in possession of one of these items will be asked to leave immediately, and will only be allowed to return without the weapon. Community members are further expected to comply with all state and local laws on this matter.
|
||||
|
||||
## 6. Consequences of Unacceptable Behavior
|
||||
|
||||
Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated.
|
||||
|
||||
Anyone asked to stop unacceptable behavior is expected to comply immediately.
|
||||
|
||||
If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event).
|
||||
|
||||
## 7. Reporting Guidelines
|
||||
|
||||
If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. hi@coollabs.io.
|
||||
|
||||
|
||||
|
||||
Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress.
|
||||
|
||||
## 8. Addressing Grievances
|
||||
|
||||
If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify coollabsio with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies.
|
||||
|
||||
|
||||
|
||||
## 9. Scope
|
||||
|
||||
We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues--online and in-person--as well as in all one-on-one communications pertaining to community business.
|
||||
|
||||
This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members.
|
||||
|
||||
## 10. Contact info
|
||||
|
||||
hi@coollabs.io
|
||||
|
||||
## 11. License and attribution
|
||||
|
||||
The Citizen Code of Conduct is distributed by [Stumptown Syndicate](http://stumptownsyndicate.org) under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/).
|
||||
|
||||
Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy).
|
||||
|
||||
_Revision 2.3. Posted 6 March 2017._
|
||||
|
||||
_Revision 2.2. Posted 4 February 2016._
|
||||
|
||||
_Revision 2.1. Posted 23 June 2014._
|
||||
|
||||
_Revision 2.0, adopted by the [Stumptown Syndicate](http://stumptownsyndicate.org) board on 10 January 2013. Posted 17 March 2013._
|
@ -1,34 +0,0 @@
|
||||
# Contributing
|
||||
|
||||
> "First, thanks for considering to contribute to my project.
|
||||
It really means a lot!" - [@andrasbacsai](https://github.com/andrasbacsai)
|
||||
|
||||
You can ask for guidance anytime on our
|
||||
[Discord server](https://coollabs.io/discord) in the `#contribution` channel.
|
||||
|
||||
## Code Contribution
|
||||
|
||||
### 1) Setup your development environment
|
||||
|
||||
- You need to have Docker Engine (or equivalent) [installed](https://docs.docker.com/engine/install/) on your system.
|
||||
- For better DX, install [Spin](https://serversideup.net/open-source/spin/).
|
||||
|
||||
### 2) Set your environment variables
|
||||
|
||||
- Copy [.env.development.example](./.env.development.example) to .env.
|
||||
|
||||
## 3) Start & setup Coolify
|
||||
|
||||
- Run `spin up` - You can notice that errors will be thrown. Don't worry.
|
||||
- If you see weird permission errors, especially on Mac, run `sudo spin up` instead.
|
||||
|
||||
### 4) Start development
|
||||
You can login your Coolify instance at `localhost:8000` with `test@example.com` and `password`.
|
||||
|
||||
Your horizon (Laravel scheduler): `localhost:8000/horizon` - Only reachable if you logged in with root user.
|
||||
|
||||
Mails are caught by Mailpit: `localhost:8025`
|
||||
|
||||
## New Service Contribution
|
||||
Check out the docs [here](https://coolify.io/docs/how-to-add-a-service).
|
||||
|
105
README.md
@ -1,105 +0,0 @@
|
||||
# About the Project
|
||||
|
||||
Coolify is an open-source & self-hostable alternative to Heroku / Netlify / Vercel / etc.
|
||||
|
||||
It helps you to manage your servers, applications, databases on your own hardware, all you need is SSH connection. You can manage VPS, Bare Metal, Raspberry PI's anything.
|
||||
|
||||
Imagine if you could have the ease of a cloud but with your own servers. That is **Coolify**.
|
||||
|
||||
No vendor lock-in, which means that all the configuration for your applications/databases/etc are saved to your server. So if you decide to stop using Coolify (oh nooo), you could still manage your running resources. You just lose the automations and all the magic. 🪄️
|
||||
|
||||
For more information, take a look at our landing page [here](https://coolify.io).
|
||||
|
||||
# Installation
|
||||
|
||||
```bash
|
||||
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
|
||||
```
|
||||
You can find the installation script source [here](./scripts/install.sh).
|
||||
|
||||
# Support
|
||||
|
||||
Contact us [here](https://coolify.io/docs/contact).
|
||||
|
||||
# Donations
|
||||
To stay completely free, open-source, no feature behind paywall and evolve the project, we need your help. If you like Coolify, please consider donating to help us fund the future development of the project.
|
||||
|
||||
https://coolify.io/sponsorships
|
||||
|
||||
Thank you so much!
|
||||
|
||||
Special thanks to our biggest sponsors, [CCCareers](https://cccareers.org/) and [Appwrite](https://appwrite.io)!
|
||||
|
||||
<a href="https://cccareers.org/" target="_blank"><img src="./other/logos/ccc-logo.webp" alt="cccareers logo" width="200"/></a>
|
||||
<a href="https://appwrite.io" target="_blank"><img src="./other/logos/appwrite.svg" alt="appwrite logo" width="200"/></a>
|
||||
|
||||
## Github Sponsors ($40+)
|
||||
<a href="https://cryptojobslist.com/?utm_source=coolify.io"><img src="https://github.com/cryptojobslist.png" width="60px" alt="CryptoJobsList" /></a>
|
||||
<a href="https://typebot.io/?utm_source=coolify.io"><img src="https://pbs.twimg.com/profile_images/1509194008366657543/9I-C7uWT_400x400.jpg" width="60px" alt="typebot"/></a>
|
||||
<a href="https://bc.direct"><img width="60px" alt="BC Direct" src="https://github.com/coollabsio/coolify/assets/5845193/a4063c41-95ed-4a32-8814-cd1475572e37"/></a>
|
||||
<a href="https://github.com/automazeio"><img src="https://github.com/automazeio.png" width="60px" alt="Corentin Clichy" /></a>
|
||||
<a href="https://github.com/corentinclichy"><img src="https://github.com/corentinclichy.png" width="60px" alt="Corentin Clichy" /></a>
|
||||
<a href="https://github.com/Niki2k1"><img src="https://github.com/Niki2k1.png" width="60px" alt="Niklas Lausch" /></a>
|
||||
<a href="https://github.com/pixelinfinito"><img src="https://github.com/pixelinfinito.png" width="60px" alt="Pixel Infinito" /></a>
|
||||
<a href="https://github.com/whitesidest"><img src="https://avatars.githubusercontent.com/u/12365916?s=52&v=4" width="60px" alt="Tyler Whitesides" /></a>
|
||||
<a href="https://github.com/aniftyco"><img src="https://github.com/aniftyco.png" width="60px" alt="NiftyCo" /></a>
|
||||
<a href="https://github.com/iujlaki"><img src="https://github.com/iujlaki.png" width="60px" alt="Imre Ujlaki" /></a>
|
||||
<a href="https://il.ly"><img src="https://github.com/Illyism.png" width="60px" alt="Ilias Ism" /></a>
|
||||
<a href="https://github.com/urtho"><img src="https://github.com/urtho.png" width="60px" alt="Paweł Pierścionek" /></a>
|
||||
<a href="https://github.com/monocursive"><img src="https://github.com/monocursive.png" width="60px" alt="Michael Mazurczak" /></a>
|
||||
|
||||
## Organizations
|
||||
<a href="https://opencollective.com/coollabsio/organization/0/website"><img src="https://opencollective.com/coollabsio/organization/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/coollabsio/organization/1/website"><img src="https://opencollective.com/coollabsio/organization/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/coollabsio/organization/2/website"><img src="https://opencollective.com/coollabsio/organization/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/coollabsio/organization/3/website"><img src="https://opencollective.com/coollabsio/organization/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/coollabsio/organization/4/website"><img src="https://opencollective.com/coollabsio/organization/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/coollabsio/organization/5/website"><img src="https://opencollective.com/coollabsio/organization/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/coollabsio/organization/6/website"><img src="https://opencollective.com/coollabsio/organization/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/coollabsio/organization/7/website"><img src="https://opencollective.com/coollabsio/organization/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/coollabsio/organization/8/website"><img src="https://opencollective.com/coollabsio/organization/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/coollabsio/organization/9/website"><img src="https://opencollective.com/coollabsio/organization/9/avatar.svg"></a>
|
||||
|
||||
## Individuals
|
||||
|
||||
<a href="https://opencollective.com/coollabsio"><img src="https://opencollective.com/coollabsio/individuals.svg?width=890"></a>
|
||||
|
||||
# Cloud
|
||||
|
||||
If you do not want to self-host Coolify, there is a paid cloud version available: https://app.coolify.io
|
||||
|
||||
For more information & pricing, take a look at our landing page [here](https://coolify.io).
|
||||
|
||||
## Why should I use the Cloud version?
|
||||
The recommended way to use Coolify is to have one server for Coolify and one (or more) for the resources you are deploying. A server is around 4-5$/month.
|
||||
|
||||
By subscribing to the cloud version, you get the Coolify server for the same price, but with:
|
||||
- High-availability
|
||||
- Free email notifications
|
||||
- Better support
|
||||
- Less maintenance for you
|
||||
|
||||
|
||||
# Recognitions
|
||||
|
||||
<p>
|
||||
<a href="https://news.ycombinator.com/item?id=26624341">
|
||||
<img
|
||||
style="width: 250px; height: 54px;" width="250" height="54"
|
||||
alt="Featured on Hacker News"
|
||||
src="https://hackernews-badge.vercel.app/api?id=26624341"
|
||||
/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<a href="https://www.producthunt.com/posts/coolify?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-coolify" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=338273&theme=light" alt="Coolify - An open-source & self-hostable Heroku, Netlify alternative | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
|
||||
<a href="https://trendshift.io/repositories/634" target="_blank"><img src="https://trendshift.io/api/badge/repositories/634" alt="coollabsio%2Fcoolify | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||
|
||||
# Repo Activity
|
||||
|
||||
![Alt](https://repobeats.axiom.co/api/embed/eab1c8066f9c59d0ad37b76c23ebb5ccac4278ae.svg "Repobeats analytics image")
|
||||
|
||||
# Star History
|
||||
|
||||
[![Star History Chart](https://api.star-history.com/svg?repos=coollabsio/coolify&type=Date)](https://star-history.com/#coollabsio/coolify&Date)
|
@ -64,7 +64,7 @@ private function update()
|
||||
} else {
|
||||
ray('Running update on production server');
|
||||
remote_process([
|
||||
"curl -fsSL https://cdn.coollabs.io/coolify/upgrade.sh -o /data/coolify/source/upgrade.sh",
|
||||
"curl -fsSL https://cdn.lasthourhosting.org/lasthourcloud/scripts/upgrade.sh -o /data/coolify/source/upgrade.sh",
|
||||
"bash /data/coolify/source/upgrade.sh $this->latestVersion"
|
||||
], $this->server);
|
||||
return;
|
||||
|
@ -59,7 +59,7 @@ private function restore_coolify_db_backup()
|
||||
try {
|
||||
$database = StandalonePostgresql::withTrashed()->find(0);
|
||||
if ($database && $database->trashed()) {
|
||||
echo "Restoring coolify db backup\n";
|
||||
echo "Restoring Last Hour Cloud db backup\n";
|
||||
$database->restore();
|
||||
$scheduledBackup = ScheduledDatabaseBackup::find(0);
|
||||
if (!$scheduledBackup) {
|
||||
@ -75,7 +75,7 @@ private function restore_coolify_db_backup()
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
echo "Error in restoring coolify db backup: {$e->getMessage()}\n";
|
||||
echo "Error in restoring Last Hour Cloud db backup: {$e->getMessage()}\n";
|
||||
}
|
||||
}
|
||||
private function cleanup_stucked_helper_containers()
|
||||
@ -98,7 +98,7 @@ private function alive()
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Http::get("https://undead.coolify.io/v4/alive?appId=$id&version=$version");
|
||||
Http::get("");
|
||||
echo "I am alive!\n";
|
||||
} catch (\Throwable $e) {
|
||||
echo "Error in alive: {$e->getMessage()}\n";
|
||||
|
@ -47,7 +47,7 @@ private function showHelp()
|
||||
<<<'HTML'
|
||||
<div>
|
||||
<div class="title-box">
|
||||
Coolify
|
||||
Last Hour Cloud
|
||||
</div>
|
||||
<p class="mt-1 ml-1 ">
|
||||
Demo Notify <strong class="text-coolify">=></strong> Send a demo notification to a given channel.
|
||||
@ -70,7 +70,7 @@ private function showHelp()
|
||||
|
||||
ask(<<<'HTML'
|
||||
<div class="mr-1">
|
||||
In which manner you wish a <strong class="text-coolify">coolified</strong> notification?
|
||||
In which manner you wish a <strong class="text-coolify">Last Hour Cloud</strong> notification?
|
||||
</div>
|
||||
HTML, ['email', 'slack', 'discord', 'telegram']);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public function deploy(Request $request)
|
||||
$force = $request->query->get('force') ?? false;
|
||||
|
||||
if ($uuids && $tags) {
|
||||
return response()->json(['error' => 'You can only use uuid or tag, not both.', 'docs' => 'https://coolify.io/docs/api/deploy-webhook'], 400);
|
||||
return response()->json(['error' => 'You can only use uuid or tag, not both.', 'upstream docs' => 'https://coolify.io/docs/api/deploy-webhook'], 400);
|
||||
}
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
@ -54,7 +54,7 @@ public function deploy(Request $request)
|
||||
} else if ($uuids) {
|
||||
return $this->by_uuids($uuids, $teamId, $force);
|
||||
}
|
||||
return response()->json(['error' => 'You must provide uuid or tag.', 'docs' => 'https://coolify.io/docs/api/deploy-webhook'], 400);
|
||||
return response()->json(['error' => 'You must provide uuid or tag.', 'upstream docs' => 'https://coolify.io/docs/api/deploy-webhook'], 400);
|
||||
}
|
||||
private function by_uuids(string $uuid, int $teamId, bool $force = false)
|
||||
{
|
||||
@ -62,7 +62,7 @@ private function by_uuids(string $uuid, int $teamId, bool $force = false)
|
||||
$uuids = collect(array_filter($uuids));
|
||||
|
||||
if (count($uuids) === 0) {
|
||||
return response()->json(['error' => 'No UUIDs provided.', 'docs' => 'https://coolify.io/docs/api/deploy-webhook'], 400);
|
||||
return response()->json(['error' => 'No UUIDs provided.', 'upstream docs' => 'https://coolify.io/docs/api/deploy-webhook'], 400);
|
||||
}
|
||||
$deployments = collect();
|
||||
$payload = collect();
|
||||
@ -81,7 +81,7 @@ private function by_uuids(string $uuid, int $teamId, bool $force = false)
|
||||
$payload->put('deployments', $deployments->toArray());
|
||||
return response()->json($payload->toArray(), 200);
|
||||
}
|
||||
return response()->json(['error' => "No resources found.", 'docs' => 'https://coolify.io/docs/api/deploy-webhook'], 404);
|
||||
return response()->json(['error' => "No resources found.", 'upstream docs' => 'https://coolify.io/docs/api/deploy-webhook'], 404);
|
||||
}
|
||||
public function by_tags(string $tags, int $team_id, bool $force = false)
|
||||
{
|
||||
@ -89,7 +89,7 @@ public function by_tags(string $tags, int $team_id, bool $force = false)
|
||||
$tags = collect(array_filter($tags));
|
||||
|
||||
if (count($tags) === 0) {
|
||||
return response()->json(['error' => 'No TAGs provided.', 'docs' => 'https://coolify.io/docs/api/deploy-webhook'], 400);
|
||||
return response()->json(['error' => 'No TAGs provided.', 'upstream docs' => 'https://coolify.io/docs/api/deploy-webhook'], 400);
|
||||
}
|
||||
$message = collect([]);
|
||||
$deployments = collect();
|
||||
@ -127,7 +127,7 @@ public function by_tags(string $tags, int $team_id, bool $force = false)
|
||||
return response()->json($payload->toArray(), 200);
|
||||
}
|
||||
|
||||
return response()->json(['error' => "No resources found with this tag.", 'docs' => 'https://coolify.io/docs/api/deploy-webhook'], 404);
|
||||
return response()->json(['error' => "No resources found with this tag.", 'upstream docs' => 'https://coolify.io/docs/api/deploy-webhook'], 404);
|
||||
}
|
||||
public function deploy_resource($resource, bool $force = false): array
|
||||
{
|
||||
|
@ -58,8 +58,8 @@ public function mount()
|
||||
AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV
|
||||
uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||
-----END OPENSSH PRIVATE KEY-----';
|
||||
$this->privateKeyDescription = 'Created by Coolify';
|
||||
$this->remoteServerDescription = 'Created by Coolify';
|
||||
$this->privateKeyDescription = 'Created by Last Hour Cloud';
|
||||
$this->remoteServerDescription = 'Created by Last Hour Cloud';
|
||||
$this->remoteServerHost = 'coolify-testing-host';
|
||||
}
|
||||
}
|
||||
@ -281,7 +281,7 @@ public function showNewResource()
|
||||
private function createNewPrivateKey()
|
||||
{
|
||||
$this->privateKeyName = generate_random_name();
|
||||
$this->privateKeyDescription = 'Created by Coolify';
|
||||
$this->privateKeyDescription = 'Created by Last Hour Cloud';
|
||||
['private' => $this->privateKey, 'public' => $this->publicKey] = generateSSHKey();
|
||||
}
|
||||
public function render()
|
||||
|
@ -53,9 +53,9 @@ public function submit()
|
||||
'content' => "User: `" . auth()->user()?->email . "` with subject: `" . $this->subject . "` has the following problem: `" . $this->description . "`"
|
||||
]);
|
||||
} else {
|
||||
send_user_an_email($mail, auth()->user()?->email, 'hi@coollabs.io');
|
||||
send_user_an_email($mail, auth()->user()?->email, 'support@lasthourhosting.org');
|
||||
}
|
||||
$this->dispatch('success', 'Feedback sent.', 'We will get in touch with you as soon as possible.');
|
||||
$this->dispatch('success', 'Help request sent.', 'Thank you! We will get in touch with you as soon as possible.');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ public function submit($showToaster = true)
|
||||
if ($this->application->additional_servers->count() === 0) {
|
||||
foreach ($domains as $domain) {
|
||||
if (!validate_dns_entry($domain, $this->application->destination->server)) {
|
||||
$showToaster && $this->dispatch('error', "Validating DNS ($domain) failed.", "Make sure you have added the DNS records correctly.<br><br>Check this <a target='_blank' class='text-white underline' href='https://coolify.io/docs/dns-settings'>documentation</a> for further help.");
|
||||
$showToaster && $this->dispatch('error', "Validating DNS ($domain) failed.", "Make sure you have added the DNS records correctly.<br><br>Check this upstream <a target='_blank' class='text-white underline' href='https://coolify.io/docs/dns-settings'>documentation</a> for further help.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public function deploy(bool $force_rebuild = false)
|
||||
return;
|
||||
}
|
||||
if (data_get($this->application, 'settings.is_build_server_enabled') && str($this->application->docker_registry_image_name)->isEmpty()) {
|
||||
$this->dispatch('error', 'Failed to deploy.', 'To use a build server, you must first set a Docker image.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/build-server">documentation</a>');
|
||||
$this->dispatch('error', 'Failed to deploy.', 'To use a build server, you must first set a Docker image.<br>More information here in upstream docs: <a target="_blank" class="underline" href="https://coolify.io/docs/server/build-server">documentation</a>');
|
||||
return;
|
||||
}
|
||||
if ($this->application->additional_servers->count() > 0 && str($this->application->docker_registry_image_name)->isEmpty()) {
|
||||
@ -99,7 +99,7 @@ public function stop()
|
||||
public function restart()
|
||||
{
|
||||
if ($this->application->additional_servers->count() > 0 && str($this->application->docker_registry_image_name)->isEmpty()) {
|
||||
$this->dispatch('error', 'Failed to deploy', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/multiple-servers">documentation</a>');
|
||||
$this->dispatch('error', 'Failed to deploy', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here in upstream docs: <a target="_blank" class="underline" href="https://coolify.io/docs/server/multiple-servers">documentation</a>');
|
||||
return;
|
||||
}
|
||||
$this->setDeploymentUuid();
|
||||
|
@ -56,7 +56,7 @@ public function stop(int $server_id)
|
||||
public function redeploy(int $network_id, int $server_id)
|
||||
{
|
||||
if ($this->resource->additional_servers->count() > 0 && str($this->resource->docker_registry_image_name)->isEmpty()) {
|
||||
$this->dispatch('error', 'Failed to deploy.', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/multiple-servers">documentation</a>');
|
||||
$this->dispatch('error', 'Failed to deploy.', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here in upstream docs: <a target="_blank" class="underline" href="https://coolify.io/docs/server/multiple-servers">documentation</a>');
|
||||
return;
|
||||
}
|
||||
$deployment_uuid = new Cuid2(7);
|
||||
|
@ -31,7 +31,7 @@ public function generateNewKey()
|
||||
try {
|
||||
$this->rateLimit(10);
|
||||
$this->name = generate_random_name();
|
||||
$this->description = 'Created by Coolify';
|
||||
$this->description = 'Created by Last Hour Cloud';
|
||||
['private' => $this->value, 'public' => $this->publicKey] = generateSSHKey();
|
||||
} catch(\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
|
@ -82,7 +82,7 @@ public function checkLocalhostConnection()
|
||||
$this->server->settings->is_usable = true;
|
||||
$this->server->settings->save();
|
||||
} else {
|
||||
$this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.');
|
||||
$this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.<br><br>Check this upstream <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public function checkConnection()
|
||||
if ($uptime) {
|
||||
$this->dispatch('success', 'Server is reachable.');
|
||||
} else {
|
||||
$this->dispatch('error', 'Server is not reachable.<br>Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh#openssh">documentation</a> for further help.');
|
||||
$this->dispatch('error', 'Server is not reachable.<br>Please validate your configuration and connection.<br><br>Check this upstream <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh#openssh">documentation</a> for further help.');
|
||||
return;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
|
@ -75,7 +75,7 @@ public function validateConnection()
|
||||
{
|
||||
$this->uptime = $this->server->validateConnection();
|
||||
if (!$this->uptime) {
|
||||
$this->error = 'Server is not reachable. Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.';
|
||||
$this->error = 'Server is not reachable. Please validate your configuration and connection.<br><br>Check this upstream <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.';
|
||||
return;
|
||||
}
|
||||
$this->dispatch('validateOS');
|
||||
|
@ -47,7 +47,7 @@ public function testConnection(bool $shouldSave = false)
|
||||
$this->is_usable = false;
|
||||
if ($this->unusable_email_sent === false && is_transactional_emails_active()) {
|
||||
$mail = new MailMessage();
|
||||
$mail->subject('Coolify: S3 Storage Connection Error');
|
||||
$mail->subject('Last Hour Cloud: S3 Storage Connection Error');
|
||||
$mail->view('emails.s3-connection-error', ['name' => $this->name, 'reason' => $e->getMessage(), 'url' => route('team.storage.show', ['storage_uuid' => $this->uuid])]);
|
||||
$users = collect([]);
|
||||
$members = $this->team->members()->get();
|
||||
|
@ -110,7 +110,7 @@ public function sendVerificationEmail()
|
||||
$mail->view('emails.email-verification', [
|
||||
'url' => $url,
|
||||
]);
|
||||
$mail->subject('Coolify: Verify your email.');
|
||||
$mail->subject('Last Hour Cloud: Verify your email.');
|
||||
send_user_an_email($mail, $this->email);
|
||||
}
|
||||
public function sendPasswordResetNotification($token): void
|
||||
|
@ -52,10 +52,10 @@ public function toMail(): MailMessage
|
||||
$pull_request_id = data_get($this->preview, 'pull_request_id', 0);
|
||||
$fqdn = $this->fqdn;
|
||||
if ($pull_request_id === 0) {
|
||||
$mail->subject('Coolify: Deployment failed of ' . $this->application_name . '.');
|
||||
$mail->subject('Last Hour Cloud: Deployment failed of ' . $this->application_name . '.');
|
||||
} else {
|
||||
$fqdn = $this->preview->fqdn;
|
||||
$mail->subject('Coolify: Deployment failed of pull request #' . $this->preview->pull_request_id . ' of ' . $this->application_name . '.');
|
||||
$mail->subject('Last Hour Cloud: Deployment failed of pull request #' . $this->preview->pull_request_id . ' of ' . $this->application_name . '.');
|
||||
}
|
||||
$mail->view('emails.application-deployment-failed', [
|
||||
'name' => $this->application_name,
|
||||
@ -69,10 +69,10 @@ public function toMail(): MailMessage
|
||||
public function toDiscord(): string
|
||||
{
|
||||
if ($this->preview) {
|
||||
$message = 'Coolify: Pull request #' . $this->preview->pull_request_id . ' of **' . $this->application_name . '** (' . $this->preview->fqdn . ') deployment failed: ';
|
||||
$message = 'Last Hour Cloud: Pull request #' . $this->preview->pull_request_id . ' of **' . $this->application_name . '** (' . $this->preview->fqdn . ') deployment failed: ';
|
||||
$message .= '[View Deployment Logs](' . $this->deployment_url . ')';
|
||||
} else {
|
||||
$message = 'Coolify: Deployment failed of **' . $this->application_name . '** (' . $this->fqdn . '): ';
|
||||
$message = 'Last Hour Cloud: Deployment failed of **' . $this->application_name . '** (' . $this->fqdn . '): ';
|
||||
$message .= '[View Deployment Logs](' . $this->deployment_url . ')';
|
||||
}
|
||||
return $message;
|
||||
@ -80,9 +80,9 @@ public function toDiscord(): string
|
||||
public function toTelegram(): array
|
||||
{
|
||||
if ($this->preview) {
|
||||
$message = 'Coolify: Pull request #' . $this->preview->pull_request_id . ' of **' . $this->application_name . '** (' . $this->preview->fqdn . ') deployment failed: ';
|
||||
$message = 'Last Hour Cloud: Pull request #' . $this->preview->pull_request_id . ' of **' . $this->application_name . '** (' . $this->preview->fqdn . ') deployment failed: ';
|
||||
} else {
|
||||
$message = 'Coolify: Deployment failed of **' . $this->application_name . '** (' . $this->fqdn . '): ';
|
||||
$message = 'Last Hour Cloud: Deployment failed of **' . $this->application_name . '** (' . $this->fqdn . '): ';
|
||||
}
|
||||
$buttons[] = [
|
||||
"text" => "Deployment logs",
|
||||
|
@ -58,10 +58,10 @@ public function toMail(): MailMessage
|
||||
$pull_request_id = data_get($this->preview, 'pull_request_id', 0);
|
||||
$fqdn = $this->fqdn;
|
||||
if ($pull_request_id === 0) {
|
||||
$mail->subject("Coolify: New version is deployed of {$this->application_name}");
|
||||
$mail->subject("Last Hour Cloud: New version is deployed of {$this->application_name}");
|
||||
} else {
|
||||
$fqdn = $this->preview->fqdn;
|
||||
$mail->subject("Coolify: Pull request #{$pull_request_id} of {$this->application_name} deployed successfully");
|
||||
$mail->subject("Last Hour Cloud: Pull request #{$pull_request_id} of {$this->application_name} deployed successfully");
|
||||
}
|
||||
$mail->view('emails.application-deployment-success', [
|
||||
'name' => $this->application_name,
|
||||
@ -75,7 +75,7 @@ public function toMail(): MailMessage
|
||||
public function toDiscord(): string
|
||||
{
|
||||
if ($this->preview) {
|
||||
$message = 'Coolify: New PR' . $this->preview->pull_request_id . ' version successfully deployed of ' . $this->application_name . '
|
||||
$message = 'Last Hour Cloud: New PR' . $this->preview->pull_request_id . ' version successfully deployed of ' . $this->application_name . '
|
||||
|
||||
';
|
||||
if ($this->preview->fqdn) {
|
||||
@ -83,7 +83,7 @@ public function toDiscord(): string
|
||||
}
|
||||
$message .= '[Deployment logs](' . $this->deployment_url . ')';
|
||||
} else {
|
||||
$message = 'Coolify: New version successfully deployed of ' . $this->application_name . '
|
||||
$message = 'Last Hour Cloud: New version successfully deployed of ' . $this->application_name . '
|
||||
|
||||
';
|
||||
if ($this->fqdn) {
|
||||
@ -96,7 +96,7 @@ public function toDiscord(): string
|
||||
public function toTelegram(): array
|
||||
{
|
||||
if ($this->preview) {
|
||||
$message = 'Coolify: New PR' . $this->preview->pull_request_id . ' version successfully deployed of ' . $this->application_name . '';
|
||||
$message = 'Last Hour Cloud: New PR' . $this->preview->pull_request_id . ' version successfully deployed of ' . $this->application_name . '';
|
||||
if ($this->preview->fqdn) {
|
||||
$buttons[] = [
|
||||
"text" => "Open Application",
|
||||
|
@ -43,7 +43,7 @@ public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$fqdn = $this->fqdn;
|
||||
$mail->subject("Coolify: {$this->resource_name} has been stopped");
|
||||
$mail->subject("Last Hour Cloud: {$this->resource_name} has been stopped");
|
||||
$mail->view('emails.application-status-changes', [
|
||||
'name' => $this->resource_name,
|
||||
'fqdn' => $fqdn,
|
||||
@ -54,20 +54,20 @@ public function toMail(): MailMessage
|
||||
|
||||
public function toDiscord(): string
|
||||
{
|
||||
$message = 'Coolify: ' . $this->resource_name . ' has been stopped.
|
||||
$message = 'Last Hour Cloud: ' . $this->resource_name . ' has been stopped.
|
||||
|
||||
';
|
||||
$message .= '[Open Application in Coolify](' . $this->resource_url . ')';
|
||||
$message .= '[Open Application in Last Hour Cloud](' . $this->resource_url . ')';
|
||||
return $message;
|
||||
}
|
||||
public function toTelegram(): array
|
||||
{
|
||||
$message = 'Coolify: ' . $this->resource_name . ' has been stopped.';
|
||||
$message = 'Last Hour Cloud: ' . $this->resource_name . ' has been stopped.';
|
||||
return [
|
||||
"message" => $message,
|
||||
"buttons" => [
|
||||
[
|
||||
"text" => "Open Application in Coolify",
|
||||
"text" => "Open Application in Last Hour Cloud",
|
||||
"url" => $this->resource_url
|
||||
]
|
||||
],
|
||||
|
@ -27,7 +27,7 @@ public function via(object $notifiable): array
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject("Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}");
|
||||
$mail->subject("Last Hour Cloud: A resource ({$this->name}) has been restarted automatically on {$this->server->name}");
|
||||
$mail->view('emails.container-restarted', [
|
||||
'containerName' => $this->name,
|
||||
'serverName' => $this->server->name,
|
||||
@ -38,12 +38,12 @@ public function toMail(): MailMessage
|
||||
|
||||
public function toDiscord(): string
|
||||
{
|
||||
$message = "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}";
|
||||
$message = "Last Hour Cloud: A resource ({$this->name}) has been restarted automatically on {$this->server->name}";
|
||||
return $message;
|
||||
}
|
||||
public function toTelegram(): array
|
||||
{
|
||||
$message = "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}";
|
||||
$message = "Last Hour Cloud: A resource ({$this->name}) has been restarted automatically on {$this->server->name}";
|
||||
$payload = [
|
||||
"message" => $message,
|
||||
];
|
||||
@ -51,7 +51,7 @@ public function toTelegram(): array
|
||||
$payload['buttons'] = [
|
||||
[
|
||||
[
|
||||
"text" => "Check Proxy in Coolify",
|
||||
"text" => "Check Proxy in Last Hour Cloud",
|
||||
"url" => $this->url
|
||||
]
|
||||
]
|
||||
|
@ -26,7 +26,7 @@ public function via(object $notifiable): array
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject("Coolify: A resource has been stopped unexpectedly on {$this->server->name}");
|
||||
$mail->subject("Last Hour Cloud: A resource has been stopped unexpectedly on {$this->server->name}");
|
||||
$mail->view('emails.container-stopped', [
|
||||
'containerName' => $this->name,
|
||||
'serverName' => $this->server->name,
|
||||
@ -37,12 +37,12 @@ public function toMail(): MailMessage
|
||||
|
||||
public function toDiscord(): string
|
||||
{
|
||||
$message = "Coolify: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}";
|
||||
$message = "Last Hour Cloud: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}";
|
||||
return $message;
|
||||
}
|
||||
public function toTelegram(): array
|
||||
{
|
||||
$message = "Coolify: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}";
|
||||
$message = "Last Hour Cloud: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}";
|
||||
$payload = [
|
||||
"message" => $message,
|
||||
];
|
||||
@ -50,7 +50,7 @@ public function toTelegram(): array
|
||||
$payload['buttons'] = [
|
||||
[
|
||||
[
|
||||
"text" => "Open Application in Coolify",
|
||||
"text" => "Open Application in Last Hour Cloud",
|
||||
"url" => $this->url
|
||||
]
|
||||
]
|
||||
|
@ -33,7 +33,7 @@ public function via(object $notifiable): array
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject("Coolify: [ACTION REQUIRED] Backup FAILED for {$this->database->name}");
|
||||
$mail->subject("Last Hour Cloud: [ACTION REQUIRED] Backup FAILED for {$this->database->name}");
|
||||
$mail->view('emails.backup-failed', [
|
||||
'name' => $this->name,
|
||||
'frequency' => $this->frequency,
|
||||
@ -44,11 +44,11 @@ public function toMail(): MailMessage
|
||||
|
||||
public function toDiscord(): string
|
||||
{
|
||||
return "Coolify: Database backup for {$this->name} with frequency of {$this->frequency} was FAILED.\n\nReason: {$this->output}";
|
||||
return "Last Hour Cloud: Database backup for {$this->name} with frequency of {$this->frequency} was FAILED.\n\nReason: {$this->output}";
|
||||
}
|
||||
public function toTelegram(): array
|
||||
{
|
||||
$message = "Coolify: Database backup for {$this->name} with frequency of {$this->frequency} was FAILED.\n\nReason: {$this->output}";
|
||||
$message = "Last Hour Cloud: Database backup for {$this->name} with frequency of {$this->frequency} was FAILED.\n\nReason: {$this->output}";
|
||||
return [
|
||||
"message" => $message,
|
||||
];
|
||||
|
@ -30,7 +30,7 @@ public function via(object $notifiable): array
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject("Coolify: Backup successfully done for {$this->database->name}");
|
||||
$mail->subject("Last Hour Cloud: Backup successfully done for {$this->database->name}");
|
||||
$mail->view('emails.backup-success', [
|
||||
'name' => $this->name,
|
||||
'frequency' => $this->frequency,
|
||||
@ -40,11 +40,11 @@ public function toMail(): MailMessage
|
||||
|
||||
public function toDiscord(): string
|
||||
{
|
||||
return "Coolify: Database backup for {$this->name} with frequency of {$this->frequency} was successful.";
|
||||
return "Last Hour Cloud: Database backup for {$this->name} with frequency of {$this->frequency} was successful.";
|
||||
}
|
||||
public function toTelegram(): array
|
||||
{
|
||||
$message = "Coolify: Database backup for {$this->name} with frequency of {$this->frequency} was successful.";
|
||||
$message = "Last Hour Cloud: Database backup for {$this->name} with frequency of {$this->frequency} was successful.";
|
||||
return [
|
||||
"message" => $message,
|
||||
];
|
||||
|
@ -42,7 +42,7 @@ public function via(object $notifiable): array
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject("Coolify: Server ({$this->server->name}) high disk usage detected!");
|
||||
$mail->subject("Last Hour Cloud: Server ({$this->server->name}) high disk usage detected!");
|
||||
$mail->view('emails.high-disk-usage', [
|
||||
'name' => $this->server->name,
|
||||
'disk_usage' => $this->disk_usage,
|
||||
@ -53,13 +53,13 @@ public function toMail(): MailMessage
|
||||
|
||||
public function toDiscord(): string
|
||||
{
|
||||
$message = "Coolify: Server '{$this->server->name}' high disk usage detected!\nDisk usage: {$this->disk_usage}%. Threshold: {$this->cleanup_after_percentage}%.\nPlease cleanup your disk to prevent data-loss.\nHere are some tips: https://coolify.io/docs/automated-cleanup.";
|
||||
$message = "Last Hour Cloud: Server '{$this->server->name}' high disk usage detected!\nDisk usage: {$this->disk_usage}%. Threshold: {$this->cleanup_after_percentage}%.\nPlease cleanup your disk to prevent data-loss.\nHere are some tips from upstream docs: https://coolify.io/docs/automated-cleanup.";
|
||||
return $message;
|
||||
}
|
||||
public function toTelegram(): array
|
||||
{
|
||||
return [
|
||||
"message" => "Coolify: Server '{$this->server->name}' high disk usage detected!\nDisk usage: {$this->disk_usage}%. Threshold: {$this->cleanup_after_percentage}%.\nPlease cleanup your disk to prevent data-loss.\nHere are some tips: https://coolify.io/docs/automated-cleanup."
|
||||
"message" => "Last Hour Cloud: Server '{$this->server->name}' high disk usage detected!\nDisk usage: {$this->disk_usage}%. Threshold: {$this->cleanup_after_percentage}%.\nPlease cleanup your disk to prevent data-loss.\nHere are some tips from upstream docs: https://coolify.io/docs/automated-cleanup."
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public function via(object $notifiable): array
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject("Coolify: Server ({$this->server->name}) revived.");
|
||||
$mail->subject("Last Hour Cloud: Server ({$this->server->name}) revived.");
|
||||
$mail->view('emails.server-revived', [
|
||||
'name' => $this->server->name,
|
||||
]);
|
||||
@ -54,13 +54,13 @@ public function toMail(): MailMessage
|
||||
|
||||
public function toDiscord(): string
|
||||
{
|
||||
$message = "Coolify: Server '{$this->server->name}' revived. All automations & integrations are turned on again!";
|
||||
$message = "Last Hour Cloud: Server '{$this->server->name}' revived. All automations & integrations are turned on again!";
|
||||
return $message;
|
||||
}
|
||||
public function toTelegram(): array
|
||||
{
|
||||
return [
|
||||
"message" => "Coolify: Server '{$this->server->name}' revived. All automations & integrations are turned on again!"
|
||||
"message" => "Last Hour Cloud: Server '{$this->server->name}' revived. All automations & integrations are turned on again!"
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public function via(object $notifiable): array
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject("Coolify: Your server ({$this->server->name}) is unreachable.");
|
||||
$mail->subject("Last Hour Cloud: Your server ({$this->server->name}) is unreachable.");
|
||||
$mail->view('emails.server-lost-connection', [
|
||||
'name' => $this->server->name,
|
||||
]);
|
||||
@ -52,13 +52,13 @@ public function toMail(): MailMessage
|
||||
|
||||
public function toDiscord(): string
|
||||
{
|
||||
$message = "Coolify: Your server '{$this->server->name}' is unreachable. All automations & integrations are turned off! Please check your server! IMPORTANT: We automatically try to revive your server and turn on all automations & integrations.";
|
||||
$message = "Last Hour Cloud: Your server '{$this->server->name}' is unreachable. All automations & integrations are turned off! Please check your server! IMPORTANT: We automatically try to revive your server and turn on all automations & integrations.";
|
||||
return $message;
|
||||
}
|
||||
public function toTelegram(): array
|
||||
{
|
||||
return [
|
||||
"message" => "Coolify: Your server '{$this->server->name}' is unreachable. All automations & integrations are turned off! Please check your server! IMPORTANT: We automatically try to revive your server and turn on all automations & integrations."
|
||||
"message" => "Last Hour Cloud: Your server '{$this->server->name}' is unreachable. All automations & integrations are turned off! Please check your server! IMPORTANT: We automatically try to revive your server and turn on all automations & integrations."
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -24,14 +24,14 @@ public function via(object $notifiable): array
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject("Coolify: Test Email");
|
||||
$mail->subject("Last Hour Cloud: Test Email");
|
||||
$mail->view('emails.test');
|
||||
return $mail;
|
||||
}
|
||||
|
||||
public function toDiscord(): string
|
||||
{
|
||||
$message = 'Coolify: This is a test Discord notification from Coolify.';
|
||||
$message = 'Last Hour Cloud: This is a test Discord notification from Last Hour Cloud.';
|
||||
$message .= "\n\n";
|
||||
$message .= '[Go to your dashboard](' . base_url() . ')';
|
||||
return $message;
|
||||
@ -39,7 +39,7 @@ public function toDiscord(): string
|
||||
public function toTelegram(): array
|
||||
{
|
||||
return [
|
||||
"message" => 'Coolify: This is a test Telegram notification from Coolify.',
|
||||
"message" => 'Last Hour Cloud: This is a test Telegram notification from Last Hour Cloud.',
|
||||
"buttons" => [
|
||||
[
|
||||
"text" => "Go to your dashboard",
|
||||
|
@ -30,7 +30,7 @@ public function toMail(): MailMessage
|
||||
$invitation_team = Team::find($invitation->team->id);
|
||||
|
||||
$mail = new MailMessage();
|
||||
$mail->subject('Coolify: Invitation for ' . $invitation_team->name);
|
||||
$mail->subject('Last Hour Cloud: Invitation for ' . $invitation_team->name);
|
||||
$mail->view('emails.invitation-link', [
|
||||
'team' => $invitation_team->name,
|
||||
'email' => $this->user->email,
|
||||
|
@ -50,7 +50,7 @@ public function toMail($notifiable)
|
||||
protected function buildMailMessage($url)
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject('Coolify: Reset Password');
|
||||
$mail->subject('Last Hour Cloud: Reset Password');
|
||||
$mail->view('emails.reset-password', ['url' => $url, 'count' => config('auth.passwords.' . config('auth.defaults.passwords') . '.expire')]);
|
||||
return $mail;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public function via(): array
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$mail->subject('Coolify: Test Email');
|
||||
$mail->subject('Last Hour Cloud: Test Email');
|
||||
$mail->view('emails.test');
|
||||
return $mail;
|
||||
}
|
||||
|
@ -143,9 +143,9 @@ function get_route_parameters(): array
|
||||
function get_latest_version_of_coolify(): string
|
||||
{
|
||||
try {
|
||||
$response = Http::get('https://cdn.coollabs.io/coolify/versions.json');
|
||||
$response = Http::get('https://cdn.lasthourhosting.org/lasthourcloud/versions.json');
|
||||
$versions = $response->json();
|
||||
return data_get($versions, 'coolify.v4.version');
|
||||
return data_get($versions, 'lasthourcloud.v4.version');
|
||||
} catch (\Throwable $e) {
|
||||
//throw $e;
|
||||
ray($e->getMessage());
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
|
||||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Coolify'),
|
||||
'name' => env('APP_NAME', 'Last Hour Cloud'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -2,7 +2,7 @@
|
||||
return [
|
||||
'docs' => [
|
||||
'base_url' => 'https://coolify.io/docs',
|
||||
'contact' => 'https://coolify.io/docs/contact',
|
||||
'contact' => 'https://lasthourhosting.org/contact.html',
|
||||
],
|
||||
'ssh' => [
|
||||
'connection_timeout' => 10,
|
||||
@ -19,7 +19,7 @@
|
||||
],
|
||||
],
|
||||
'services' => [
|
||||
'official' => 'https://cdn.coollabs.io/coolify/service-templates.json',
|
||||
'official' => 'https://cdn.lasthourhosting.org/lasthourcloud/templates/service-templates.json',
|
||||
],
|
||||
'limits' => [
|
||||
'trial_period' => 0,
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
return [
|
||||
'docs' => 'https://coolify.io/docs/',
|
||||
'contact' => 'https://coolify.io/docs/contact',
|
||||
'contact' => 'https://lasthourhosting.org/contact.html',
|
||||
'feedback_discord_webhook' => env('FEEDBACK_DISCORD_WEBHOOK'),
|
||||
'self_hosted' => env('SELF_HOSTED', true),
|
||||
'waitlist' => env('WAITLIST', false),
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
// The release version of your application
|
||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||
'release' => '4.0.0-beta.239',
|
||||
'release' => '4.0.3',
|
||||
// When left empty or `null` the Laravel environment will be used
|
||||
'environment' => config('app.env'),
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
return '4.0.0-beta.239';
|
||||
return '4.0.3';
|
||||
|
@ -20,7 +20,7 @@ public function up(): void
|
||||
$table->string('default_redirect_404')->nullable();
|
||||
$table->integer('public_port_min')->default(9000);
|
||||
$table->integer('public_port_max')->default(9100);
|
||||
$table->boolean('do_not_track')->default(false);
|
||||
$table->boolean('do_not_track')->default(true);
|
||||
$table->boolean('is_auto_update_enabled')->default(true);
|
||||
$table->boolean('is_registration_enabled')->default(true);
|
||||
$table->schemalessAttributes('smtp');
|
||||
|
@ -13,7 +13,7 @@ public function up(): void
|
||||
{
|
||||
Schema::table('instance_settings', function (Blueprint $table) {
|
||||
$table->boolean('is_dns_validation_enabled')->default(true);
|
||||
$table->string('custom_dns_servers')->nullable()->default('1.1.1.1');
|
||||
$table->string('custom_dns_servers')->nullable()->default('9.9.9.9');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ public function run(): void
|
||||
$server_details = [
|
||||
'id' => 0,
|
||||
'name' => "localhost",
|
||||
'description' => "This is the server where Coolify is running on. Don't delete this!",
|
||||
'description' => "This is the server where Last Hour Cloud is running on. Don't delete this!",
|
||||
'user' => 'root',
|
||||
'ip' => "host.docker.internal",
|
||||
'team_id' => 0,
|
||||
@ -147,7 +147,7 @@ public function run(): void
|
||||
'id' => 0,
|
||||
'uuid' => 'coolify-testing-host',
|
||||
'name' => "localhost",
|
||||
'description' => "This is the server where Coolify is running on. Don't delete this!",
|
||||
'description' => "This is the server where Last Hour Cloud is running on. Don't delete this!",
|
||||
'user' => 'root',
|
||||
'ip' => "coolify-testing-host",
|
||||
'team_id' => 0,
|
||||
|
@ -1,117 +1,149 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
coolify:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./docker/dev-ssu/Dockerfile
|
||||
image: "githaven.org/shiloh/lasthourcloud:beta"
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /data/coolify/source/.env
|
||||
target: /var/www/html/.env
|
||||
read_only: true
|
||||
- /data/coolify/ssh:/var/www/html/storage/app/ssh
|
||||
- /data/coolify/applications:/var/www/html/storage/app/applications
|
||||
- /data/coolify/databases:/var/www/html/storage/app/databases
|
||||
- /data/coolify/services:/var/www/html/storage/app/services
|
||||
- /data/coolify/backups:/var/www/html/storage/app/backups
|
||||
- /data/coolify/webhooks-during-maintenance:/var/www/html/storage/app/webhooks-during-maintenance
|
||||
environment:
|
||||
- APP_ID
|
||||
- APP_ENV=production
|
||||
- APP_DEBUG
|
||||
- APP_NAME
|
||||
- APP_KEY
|
||||
- APP_URL
|
||||
- DB_CONNECTION
|
||||
- DB_HOST
|
||||
- DB_PORT
|
||||
- DB_DATABASE
|
||||
- DB_USERNAME
|
||||
- DB_PASSWORD
|
||||
- QUEUE_CONNECTION
|
||||
- REDIS_HOST
|
||||
- REDIS_PASSWORD
|
||||
- HORIZON_MAX_PROCESSES
|
||||
- HORIZON_BALANCE_MAX_SHIFT
|
||||
- HORIZON_BALANCE_COOLDOWN
|
||||
- SSL_MODE=off
|
||||
- PHP_PM_CONTROL=dynamic
|
||||
- PHP_PM_START_SERVERS=1
|
||||
- PHP_PM_MIN_SPARE_SERVERS=1
|
||||
- PHP_PM_MAX_SPARE_SERVERS=10
|
||||
- PUSHER_HOST
|
||||
- PUSHER_BACKEND_HOST
|
||||
- PUSHER_PORT
|
||||
- PUSHER_BACKEND_PORT
|
||||
- PUSHER_SCHEME
|
||||
- PUSHER_APP_ID
|
||||
- PUSHER_APP_KEY
|
||||
- PUSHER_APP_SECRET
|
||||
- AUTOUPDATE
|
||||
- SELF_HOSTED
|
||||
- FEEDBACK_DISCORD_WEBHOOK
|
||||
- WAITLIST
|
||||
- SUBSCRIPTION_PROVIDER
|
||||
- STRIPE_API_KEY
|
||||
- STRIPE_WEBHOOK_SECRET
|
||||
- STRIPE_PRICE_ID_BASIC_MONTHLY
|
||||
- STRIPE_PRICE_ID_BASIC_YEARLY
|
||||
- STRIPE_PRICE_ID_PRO_MONTHLY
|
||||
- STRIPE_PRICE_ID_PRO_YEARLY
|
||||
- STRIPE_PRICE_ID_ULTIMATE_MONTHLY
|
||||
- STRIPE_PRICE_ID_ULTIMATE_YEARLY
|
||||
- STRIPE_PRICE_ID_BASIC_MONTHLY_OLD
|
||||
- STRIPE_PRICE_ID_BASIC_YEARLY_OLD
|
||||
- STRIPE_PRICE_ID_PRO_MONTHLY_OLD
|
||||
- STRIPE_PRICE_ID_PRO_YEARLY_OLD
|
||||
- STRIPE_PRICE_ID_ULTIMATE_MONTHLY_OLD
|
||||
- STRIPE_PRICE_ID_ULTIMATE_YEARLY_OLD
|
||||
- STRIPE_EXCLUDED_PLANS
|
||||
- PADDLE_VENDOR_ID
|
||||
- PADDLE_WEBHOOK_SECRET
|
||||
- PADDLE_VENDOR_AUTH_CODE
|
||||
- PADDLE_PUBLIC_KEY
|
||||
- PADDLE_PRICE_ID_BASIC_MONTHLY
|
||||
- PADDLE_PRICE_ID_BASIC_YEARLY
|
||||
- PADDLE_PRICE_ID_PRO_MONTHLY
|
||||
- PADDLE_PRICE_ID_PRO_YEARLY
|
||||
- PADDLE_PRICE_ID_ULTIMATE_MONTHLY
|
||||
- PADDLE_PRICE_ID_ULTIMATE_YEARLY
|
||||
- LEMON_SQUEEZY_API_KEY
|
||||
- LEMON_SQUEEZY_WEBHOOK_SECRET
|
||||
- LEMON_SQUEEZY_CHECKOUT_ID_BASIC_MONTHLY
|
||||
- LEMON_SQUEEZY_CHECKOUT_ID_BASIC_YEARLY
|
||||
- LEMON_SQUEEZY_CHECKOUT_ID_PRO_MONTHLY
|
||||
- LEMON_SQUEEZY_CHECKOUT_ID_PRO_YEARLY
|
||||
- LEMON_SQUEEZY_CHECKOUT_ID_ULTIMATE_MONTHLY
|
||||
- LEMON_SQUEEZY_CHECKOUT_ID_ULTIMATE_YEARLY
|
||||
- LEMON_SQUEEZY_BASIC_PLAN_IDS
|
||||
- LEMON_SQUEEZY_PRO_PLAN_IDS
|
||||
- LEMON_SQUEEZY_ULTIMATE_PLAN_IDS
|
||||
ports:
|
||||
- "${APP_PORT:-8000}:80"
|
||||
environment:
|
||||
PUID: "${USERID:-1000}"
|
||||
PGID: "${GROUPID:-1000}"
|
||||
SSL_MODE: "off"
|
||||
AUTORUN_LARAVEL_STORAGE_LINK: "false"
|
||||
AUTORUN_LARAVEL_MIGRATION: "false"
|
||||
PUSHER_HOST: "${PUSHER_HOST}"
|
||||
PUSHER_PORT: "${PUSHER_PORT}"
|
||||
PUSHER_SCHEME: "${PUSHER_SCHEME:-http}"
|
||||
PUSHER_APP_ID: "${PUSHER_APP_ID:-coolify}"
|
||||
PUSHER_APP_KEY: "${PUSHER_APP_KEY:-coolify}"
|
||||
PUSHER_APP_SECRET: "${PUSHER_APP_SECRET:-coolify}"
|
||||
volumes:
|
||||
- .:/var/www/html/:cached
|
||||
expose:
|
||||
- "${APP_PORT:-8000}"
|
||||
healthcheck:
|
||||
test: curl --fail http://localhost:80/api/health || exit 1
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
pull_policy: always
|
||||
ports:
|
||||
- "${FORWARD_DB_PORT:-5432}:5432"
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- coolify-db:/var/lib/postgresql/data
|
||||
environment:
|
||||
POSTGRES_USER: "${DB_USERNAME:-coolify}"
|
||||
POSTGRES_PASSWORD: "${DB_PASSWORD:-password}"
|
||||
POSTGRES_PASSWORD: "${DB_PASSWORD}"
|
||||
POSTGRES_DB: "${DB_DATABASE:-coolify}"
|
||||
POSTGRES_HOST_AUTH_METHOD: "trust"
|
||||
volumes:
|
||||
- /data/coolify/_volumes/database/:/var/lib/postgresql/data
|
||||
# - coolify-pg-data-dev:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"pg_isready -U ${DB_USERNAME:-coolify}",
|
||||
"-d",
|
||||
"${DB_DATABASE:-coolify}",
|
||||
]
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
redis:
|
||||
pull_policy: always
|
||||
ports:
|
||||
- "${FORWARD_REDIS_PORT:-6379}:6379"
|
||||
env_file:
|
||||
- .env
|
||||
command: redis-server --save 20 1 --loglevel warning --requirepass ${REDIS_PASSWORD}
|
||||
environment:
|
||||
REDIS_PASSWORD: "${REDIS_PASSWORD}"
|
||||
volumes:
|
||||
- /data/coolify/_volumes/redis/:/data
|
||||
# - coolify-redis-data-dev:/data
|
||||
- coolify-redis:/data
|
||||
healthcheck:
|
||||
test: redis-cli ping
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
soketi:
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "${FORWARD_SOKETI_PORT:-6001}:6001"
|
||||
- "${SOKETI_PORT:-6001}:6001"
|
||||
environment:
|
||||
SOKETI_DEBUG: "false"
|
||||
SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID:-coolify}"
|
||||
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY:-coolify}"
|
||||
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET:-coolify}"
|
||||
vite:
|
||||
image: node:20
|
||||
pull_policy: always
|
||||
working_dir: /var/www/html
|
||||
# environment:
|
||||
# VITE_PUSHER_APP_KEY: "${PUSHER_APP_KEY:-coolify}"
|
||||
ports:
|
||||
- "${VITE_PORT:-5173}:${VITE_PORT:-5173}"
|
||||
volumes:
|
||||
- .:/var/www/html:cached
|
||||
command: sh -c "npm install && npm run dev"
|
||||
networks:
|
||||
- coolify
|
||||
testing-host:
|
||||
image: "ghcr.io/coollabsio/coolify-testing-host:latest"
|
||||
pull_policy: always
|
||||
init: true
|
||||
container_name: coolify-testing-host
|
||||
volumes:
|
||||
- /:/host
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /data/coolify/:/data/coolify
|
||||
networks:
|
||||
- coolify
|
||||
mailpit:
|
||||
image: "axllent/mailpit:latest"
|
||||
pull_policy: always
|
||||
container_name: coolify-mail
|
||||
ports:
|
||||
- "${FORWARD_MAILPIT_PORT:-1025}:1025"
|
||||
- "${FORWARD_MAILPIT_DASHBOARD_PORT:-8025}:8025"
|
||||
networks:
|
||||
- coolify
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
pull_policy: always
|
||||
container_name: coolify-minio
|
||||
command: server /data --console-address ":9001"
|
||||
ports:
|
||||
- "${FORWARD_MINIO_PORT:-9000}:9000"
|
||||
- "${FORWARD_MINIO_PORT_CONSOLE:-9001}:9001"
|
||||
environment:
|
||||
MINIO_ACCESS_KEY: "${MINIO_ACCESS_KEY:-minioadmin}"
|
||||
MINIO_SECRET_KEY: "${MINIO_SECRET_KEY:-minioadmin}"
|
||||
volumes:
|
||||
- /data/coolify/_volumes/minio/:/data
|
||||
# - coolify-minio-data-dev:/data
|
||||
networks:
|
||||
- coolify
|
||||
|
||||
SOKETI_DEBUG: "${SOKETI_DEBUG:-false}"
|
||||
SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID}"
|
||||
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY}"
|
||||
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET}"
|
||||
healthcheck:
|
||||
test: wget -qO- http://localhost:6001/ready || exit 1
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
volumes:
|
||||
coolify-data-dev:
|
||||
coolify-pg-data-dev:
|
||||
coolify-redis-data-dev:
|
||||
coolify-minio-data-dev:
|
||||
|
||||
|
||||
networks:
|
||||
coolify:
|
||||
name: coolify
|
||||
external: false
|
||||
coolify-db:
|
||||
name: coolify-db
|
||||
coolify-redis:
|
||||
name: coolify-redis
|
||||
|
@ -1,7 +1,7 @@
|
||||
version: '3.8'
|
||||
version: "3.8"
|
||||
services:
|
||||
coolify:
|
||||
image: "ghcr.io/coollabsio/coolify:${LATEST_IMAGE:-latest}"
|
||||
image: "githaven.org/shiloh/lasthourcloud:latest"
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /data/coolify/source/.env
|
||||
@ -113,7 +113,7 @@ services:
|
||||
"CMD-SHELL",
|
||||
"pg_isready -U ${DB_USERNAME:-coolify}",
|
||||
"-d",
|
||||
"${DB_DATABASE:-coolify}"
|
||||
"${DB_DATABASE:-coolify}",
|
||||
]
|
||||
interval: 5s
|
||||
retries: 10
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: '3.8'
|
||||
version: "3.8"
|
||||
services:
|
||||
coolify-testing-host:
|
||||
init: true
|
||||
@ -15,7 +15,7 @@ services:
|
||||
restart: always
|
||||
working_dir: /var/www/html
|
||||
extra_hosts:
|
||||
- 'host.docker.internal:host-gateway'
|
||||
- "host.docker.internal:host-gateway"
|
||||
volumes:
|
||||
- type: bind
|
||||
source: .env
|
||||
@ -81,7 +81,7 @@ services:
|
||||
"CMD-SHELL",
|
||||
"pg_isready -U ${DB_USERNAME:-coolify}",
|
||||
"-d",
|
||||
"${DB_DATABASE:-coolify}"
|
||||
"${DB_DATABASE:-coolify}",
|
||||
]
|
||||
interval: 5s
|
||||
retries: 10
|
||||
@ -104,7 +104,7 @@ services:
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
soketi:
|
||||
image: 'quay.io/soketi/soketi:1.6-16-alpine'
|
||||
image: "quay.io/soketi/soketi:1.6-16-alpine"
|
||||
pull_policy: always
|
||||
container_name: coolify-realtime
|
||||
restart: always
|
||||
|
@ -7,7 +7,7 @@
|
||||
"auth.register_now": "Register a new account",
|
||||
"auth.logout": "Logout",
|
||||
"auth.register": "Register",
|
||||
"auth.registration_disabled": "Registration is disabled. Please contact the administrator.",
|
||||
"auth.registration_disabled": "Your registration is set to disabled. Please contact support@lasthourhosting.org for help.",
|
||||
"auth.reset_password": "Reset password",
|
||||
"auth.failed": "These credentials do not match our records.",
|
||||
"auth.failed.password": "The provided password is incorrect.",
|
||||
|
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 641 KiB |
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 70 KiB |
BIN
public/lasthour-transparent.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
public/lasthour.png
Normal file
After Width: | Height: | Size: 34 KiB |
@ -2,7 +2,7 @@
|
||||
<div class="flex items-center justify-center h-screen">
|
||||
<div>
|
||||
<div class="flex flex-col items-center pb-8">
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Coolify</div>
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Last Hour Cloud</div>
|
||||
<x-version />
|
||||
</div>
|
||||
<div class="w-96">
|
||||
|
@ -3,7 +3,7 @@
|
||||
<div>
|
||||
<div class="flex flex-col items-center pb-8">
|
||||
<a href="{{ route('dashboard') }}">
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Coolify</div>
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Last Hour Cloud</div>
|
||||
</a>
|
||||
<x-version />
|
||||
</div>
|
||||
|
@ -2,66 +2,62 @@
|
||||
<div class="min-h-screen hero">
|
||||
<div class="w-96 min-w-fit">
|
||||
<div class="flex flex-col items-center pb-8">
|
||||
<div class="text-5xl font-extrabold tracking-tight text-center text-white">Coolify</div>
|
||||
<img class="transition rounded w-[10rem] h-[10rem]" src="{{ asset('lasthour-transparent.png') }}">
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h1>{{ __('auth.login') }}</h1>
|
||||
@if ($is_registration_enabled)
|
||||
@if (config('coolify.waitlist'))
|
||||
<a href="/waitlist"
|
||||
class="text-xs text-center text-white normal-case bg-transparent border-none rounded no-animation hover:no-underline btn btn-sm bg-coollabs-gradient">
|
||||
Join the waitlist
|
||||
</a>
|
||||
@else
|
||||
<a href="/register"
|
||||
class="text-xs text-center text-white normal-case bg-transparent border-none rounded no-animation hover:no-underline btn btn-sm bg-coollabs-gradient">
|
||||
{{ __('auth.register_now') }}
|
||||
</a>
|
||||
@endif
|
||||
@if (config('coolify.waitlist'))
|
||||
<a href="/waitlist" class="text-xs text-center text-white normal-case bg-transparent border-none rounded no-animation hover:no-underline btn btn-sm bg-coollabs-gradient">
|
||||
Join the waitlist
|
||||
</a>
|
||||
@else
|
||||
<a href="/register" class="text-xs text-center text-white normal-case bg-transparent border-none rounded no-animation hover:no-underline btn btn-sm bg-coollabs-gradient">
|
||||
{{ __('auth.register_now') }}
|
||||
</a>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<form action="/login" method="POST" class="flex flex-col gap-2">
|
||||
@csrf
|
||||
@env('local')
|
||||
<x-forms.input value="test@example.com" type="email" name="email" required
|
||||
label="{{ __('input.email') }}" autofocus />
|
||||
<x-forms.input value="test@example.com" type="email" name="email" required label="{{ __('input.email') }}" autofocus />
|
||||
|
||||
<x-forms.input value="password" type="password" name="password" required
|
||||
label="{{ __('input.password') }}" />
|
||||
<a href="/forgot-password" class="text-xs">
|
||||
{{ __('auth.forgot_password') }}?
|
||||
</a>
|
||||
<x-forms.input value="password" type="password" name="password" required label="{{ __('input.password') }}" />
|
||||
<a href="/forgot-password" class="text-xs">
|
||||
{{ __('auth.forgot_password') }}?
|
||||
</a>
|
||||
@else
|
||||
<x-forms.input type="email" name="email" required label="{{ __('input.email') }}" autofocus />
|
||||
<x-forms.input type="password" name="password" required label="{{ __('input.password') }}" />
|
||||
<a href="/forgot-password" class="text-xs">
|
||||
{{ __('auth.forgot_password') }}?
|
||||
</a>
|
||||
<x-forms.input type="email" name="email" required label="{{ __('input.email') }}" autofocus />
|
||||
<x-forms.input type="password" name="password" required label="{{ __('input.password') }}" />
|
||||
<a href="/forgot-password" class="text-xs">
|
||||
{{ __('auth.forgot_password') }}?
|
||||
</a>
|
||||
@endenv
|
||||
<x-forms.button type="submit">{{ __('auth.login') }}</x-forms.button>
|
||||
@if (!$is_registration_enabled)
|
||||
<div class="text-center ">{{ __('auth.registration_disabled') }}</div>
|
||||
<div class="text-center ">{{ __('auth.registration_disabled') }}</div>
|
||||
@endif
|
||||
@if ($errors->any())
|
||||
<div class="text-xs text-center text-error">
|
||||
@foreach ($errors->all() as $error)
|
||||
<p>{{ $error }}</p>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="text-xs text-center text-error">
|
||||
@foreach ($errors->all() as $error)
|
||||
<p>{{ $error }}</p>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
@if (session('status'))
|
||||
<div class="mb-4 font-medium text-green-600">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
<div class="mb-4 font-medium text-green-600">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
@if (session('error'))
|
||||
<div class="mb-4 font-medium text-red-600">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
<div class="mb-4 font-medium text-red-600">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-layout-simple>
|
||||
</x-layout-simple>
|
@ -2,47 +2,41 @@
|
||||
<div class="flex items-center justify-center min-h-screen ">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col items-center pb-8">
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Coolify</div>
|
||||
<img class="transition rounded w-11 h-11" src="{{ asset('lasthour-transparent.png') }}">
|
||||
<x-version />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h1>{{ __('auth.register') }}</h1>
|
||||
<a href="/login"
|
||||
class="text-xs text-center text-white normal-case bg-transparent border-none rounded no-animation hover:no-underline btn btn-sm bg-coollabs-gradient">
|
||||
<a href="/login" class="text-xs text-center text-white normal-case bg-transparent border-none rounded no-animation hover:no-underline btn btn-sm bg-coollabs-gradient">
|
||||
{{ __('auth.already_registered') }}
|
||||
</a>
|
||||
</div>
|
||||
<form action="/register" method="POST" class="flex flex-col gap-2">
|
||||
@csrf
|
||||
@env('local')
|
||||
<x-forms.input required value="test3 normal user" type="text" name="name"
|
||||
label="{{ __('input.name') }}" />
|
||||
<x-forms.input required value="test3@example.com" type="email" name="email"
|
||||
label="{{ __('input.email') }}" />
|
||||
<x-forms.input required value="test3 normal user" type="text" name="name" label="{{ __('input.name') }}" />
|
||||
<x-forms.input required value="test3@example.com" type="email" name="email" label="{{ __('input.email') }}" />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required value="password" type="password" name="password"
|
||||
label="{{ __('input.password') }}" />
|
||||
<x-forms.input required value="password" type="password" name="password_confirmation"
|
||||
label="{{ __('input.password.again') }}" />
|
||||
<x-forms.input required value="password" type="password" name="password" label="{{ __('input.password') }}" />
|
||||
<x-forms.input required value="password" type="password" name="password_confirmation" label="{{ __('input.password.again') }}" />
|
||||
</div>
|
||||
@else
|
||||
@else
|
||||
<x-forms.input required type="text" name="name" label="{{ __('input.name') }}" />
|
||||
<x-forms.input required type="email" name="email" label="{{ __('input.email') }}" />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required type="password" name="password" label="{{ __('input.password') }}" />
|
||||
<x-forms.input required type="password" name="password_confirmation"
|
||||
label="{{ __('input.password.again') }}" />
|
||||
<x-forms.input required type="password" name="password_confirmation" label="{{ __('input.password.again') }}" />
|
||||
</div>
|
||||
@endenv
|
||||
<x-forms.button type="submit">{{ __('auth.register') }}</x-forms.button>
|
||||
</form>
|
||||
@if ($errors->any())
|
||||
<div class="text-xs text-center text-error">
|
||||
@foreach ($errors->all() as $error)
|
||||
<p>{{ $error }}</p>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="text-xs text-center text-error">
|
||||
@foreach ($errors->all() as $error)
|
||||
<p>{{ $error }}</p>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</x-layout-simple>
|
||||
</x-layout-simple>
|
@ -3,7 +3,7 @@
|
||||
<div>
|
||||
<div class="flex flex-col items-center ">
|
||||
<a href="{{ route('dashboard') }}">
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Coolify</div>
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Last Hour Cloud</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex items-center justify-center pb-4 text-center">
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="flex items-center justify-center h-screen">
|
||||
<div>
|
||||
<div class="flex flex-col items-center pb-8">
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Coolify</div>
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Last Hour Cloud</div>
|
||||
<x-version />
|
||||
</div>
|
||||
<div class="w-96" x-data="{ showRecovery: false }">
|
||||
|
@ -1,6 +1,6 @@
|
||||
{{ Illuminate\Mail\Markdown::parse('---') }}
|
||||
|
||||
Thank you,<br>
|
||||
{{ config('app.name') ?? 'Coolify' }}
|
||||
Last Hour Cloud
|
||||
|
||||
{{ Illuminate\Mail\Markdown::parse('[Contact Support](https://coolify.io/docs/contact)') }}
|
||||
{{ Illuminate\Mail\Markdown::parse('[Contact Support](https://lasthourhosting.org/contact.html)') }}
|
@ -1,47 +1,38 @@
|
||||
@auth
|
||||
<nav class="fixed h-full overflow-hidden overflow-y-auto pt-14 scrollbar">
|
||||
<a href="/" class="fixed top-0 z-50 mx-3 mt-3 bg-transparent cursor-pointer"><img
|
||||
class="transition rounded w-11 h-11" src="{{ asset('coolify-transparent.png') }}"></a>
|
||||
<ul class="flex flex-col h-full gap-4 menu flex-nowrap">
|
||||
<li title="Dashboard">
|
||||
<a class="hover:bg-transparent" @if (!request()->is('/')) href="/" @endif>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('/') ? 'text-warning icon' : 'icon' }}"
|
||||
fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li title="Help us!">
|
||||
<a class="hover:bg-transparent" href="https://coolify.io/sponsorships" target="_blank">
|
||||
<svg class="icon hover:text-pink-500" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2">
|
||||
<path d="M19.5 12.572L12 20l-7.5-7.428A5 5 0 1 1 12 6.006a5 5 0 1 1 7.5 6.572" />
|
||||
<path
|
||||
d="M12 6L8.707 9.293a1 1 0 0 0 0 1.414l.543.543c.69.69 1.81.69 2.5 0l1-1a3.182 3.182 0 0 1 4.5 0l2.25 2.25m-7 3l2 2M15 13l2 2" />
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li title="Send us feedback or get help!" class="fixed top-0 right-0 p-2 px-4 pt-4 mt-auto text-xs">
|
||||
<div class="justify-center" wire:click="help" onclick="help.showModal()">
|
||||
<svg class="icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M140 180a12 12 0 1 1-12-12a12 12 0 0 1 12 12M128 72c-22.06 0-40 16.15-40 36v4a8 8 0 0 0 16 0v-4c0-11 10.77-20 24-20s24 9 24 20s-10.77 20-24 20a8 8 0 0 0-8 8v8a8 8 0 0 0 16 0v-.72c18.24-3.35 32-17.9 32-35.28c0-19.85-17.94-36-40-36m104 56A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88" />
|
||||
</svg>
|
||||
<nav class="fixed h-full overflow-hidden overflow-y-auto pt-14 scrollbar">
|
||||
<a href="/" class="fixed top-0 z-50 mx-3 mt-3 bg-transparent cursor-pointer"><img class="transition rounded w-11 h-11" src="{{ asset('lasthour-transparent.png') }}"></a>
|
||||
<ul class="flex flex-col h-full gap-4 menu flex-nowrap">
|
||||
<li title="Dashboard">
|
||||
<a class="hover:bg-transparent" @if (!request()->is('/')) href="/" @endif>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('/') ? 'text-warning icon' : 'icon' }}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li title="Get Involved">
|
||||
<a class="hover:text-blue-500 fill:" href="https://shilohcode.com/getinvolved" target="_blank">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 16 16">
|
||||
<path d="M13.5 1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3M11 2.5a2.5 2.5 0 1 1 .603 1.628l-6.718 3.12a2.5 2.5 0 0 1 0 1.504l6.718 3.12a2.5 2.5 0 1 1-.488.876l-6.718-3.12a2.5 2.5 0 1 1 0-3.256l6.718-3.12A2.5 2.5 0 0 1 11 2.5m-8.5 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3m11 5.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<!-- <li title="Get help!" class="icon">
|
||||
<div class="flex items-center gap-2 rounded-none hover:text-white hover:bg-transparent" wire:click="help" onclick="help.showModal()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chat-dots-fill" viewBox="0 0 16 16">
|
||||
<path d="M16 8c0 3.866-3.582 7-8 7a9 9 0 0 1-2.347-.306c-.584.296-1.925.864-4.181 1.234-.2.032-.352-.176-.273-.362.354-.836.674-1.95.77-2.966C.744 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7M5 8a1 1 0 1 0-2 0 1 1 0 0 0 2 0m4 0a1 1 0 1 0-2 0 1 1 0 0 0 2 0m3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2"/>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
<li class="pb-6" title="Logout">
|
||||
<form action="/logout" method="POST" class="hover:bg-transparent">
|
||||
@csrf
|
||||
<button class="flex items-center gap-2 rounded-none hover:text-white hover:bg-transparent">
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2a9.985 9.985 0 0 1 8 4h-2.71a8 8 0 1 0 .001 12h2.71A9.985 9.985 0 0 1 12 22m7-6v-3h-8v-2h8V8l5 4z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
@endauth
|
||||
</li> -->
|
||||
<li class="pb-6" title="Logout">
|
||||
<form action="/logout" method="POST" class="hover:bg-transparent">
|
||||
@csrf
|
||||
<button class="flex items-center gap-2 rounded-none hover:text-white hover:bg-transparent">
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2a9.985 9.985 0 0 1 8 4h-2.71a8 8 0 1 0 .001 12h2.71A9.985 9.985 0 0 1 12 22m7-6v-3h-8v-2h8V8l5 4z" />
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
@endauth
|
@ -1,243 +1,182 @@
|
||||
@auth
|
||||
<nav class="fixed h-full pt-28 scrollbar">
|
||||
<a href="/" class="fixed top-0 z-50 mx-3 mt-3 bg-transparent cursor-pointer"><img
|
||||
class="transition rounded w-11 h-11" src="{{ asset('coolify-transparent.png') }}"></a>
|
||||
<ul class="flex flex-col h-full gap-4 menu flex-nowrap">
|
||||
<li title="Dashboard">
|
||||
<a class="hover:bg-transparent" href="/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('/') ? 'text-warning icon' : 'icon' }}"
|
||||
fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
||||
<nav class="fixed h-full pt-28 scrollbar">
|
||||
<a href="/" class="fixed top-0 z-50 mx-3 mt-3 bg-transparent cursor-pointer"><img class="transition rounded w-11 h-11" src="{{ asset('lasthour-transparent.png') }}"></a>
|
||||
<ul class="flex flex-col h-full gap-4 menu flex-nowrap">
|
||||
<li title="Dashboard">
|
||||
<a class="hover:bg-transparent" href="/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('/') ? 'text-warning icon' : 'icon' }}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li title="Servers">
|
||||
<a class="hover:bg-transparent" href="/servers">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('server/*') || request()->is('servers') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M3 4m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z" />
|
||||
<path d="M15 20h-9a3 3 0 0 1 -3 -3v-2a3 3 0 0 1 3 -3h12" />
|
||||
<path d="M7 8v.01" />
|
||||
<path d="M7 16v.01" />
|
||||
<path d="M20 15l-2 3h3l-2 3" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li title="Projects">
|
||||
<a class="hover:bg-transparent" href="/projects">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('project/*') || request()->is('projects') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 4l-8 4l8 4l8 -4l-8 -4" />
|
||||
<path d="M4 12l8 4l8 -4" />
|
||||
<path d="M4 16l8 4l8 -4" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<div class="inline-block text-left " x-data="{ open: false }">
|
||||
<div>
|
||||
<button x-on:click.prevent="open = !open" x-on:click.away="open = false" type="button" class="py-4 mx-4" id="menu-button" aria-expanded="true" aria-haspopup="true">
|
||||
<svg class="icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M224 128a8 8 0 0 1-8 8h-80v80a8 8 0 0 1-16 0v-80H40a8 8 0 0 1 0-16h80V40a8 8 0 0 1 16 0v80h80a8 8 0 0 1 8 8" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li title="Servers">
|
||||
<a class="hover:bg-transparent" href="/servers">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('server/*') || request()->is('servers') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M3 4m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z" />
|
||||
<path d="M15 20h-9a3 3 0 0 1 -3 -3v-2a3 3 0 0 1 3 -3h12" />
|
||||
<path d="M7 8v.01" />
|
||||
<path d="M7 16v.01" />
|
||||
<path d="M20 15l-2 3h3l-2 3" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li title="Projects">
|
||||
<a class="hover:bg-transparent" href="/projects">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('project/*') || request()->is('projects') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 4l-8 4l8 4l8 -4l-8 -4" />
|
||||
<path d="M4 12l8 4l8 -4" />
|
||||
<path d="M4 16l8 4l8 -4" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<div class="inline-block text-left " x-data="{ open: false }">
|
||||
<div>
|
||||
<button x-on:click.prevent="open = !open" x-on:click.away="open = false" type="button"
|
||||
class="py-4 mx-4" id="menu-button" aria-expanded="true" aria-haspopup="true">
|
||||
<svg class="icon text-neutral-400" xmlns="http://www.w3.org/2000/svg" width="200" height="200"
|
||||
viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div x-show="open" x-cloak
|
||||
class="absolute left-0 z-10 w-56 mx-4 mt-2 origin-top-right rounded shadow-lg bg-coolgray-100 ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
|
||||
<div class="py-1" role="none">
|
||||
<li title="Tags" class="border-transparent hover:bg-coolgray-200 ">
|
||||
<a class=" hover:bg-transparent hover:no-underline" href="{{ route('tags.index') }}">
|
||||
<svg class="{{ request()->is('tags*') ? 'text-warning icon' : 'icon' }}"viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2">
|
||||
<path
|
||||
d="M3 8v4.172a2 2 0 0 0 .586 1.414l5.71 5.71a2.41 2.41 0 0 0 3.408 0l3.592-3.592a2.41 2.41 0 0 0 0-3.408l-5.71-5.71A2 2 0 0 0 9.172 6H5a2 2 0 0 0-2 2" />
|
||||
<path d="m18 19l1.592-1.592a4.82 4.82 0 0 0 0-6.816L15 6m-8 4h-.01" />
|
||||
</g>
|
||||
</svg>
|
||||
Tags
|
||||
</a>
|
||||
</li>
|
||||
<li title="Command Center" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('command-center') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('command-center*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M5 7l5 5l-5 5" />
|
||||
<path d="M12 19l7 0" />
|
||||
</svg>
|
||||
Command Center
|
||||
</a>
|
||||
</li>
|
||||
<li title="Source" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('source.all') }}">
|
||||
<svg class="{{ request()->is('source*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="m6.793 1.207l.353.354l-.353-.354ZM1.207 6.793l-.353-.354l.353.354Zm0 1.414l.354-.353l-.354.353Zm5.586 5.586l-.354.353l.354-.353Zm1.414 0l-.353-.354l.353.354Zm5.586-5.586l.353.354l-.353-.354Zm0-1.414l-.354.353l.354-.353ZM8.207 1.207l.354-.353l-.354.353ZM6.44.854L.854 6.439l.707.707l5.585-5.585L6.44.854ZM.854 8.56l5.585 5.585l.707-.707l-5.585-5.585l-.707.707Zm7.707 5.585l5.585-5.585l-.707-.707l-5.585 5.585l.707.707Zm5.585-7.707L8.561.854l-.707.707l5.585 5.585l.707-.707Zm0 2.122a1.5 1.5 0 0 0 0-2.122l-.707.707a.5.5 0 0 1 0 .708l.707.707ZM6.44 14.146a1.5 1.5 0 0 0 2.122 0l-.707-.707a.5.5 0 0 1-.708 0l-.707.707ZM.854 6.44a1.5 1.5 0 0 0 0 2.122l.707-.707a.5.5 0 0 1 0-.708L.854 6.44Zm6.292-4.878a.5.5 0 0 1 .708 0L8.56.854a1.5 1.5 0 0 0-2.122 0l.707.707Zm-2 1.293l1 1l.708-.708l-1-1l-.708.708ZM7.5 5a.5.5 0 0 1-.5-.5H6A1.5 1.5 0 0 0 7.5 6V5Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 9 4.5H8ZM7.5 4a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 7.5 3v1Zm0-1A1.5 1.5 0 0 0 6 4.5h1a.5.5 0 0 1 .5-.5V3Zm.646 2.854l1.5 1.5l.707-.708l-1.5-1.5l-.707.708ZM10.5 8a.5.5 0 0 1-.5-.5H9A1.5 1.5 0 0 0 10.5 9V8Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 12 7.5h-1Zm-.5-.5a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 10.5 6v1Zm0-1A1.5 1.5 0 0 0 9 7.5h1a.5.5 0 0 1 .5-.5V6ZM7 5.5v4h1v-4H7Zm.5 5.5a.5.5 0 0 1-.5-.5H6A1.5 1.5 0 0 0 7.5 12v-1Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 9 10.5H8Zm-.5-.5a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 7.5 9v1Zm0-1A1.5 1.5 0 0 0 6 10.5h1a.5.5 0 0 1 .5-.5V9Z" />
|
||||
</svg>
|
||||
Sources
|
||||
</a>
|
||||
</li>
|
||||
<li title="Security" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline"
|
||||
href="{{ route('security.private-key.index') }}">
|
||||
<svg class="{{ request()->is('security*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round"
|
||||
stroke-linejoin="round" stroke-width="2"
|
||||
d="m16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1-4.069 0l-.301-.301l-6.558 6.558a2 2 0 0 1-1.239.578L5.172 21H4a1 1 0 0 1-.993-.883L3 20v-1.172a2 2 0 0 1 .467-1.284l.119-.13L4 17h2v-2h2v-2l2.144-2.144l-.301-.301a2.877 2.877 0 0 1 0-4.069l2.643-2.643a2.877 2.877 0 0 1 4.069 0zM15 9h.01" />
|
||||
</svg>
|
||||
Security
|
||||
</a>
|
||||
</li>
|
||||
<li title="Profile" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('profile') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('profile*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
|
||||
<path d="M12 10m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
|
||||
<path d="M6.168 18.849a4 4 0 0 1 3.832 -2.849h4a4 4 0 0 1 3.834 2.855" />
|
||||
</svg>
|
||||
Profile
|
||||
</a>
|
||||
</li>
|
||||
<li title="Teams" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('team.index') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
|
||||
class="{{ request()->is('team*') ? 'text-warning icon' : 'icon' }}"
|
||||
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 13a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M8 21v-1a2 2 0 0 1 2 -2h4a2 2 0 0 1 2 2v1" />
|
||||
<path d="M15 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M17 10h2a2 2 0 0 1 2 2v1" />
|
||||
<path d="M5 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M3 13v-1a2 2 0 0 1 2 -2h2" />
|
||||
</svg>
|
||||
Teams
|
||||
</a>
|
||||
</li>
|
||||
@if (isCloud())
|
||||
<li title="Subscription" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline"
|
||||
href="{{ route('subscription.show') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('subscription*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round"
|
||||
stroke-linejoin="round" stroke-width="2"
|
||||
d="M3 8a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3zm0 2h18M7 15h.01M11 15h2" />
|
||||
</svg>
|
||||
Subscription
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<li title="Notifications" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('notification.index') }}">
|
||||
<svg class="{{ request()->is('notifications*') ? 'text-warning icon' : 'icon' }}"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round"
|
||||
stroke-linejoin="round" stroke-width="2"
|
||||
d="M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3H4a4 4 0 0 0 2-3v-3a7 7 0 0 1 4-6M9 17v1a3 3 0 0 0 6 0v-1" />
|
||||
</svg>
|
||||
Notifications
|
||||
</a>
|
||||
</li>
|
||||
@if (isInstanceAdmin())
|
||||
<li title="Settings" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="/settings">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('settings*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path
|
||||
d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z" />
|
||||
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
|
||||
</svg>
|
||||
Settings
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<li title="Onboarding" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('onboarding') }}">
|
||||
<svg class="{{ request()->is('onboarding*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M224 128a8 8 0 0 1-8 8h-88a8 8 0 0 1 0-16h88a8 8 0 0 1 8 8m-96-56h88a8 8 0 0 0 0-16h-88a8 8 0 0 0 0 16m88 112h-88a8 8 0 0 0 0 16h88a8 8 0 0 0 0-16M82.34 42.34L56 68.69L45.66 58.34a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32 0l32-32a8 8 0 0 0-11.32-11.32m0 64L56 132.69l-10.34-10.35a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32 0l32-32a8 8 0 0 0-11.32-11.32m0 64L56 196.69l-10.34-10.35a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32 0l32-32a8 8 0 0 0-11.32-11.32" />
|
||||
</svg>
|
||||
Onboarding
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div x-show="open" x-cloak class="absolute left-0 z-10 w-56 mx-4 mt-2 origin-top-right rounded shadow-lg bg-coolgray-100 ring-1 ring-black ring-opacity-5 focus:outline-none" role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
|
||||
<div class="py-1" role="none">
|
||||
<li title="Tags" class="border-transparent hover:bg-coolgray-200 ">
|
||||
<a class=" hover:bg-transparent hover:no-underline" href="{{ route('tags.index') }}">
|
||||
<svg class="{{ request()->is('tags*') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
|
||||
<path d="M3 8v4.172a2 2 0 0 0 .586 1.414l5.71 5.71a2.41 2.41 0 0 0 3.408 0l3.592-3.592a2.41 2.41 0 0 0 0-3.408l-5.71-5.71A2 2 0 0 0 9.172 6H5a2 2 0 0 0-2 2" />
|
||||
<path d="m18 19l1.592-1.592a4.82 4.82 0 0 0 0-6.816L15 6m-8 4h-.01" />
|
||||
</g>
|
||||
</svg>
|
||||
Tags
|
||||
</a>
|
||||
</li>
|
||||
<li title="Command Center" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('command-center') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('command-center*') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M5 7l5 5l-5 5" />
|
||||
<path d="M12 19l7 0" />
|
||||
</svg>
|
||||
Command Center
|
||||
</a>
|
||||
</li>
|
||||
<li title="Source" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('source.all') }}">
|
||||
<svg class="{{ request()->is('source*') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="m6.793 1.207l.353.354l-.353-.354ZM1.207 6.793l-.353-.354l.353.354Zm0 1.414l.354-.353l-.354.353Zm5.586 5.586l-.354.353l.354-.353Zm1.414 0l-.353-.354l.353.354Zm5.586-5.586l.353.354l-.353-.354Zm0-1.414l-.354.353l.354-.353ZM8.207 1.207l.354-.353l-.354.353ZM6.44.854L.854 6.439l.707.707l5.585-5.585L6.44.854ZM.854 8.56l5.585 5.585l.707-.707l-5.585-5.585l-.707.707Zm7.707 5.585l5.585-5.585l-.707-.707l-5.585 5.585l.707.707Zm5.585-7.707L8.561.854l-.707.707l5.585 5.585l.707-.707Zm0 2.122a1.5 1.5 0 0 0 0-2.122l-.707.707a.5.5 0 0 1 0 .708l.707.707ZM6.44 14.146a1.5 1.5 0 0 0 2.122 0l-.707-.707a.5.5 0 0 1-.708 0l-.707.707ZM.854 6.44a1.5 1.5 0 0 0 0 2.122l.707-.707a.5.5 0 0 1 0-.708L.854 6.44Zm6.292-4.878a.5.5 0 0 1 .708 0L8.56.854a1.5 1.5 0 0 0-2.122 0l.707.707Zm-2 1.293l1 1l.708-.708l-1-1l-.708.708ZM7.5 5a.5.5 0 0 1-.5-.5H6A1.5 1.5 0 0 0 7.5 6V5Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 9 4.5H8ZM7.5 4a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 7.5 3v1Zm0-1A1.5 1.5 0 0 0 6 4.5h1a.5.5 0 0 1 .5-.5V3Zm.646 2.854l1.5 1.5l.707-.708l-1.5-1.5l-.707.708ZM10.5 8a.5.5 0 0 1-.5-.5H9A1.5 1.5 0 0 0 10.5 9V8Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 12 7.5h-1Zm-.5-.5a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 10.5 6v1Zm0-1A1.5 1.5 0 0 0 9 7.5h1a.5.5 0 0 1 .5-.5V6ZM7 5.5v4h1v-4H7Zm.5 5.5a.5.5 0 0 1-.5-.5H6A1.5 1.5 0 0 0 7.5 12v-1Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 9 10.5H8Zm-.5-.5a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 7.5 9v1Zm0-1A1.5 1.5 0 0 0 6 10.5h1a.5.5 0 0 1 .5-.5V9Z" />
|
||||
</svg>
|
||||
Sources
|
||||
</a>
|
||||
</li>
|
||||
<li title="Security" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('security.private-key.index') }}">
|
||||
<svg class="{{ request()->is('security*') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1-4.069 0l-.301-.301l-6.558 6.558a2 2 0 0 1-1.239.578L5.172 21H4a1 1 0 0 1-.993-.883L3 20v-1.172a2 2 0 0 1 .467-1.284l.119-.13L4 17h2v-2h2v-2l2.144-2.144l-.301-.301a2.877 2.877 0 0 1 0-4.069l2.643-2.643a2.877 2.877 0 0 1 4.069 0zM15 9h.01" />
|
||||
</svg>
|
||||
Security
|
||||
</a>
|
||||
</li>
|
||||
<li title="Profile" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('profile') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('profile*') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
|
||||
<path d="M12 10m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
|
||||
<path d="M6.168 18.849a4 4 0 0 1 3.832 -2.849h4a4 4 0 0 1 3.834 2.855" />
|
||||
</svg>
|
||||
Profile
|
||||
</a>
|
||||
</li>
|
||||
<li title="Teams" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('team.index') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="{{ request()->is('team*') ? 'text-warning icon' : 'icon' }}" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 13a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M8 21v-1a2 2 0 0 1 2 -2h4a2 2 0 0 1 2 2v1" />
|
||||
<path d="M15 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M17 10h2a2 2 0 0 1 2 2v1" />
|
||||
<path d="M5 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M3 13v-1a2 2 0 0 1 2 -2h2" />
|
||||
</svg>
|
||||
Teams @if (isCloud())
|
||||
/ Subscription
|
||||
@endif
|
||||
</a>
|
||||
</li>
|
||||
<li title="Notifications" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('notification.index') }}">
|
||||
<svg class="{{ request()->is('notifications*') ? 'text-warning icon' : 'icon' }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3H4a4 4 0 0 0 2-3v-3a7 7 0 0 1 4-6M9 17v1a3 3 0 0 0 6 0v-1" />
|
||||
</svg>
|
||||
Notifications
|
||||
</a>
|
||||
</li>
|
||||
@if (isInstanceAdmin())
|
||||
<li title="Settings" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="/settings">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('settings*') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z" />
|
||||
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
|
||||
</svg>
|
||||
Settings
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<li title="Guided Tour" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('onboarding') }}">
|
||||
<svg class="{{ request()->is('onboarding*') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M224 128a8 8 0 0 1-8 8h-88a8 8 0 0 1 0-16h88a8 8 0 0 1 8 8m-96-56h88a8 8 0 0 0 0-16h-88a8 8 0 0 0 0 16m88 112h-88a8 8 0 0 0 0 16h88a8 8 0 0 0 0-16M82.34 42.34L56 68.69L45.66 58.34a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32 0l32-32a8 8 0 0 0-11.32-11.32m0 64L56 132.69l-10.34-10.35a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32 0l32-32a8 8 0 0 0-11.32-11.32m0 64L56 196.69l-10.34-10.35a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32 0l32-32a8 8 0 0 0-11.32-11.32" />
|
||||
</svg>
|
||||
Guided Tour
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
@if (isCloud() && isInstanceAdmin())
|
||||
<li title="Admin">
|
||||
<a class="hover:bg-transparent" href="/admin">
|
||||
<svg class="text-pink-600 icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M177.62 159.6a52 52 0 0 1-34 34a12.2 12.2 0 0 1-3.6.55a12 12 0 0 1-3.6-23.45a28 28 0 0 0 18.32-18.32a12 12 0 0 1 22.9 7.2ZM220 144a92 92 0 0 1-184 0c0-28.81 11.27-58.18 33.48-87.28a12 12 0 0 1 17.9-1.33l19.69 19.11L127 19.89a12 12 0 0 1 18.94-5.12C168.2 33.25 220 82.85 220 144m-24 0c0-41.71-30.61-78.39-52.52-99.29l-20.21 55.4a12 12 0 0 1-19.63 4.5L80.71 82.36C67 103.38 60 124.06 60 144a68 68 0 0 0 136 0" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<div class="flex-1"></div>
|
||||
@if (isInstanceAdmin() && !isCloud())
|
||||
@persist('upgrade')
|
||||
<livewire:upgrade />
|
||||
@endpersist
|
||||
@endif
|
||||
<li title="Help us!">
|
||||
<a class="hover:bg-transparent" href="https://coolify.io/sponsorships" target="_blank">
|
||||
<svg class="icon hover:text-pink-500" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2">
|
||||
<path d="M19.5 12.572L12 20l-7.5-7.428A5 5 0 1 1 12 6.006a5 5 0 1 1 7.5 6.572" />
|
||||
<path
|
||||
d="M12 6L8.707 9.293a1 1 0 0 0 0 1.414l.543.543c.69.69 1.81.69 2.5 0l1-1a3.182 3.182 0 0 1 4.5 0l2.25 2.25m-7 3l2 2M15 13l2 2" />
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li title="Send us feedback or get help!" class="hover:bg-transparent">
|
||||
<div class="justify-center" wire:click="help" onclick="help.showModal()">
|
||||
<svg class="icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M140 180a12 12 0 1 1-12-12a12 12 0 0 1 12 12M128 72c-22.06 0-40 16.15-40 36v4a8 8 0 0 0 16 0v-4c0-11 10.77-20 24-20s24 9 24 20s-10.77 20-24 20a8 8 0 0 0-8 8v8a8 8 0 0 0 16 0v-.72c18.24-3.35 32-17.9 32-35.28c0-19.85-17.94-36-40-36m104 56A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88" />
|
||||
</div>
|
||||
@if (isCloud() && isInstanceAdmin())
|
||||
<li title="Admin">
|
||||
<a class="hover:bg-transparent" href="/admin">
|
||||
<svg class="text-pink-600 icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M177.62 159.6a52 52 0 0 1-34 34a12.2 12.2 0 0 1-3.6.55a12 12 0 0 1-3.6-23.45a28 28 0 0 0 18.32-18.32a12 12 0 0 1 22.9 7.2ZM220 144a92 92 0 0 1-184 0c0-28.81 11.27-58.18 33.48-87.28a12 12 0 0 1 17.9-1.33l19.69 19.11L127 19.89a12 12 0 0 1 18.94-5.12C168.2 33.25 220 82.85 220 144m-24 0c0-41.71-30.61-78.39-52.52-99.29l-20.21 55.4a12 12 0 0 1-19.63 4.5L80.71 82.36C67 103.38 60 124.06 60 144a68 68 0 0 0 136 0" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<div class="flex-1"></div>
|
||||
@if (isInstanceAdmin() && !isCloud())
|
||||
@persist('upgrade')
|
||||
<livewire:upgrade />
|
||||
@endpersist
|
||||
@endif
|
||||
<li title="Get Involved">
|
||||
<a class="justify-center hover:text-white hover:bg-transparent" href="https://shilohcode.com/get-involved" target="_blank">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 16 16">
|
||||
<path fill="currentColor" d="M13.5 1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3M11 2.5a2.5 2.5 0 1 1 .603 1.628l-6.718 3.12a2.5 2.5 0 0 1 0 1.504l6.718 3.12a2.5 2.5 0 1 1-.488.876l-6.718-3.12a2.5 2.5 0 1 1 0-3.256l6.718-3.12A2.5 2.5 0 0 1 11 2.5m-8.5 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3m11 5.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li title="Get help!">
|
||||
<a href="https://lasthourhosting.org/contact.html" target="_blank">
|
||||
<div class="justify-center items-center hover:text-white hover:bg-transparent">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill="currentColor" d="M16 8c0 3.866-3.582 7-8 7a9 9 0 0 1-2.347-.306c-.584.296-1.925.864-4.181 1.234-.2.032-.352-.176-.273-.362.354-.836.674-1.95.77-2.966C.744 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7M5 8a1 1 0 1 0-2 0 1 1 0 0 0 2 0m4 0a1 1 0 1 0-2 0 1 1 0 0 0 2 0m3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2" />
|
||||
</svg>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<form action="/logout" method="POST" class="hover:bg-transparent">
|
||||
<li title="Logout" class="mb-6 hover:transparent">
|
||||
@csrf
|
||||
<button type="submit" class="rounded-none hover:text-white hover:bg-transparent">
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2a9.985 9.985 0 0 1 8 4h-2.71a8 8 0 1 0 .001 12h2.71A9.985 9.985 0 0 1 12 22m7-6v-3h-8v-2h8V8l5 4z" />
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
<form action="/logout" method="POST" class="hover:bg-transparent">
|
||||
<li title="Logout" class="mb-6 hover:transparent">
|
||||
@csrf
|
||||
<button type="submit" class="rounded-none hover:text-white hover:bg-transparent">
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2a9.985 9.985 0 0 1 8 4h-2.71a8 8 0 1 0 .001 12h2.71A9.985 9.985 0 0 1 12 22m7-6v-3h-8v-2h8V8l5 4z" />
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
</form>
|
||||
</ul>
|
||||
</nav>
|
||||
@endauth
|
||||
</form>
|
||||
</ul>
|
||||
</nav>
|
||||
@endauth
|
@ -327,7 +327,7 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap
|
||||
</div>
|
||||
<div class="mt-1 text-base leading-7 text-gray-300">
|
||||
You own your own data. All configurations saved on your own servers, so if
|
||||
you decide to stop using Coolify, you can still continue to manage your
|
||||
you decide to stop using Last Hour Cloud, you can still continue to manage your
|
||||
deployed resources.
|
||||
</div>
|
||||
</div>
|
||||
@ -349,7 +349,7 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap
|
||||
<div class="text-2xl font-semibold text-white">Monitoring</div>
|
||||
</div>
|
||||
<div class="mt-1 text-base leading-7 text-gray-300">
|
||||
Coolify will automatically monitor your configured servers and deployed
|
||||
Last Hour Cloud will automatically monitor your configured servers and deployed
|
||||
resources. Notifies you if something goes wrong on your favourite
|
||||
channels, like Discord, Telegram, via Email and more...
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="pb-5">
|
||||
<h1>Settings</h1>
|
||||
<div class="subtitle">Instance wide settings for Coolify.</div>
|
||||
<div class="subtitle">Instance wide settings for Last Hour Cloud.</div>
|
||||
<nav class="navbar-main">
|
||||
<a class="{{ request()->routeIs('settings.index') ? 'text-white' : '' }}"
|
||||
href="{{ route('settings.index') }}">
|
||||
|
@ -1,2 +1 @@
|
||||
<a {{ $attributes->merge(['class' => 'text-xs cursor-pointer opacity-60 hover:opacity-100 hover:text-white z-50']) }}
|
||||
href="https://github.com/coollabsio/coolify/releases/tag/v{{ config('version') }}">v{{ config('version') }}</a>
|
||||
<a {{ $attributes->merge(['class' => 'text-xs cursor-pointer opacity-60 hover:opacity-100 hover:text-white z-50']) }} href="https://githaven.org/Shiloh/lasthourcloud/releases/tag/v{{ config('version') }}">v{{ config('version') }}</a>
|
@ -2,8 +2,8 @@
|
||||
A resource ({{ $containerName }}) has been restarted automatically on {{ $serverName }}, because it was stopped unexpectedly.
|
||||
|
||||
@if ($containerName === 'coolify-proxy')
|
||||
Coolify Proxy should run on your server as you have FQDNs set up in one of your resources.
|
||||
Last Hour Cloud Proxy should run on your server as you have FQDNs set up in one of your resources.
|
||||
|
||||
If you don't want to use Coolify Proxy, please remove FQDN from your resources or set Proxy type to Custom(None).
|
||||
If you don't want to use Last Hour Cloud Proxy, please remove FQDN from your resources or set Proxy type to Custom(None).
|
||||
@endif
|
||||
</x-emails.layout>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<x-emails.layout>
|
||||
Your server ({{ $name }}) has high disk usage ({{ $disk_usage }}% used). Threshold is {{ $threshold }}%.
|
||||
|
||||
Please cleanup your disk to prevent data-loss. Here are some [tips](https://coolify.io/docs/automated-cleanup).
|
||||
Please cleanup your disk to prevent data-loss. Here are some [tips](https://coolify.io/docs/automated-cleanup) from the upstream project.
|
||||
|
||||
(You can change the threshold in the Server Settings menu.)
|
||||
</x-emails.layout>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<x-emails.layout>
|
||||
Coolify cannot connect to your server ({{ $name }}). Please check your server and make sure it is running.
|
||||
Last Hour Cloud cannot connect to your server ({{ $name }}). Please check your server and make sure it is running.
|
||||
|
||||
All automations & integrations are turned off!
|
||||
|
||||
|
@ -10,11 +10,11 @@
|
||||
<link rel="preload" href="https://cdn.fonts.coollabs.io/inter/normal/400.woff2" as="style" />
|
||||
<link href="https://api.fonts.coollabs.io/css2?family=Inter&display=swap" rel="stylesheet">
|
||||
<meta name="robots" content="noindex">
|
||||
<title>Coolify</title>
|
||||
<title>Last Hour Cloud</title>
|
||||
@env('local')
|
||||
<link rel="icon" href="{{ asset('favicon-dev.png') }}" type="image/x-icon" />
|
||||
@else
|
||||
<link rel="icon" href="{{ asset('coolify-transparent.png') }}" type="image/x-icon" />
|
||||
<link rel="icon" href="{{ asset('lasthour-transparent.png') }}" type="image/x-icon" />
|
||||
@endenv
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
@vite(['resources/js/app.js', 'resources/css/app.css'])
|
||||
@ -92,7 +92,7 @@ function revive() {
|
||||
fetch('/api/health')
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
window.toast('Coolify is back online. Reloading...', {
|
||||
window.toast('Last Hour Cloud is back online. Reloading...', {
|
||||
type: 'success',
|
||||
})
|
||||
if (checkHealthInterval) clearInterval(checkHealthInterval);
|
||||
@ -115,7 +115,7 @@ function upgrade() {
|
||||
if (response.ok) {
|
||||
console.log('It\'s alive. Waiting for server to be dead...');
|
||||
} else {
|
||||
window.toast('Update done, restarting Coolify!', {
|
||||
window.toast('Update done, restarting Last Hour Cloud!', {
|
||||
type: 'success',
|
||||
})
|
||||
console.log('It\'s dead. Reviving... Standby... Bzz... Bzz...')
|
||||
|
@ -1,16 +1,18 @@
|
||||
@extends('layouts.base')
|
||||
@section('body')
|
||||
<div title="Send us feedback or get help!" class="fixed top-0 right-0 p-2 px-4 pt-4 mt-auto text-xs">
|
||||
<button class="flex items-center justify-center gap-2" wire:click="help" onclick="help.showModal()">
|
||||
<div title="Send us feedback or get help!" class="fixed top-0 right-0 p-2 px-4 pt-4 mt-auto text-xs">
|
||||
<a href="https://lasthourhosting.org/contact.html" target="_blank">
|
||||
<div class="justify-center items-center hover:text-white hover:bg-transparent">
|
||||
<svg class="icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M140 180a12 12 0 1 1-12-12a12 12 0 0 1 12 12M128 72c-22.06 0-40 16.15-40 36v4a8 8 0 0 0 16 0v-4c0-11 10.77-20 24-20s24 9 24 20s-10.77 20-24 20a8 8 0 0 0-8 8v8a8 8 0 0 0 16 0v-.72c18.24-3.35 32-17.9 32-35.28c0-19.85-17.94-36-40-36m104 56A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88"/>
|
||||
<path fill="currentColor" d="M140 180a12 12 0 1 1-12-12a12 12 0 0 1 12 12M128 72c-22.06 0-40 16.15-40 36v4a8 8 0 0 0 16 0v-4c0-11 10.77-20 24-20s24 9 24 20s-10.77 20-24 20a8 8 0 0 0-8 8v8a8 8 0 0 0 16 0v-.72c18.24-3.35 32-17.9 32-35.28c0-19.85-17.94-36-40-36m104 56A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<main class="min-h-screen hero">
|
||||
<div class="hero-content">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</main>
|
||||
@parent
|
||||
@endsection
|
||||
</a>
|
||||
</div>
|
||||
<main class="min-h-screen hero">
|
||||
<div class="hero-content">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</main>
|
||||
@parent
|
||||
@endsection
|
@ -2,263 +2,247 @@
|
||||
<div>
|
||||
<div>
|
||||
@if ($currentState === 'welcome')
|
||||
<h1 class="text-5xl font-bold">Welcome to Coolify</h1>
|
||||
<p class="py-6 text-xl text-center">Let me help you set up the basics.</p>
|
||||
<div class="flex justify-center ">
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="$set('currentState','explanation')">Get
|
||||
Started
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<h1 class="text-5xl font-bold">Welcome to Last Hour Cloud</h1>
|
||||
<p class="py-6 text-xl text-center">Let me help you set up the basics.</p>
|
||||
<div class="flex justify-center ">
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="$set('currentState','explanation')">Get
|
||||
Started
|
||||
</x-forms.button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'explanation')
|
||||
<x-boarding-step title="What is Coolify?">
|
||||
<x-slot:question>
|
||||
Coolify is an all-in-one application to automate tasks on your servers, deploy application with Git
|
||||
integrations, deploy databases and services, monitor these resources with notifications and alerts
|
||||
without vendor lock-in
|
||||
and <a href="https://coolify.io" class="text-white hover:underline">much much more</a>.
|
||||
<br><br>
|
||||
<span class="text-xl">
|
||||
<x-highlighted text="Self-hosting with superpowers!" /></span>
|
||||
</x-slot:question>
|
||||
<x-slot:explanation>
|
||||
<p><x-highlighted text="Task automation:" /> You don't need to manage your servers anymore. Coolify does
|
||||
it for you.</p>
|
||||
<p><x-highlighted text="No vendor lock-in:" /> All configurations are stored on your servers, so
|
||||
everything works without a connection to Coolify (except integrations and automations).</p>
|
||||
<p><x-highlighted text="Monitoring:" />You can get notified on your favourite platforms (Discord,
|
||||
Telegram, Email, etc.) when something goes wrong, or an action is needed from your side.</p>
|
||||
</x-slot:explanation>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="explanation">Next
|
||||
</x-forms.button>
|
||||
</x-slot:actions>
|
||||
</x-boarding-step>
|
||||
<x-boarding-step title="What is Last Hour Cloud?">
|
||||
<x-slot:question>
|
||||
Last Hour Cloud is an all-in-one application to automate tasks on your servers, deploy applications with Git
|
||||
integrations, deploy databases and services, monitor these resources with notifications and alerts
|
||||
without vendor lock-in
|
||||
and <a href="https://lasthourhosting.org/cloud.html" class="text-white hover:underline">much much more</a>.
|
||||
<br><br>
|
||||
<span class="text-xl">
|
||||
<x-highlighted text="Self-hosting with superpowers!" /></span>
|
||||
</x-slot:question>
|
||||
<x-slot:explanation>
|
||||
<p><x-highlighted text="Task automation:" /> You don't need to manage your servers anymore. Last Hour Cloud does
|
||||
it for you.</p>
|
||||
<p><x-highlighted text="No vendor lock-in:" /> All configurations are stored on your servers, so
|
||||
everything works without a connection to Last Hour Cloud (except integrations and automations).</p>
|
||||
<p><x-highlighted text="Monitoring:" />You can get notified on your favourite platforms (Discord,
|
||||
Telegram, Email, etc.) when something goes wrong, or an action is needed from your side.</p>
|
||||
</x-slot:explanation>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="explanation">Next
|
||||
</x-forms.button>
|
||||
</x-slot:actions>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
@if ($currentState === 'select-server-type')
|
||||
<x-boarding-step title="Server">
|
||||
<x-slot:question>
|
||||
Do you want to deploy your resources to your <x-highlighted text="Localhost" />
|
||||
or to a <x-highlighted text="Remote Server" />?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setServerType('localhost')"
|
||||
wire:click="setServerType('localhost')">Localhost
|
||||
</x-forms.button>
|
||||
<x-boarding-step title="Server">
|
||||
<x-slot:question>
|
||||
Do you want to deploy your resources to your <x-highlighted text="Localhost" />
|
||||
or to a <x-highlighted text="Remote Server" />?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setServerType('localhost')" wire:click="setServerType('localhost')">Localhost
|
||||
</x-forms.button>
|
||||
|
||||
<x-forms.button class="justify-center w-64 box " wire:target="setServerType('remote')"
|
||||
wire:click="setServerType('remote')">Remote Server
|
||||
</x-forms.button>
|
||||
@if (!$serverReachable)
|
||||
Localhost is not reachable with the following public key.
|
||||
<br /> <br />
|
||||
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for user
|
||||
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
||||
server.
|
||||
<br />
|
||||
Check this <a target="_blank" class="underline"
|
||||
href="https://coolify.io/docs/server/openssh">documentation</a> for further help.
|
||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||
<x-forms.button class="w-64 box" wire:target="setServerType('localhost')"
|
||||
wire:click="setServerType('localhost')">Check again
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Servers are the main building blocks, as they will host your applications, databases,
|
||||
services, called resources. Any CPU intensive process will use the server's CPU where you
|
||||
are deploying your resources.</p>
|
||||
<p>Localhost is the server where Coolify is running on. It is not recommended to use one server
|
||||
for everything.</p>
|
||||
<p>Remote Server is a server reachable through SSH. It can be hosted at home, or from any cloud
|
||||
provider.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
<x-forms.button class="justify-center w-64 box " wire:target="setServerType('remote')" wire:click="setServerType('remote')">Remote Server
|
||||
</x-forms.button>
|
||||
@if (!$serverReachable)
|
||||
Localhost is not reachable with the following public key.
|
||||
<br /> <br />
|
||||
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for user
|
||||
'root' or skip the onboarding process and add a new private key manually to Last Hour Cloud and to the
|
||||
server.
|
||||
<br />
|
||||
Check this upstream <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.
|
||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||
<x-forms.button class="w-64 box" wire:target="setServerType('localhost')" wire:click="setServerType('localhost')">Check again
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Servers are the main building blocks, as they will host your applications, databases,
|
||||
services, called resources. Any CPU intensive process will use the server's CPU where you
|
||||
are deploying your resources.</p>
|
||||
<p>Localhost is the server where Last Hour Cloud is running on. It is not recommended to use one server
|
||||
for everything.</p>
|
||||
<p>Remote Server is a server reachable through SSH. It can be hosted at home, or from any cloud
|
||||
provider.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'private-key')
|
||||
<x-boarding-step title="SSH Key">
|
||||
<x-slot:question>
|
||||
Do you have your own SSH Private Key?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('own')"
|
||||
wire:click="setPrivateKey('own')">Yes
|
||||
</x-forms.button>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('create')"
|
||||
wire:click="setPrivateKey('create')">No (create one for me)
|
||||
</x-forms.button>
|
||||
@if (count($privateKeys) > 0)
|
||||
<form wire:submit='selectExistingPrivateKey' class="flex flex-col w-full gap-4 pr-10">
|
||||
<x-forms.select label="Existing SSH Keys" id='selectedExistingPrivateKey'>
|
||||
@foreach ($privateKeys as $privateKey)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $privateKey->id }}">
|
||||
{{ $privateKey->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this SSH Key</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>SSH Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own ssh private key, or you can let Coolify to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your ssh private key to the remote
|
||||
server's
|
||||
<code class="text-warning">~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
<x-boarding-step title="SSH Key">
|
||||
<x-slot:question>
|
||||
Do you have your own SSH Private Key?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('own')" wire:click="setPrivateKey('own')">Yes
|
||||
</x-forms.button>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('create')" wire:click="setPrivateKey('create')">No (create one for me)
|
||||
</x-forms.button>
|
||||
@if (count($privateKeys) > 0)
|
||||
<form wire:submit='selectExistingPrivateKey' class="flex flex-col w-full gap-4 pr-10">
|
||||
<x-forms.select label="Existing SSH Keys" id='selectedExistingPrivateKey'>
|
||||
@foreach ($privateKeys as $privateKey)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $privateKey->id }}">
|
||||
{{ $privateKey->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this SSH Key</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>SSH Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own ssh private key, or you can let Last Hour Cloud to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your ssh private key to the remote
|
||||
server's
|
||||
<code class="text-warning">~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'select-existing-server')
|
||||
<x-boarding-step title="Select a server">
|
||||
<x-slot:question>
|
||||
There are already servers available for your Team. Do you want to use one of them?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewServer">No (create one
|
||||
for
|
||||
me)
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div>
|
||||
<form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing servers" class="w-96" id='selectedExistingServer'>
|
||||
@foreach ($servers as $server)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $server->id }}">
|
||||
{{ $server->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Server</x-forms.button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@if (!$serverReachable)
|
||||
This server is not reachable with the following public key.
|
||||
<br /> <br />
|
||||
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for user
|
||||
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
||||
server.
|
||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||
<x-forms.button class="w-64 box" wire:target="validateServer" wire:click="validateServer">Check
|
||||
again
|
||||
<x-boarding-step title="Select a server">
|
||||
<x-slot:question>
|
||||
There are already servers available for your Team. Do you want to use one of them?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewServer">No (create one
|
||||
for
|
||||
me)
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Private Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own private key, or you can let Coolify to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your private key to the remote server's
|
||||
<code>~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
</div>
|
||||
<div>
|
||||
<form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing servers" class="w-96" id='selectedExistingServer'>
|
||||
@foreach ($servers as $server)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $server->id }}">
|
||||
{{ $server->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Server</x-forms.button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@if (!$serverReachable)
|
||||
This server is not reachable with the following public key.
|
||||
<br /> <br />
|
||||
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for user
|
||||
'root' or skip the onboarding process and add a new private key manually to Last Hour Cloud and to the
|
||||
server.
|
||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||
<x-forms.button class="w-64 box" wire:target="validateServer" wire:click="validateServer">Check
|
||||
again
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Private Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own private key, or you can let Last Hour Cloud to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your private key to the remote server's
|
||||
<code>~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'create-private-key')
|
||||
<x-boarding-step title="Create Private Key">
|
||||
<x-slot:question>
|
||||
Please let me know your key details.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<form wire:submit='savePrivateKey' class="flex flex-col w-full gap-4 pr-10">
|
||||
<x-forms.input required placeholder="Choose a name for your Private Key. Could be anything."
|
||||
label="Name" id="privateKeyName" />
|
||||
<x-forms.input placeholder="Description, so others will know more about this."
|
||||
label="Description" id="privateKeyDescription" />
|
||||
<x-forms.textarea required placeholder="-----BEGIN OPENSSH PRIVATE KEY-----" label="Private Key"
|
||||
id="privateKey" />
|
||||
@if ($privateKeyType === 'create')
|
||||
<x-forms.textarea rows="7" readonly label="Public Key" id="publicKey" />
|
||||
<span class="font-bold text-warning">ACTION REQUIRED: Copy the 'Public Key' to your server's
|
||||
~/.ssh/authorized_keys
|
||||
file.</span>
|
||||
@endif
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
</form>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Private Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own private key, or you can let Coolify to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your private key to the remote server's
|
||||
<code>~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
<x-boarding-step title="Create Private Key">
|
||||
<x-slot:question>
|
||||
Please let me know your key details.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<form wire:submit='savePrivateKey' class="flex flex-col w-full gap-4 pr-10">
|
||||
<x-forms.input required placeholder="Choose a name for your Private Key. Could be anything." label="Name" id="privateKeyName" />
|
||||
<x-forms.input placeholder="Description, so others will know more about this." label="Description" id="privateKeyDescription" />
|
||||
<x-forms.textarea required placeholder="-----BEGIN OPENSSH PRIVATE KEY-----" label="Private Key" id="privateKey" />
|
||||
@if ($privateKeyType === 'create')
|
||||
<x-forms.textarea rows="7" readonly label="Public Key" id="publicKey" />
|
||||
<span class="font-bold text-warning">ACTION REQUIRED: Copy the 'Public Key' to your server's
|
||||
~/.ssh/authorized_keys
|
||||
file.</span>
|
||||
@endif
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
</form>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Private Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own private key, or you can let Last Hour Cloud to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your private key to the remote server's
|
||||
<code>~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'create-server')
|
||||
<x-boarding-step title="Create Server">
|
||||
<x-slot:question>
|
||||
Please let me know your server details.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<form wire:submit='saveServer' class="flex flex-col w-full gap-4 pr-10">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required placeholder="Choose a name for your Server. Could be anything."
|
||||
label="Name" id="remoteServerName" />
|
||||
<x-forms.input placeholder="Description, so others will know more about this."
|
||||
label="Description" id="remoteServerDescription" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required placeholder="127.0.0.1" label="IP Address" id="remoteServerHost" />
|
||||
<x-forms.input required placeholder="Port number of your server. Default is 22."
|
||||
label="Port" id="remoteServerPort" />
|
||||
<x-forms.input required readonly
|
||||
placeholder="Username to connect to your server. Default is root." label="Username"
|
||||
id="remoteServerUser" />
|
||||
</div>
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<br><span class='text-warning'>Coolify does not install/setup Cloudflare (cloudflared) on your server.</span>"
|
||||
id="isCloudflareTunnel" label="Cloudflare Tunnel" />
|
||||
</div>
|
||||
<x-forms.button type="submit">Continue</x-forms.button>
|
||||
</form>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Username should be <x-highlighted text="root" /> for now. We are working on to use
|
||||
non-root users.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
<x-boarding-step title="Create Server">
|
||||
<x-slot:question>
|
||||
Please let me know your server details.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<form wire:submit='saveServer' class="flex flex-col w-full gap-4 pr-10">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required placeholder="Choose a name for your Server. Could be anything." label="Name" id="remoteServerName" />
|
||||
<x-forms.input placeholder="Description, so others will know more about this." label="Description" id="remoteServerDescription" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required placeholder="127.0.0.1" label="IP Address" id="remoteServerHost" />
|
||||
<x-forms.input required placeholder="Port number of your server. Default is 22." label="Port" id="remoteServerPort" />
|
||||
<x-forms.input required readonly placeholder="Username to connect to your server. Default is root." label="Username" id="remoteServerUser" />
|
||||
</div>
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<br><span class='text-warning'>Last Hour Cloud does not install/setup Cloudflare (cloudflared) on your server.</span>" id="isCloudflareTunnel" label="Cloudflare Tunnel" />
|
||||
</div>
|
||||
<x-forms.button type="submit">Continue</x-forms.button>
|
||||
</form>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Username should be <x-highlighted text="root" /> for now. We are working on to use
|
||||
non-root users.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'validate-server')
|
||||
<x-boarding-step title="Validate & Configure Server">
|
||||
<x-slot:question>
|
||||
I need to validate your server (connection, Docker Engine, etc) and configure if something is
|
||||
missing for me. Are you okay with this?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Validate & configure</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$this->createdServer" />
|
||||
</x-slot:content>
|
||||
<x-forms.button @click="slideOverOpen=true" class="font-bold box w-96"
|
||||
wire:click.prevent='installServer' isHighlighted>
|
||||
Let's do it!
|
||||
</x-forms.button>
|
||||
</x-slide-over>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>This will install the latest Docker Engine on your server, configure a few things to be able
|
||||
to run optimal.<br><br>Minimum Docker Engine version is: 22<br><br>To manually install Docker
|
||||
Engine, check <a target="_blank" class="underline text-warning"
|
||||
href="https://docs.docker.com/engine/install/#server">this
|
||||
documentation</a>.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
<x-boarding-step title="Validate & Configure Server">
|
||||
<x-slot:question>
|
||||
I need to validate your server (connection, Docker Engine, etc) and configure if something is
|
||||
missing for me. Are you okay with this?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Validate & configure</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$this->createdServer" />
|
||||
</x-slot:content>
|
||||
<x-forms.button @click="slideOverOpen=true" class="font-bold box w-96" wire:click.prevent='installServer' isHighlighted>
|
||||
Let's do it!
|
||||
</x-forms.button>
|
||||
</x-slide-over>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>This will install the latest Docker Engine on your server, configure a few things to be able
|
||||
to run optimal.<br><br>Minimum Docker Engine version is: 22<br><br>To manually install Docker
|
||||
Engine, check <a target="_blank" class="underline text-warning" href="https://docs.docker.com/engine/install/#server">this
|
||||
documentation</a>.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
{{-- <div>
|
||||
@ -272,79 +256,79 @@
|
||||
Decide later
|
||||
</x-forms.button>
|
||||
<x-forms.button class="w-32 box" wire:click="selectProxy('{{ ProxyTypes::TRAEFIK_V2 }}')">
|
||||
Traefik
|
||||
v2
|
||||
</x-forms.button>
|
||||
<x-forms.button disabled class="w-32 box">
|
||||
Nginx
|
||||
</x-forms.button>
|
||||
<x-forms.button disabled class="w-32 box">
|
||||
Caddy
|
||||
</x-forms.button>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>This will install the latest Docker Engine on your server, configure a few things to be able
|
||||
to run optimal.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div> --}}
|
||||
<div>
|
||||
@if ($currentState === 'create-project')
|
||||
<x-boarding-step title="Project">
|
||||
<x-slot:question>
|
||||
@if (count($projects) > 0)
|
||||
You already have some projects. Do you want to use one of them or should I create a new one for
|
||||
you?
|
||||
@else
|
||||
Let's create an initial project for you. You can change all the details later on.
|
||||
@endif
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewProject">Create new
|
||||
project!</x-forms.button>
|
||||
<div>
|
||||
@if (count($projects) > 0)
|
||||
<form wire:submit='selectExistingProject' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing projects" class="w-96"
|
||||
id='selectedExistingProject'>
|
||||
@foreach ($projects as $project)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $project->id }}">
|
||||
{{ $project->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Project</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Projects contain several resources combined into one virtual group. There are no
|
||||
limitations on the number of projects you can add.</p>
|
||||
<p>Each project should have at least one environment, this allows you to create a production &
|
||||
staging version of the same application, but grouped separately.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'create-resource')
|
||||
<x-boarding-step title="Resources">
|
||||
<x-slot:question>
|
||||
Let's go to the new resource page, where you can create your first resource.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<div class="items-center justify-center w-64 box" wire:click="showNewResource">Let's do
|
||||
it!</div>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>A resource could be an application, a database or a service (like WordPress).</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex justify-center gap-2 pt-4">
|
||||
<a wire:click='skipBoarding'>Skip boarding process</a>
|
||||
<a wire:click='restartBoarding'>Restart boarding process</a>
|
||||
</div>
|
||||
Traefik
|
||||
v2
|
||||
</x-forms.button>
|
||||
<x-forms.button disabled class="w-32 box">
|
||||
Nginx
|
||||
</x-forms.button>
|
||||
<x-forms.button disabled class="w-32 box">
|
||||
Caddy
|
||||
</x-forms.button>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>This will install the latest Docker Engine on your server, configure a few things to be able
|
||||
to run optimal.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div> --}}
|
||||
<div>
|
||||
@if ($currentState === 'create-project')
|
||||
<x-boarding-step title="Project">
|
||||
<x-slot:question>
|
||||
@if (count($projects) > 0)
|
||||
You already have some projects. Do you want to use one of them or should I create a new one for
|
||||
you?
|
||||
@else
|
||||
Let's create an initial project for you. You can change all the details later on.
|
||||
@endif
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewProject">Create new
|
||||
project!</x-forms.button>
|
||||
<div>
|
||||
@if (count($projects) > 0)
|
||||
<form wire:submit='selectExistingProject' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing projects" class="w-96" id='selectedExistingProject'>
|
||||
@foreach ($projects as $project)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $project->id }}">
|
||||
{{ $project->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Project</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Projects contain several resources combined into one virtual group. There are no
|
||||
limitations on the number of projects you can add.</p>
|
||||
<p>Each project should have at least one environment, this allows you to create a production &
|
||||
staging version of the same application, but grouped separately.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'create-resource')
|
||||
<x-boarding-step title="Resources">
|
||||
<x-slot:question>
|
||||
Let's go to the new resource page, where you can create your first resource.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<div class="items-center justify-center w-64 box" wire:click="showNewResource">Let's do
|
||||
it!</div>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>A resource could be an application, a database or a service (like WordPress).</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex justify-center gap-2 pt-4">
|
||||
<a wire:click='skipBoarding'>Skip Guided Tour</a>
|
||||
<a wire:click='restartBoarding'>Restart Guided Tour</a>
|
||||
</div>
|
||||
</div>
|
@ -91,7 +91,7 @@
|
||||
&
|
||||
@endif
|
||||
@if (!$server->settings->is_usable)
|
||||
<span>Not usable by Coolify</span>
|
||||
<span>Not usable by Last Hour Cloud</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="w-96 min-w-fit">
|
||||
<div class="flex flex-col items-center">
|
||||
<a href="{{ route('dashboard') }}">
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Coolify</div>
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Last Hour Cloud</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="flex flex-col w-11/12 max-w-5xl gap-2 modal-box">
|
||||
<h3>How can we help?</h3>
|
||||
<div>Your feedback helps us to improve Coolify. Thank you! 💜</div>
|
||||
<div>Give us feedback or ask a question and our team will get back to you within 24 hours.</div>
|
||||
<form wire:submit="submit" class="flex flex-col gap-4 pt-4">
|
||||
<x-forms.input id="subject" label="Subject" placeholder="Summary of your problem."></x-forms.input>
|
||||
<x-forms.textarea rows="10" id="description" label="Description"
|
||||
|
@ -1,36 +1,31 @@
|
||||
<div>
|
||||
@if (data_get(auth()->user(), 'is_notification_sponsorship_enabled'))
|
||||
<div class="toast">
|
||||
<div class="flex flex-col text-white rounded alert bg-coolgray-200">
|
||||
<span>Love Coolify as we do? <a href="https://coolify.io/sponsorships"
|
||||
class="underline text-warning">Please
|
||||
consider donating!</a>💜</span>
|
||||
<span>It enables us to keep creating features without paywalls, ensuring our work remains free and
|
||||
open.</span>
|
||||
<x-forms.button class="bg-coolgray-400" wire:click='disableSponsorship'>Disable This
|
||||
Popup</x-forms.button>
|
||||
</div>
|
||||
<div class="toast">
|
||||
<div class="flex flex-col text-white rounded alert bg-coolgray-200">
|
||||
<span>Like Last Hour Cloud? <a href="https://lasthourhosting.org/" class="underline text-warning">Please
|
||||
consider sharing about us!</a></span>
|
||||
<span>Your support enables us to keep creating services that support sharing the Gospel of Jesus Christ. 1 John 2:18</span>
|
||||
<x-forms.button class="bg-coolgray-400" wire:click='disableSponsorship'>Disable This Popup</x-forms.button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@if (currentTeam()->serverOverflow())
|
||||
<x-banner :closable=false>
|
||||
<div><span class="font-bold text-red-500">WARNING:</span> The number of active servers exceeds the limit
|
||||
covered by your payment. If not resolved, some of your servers <span class="font-bold text-red-500">will
|
||||
be deactivated</span>. Visit <a href="{{ route('subscription.show') }}"
|
||||
class="text-white underline">/subscription</a> to update your subscription or remove some servers.
|
||||
</div>
|
||||
</x-banner>
|
||||
<x-banner :closable=false>
|
||||
<div><span class="font-bold text-red-500">WARNING:</span> The number of active servers exceeds the limit
|
||||
covered by your payment. If not resolved, some of your servers <span class="font-bold text-red-500">will
|
||||
be deactivated</span>. Visit <a href="{{ route('subscription.show') }}" class="text-white underline">/subscription</a> to update your subscription or remove some servers.
|
||||
</div>
|
||||
</x-banner>
|
||||
@endif
|
||||
@if (!currentTeam()->isAnyNotificationEnabled())
|
||||
<div class="toast">
|
||||
<div class="flex flex-col text-white rounded alert bg-coolgray-200">
|
||||
<span><span class="font-bold text-red-500">WARNING:</span> No notifications enabled.<br><br> It is highly recommended to enable at least
|
||||
one
|
||||
notification channel to receive important alerts.<br>Visit <a href="{{ route('notification.index') }}"
|
||||
class="text-white underline">/notification</a> to enable notifications.</span>
|
||||
<x-forms.button class="bg-coolgray-400" wire:click='disableNotifications'>Disable This
|
||||
Popup</x-forms.button>
|
||||
</div>
|
||||
<div class="toast">
|
||||
<div class="flex flex-col text-white rounded alert bg-coolgray-200">
|
||||
<span><span class="font-bold text-red-500">WARNING:</span> No notifications enabled.<br><br> It is highly recommended to enable at least
|
||||
one
|
||||
notification channel to receive important alerts.<br>Visit <a href="{{ route('notification.index') }}" class="text-white underline">/notification</a> to enable notifications.</span>
|
||||
<x-forms.button class="bg-coolgray-400" wire:click='disableNotifications'>Disable This
|
||||
Popup</x-forms.button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
@ -1,7 +1,7 @@
|
||||
<dialog id="newEmptyProject" class="modal">
|
||||
<form method="dialog" class="flex flex-col gap-2 rounded modal-box" wire:submit='submit'>
|
||||
<x-forms.input placeholder="Your Cool Project" id="name" label="Name" required />
|
||||
<x-forms.input placeholder="This is my cool project everyone knows about" id="description" label="Description" />
|
||||
<x-forms.input placeholder="Your New Project" id="name" label="Name" required />
|
||||
<x-forms.input placeholder="This is my new project" id="description" label="Description" />
|
||||
<x-forms.button onclick="newEmptyProject.close()" type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@ -9,4 +9,4 @@
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
</dialog>
|
@ -6,12 +6,11 @@
|
||||
Save
|
||||
</x-forms.button>
|
||||
@if ($isConfigurationChanged && !is_null($application->config_hash) && !$application->isExited())
|
||||
<div title="Configuration not applied to the running application. You need to redeploy.">
|
||||
<svg class="w-6 h-6 text-warning" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16" />
|
||||
</svg>
|
||||
</div>
|
||||
<div title="Configuration not applied to the running application. You need to redeploy.">
|
||||
<svg class="w-6 h-6 text-warning" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16" />
|
||||
</svg>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div>General configuration for your application.</div>
|
||||
@ -22,249 +21,191 @@
|
||||
</div>
|
||||
|
||||
@if (!$application->dockerfile && $application->build_pack !== 'dockerimage')
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.select wire:model.live="application.build_pack" label="Build Pack" required>
|
||||
<option value="nixpacks">Nixpacks</option>
|
||||
<option value="static">Static</option>
|
||||
<option value="dockerfile">Dockerfile</option>
|
||||
<option value="dockercompose">Docker Compose</option>
|
||||
</x-forms.select>
|
||||
@if ($application->settings->is_static || $application->build_pack === 'static')
|
||||
<x-forms.select id="application.static_image" label="Static Image" required>
|
||||
<option value="nginx:alpine">nginx:alpine</option>
|
||||
<option disabled value="apache:alpine">apache:alpine</option>
|
||||
</x-forms.select>
|
||||
@endif
|
||||
</div>
|
||||
@if ($application->could_set_build_commands())
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox instantSave id="application.settings.is_static"
|
||||
label="Is it a static site?"
|
||||
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
|
||||
</div>
|
||||
@endif
|
||||
@if ($application->build_pack === 'dockercompose')
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave id="application.settings.is_raw_compose_deployment_enabled"
|
||||
label="Raw Compose Deployment"
|
||||
helper="WARNING: Advanced use cases only. Your docker compose file will be deployed as-is. Nothing is modified by Coolify. You need to configure the proxy parts. More info in the <a href='https://coolify.io/docs/docker/compose#raw-docker-compose-deployment'>documentation.</a>" />
|
||||
</div>
|
||||
@if (count($parsedServices) > 0 && !$application->settings->is_raw_compose_deployment_enabled)
|
||||
@foreach (data_get($parsedServices, 'services') as $serviceName => $service)
|
||||
@if (!isDatabaseImage(data_get($service, 'image')))
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input
|
||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. "
|
||||
label="Domains for {{ str($serviceName)->headline() }}"
|
||||
id="parsedServiceDomains.{{ $serviceName }}.domain"></x-forms.input>
|
||||
@if (!data_get($parsedServiceDomains, "$serviceName.domain"))
|
||||
<x-forms.button wire:click="generateDomain('{{ $serviceName }}')">Generate
|
||||
Domain</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.select wire:model.live="application.build_pack" label="Build Pack" required>
|
||||
<option value="nixpacks">Nixpacks</option>
|
||||
<option value="static">Static</option>
|
||||
<option value="dockerfile">Dockerfile</option>
|
||||
<option value="dockercompose">Docker Compose</option>
|
||||
</x-forms.select>
|
||||
@if ($application->settings->is_static || $application->build_pack === 'static')
|
||||
<x-forms.select id="application.static_image" label="Static Image" required>
|
||||
<option value="nginx:alpine">nginx:alpine</option>
|
||||
<option disabled value="apache:alpine">apache:alpine</option>
|
||||
</x-forms.select>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@if ($application->build_pack !== 'dockercompose')
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="https://coolify.io" id="application.fqdn" label="Domains"
|
||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. " />
|
||||
<x-forms.button wire:click="getWildcardDomain">Generate Domain
|
||||
</x-forms.button>
|
||||
@if ($application->could_set_build_commands())
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox instantSave id="application.settings.is_static" label="Is it a static site?" helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
|
||||
</div>
|
||||
@endif
|
||||
@if ($application->build_pack !== 'dockercompose')
|
||||
<div class="flex items-center gap-2 pt-8">
|
||||
<h3>Docker Registry</h3>
|
||||
@if ($application->build_pack !== 'dockerimage' && !$application->destination->server->isSwarm())
|
||||
<x-helper
|
||||
helper='Push the built image to a docker registry. More info <a class="underline"
|
||||
href="https://coolify.io/docs/docker/registry" target="_blank">here</a>' />
|
||||
@endif
|
||||
</div>
|
||||
@if ($application->destination->server->isSwarm())
|
||||
@if ($application->build_pack !== 'dockerimage')
|
||||
<div>Docker Swarm requires the image to be available in a registry. More info <a
|
||||
class="underline" href="https://coolify.io/docs/docker/registry"
|
||||
target="_blank">here</a>.</div>
|
||||
@endif
|
||||
@endif
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
@if ($application->build_pack === 'dockerimage')
|
||||
@if ($application->destination->server->isSwarm())
|
||||
<x-forms.input required id="application.docker_registry_image_name" label="Docker Image" />
|
||||
<x-forms.input id="application.docker_registry_image_tag" label="Docker Image Tag" />
|
||||
@else
|
||||
<x-forms.input id="application.docker_registry_image_name" label="Docker Image" />
|
||||
<x-forms.input id="application.docker_registry_image_tag" label="Docker Image Tag" />
|
||||
@endif
|
||||
@else
|
||||
@if (
|
||||
$application->destination->server->isSwarm() ||
|
||||
$application->additional_servers->count() > 0 ||
|
||||
$application->settings->is_build_server_enabled)
|
||||
<x-forms.input id="application.docker_registry_image_name" required label="Docker Image"
|
||||
placeholder="Required!" />
|
||||
<x-forms.input id="application.docker_registry_image_tag"
|
||||
helper="If set, it will tag the built image with this tag too. <br><br>Example: If you set it to 'latest', it will push the image with the commit sha tag + with the latest tag."
|
||||
placeholder="Empty means latest will be used." label="Docker Image Tag" />
|
||||
@else
|
||||
<x-forms.input id="application.docker_registry_image_name"
|
||||
helper="Empty means it won't push the image to a docker registry."
|
||||
placeholder="Empty means it won't push the image to a docker registry."
|
||||
label="Docker Image" />
|
||||
<x-forms.input id="application.docker_registry_image_tag"
|
||||
placeholder="Empty means only push commit sha tag."
|
||||
helper="If set, it will tag the built image with this tag too. <br><br>Example: If you set it to 'latest', it will push the image with the commit sha tag + with the latest tag."
|
||||
label="Docker Image Tag" />
|
||||
@endif
|
||||
@if ($application->build_pack === 'dockercompose')
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave id="application.settings.is_raw_compose_deployment_enabled" label="Raw Compose Deployment" helper="WARNING: Advanced use cases only. Your docker compose file will be deployed as-is. Nothing is modified by Coolify. You need to configure the proxy parts. More info in the <a href='https://coolify.io/docs/docker/compose#raw-docker-compose-deployment'>documentation.</a>" />
|
||||
</div>
|
||||
@if (count($parsedServices) > 0 && !$application->settings->is_raw_compose_deployment_enabled)
|
||||
@foreach (data_get($parsedServices, 'services') as $serviceName => $service)
|
||||
@if (!isDatabaseImage(data_get($service, 'image')))
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. " label="Domains for {{ str($serviceName)->headline() }}" id="parsedServiceDomains.{{ $serviceName }}.domain"></x-forms.input>
|
||||
@if (!data_get($parsedServiceDomains, "$serviceName.domain"))
|
||||
<x-forms.button wire:click="generateDomain('{{ $serviceName }}')">Generate
|
||||
Domain</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@if ($application->build_pack !== 'dockercompose')
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="https://lasthourhosting.org" id="application.fqdn" label="Domains" helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.lasthourhosting.org, https://cloud.lasthourhosting.org/dashboard<br>- http://app.lasthourhosting.org/api/v3<br>- http://app.lasthourhosting.org:3000 -> app.lasthourhosting.org will point to port 3000 inside the container. " />
|
||||
<x-forms.button wire:click="getWildcardDomain">Generate Domain
|
||||
</x-forms.button>
|
||||
</div>
|
||||
@endif
|
||||
@if ($application->build_pack !== 'dockercompose')
|
||||
<div class="flex items-center gap-2 pt-8">
|
||||
<h3>Docker Registry</h3>
|
||||
@if ($application->build_pack !== 'dockerimage' && !$application->destination->server->isSwarm())
|
||||
<x-helper helper='Push the built image to a docker registry. More info <a class="underline"
|
||||
href="https://coolify.io/docs/docker/registry" target="_blank">here</a>' />
|
||||
@endif
|
||||
</div>
|
||||
@if ($application->destination->server->isSwarm())
|
||||
@if ($application->build_pack !== 'dockerimage')
|
||||
<div>Docker Swarm requires the image to be available in a registry. More info in upstream docs<a class="underline" href="https://coolify.io/docs/docker/registry" target="_blank">here</a>.</div>
|
||||
@endif
|
||||
@endif
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
@if ($application->build_pack === 'dockerimage')
|
||||
@if ($application->destination->server->isSwarm())
|
||||
<x-forms.input required id="application.docker_registry_image_name" label="Docker Image" />
|
||||
<x-forms.input id="application.docker_registry_image_tag" label="Docker Image Tag" />
|
||||
@else
|
||||
<x-forms.input id="application.docker_registry_image_name" label="Docker Image" />
|
||||
<x-forms.input id="application.docker_registry_image_tag" label="Docker Image Tag" />
|
||||
@endif
|
||||
@else
|
||||
@if (
|
||||
$application->destination->server->isSwarm() ||
|
||||
$application->additional_servers->count() > 0 ||
|
||||
$application->settings->is_build_server_enabled)
|
||||
<x-forms.input id="application.docker_registry_image_name" required label="Docker Image" placeholder="Required!" />
|
||||
<x-forms.input id="application.docker_registry_image_tag" helper="If set, it will tag the built image with this tag too. <br><br>Example: If you set it to 'latest', it will push the image with the commit sha tag + with the latest tag." placeholder="Empty means latest will be used." label="Docker Image Tag" />
|
||||
@else
|
||||
<x-forms.input id="application.docker_registry_image_name" helper="Empty means it won't push the image to a docker registry." placeholder="Empty means it won't push the image to a docker registry." label="Docker Image" />
|
||||
<x-forms.input id="application.docker_registry_image_tag" placeholder="Empty means only push commit sha tag." helper="If set, it will tag the built image with this tag too. <br><br>Example: If you set it to 'latest', it will push the image with the commit sha tag + with the latest tag." label="Docker Image Tag" />
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($application->build_pack !== 'dockerimage')
|
||||
<h3 class="pt-8">Build</h3>
|
||||
@if ($application->build_pack !== 'dockercompose')
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox
|
||||
helper="Use a build server to build your application. You can configure your build server in the Server settings. This is experimental. For more info, check the <a href='https://coolify.io/docs/server/build-server' class='underline' target='_blank'>documentation</a>."
|
||||
instantSave id="application.settings.is_build_server_enabled"
|
||||
label="Use a Build Server? (experimental)" />
|
||||
</div>
|
||||
@endif
|
||||
@if ($application->could_set_build_commands())
|
||||
@if ($application->build_pack === 'nixpacks')
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
<x-forms.input placeholder="If you modify this, you probably need to have a nixpacks.toml"
|
||||
id="application.install_command" label="Install Command" />
|
||||
<x-forms.input placeholder="If you modify this, you probably need to have a nixpacks.toml"
|
||||
id="application.build_command" label="Build Command" />
|
||||
<x-forms.input placeholder="If you modify this, you probably need to have a nixpacks.toml"
|
||||
id="application.start_command" label="Start Command" />
|
||||
</div>
|
||||
<div>Nixpacks will detect the required configuration automatically.
|
||||
<a class="underline" href="https://coolify.io/docs/frameworks/">Framework Specific Docs</a>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
@if ($application->build_pack === 'dockercompose')
|
||||
<div class="flex flex-col gap-2" wire:init='loadComposeFile(true)'>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input placeholder="/" id="application.base_directory" label="Base Directory"
|
||||
helper="Directory to use as root. Useful for monorepos." />
|
||||
<x-forms.input placeholder="/docker-compose.yaml" id="application.docker_compose_location"
|
||||
label="Docker Compose Location"
|
||||
helper="It is calculated together with the Base Directory:<br><span class='text-warning'>{{ Str::start($application->base_directory . $application->docker_compose_location, '/') }}</span>" />
|
||||
</div>
|
||||
<div class="pt-4">The following commands are for advanced use cases. Only modify them if you
|
||||
know what are
|
||||
you doing.</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input placeholder="docker compose build"
|
||||
id="application.docker_compose_custom_build_command"
|
||||
helper="If you use this, you need to specify paths relatively and should use the same compose file in the custom command, otherwise the automatically configured labels / etc won't work.<br><br>So in your case, use: <span class='text-warning'>docker compose -f .{{ Str::start($application->base_directory . $application->docker_compose_location, '/') }} build</span>"
|
||||
label="Custom Build Command" />
|
||||
<x-forms.input placeholder="docker compose up -d"
|
||||
id="application.docker_compose_custom_start_command"
|
||||
helper="If you use this, you need to specify paths relatively and should use the same compose file in the custom command, otherwise the automatically configured labels / etc won't work.<br><br>So in your case, use: <span class='text-warning'>docker compose -f .{{ Str::start($application->base_directory . $application->docker_compose_location, '/') }} up -d</span>"
|
||||
label="Custom Start Command" />
|
||||
{{-- <x-forms.input placeholder="/docker-compose.yaml" id="application.docker_compose_pr_location"
|
||||
label="Docker Compose Location For Pull Requests"
|
||||
helper="It is calculated together with the Base Directory:<br><span class='text-warning'>{{ Str::start($application->base_directory . $application->docker_compose_pr_location, '/') }}</span>" /> --}}
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
<x-forms.input placeholder="/" id="application.base_directory" label="Base Directory"
|
||||
helper="Directory to use as root. Useful for monorepos." />
|
||||
@if ($application->build_pack === 'dockerfile' && !$application->dockerfile)
|
||||
<x-forms.input placeholder="/Dockerfile" id="application.dockerfile_location"
|
||||
label="Dockerfile Location"
|
||||
helper="It is calculated together with the Base Directory:<br><span class='text-warning'>{{ Str::start($application->base_directory . $application->dockerfile_location, '/') }}</span>" />
|
||||
@endif
|
||||
|
||||
@if ($application->build_pack === 'dockerfile')
|
||||
<x-forms.input id="application.dockerfile_target_build" label="Docker Build Stage Target"
|
||||
helper="Useful if you have multi-staged dockerfile." />
|
||||
@endif
|
||||
@if ($application->could_set_build_commands())
|
||||
@if ($application->settings->is_static)
|
||||
<x-forms.input placeholder="/dist" id="application.publish_directory"
|
||||
label="Publish Directory" required />
|
||||
@else
|
||||
<x-forms.input placeholder="/" id="application.publish_directory"
|
||||
label="Publish Directory" />
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
<div>The following options are for advanced use cases. Only modify them if you
|
||||
know what are
|
||||
you doing.</div>
|
||||
<x-forms.input
|
||||
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='text-white underline' href='https://coolify.io/docs/custom-docker-options'>docs.</a>"
|
||||
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k"
|
||||
id="application.custom_docker_run_options" label="Custom Docker Options" />
|
||||
@endif
|
||||
@else
|
||||
<x-forms.input
|
||||
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='text-white underline' href='https://coolify.io/docs/custom-docker-options'>docs.</a>"
|
||||
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k"
|
||||
id="application.custom_docker_run_options" label="Custom Docker Options" />
|
||||
<h3 class="pt-8">Build</h3>
|
||||
@if ($application->build_pack !== 'dockercompose')
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox helper="Use a build server to build your application. You can configure your build server in the Server settings. This is experimental. For more info, check the upstream <a href='https://coolify.io/docs/server/build-server' class='underline' target='_blank'>documentation</a>." instantSave id="application.settings.is_build_server_enabled" label="Use a Build Server? (experimental)" />
|
||||
</div>
|
||||
@endif
|
||||
@if ($application->could_set_build_commands())
|
||||
@if ($application->build_pack === 'nixpacks')
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
<x-forms.input placeholder="If you modify this, you probably need to have a nixpacks.toml" id="application.install_command" label="Install Command" />
|
||||
<x-forms.input placeholder="If you modify this, you probably need to have a nixpacks.toml" id="application.build_command" label="Build Command" />
|
||||
<x-forms.input placeholder="If you modify this, you probably need to have a nixpacks.toml" id="application.start_command" label="Start Command" />
|
||||
</div>
|
||||
<div>Nixpacks will detect the required configuration automatically.
|
||||
<a class="underline" href="https://coolify.io/docs/frameworks/">Framework Specific Upstream Docs</a>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
@if ($application->build_pack === 'dockercompose')
|
||||
<x-forms.button wire:click="loadComposeFile">Reload Compose File</x-forms.button>
|
||||
@if ($application->settings->is_raw_compose_deployment_enabled)
|
||||
<x-forms.textarea rows="10" readonly id="application.docker_compose_raw"
|
||||
label="Docker Compose Content (applicationId: {{ $application->id }})"
|
||||
helper="You need to modify the docker compose file." />
|
||||
@else
|
||||
<x-forms.textarea rows="10" readonly id="application.docker_compose"
|
||||
label="Docker Compose Content" helper="You need to modify the docker compose file." />
|
||||
<div class="flex flex-col gap-2" wire:init='loadComposeFile(true)'>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input placeholder="/" id="application.base_directory" label="Base Directory" helper="Directory to use as root. Useful for monorepos." />
|
||||
<x-forms.input placeholder="/docker-compose.yaml" id="application.docker_compose_location" label="Docker Compose Location" helper="It is calculated together with the Base Directory:<br><span class='text-warning'>{{ Str::start($application->base_directory . $application->docker_compose_location, '/') }}</span>" />
|
||||
</div>
|
||||
<div class="pt-4">The following commands are for advanced use cases. Only modify them if you
|
||||
know what are
|
||||
you doing.</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input placeholder="docker compose build" id="application.docker_compose_custom_build_command" helper="If you use this, you need to specify paths relatively and should use the same compose file in the custom command, otherwise the automatically configured labels / etc won't work.<br><br>So in your case, use: <span class='text-warning'>docker compose -f .{{ Str::start($application->base_directory . $application->docker_compose_location, '/') }} build</span>" label="Custom Build Command" />
|
||||
<x-forms.input placeholder="docker compose up -d" id="application.docker_compose_custom_start_command" helper="If you use this, you need to specify paths relatively and should use the same compose file in the custom command, otherwise the automatically configured labels / etc won't work.<br><br>So in your case, use: <span class='text-warning'>docker compose -f .{{ Str::start($application->base_directory . $application->docker_compose_location, '/') }} up -d</span>" label="Custom Start Command" />
|
||||
{{-- <x-forms.input placeholder="/docker-compose.yaml" id="application.docker_compose_pr_location"
|
||||
label="Docker Compose Location For Pull Requests"
|
||||
helper="It is calculated together with the Base Directory:<br><span class='text-warning'>{{ Str::start($application->base_directory . $application->docker_compose_pr_location, '/') }}</span>" /> --}}
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
<x-forms.input placeholder="/" id="application.base_directory" label="Base Directory" helper="Directory to use as root. Useful for monorepos." />
|
||||
@if ($application->build_pack === 'dockerfile' && !$application->dockerfile)
|
||||
<x-forms.input placeholder="/Dockerfile" id="application.dockerfile_location" label="Dockerfile Location" helper="It is calculated together with the Base Directory:<br><span class='text-warning'>{{ Str::start($application->base_directory . $application->dockerfile_location, '/') }}</span>" />
|
||||
@endif
|
||||
{{-- <x-forms.textarea rows="10" readonly id="application.docker_compose_pr"
|
||||
|
||||
@if ($application->build_pack === 'dockerfile')
|
||||
<x-forms.input id="application.dockerfile_target_build" label="Docker Build Stage Target" helper="Useful if you have multi-staged dockerfile." />
|
||||
@endif
|
||||
@if ($application->could_set_build_commands())
|
||||
@if ($application->settings->is_static)
|
||||
<x-forms.input placeholder="/dist" id="application.publish_directory" label="Publish Directory" required />
|
||||
@else
|
||||
<x-forms.input placeholder="/" id="application.publish_directory" label="Publish Directory" />
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
<div>The following options are for advanced use cases. Only modify them if you
|
||||
know what are
|
||||
you doing.</div>
|
||||
<x-forms.input helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='text-white underline' href='https://coolify.io/docs/custom-docker-options'>docs.</a>" placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k" id="application.custom_docker_run_options" label="Custom Docker Options" />
|
||||
@endif
|
||||
@else
|
||||
<x-forms.input helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='text-white underline' href='https://coolify.io/docs/custom-docker-options'>docs.</a>" placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k" id="application.custom_docker_run_options" label="Custom Docker Options" />
|
||||
@endif
|
||||
@if ($application->build_pack === 'dockercompose')
|
||||
<x-forms.button wire:click="loadComposeFile">Reload Compose File</x-forms.button>
|
||||
@if ($application->settings->is_raw_compose_deployment_enabled)
|
||||
<x-forms.textarea rows="10" readonly id="application.docker_compose_raw" label="Docker Compose Content (applicationId: {{ $application->id }})" helper="You need to modify the docker compose file." />
|
||||
@else
|
||||
<x-forms.textarea rows="10" readonly id="application.docker_compose" label="Docker Compose Content" helper="You need to modify the docker compose file." />
|
||||
@endif
|
||||
{{-- <x-forms.textarea rows="10" readonly id="application.docker_compose_pr"
|
||||
label="Docker PR Compose Content" helper="You need to modify the docker compose file." /> --}}
|
||||
@endif
|
||||
|
||||
@if ($application->dockerfile)
|
||||
<x-forms.textarea label="Dockerfile" id="application.dockerfile" rows="6"> </x-forms.textarea>
|
||||
<x-forms.textarea label="Dockerfile" id="application.dockerfile" rows="6"> </x-forms.textarea>
|
||||
@endif
|
||||
@if ($application->build_pack !== 'dockercompose')
|
||||
<h3 class="pt-8">Network</h3>
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
@if ($application->settings->is_static || $application->build_pack === 'static')
|
||||
<x-forms.input id="application.ports_exposes" label="Ports Exposes" readonly />
|
||||
@else
|
||||
<x-forms.input placeholder="3000,3001" id="application.ports_exposes" label="Ports Exposes"
|
||||
required
|
||||
helper="A comma separated list of ports your application uses. The first port will be used as default healthcheck port if nothing defined in the Healthcheck menu. Be sure to set this correctly." />
|
||||
@endif
|
||||
@if (!$application->destination->server->isSwarm())
|
||||
<x-forms.input placeholder="3000:3000" id="application.ports_mappings" label="Ports Mappings"
|
||||
helper="A comma separated list of ports you would like to map to the host system. Useful when you do not want to use domains.<br><br><span class='inline-block font-bold text-warning'>Example:</span><br>3000:3000,3002:3002<br><br>Rolling update is not supported if you have a port mapped to the host." />
|
||||
@endif
|
||||
</div>
|
||||
<x-forms.textarea label="Container Labels" rows="15" id="customLabels"></x-forms.textarea>
|
||||
<x-forms.button wire:click="resetDefaultLabels">Reset to Coolify Generated Labels</x-forms.button>
|
||||
<h3 class="pt-8">Network</h3>
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
@if ($application->settings->is_static || $application->build_pack === 'static')
|
||||
<x-forms.input id="application.ports_exposes" label="Ports Exposes" readonly />
|
||||
@else
|
||||
<x-forms.input placeholder="3000,3001" id="application.ports_exposes" label="Ports Exposes" required helper="A comma separated list of ports your application uses. The first port will be used as default healthcheck port if nothing defined in the Healthcheck menu. Be sure to set this correctly." />
|
||||
@endif
|
||||
@if (!$application->destination->server->isSwarm())
|
||||
<x-forms.input placeholder="3000:3000" id="application.ports_mappings" label="Ports Mappings" helper="A comma separated list of ports you would like to map to the host system. Useful when you do not want to use domains.<br><br><span class='inline-block font-bold text-warning'>Example:</span><br>3000:3000,3002:3002<br><br>Rolling update is not supported if you have a port mapped to the host." />
|
||||
@endif
|
||||
</div>
|
||||
<x-forms.textarea label="Container Labels" rows="15" id="customLabels"></x-forms.textarea>
|
||||
<x-forms.button wire:click="resetDefaultLabels">Reset to Last Hour Generated Labels</x-forms.button>
|
||||
@endif
|
||||
|
||||
<h3 class="pt-8">Pre/Post Deployment Commands</h3>
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
<x-forms.input id="application.pre_deployment_command" label="Pre-deployment Command"
|
||||
helper="An optional script or command to execute in the existing container before the deployment begins." />
|
||||
<x-forms.input id="application.pre_deployment_command_container" label="Container Name"
|
||||
helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
|
||||
<x-forms.input id="application.pre_deployment_command" label="Pre-deployment Command" helper="An optional script or command to execute in the existing container before the deployment begins." />
|
||||
<x-forms.input id="application.pre_deployment_command_container" label="Container Name" helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
<x-forms.input placeholder="php artisan migrate" id="application.post_deployment_command"
|
||||
label="Post-deployment Command"
|
||||
helper="An optional script or command to execute in the newly built container after the deployment completes." />
|
||||
<x-forms.input id="application.post_deployment_command_container" label="Container Name"
|
||||
helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
|
||||
<x-forms.input placeholder="php artisan migrate" id="application.post_deployment_command" label="Post-deployment Command" helper="An optional script or command to execute in the newly built container after the deployment completes." />
|
||||
<x-forms.input id="application.post_deployment_command_container" label="Container Name" helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -26,7 +26,7 @@ class="font-normal text-white normal-case border-none rounded btn btn-primary bt
|
||||
</div>
|
||||
<div class="flex items-center gap-2 pb-4">You can use these variables anywhere with <span
|
||||
class="text-warning">@{{ project.VARIABLENAME }}</span><x-helper
|
||||
helper="More info <a class='text-white underline' href='https://coolify.io/docs/environment-variables#shared-variables' target='_blank'>here</a>."></x-helper>
|
||||
helper="More info in upstream docs <a class='text-white underline' href='https://coolify.io/docs/environment-variables#shared-variables' target='_blank'>here</a>."></x-helper>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
@forelse ($project->environment_variables->sort()->sortBy('real_value') as $env)
|
||||
|
@ -55,7 +55,7 @@ class="font-normal text-white normal-case border-none rounded btn btn-primary bt
|
||||
</x-slide-over>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 pb-4">You can use these variables anywhere with <span class="text-warning">@{{environment.VARIABLENAME}}</span><x-helper
|
||||
helper="More info <a class='text-white underline' href='https://coolify.io/docs/environment-variables#shared-variables' target='_blank'>here</a>."></x-helper>
|
||||
helper="More info in upstream docs<a class='text-white underline' href='https://coolify.io/docs/environment-variables#shared-variables' target='_blank'>here</a>."></x-helper>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
@forelse ($environment->environment_variables->sort()->sortBy('real_value') as $env)
|
||||
|
@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<x-forms.textarea label="Docker Compose file"
|
||||
helper="
|
||||
You can use these variables in your Docker Compose file and Coolify will generate default values or replace them with the values you set on the UI forms.<br>
|
||||
You can use these variables in your Docker Compose file and Last Hour Cloud will generate default values or replace them with the values you set on the UI forms.<br>
|
||||
<br>
|
||||
- SERVICE_FQDN_*: FQDN - could be changeable from the UI. (example: SERVICE_FQDN_GHOST)<br>
|
||||
- SERVICE_URL_*: URL parsed from FQDN - could be changeable from the UI. (example: SERVICE_URL_GHOST)<br>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div class="w-96">
|
||||
<x-forms.select wire:model="selectedEnvironment">
|
||||
@foreach ($environments as $environment)
|
||||
<option value="{{ $environment->name }}">Environment: {{ $environment->name }}</option>
|
||||
<option value="{{ $environment->name }}">Environment: {{ $environment->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
</div>
|
||||
@ -12,147 +12,136 @@
|
||||
<div class="pb-4 ">Deploy resources, like Applications, Databases, Services...</div>
|
||||
<div class="flex flex-col gap-4 pt-10 sm:px-20">
|
||||
@if ($current_step === 'type')
|
||||
<ul class="pb-10 steps">
|
||||
<li class="step step-secondary">Select Resource Type</li>
|
||||
<li class="step">Select a Server</li>
|
||||
<li class="step">Select a Destination</li>
|
||||
</ul>
|
||||
<h2>Applications</h2>
|
||||
<div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
|
||||
<x-resource-view wire="setType('public')">
|
||||
<x-slot:title>Public Repository</x-slot>
|
||||
<ul class="pb-10 steps">
|
||||
<li class="step step-secondary">Select Resource Type</li>
|
||||
<li class="step">Select a Server</li>
|
||||
<li class="step">Select a Destination</li>
|
||||
</ul>
|
||||
<h2>Applications</h2>
|
||||
<div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
|
||||
<x-resource-view wire="setType('public')">
|
||||
<x-slot:title>Public Repository</x-slot>
|
||||
<x-slot:description>
|
||||
You can deploy any kind of public repositories from the supported git providers.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/git.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('private-gh-app')">
|
||||
<x-slot:title>Private Repository (with GitHub App)</x-slot>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/git.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('private-gh-app')">
|
||||
<x-slot:title>Private Repository (with GitHub App)</x-slot>
|
||||
<x-slot:description>
|
||||
You can deploy public & private repositories through your GitHub Apps.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/github.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/github.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
|
||||
<x-resource-view wire="setType('private-deploy-key')">
|
||||
<x-slot:title> Private Repository (with deploy key)</x-slot>
|
||||
<x-resource-view wire="setType('private-deploy-key')">
|
||||
<x-slot:title> Private Repository (with deploy key)</x-slot>
|
||||
<x-slot:description>
|
||||
You can deploy public & private repositories with a simple deploy key (SSH key).
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/git.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
</div>
|
||||
<div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
|
||||
<x-resource-view wire="setType('dockerfile')">
|
||||
<x-slot:title>Based on a Dockerfile</x-slot>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/git.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
</div>
|
||||
<div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
|
||||
<x-resource-view wire="setType('dockerfile')">
|
||||
<x-slot:title>Based on a Dockerfile</x-slot>
|
||||
<x-slot:description>
|
||||
You can deploy a simple Dockerfile, without Git.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/docker.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('docker-compose-empty')">
|
||||
<x-slot:title>Based on a Docker Compose</x-slot>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/docker.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('docker-compose-empty')">
|
||||
<x-slot:title>Based on a Docker Compose</x-slot>
|
||||
<x-slot:description>
|
||||
You can deploy complex application easily with Docker Compose, without Git.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/docker.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('docker-image')">
|
||||
<x-slot:title>Based on an existing Docker Image</x-slot>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/docker.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('docker-image')">
|
||||
<x-slot:title>Based on an existing Docker Image</x-slot>
|
||||
<x-slot:description>
|
||||
You can deploy an existing Docker Image from any Registry, without Git.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/docker.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
</div>
|
||||
<h2 class="py-4">Databases</h2>
|
||||
<div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
|
||||
<x-resource-view wire="setType('postgresql')">
|
||||
<x-slot:title> New PostgreSQL</x-slot>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/docker.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
</div>
|
||||
<h2 class="py-4">Databases</h2>
|
||||
<div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
|
||||
<x-resource-view wire="setType('postgresql')">
|
||||
<x-slot:title> New PostgreSQL</x-slot>
|
||||
<x-slot:description>
|
||||
PostgreSQL is an object-relational database known for its
|
||||
robustness, advanced features, and strong standards compliance.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/postgres.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('redis')">
|
||||
<x-slot:title> New Redis</x-slot>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/postgres.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('redis')">
|
||||
<x-slot:title> New Redis</x-slot>
|
||||
<x-slot:description>
|
||||
Redis is an open-source, in-memory data structure store, used as a database, cache, and message
|
||||
broker.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/redis.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('mongodb')">
|
||||
<x-slot:title> New MongoDB</x-slot>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/redis.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('mongodb')">
|
||||
<x-slot:title> New MongoDB</x-slot>
|
||||
<x-slot:description>
|
||||
MongoDB is a source-available, NoSQL database that uses JSON-like documents with
|
||||
optional schemas.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/mongodb.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('mysql')">
|
||||
<x-slot:title>New MySQL</x-slot>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/mongodb.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('mysql')">
|
||||
<x-slot:title>New MySQL</x-slot>
|
||||
<x-slot:description>
|
||||
MySQL is a relational database known for its speed, reliability, and
|
||||
flexibility.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/mysql.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('mariadb')">
|
||||
<x-slot:title> New Mariadb</x-slot>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/mysql.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('mariadb')">
|
||||
<x-slot:title> New Mariadb</x-slot>
|
||||
<x-slot:description>
|
||||
MariaDB is a relational database that serves as a drop-in
|
||||
replacement for MySQL.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/mariadb.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/mariadb.svg') }}">
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
|
||||
{{-- <div class="box group" wire="setType('existing-postgresql')">
|
||||
{{-- <div class="box group" wire="setType('existing-postgresql')">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="group-hover:text-white">
|
||||
Backup Existing PostgreSQL
|
||||
@ -162,185 +151,178 @@
|
||||
</div>
|
||||
</div>
|
||||
</div> --}}
|
||||
</div>
|
||||
<div class="flex items-center gap-4" wire:init='loadServices'>
|
||||
<h2 class="py-4">Services</h2>
|
||||
<x-forms.button wire:click="loadServices('force')">Reload List</x-forms.button>
|
||||
<input
|
||||
class="w-full text-white rounded input input-sm bg-coolgray-200 disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500 read-only:text-neutral-500 read-only:bg-coolgray-200/50"
|
||||
wire:model.live.debounce.200ms="search" autofocus placeholder="Search...">
|
||||
</div>
|
||||
<div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
|
||||
@if ($loadingServices)
|
||||
<span class="loading loading-xs loading-spinner"></span>
|
||||
@else
|
||||
@forelse ($services as $serviceName => $service)
|
||||
@if (data_get($service, 'minversion') && version_compare(config('version'), data_get($service, 'minversion'), '<'))
|
||||
<x-resource-view wire="setType('one-click-service-{{ $serviceName }}')">
|
||||
<x-slot:title> {{ Str::headline($serviceName) }}</x-slot>
|
||||
<x-slot:description>
|
||||
@if (data_get($service, 'slogan'))
|
||||
{{ data_get($service, 'slogan') }}
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex items-center gap-4" wire:init='loadServices'>
|
||||
<h2 class="py-4">Services</h2>
|
||||
<x-forms.button wire:click="loadServices('force')">Reload List</x-forms.button>
|
||||
<input class="w-full text-white rounded input input-sm bg-coolgray-200 disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500 read-only:text-neutral-500 read-only:bg-coolgray-200/50" wire:model.live.debounce.200ms="search" autofocus placeholder="Search...">
|
||||
</div>
|
||||
<div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
|
||||
@if ($loadingServices)
|
||||
<span class="loading loading-xs loading-spinner"></span>
|
||||
@else
|
||||
@forelse ($services as $serviceName => $service)
|
||||
@if (data_get($service, 'minversion') && version_compare(config('version'), data_get($service, 'minversion'), '<')) <x-resource-view wire="setType('one-click-service-{{ $serviceName }}')">
|
||||
<x-slot:title> {{ Str::headline($serviceName) }}</x-slot>
|
||||
<x-slot:description>
|
||||
@if (data_get($service, 'slogan'))
|
||||
{{ data_get($service, 'slogan') }}
|
||||
@endif
|
||||
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
@if (data_get($service, 'logo'))
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset(data_get($service, 'logo')) }}">
|
||||
@endif
|
||||
</x-slot:logo>
|
||||
<x-slot:documentation>
|
||||
{{ data_get($service, 'documentation') }}
|
||||
</x-slot>
|
||||
<x-slot:upgrade>
|
||||
You need to upgrade Last Hour Cloud to {{ data_get($service, 'minversion') }} to use this
|
||||
service.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
@if (data_get($service, 'logo'))
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset(data_get($service, 'logo')) }}">
|
||||
@endif
|
||||
</x-slot:logo>
|
||||
<x-slot:documentation>
|
||||
{{ data_get($service, 'documentation') }}
|
||||
</x-slot>
|
||||
<x-slot:upgrade>
|
||||
You need to upgrade Coolify to {{ data_get($service, 'minversion') }} to use this
|
||||
service.
|
||||
</x-slot>
|
||||
</x-resource-view>
|
||||
{{-- <button class="text-left cursor-not-allowed bg-coolgray-100 box-without-bg" disabled>
|
||||
</x-resource-view>
|
||||
{{-- <button class="text-left cursor-not-allowed bg-coolgray-100 box-without-bg" disabled>
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold">
|
||||
{{ Str::headline($serviceName) }}
|
||||
</div>
|
||||
You need to upgrade to {{ data_get($service, 'minversion') }} to use this service.
|
||||
</div>
|
||||
</button> --}}
|
||||
@else
|
||||
<x-resource-view wire="setType('one-click-service-{{ $serviceName }}')">
|
||||
<x-slot:title> {{ Str::headline($serviceName) }}</x-slot>
|
||||
<x-slot:description>
|
||||
@if (data_get($service, 'slogan'))
|
||||
{{ data_get($service, 'slogan') }}
|
||||
@endif
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
@if (file_exists(public_path(data_get($service, 'logo'))))
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset(data_get($service, 'logo')) }}">
|
||||
@else
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset('svgs/unknown.svg') }}">
|
||||
@endif
|
||||
</x-slot:logo>
|
||||
<x-slot:documentation>
|
||||
{{ data_get($service, 'documentation') }}
|
||||
</x-slot>
|
||||
</x-resource-view>
|
||||
{{-- <button class="text-left box group" wire:loading.attr="disabled"
|
||||
wire:click="setType('one-click-service-{{ $serviceName }}')">
|
||||
<div class="flex flex-col mx-2">
|
||||
<div class="font-bold text-white group-hover:text-white">
|
||||
{{ Str::headline($serviceName) }}
|
||||
</div>
|
||||
@if (data_get($service, 'slogan'))
|
||||
<div class="description">
|
||||
{{ data_get($service, 'slogan') }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</button> --}}
|
||||
@endif
|
||||
@empty
|
||||
<div class="w-96">No service found. Please try to reload the list!</div>
|
||||
@endforelse
|
||||
</div>
|
||||
You need to upgrade to {{ data_get($service, 'minversion') }} to use this service.
|
||||
</div>
|
||||
</button> --}}
|
||||
@else
|
||||
<x-resource-view wire="setType('one-click-service-{{ $serviceName }}')">
|
||||
<x-slot:title> {{ Str::headline($serviceName) }}</x-slot>
|
||||
<x-slot:description>
|
||||
@if (data_get($service, 'slogan'))
|
||||
{{ data_get($service, 'slogan') }}
|
||||
@endif
|
||||
</div>
|
||||
<div class="py-4 pb-10">Trademarks Policy: The respective trademarks mentioned here are owned by the
|
||||
respective
|
||||
companies, and use of them does not imply any affiliation or endorsement.</div>
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
@if (file_exists(public_path(data_get($service, 'logo'))))
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset(data_get($service, 'logo')) }}">
|
||||
@else
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100" src="{{ asset('svgs/unknown.svg') }}">
|
||||
@endif
|
||||
</x-slot:logo>
|
||||
<x-slot:documentation>
|
||||
{{ data_get($service, 'documentation') }}
|
||||
</x-slot>
|
||||
</x-resource-view>
|
||||
{{-- <button class="text-left box group" wire:loading.attr="disabled"
|
||||
wire:click="setType('one-click-service-{{ $serviceName }}')">
|
||||
<div class="flex flex-col mx-2">
|
||||
<div class="font-bold text-white group-hover:text-white">
|
||||
{{ Str::headline($serviceName) }}
|
||||
</div>
|
||||
@if (data_get($service, 'slogan'))
|
||||
<div class="description">
|
||||
{{ data_get($service, 'slogan') }}
|
||||
</div>
|
||||
@endif
|
||||
@if ($current_step === 'servers')
|
||||
<ul class="pb-10 steps">
|
||||
<li class="step step-secondary">Select Resource Type</li>
|
||||
<li class="step step-secondary">Select a Server</li>
|
||||
<li class="step">Select a Destination</li>
|
||||
</ul>
|
||||
</div>
|
||||
</button> --}}
|
||||
@endif
|
||||
@empty
|
||||
<div class="w-96">No service found. Please try to reload the list!</div>
|
||||
@endforelse
|
||||
@endif
|
||||
</div>
|
||||
<div class="py-4 pb-10">Trademarks Policy: The respective trademarks mentioned here are owned by the
|
||||
respective
|
||||
companies, and use of them does not imply any affiliation or endorsement.</div>
|
||||
@endif
|
||||
@if ($current_step === 'servers')
|
||||
<ul class="pb-10 steps">
|
||||
<li class="step step-secondary">Select Resource Type</li>
|
||||
<li class="step step-secondary">Select a Server</li>
|
||||
<li class="step">Select a Destination</li>
|
||||
</ul>
|
||||
|
||||
{{-- @if ($isDatabase)
|
||||
{{-- @if ($isDatabase)
|
||||
<div class="flex items-center justify-center pt-4">
|
||||
<x-forms.checkbox instantSave wire:model="includeSwarm"
|
||||
helper="Swarm clusters are excluded from this list by default. For database, services or complex compose deployments with databases to work with Swarm,
|
||||
you need to set a few things on the server. Read more <a class='text-white underline' href='https://coolify.io/docs/docker/swarm#database-requirements' target='_blank'>here</a>."
|
||||
you need to set a few things on the server. Read more in upstream docs <a class='text-white underline' href='https://coolify.io/docs/docker/swarm#database-requirements' target='_blank'>here</a>."
|
||||
label="Include Swarm Clusters" />
|
||||
</div>
|
||||
@endif --}}
|
||||
<div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap">
|
||||
@forelse($servers as $server)
|
||||
<div class="w-64 box group" wire:click="setServer({{ $server }})">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold group-hover:text-white">
|
||||
{{ $server->name }}
|
||||
</div>
|
||||
<div class="text-xs group-hover:text-white">
|
||||
{{ $server->description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div>
|
||||
<div>No validated & reachable servers found. <a class="text-white underline" href="/servers">
|
||||
Go to servers page
|
||||
</a></div>
|
||||
|
||||
<x-use-magic-bar link="/server/new" />
|
||||
</div>
|
||||
@endforelse
|
||||
<div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap">
|
||||
@forelse($servers as $server)
|
||||
<div class="w-64 box group" wire:click="setServer({{ $server }})">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold group-hover:text-white">
|
||||
{{ $server->name }}
|
||||
</div>
|
||||
{{-- @if ($isDatabase)
|
||||
<div class="text-xs group-hover:text-white">
|
||||
{{ $server->description }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div>
|
||||
<div>No validated & reachable servers found. <a class="text-white underline" href="/servers">
|
||||
Go to servers page
|
||||
</a></div>
|
||||
|
||||
<x-use-magic-bar link="/server/new" />
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
{{-- @if ($isDatabase)
|
||||
<div class="text-center">Swarm clusters are excluded from this type of resource at the moment. It will
|
||||
be activated soon. Stay tuned.</div>
|
||||
@endif --}}
|
||||
@endif
|
||||
@if ($current_step === 'destinations')
|
||||
<ul class="pb-10 steps">
|
||||
<li class="step step-secondary">Select Resource Type</li>
|
||||
<li class="step step-secondary">Select a Server</li>
|
||||
<li class="step step-secondary">Select a Destination</li>
|
||||
</ul>
|
||||
@endif
|
||||
@if ($current_step === 'destinations')
|
||||
<ul class="pb-10 steps">
|
||||
<li class="step step-secondary">Select Resource Type</li>
|
||||
<li class="step step-secondary">Select a Server</li>
|
||||
<li class="step step-secondary">Select a Destination</li>
|
||||
</ul>
|
||||
|
||||
<div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap">
|
||||
@if ($server->isSwarm())
|
||||
@foreach ($swarmDockers as $swarmDocker)
|
||||
<div class="box group" wire:click="setDestination('{{ $swarmDocker->uuid }}')">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold group-hover:text-white">
|
||||
Swarm Docker <span class="text-xs">({{ $swarmDocker->name }})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@else
|
||||
@foreach ($standaloneDockers as $standaloneDocker)
|
||||
<div class="box group" wire:click="setDestination('{{ $standaloneDocker->uuid }}')">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold group-hover:text-white">
|
||||
Standalone Docker <span class="text-xs">({{ $standaloneDocker->name }})</span>
|
||||
</div>
|
||||
<div class="text-xs group-hover:text-white">
|
||||
Network: {{ $standaloneDocker->network }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
<a href="{{ route('destination.new', ['server_id' => $server_id]) }}"
|
||||
class="items-center justify-center text-center box-without-bg group bg-coollabs hover:bg-coollabs-100">
|
||||
<div class="flex flex-col mx-6 ">
|
||||
<div class="font-bold text-white">
|
||||
+ Add New
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap">
|
||||
@if ($server->isSwarm())
|
||||
@foreach ($swarmDockers as $swarmDocker)
|
||||
<div class="box group" wire:click="setDestination('{{ $swarmDocker->uuid }}')">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold group-hover:text-white">
|
||||
Swarm Docker <span class="text-xs">({{ $swarmDocker->name }})</span>
|
||||
</div>
|
||||
@endif
|
||||
@if ($current_step === 'existing-postgresql')
|
||||
<form wire:submit='addExistingPostgresql' class="flex items-end gap-4">
|
||||
<x-forms.input placeholder="postgres://username:password@database:5432" label="Database URL"
|
||||
id="existingPostgresqlUrl" />
|
||||
<x-forms.button type="submit">Add Database</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@else
|
||||
@foreach ($standaloneDockers as $standaloneDocker)
|
||||
<div class="box group" wire:click="setDestination('{{ $standaloneDocker->uuid }}')">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold group-hover:text-white">
|
||||
Standalone Docker <span class="text-xs">({{ $standaloneDocker->name }})</span>
|
||||
</div>
|
||||
<div class="text-xs group-hover:text-white">
|
||||
Network: {{ $standaloneDocker->network }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
<a href="{{ route('destination.new', ['server_id' => $server_id]) }}" class="items-center justify-center text-center box-without-bg group bg-coollabs hover:bg-coollabs-100">
|
||||
<div class="flex flex-col mx-6 ">
|
||||
<div class="font-bold text-white">
|
||||
+ Add New
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
@if ($current_step === 'existing-postgresql')
|
||||
<form wire:submit='addExistingPostgresql' class="flex items-end gap-4">
|
||||
<x-forms.input placeholder="postgres://username:password@database:5432" label="Database URL" id="existingPostgresqlUrl" />
|
||||
<x-forms.button type="submit">Add Database</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
@ -18,12 +18,12 @@
|
||||
<div class="flex gap-2">
|
||||
@if (!$application->serviceType()?->contains(str($application->image)->before(':')))
|
||||
@if ($application->required_fqdn)
|
||||
<x-forms.input required placeholder="https://app.coolify.io" label="Domains"
|
||||
<x-forms.input required placeholder="https://app.lasthourhosting.org" label="Domains"
|
||||
id="application.fqdn"
|
||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. "></x-forms.input>
|
||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.lasthourhosting.org, https://cloud.lasthourhosting.org/dashboard<br>- http://app.lasthourhosting.org/api/v3<br>- http://app.lasthourhosting.org:3000 -> app.lasthourhosting.org will point to port 3000 inside the container. "></x-forms.input>
|
||||
@else
|
||||
<x-forms.input placeholder="https://app.coolify.io" label="Domains" id="application.fqdn"
|
||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. "></x-forms.input>
|
||||
<x-forms.input placeholder="https://app.lasthourhosting.org" label="Domains" id="application.fqdn"
|
||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.lasthourhosting.org, https://cloud.lasthourhosting.org/dashboard<br>- http://app.lasthourhosting.org/api/v3<br>- http://app.lasthourhosting.org:3000 -> app.lasthourhosting.org will point to port 3000 inside the container. "></x-forms.input>
|
||||
@endif
|
||||
@endif
|
||||
<x-forms.input required
|
||||
|
@ -5,8 +5,7 @@
|
||||
<div>Configuration</div>
|
||||
</div>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
<x-forms.button class="w-64"
|
||||
onclick="Livewire.dispatch('openModal', {component: 'modal.edit-compose', arguments: {{ json_encode(['serviceId' => $service->id]) }} })">Edit
|
||||
<x-forms.button class="w-64" onclick="Livewire.dispatch('openModal', {component: 'modal.edit-compose', arguments: {{ json_encode(['serviceId' => $service->id]) }} })">Edit
|
||||
Compose
|
||||
File</x-forms.button>
|
||||
</div>
|
||||
@ -15,21 +14,16 @@
|
||||
<x-forms.input id="service.description" label="Description" />
|
||||
</div>
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave id="service.connect_to_docker_network" label="Connect To Predefined Network"
|
||||
helper="By default, you do not reach the Coolify defined networks.<br>Starting a docker compose based resource will have an internal network. <br>If you connect to a Coolify defined network, you maybe need to use different internal DNS names to connect to a resource.<br><br>For more information, check <a class='text-white underline' target='_blank' href='https://coolify.io/docs/docker/compose#connect-to-predefined-networks'>this</a>." />
|
||||
<x-forms.checkbox instantSave id="service.connect_to_docker_network" label="Connect To Predefined Network" helper="By default, you do not reach the Last Hour Cloud defined networks.<br>Starting a docker compose based resource will have an internal network. <br>If you connect to a Last Hour Cloud defined network, you maybe need to use different internal DNS names to connect to a resource.<br><br>For more information, check the upstream <a class='text-white underline' href='https://coolify.io/docs/docker/compose#connect-to-predefined-networks'>docs</a>." />
|
||||
</div>
|
||||
@if ($fields)
|
||||
<div>
|
||||
<h3>Service Specific Configuration</h3>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
@foreach ($fields as $serviceName => $field)
|
||||
<x-forms.input type="{{ data_get($field, 'isPassword') ? 'password' : 'text' }}"
|
||||
required="{{ str(data_get($field, 'rules'))?->contains('required') }}"
|
||||
helper="Variable name: {{ $serviceName }}"
|
||||
label="{{ data_get($field, 'serviceName') }} {{ data_get($field, 'name') }}"
|
||||
id="fields.{{ $serviceName }}.value"></x-forms.input>
|
||||
@endforeach
|
||||
</div>
|
||||
<div>
|
||||
<h3>Service Specific Configuration</h3>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
@foreach ($fields as $serviceName => $field)
|
||||
<x-forms.input type="{{ data_get($field, 'isPassword') ? 'password' : 'text' }}" required="{{ str(data_get($field, 'rules'))?->contains('required') }}" helper="Variable name: {{ $serviceName }}" label="{{ data_get($field, 'serviceName') }} {{ data_get($field, 'name') }}" id="fields.{{ $serviceName }}.value"></x-forms.input>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
</form>
|
@ -2,11 +2,11 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Webhooks</h2>
|
||||
<x-helper
|
||||
helper="For more details goto our <a class='text-white underline' href='https://coolify.io/docs/api/deploy-webhook' target='_blank'>docs</a>." />
|
||||
helper="For more details go to the upstream <a class='text-white underline' href='https://coolify.io/docs/api/deploy-webhook' target='_blank'>docs</a>." />
|
||||
</div>
|
||||
<div>
|
||||
<x-forms.input readonly
|
||||
helper="See details in our <a target='_blank' class='text-white underline' href='https://coolify.io/docs/api/authentication'>documentation</a>."
|
||||
helper="See details in the upstream <a target='_blank' class='text-white underline' href='https://coolify.io/docs/api/authentication'>documentation</a>."
|
||||
label="Deploy Webhook (auth required)" id="deploywebhook"></x-forms.input>
|
||||
</div>
|
||||
@if ($resource->type() !== 'service')
|
||||
|
@ -13,12 +13,12 @@
|
||||
$wire.showNotification = true;
|
||||
@endif
|
||||
console.error(
|
||||
'Coolify could not connect to the new realtime service introduced in beta.154. This will cause unusual problems on the UI if not fixed! Please check the related documentation (https://coolify.io/docs/cloudflare/tunnels) or get help on Discord (https://coollabs.io/discord).)'
|
||||
'Last Hour Cloud could not connect to the new realtime service introduced in beta.154. This will cause unusual problems on the UI if not fixed! Please check the related upstream documentation (https://coolify.io/docs/cloudflare/tunnels) or get help on Discord (https://coollabs.io/discord).)'
|
||||
);
|
||||
clearInterval(checkPusherInterval);
|
||||
}
|
||||
} else {
|
||||
console.log('Coolify Realtime Service is connected!');
|
||||
console.log('Last Hour Cloud Realtime Service is connected!');
|
||||
clearInterval(checkPusherInterval);
|
||||
}
|
||||
} else {
|
||||
@ -26,7 +26,7 @@
|
||||
$wire.showNotification = true;
|
||||
@endif
|
||||
console.error(
|
||||
'Coolify could not connect to the new realtime service introduced in beta.154. This will cause unusual problems on the UI if not fixed! Please check the related documentation (https://coolify.io/docs/cloudflare/tunnels) or get help on Discord (https://coollabs.io/discord).)'
|
||||
'Last Hour Cloud could not connect to the new realtime service introduced in beta.154. This will cause unusual problems on the UI if not fixed! Please check the related upstream documentation (https://coolify.io/docs/cloudflare/tunnels) or get help on Discord (https://coollabs.io/discord).)'
|
||||
);
|
||||
clearInterval(checkPusherInterval);
|
||||
}
|
||||
@ -35,10 +35,10 @@
|
||||
@endscript
|
||||
<div class="toast z-[9999]" x-cloak x-show="showNotification">
|
||||
<div class="flex flex-col text-white border border-red-500 border-dashed rounded alert bg-coolgray-200">
|
||||
<span><span class="font-bold text-left text-red-500">WARNING: </span>Coolify could not connect to the new
|
||||
<span><span class="font-bold text-left text-red-500">WARNING: </span>Last Hour Cloud could not connect to the new
|
||||
realtime service introduced in beta.154. <br>This will cause unusual problems on the UI if not
|
||||
fixed!<br><br>Please check the
|
||||
related <a href='https://coolify.io/docs/cloudflare/tunnels' target='_blank'>documentation</a> or get
|
||||
related upstream <a href='https://coolify.io/docs/cloudflare/tunnels' target='_blank'>documentation</a> or get
|
||||
help on <a href='https://coollabs.io/discord' target='_blank'>Discord</a>.</span>
|
||||
<x-forms.button class="bg-coolgray-400" wire:click='disable'>Acknowledge the problem and disable this
|
||||
popup</x-forms.button>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<div>
|
||||
@if ($server->id !== 0)
|
||||
<h2 class="pt-4">Danger Zone</h2>
|
||||
<div class="">Woah. I hope you know what are you doing.</div>
|
||||
<div class="">Wait a minute, We hope you know what are you doing.</div>
|
||||
<h4 class="pt-4">Delete Server</h4>
|
||||
<div class="pb-4">This will remove this server from Coolify. Beware! There is no coming
|
||||
<div class="pb-4">This will remove this server from Last Hour Cloud. Beware! There is no coming
|
||||
back!
|
||||
</div>
|
||||
@if ($server->definedResources()->count() > 0)
|
||||
|
@ -76,27 +76,27 @@ class="w-full mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-1
|
||||
label="Use it as a build server?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all SSH requests to your server through Cloudflare.<br><span class='text-warning'>Coolify does not install or set up Cloudflare (cloudflared) on your server.</span>"
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all SSH requests to your server through Cloudflare.<br><span class='text-warning'>Last Hour Cloud does not install or set up Cloudflare (cloudflared) on your server.</span>"
|
||||
id="server.settings.is_cloudflare_tunnel" label="Cloudflare Tunnel" />
|
||||
@if ($server->isSwarm())
|
||||
<div class="pt-6"> Swarm support is experimental. </div>
|
||||
@endif
|
||||
@if ($server->settings->is_swarm_worker)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox" id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
helper="For more information, please read the upstream documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
helper="For more information, please read the upstream documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@endif
|
||||
@if ($server->settings->is_swarm_manager)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox" id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
helper="For more information, please read the upstream documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
helper="For more information, please read the upstream documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@endif
|
||||
@endif
|
||||
|
@ -28,7 +28,7 @@
|
||||
&
|
||||
@endif
|
||||
@if (!$server->settings->is_usable)
|
||||
<span>Not usable by Coolify</span>
|
||||
<span>Not usable by Last Hour Cloud</span>
|
||||
@endif
|
||||
@if ($server->settings->force_disabled)
|
||||
<span>Disabled by the system</span>
|
||||
|
@ -30,25 +30,25 @@
|
||||
</div>
|
||||
<div class="w-96">
|
||||
<h3 class="pt-6">Swarm Support</h3>
|
||||
<div> Swarm support is experimental. Read the docs <a class='text-white'
|
||||
<div> Swarm support is experimental. Read the upstream docs to learn more <a class='text-white'
|
||||
href='https://coolify.io/docs/docker/swarm#deploy-with-persistent-storage'
|
||||
target='_blank'>here</a>.</div>
|
||||
@if ($is_swarm_worker || $is_build_server)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox" id="is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
helper="For more information, please read the the upstream documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@else
|
||||
<x-forms.checkbox type="checkbox" instantSave id="is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
helper="For more information, please read the the upstream documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@endif
|
||||
@if ($is_swarm_manager|| $is_build_server)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox" id="is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
helper="For more information, please read the upstream documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@else
|
||||
<x-forms.checkbox type="checkbox" instantSave id="is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
helper="For more information, please read the upstream documentation <a class='text-white' href='https://coolify.io/docs/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@endif
|
||||
@if ($is_swarm_worker && count($swarm_managers) > 0)
|
||||
|
@ -31,7 +31,7 @@
|
||||
configurations.
|
||||
</div>
|
||||
@endif
|
||||
<x-forms.input placeholder="https://app.coolify.io" id="redirect_url" label="Default Redirect 404"
|
||||
<x-forms.input placeholder="https://lasthourhosting.org" id="redirect_url" label="Default Redirect 404"
|
||||
helper="All urls that has no service available will be redirected to this domain." />
|
||||
<div wire:loading wire:target="loadProxyConfiguration" class="pt-4">
|
||||
<x-loading text="Loading proxy configuration..." />
|
||||
|
@ -15,7 +15,7 @@
|
||||
<h2>Resources</h2>
|
||||
<x-forms.button wire:click="refreshStatus">Refresh</x-forms.button>
|
||||
</div>
|
||||
<div class="pb-4 title">Here you can find all resources that are managed by Coolify.</div>
|
||||
<div class="pb-4 title">Here you can find all resources that are managed by Last Hour Cloud.</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
|
@ -8,7 +8,7 @@
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
<div class="pb-4">Backup your Coolify instance settings</div>
|
||||
<div class="pb-4">Backup your Last Hour Cloud instance settings</div>
|
||||
<div>
|
||||
@if (isset($database))
|
||||
<div class="flex flex-col gap-3 pb-4">
|
||||
@ -24,8 +24,8 @@
|
||||
</div>
|
||||
<livewire:project.database.backup-edit :backup="$backup" :s3s="$s3s" :status="data_get($database, 'status')" />
|
||||
@else
|
||||
To configure automatic backup for your Coolify instance, you first need to add as a database resource
|
||||
into Coolify.
|
||||
To configure automatic backup for your Last Hour Cloud instance, you first need to add as a database resource
|
||||
into Last Hour Cloud.
|
||||
<x-forms.button wire:click="add_coolify_database">Add Database</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
|
@ -6,12 +6,12 @@
|
||||
Save
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div>General configuration for your Coolify instance.</div>
|
||||
<div>General configuration for your Last Hour Cloud instance.</div>
|
||||
|
||||
<div class="flex flex-col gap-2 pt-4">
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input id="settings.fqdn" label="Instance's Domain" placeholder="https://coolify.io" />
|
||||
<x-forms.input id="settings.custom_dns_servers" label="DNS Servers" helper="DNS servers for validation FQDNS againts. A comma separated list of DNS servers." placeholder="1.1.1.1,8.8.8.8" />
|
||||
<x-forms.input id="settings.fqdn" label="Instance's Domain" placeholder="https://lasthourhosting.org" />
|
||||
<x-forms.input id="settings.custom_dns_servers" label="DNS Servers" helper="DNS servers for validation FQDNS againts. A comma separated list of DNS servers." placeholder="9.9.9.9" />
|
||||
<x-forms.checkbox instantSave id="is_dns_validation_enabled" label="Validate DNS settings?" />
|
||||
</div>
|
||||
|
||||
@ -24,20 +24,16 @@
|
||||
<h2 class="pt-6">Advanced</h2>
|
||||
<div class="flex flex-col py-6 text-right w-80">
|
||||
@if(!is_null(env('AUTOUPDATE', null)))
|
||||
<x-forms.checkbox instantSave helper="AUTOUPDATE is set in .env file, you need to modify it there." disabled
|
||||
id="is_auto_update_enabled" label="Auto Update Coolify" />
|
||||
<x-forms.checkbox instantSave helper="AUTOUPDATE is set in .env file, you need to modify it there." disabled id="is_auto_update_enabled" label="Auto Update Last Hour Cloud" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave id="is_auto_update_enabled" label="Auto Update Coolify" />
|
||||
<x-forms.checkbox instantSave id="is_auto_update_enabled" label="Auto Update Last Hour Cloud" />
|
||||
@endif
|
||||
<x-forms.checkbox instantSave id="is_registration_enabled" label="Registration Allowed" />
|
||||
<x-forms.checkbox instantSave id="do_not_track" label="Do Not Track" />
|
||||
@if ($next_channel)
|
||||
<x-forms.checkbox instantSave helper="Do not recommended, only if you like to live on the edge."
|
||||
id="next_channel" label="Enable pre-release (early) updates" />
|
||||
<x-forms.checkbox instantSave helper="Do not recommended, only if you like to live on the edge." id="next_channel" label="Enable pre-release (early) updates" />
|
||||
@else
|
||||
<x-forms.checkbox disabled instantSave
|
||||
helper="Currently disabled. Do not recommended, only if you like to live on the edge." id="next_channel"
|
||||
label="Enable pre-release (early) updates" />
|
||||
<x-forms.checkbox disabled instantSave helper="Currently disabled. Do not recommended, only if you like to live on the edge." id="next_channel" label="Enable pre-release (early) updates" />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -13,22 +13,20 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Transactional Email</h2>
|
||||
</div>
|
||||
<div class="pb-4 ">Email settings for password resets, invitations, shared with Pro+ subscribers etc.</div>
|
||||
<div class="pb-4 ">Email settings for password resets, invitations, shared with users etc.</div>
|
||||
<form wire:submit='submitFromFields' class="pb-4">
|
||||
<div class="flex flex-col items-end w-full gap-2 xl:flex-row">
|
||||
<x-forms.input required id="settings.smtp_from_name" helper="Name used in emails." label="From Name" />
|
||||
<x-forms.input required id="settings.smtp_from_address" helper="Email address used in emails."
|
||||
label="From Address" />
|
||||
<x-forms.input required id="settings.smtp_from_address" helper="Email address used in emails." label="From Address" />
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@if (isEmailEnabled($settings) &&
|
||||
auth()->user()->isAdminFromSession() &&
|
||||
isTestEmailEnabled($settings))
|
||||
<x-forms.button onclick="sendTestEmail.showModal()"
|
||||
class="text-white normal-case btn btn-xs no-animation btn-primary">
|
||||
Send Test Email
|
||||
</x-forms.button>
|
||||
auth()->user()->isAdminFromSession() &&
|
||||
isTestEmailEnabled($settings))
|
||||
<x-forms.button onclick="sendTestEmail.showModal()" class="text-white normal-case btn btn-xs no-animation btn-primary">
|
||||
Send Test Email
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
</form>
|
||||
@ -43,14 +41,12 @@ class="text-white normal-case btn btn-xs no-animation btn-primary">
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input required id="settings.smtp_host" placeholder="smtp.mailgun.org" label="Host" />
|
||||
<x-forms.input required id="settings.smtp_port" placeholder="587" label="Port" />
|
||||
<x-forms.input id="settings.smtp_encryption" helper="If SMTP uses SSL, set it to 'tls'."
|
||||
placeholder="tls" label="Encryption" />
|
||||
<x-forms.input id="settings.smtp_encryption" helper="If SMTP uses SSL, set it to 'tls'." placeholder="tls" label="Encryption" />
|
||||
</div>
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input id="settings.smtp_username" label="SMTP Username" />
|
||||
<x-forms.input id="settings.smtp_password" type="password" label="SMTP Password" />
|
||||
<x-forms.input id="settings.smtp_timeout" helper="Timeout value for sending emails."
|
||||
label="Timeout" />
|
||||
<x-forms.input id="settings.smtp_timeout" helper="Timeout value for sending emails." label="Timeout" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4 pt-6">
|
||||
@ -68,8 +64,7 @@ class="text-white normal-case btn btn-xs no-animation btn-primary">
|
||||
<form wire:submit='submitResend' class="flex flex-col">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input type="password" id="settings.resend_api_key" placeholder="API key" required
|
||||
label="Host" />
|
||||
<x-forms.input type="password" id="settings.resend_api_key" placeholder="API key" required label="Host" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4 pt-6">
|
||||
@ -80,4 +75,4 @@ class="text-white normal-case btn btn-xs no-animation btn-primary">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,262 +1,246 @@
|
||||
<div>
|
||||
@if (data_get($github_app, 'app_id'))
|
||||
<form wire:submit='submit'>
|
||||
<div class="flex items-center gap-2">
|
||||
<h1>GitHub App</h1>
|
||||
<div class="flex gap-2">
|
||||
@if (data_get($github_app, 'installation_id'))
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
<a href="{{ get_installation_path($github_app) }}">
|
||||
<x-forms.button>
|
||||
Update Repositories
|
||||
<x-external-link />
|
||||
</x-forms.button>
|
||||
</a>
|
||||
@endif
|
||||
<x-new-modal isErrorButton buttonTitle="Delete">
|
||||
This source will be deleted. It is not reversible. <br>Please think again.
|
||||
</x-new-modal>
|
||||
</div>
|
||||
</div>
|
||||
<div class="subtitle">Your Private GitHub App for private repositories.</div>
|
||||
@if (!data_get($github_app, 'installation_id'))
|
||||
<div class="mb-10 rounded alert alert-warning">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
<span>You must complete this step before you can use this source!</span>
|
||||
</div>
|
||||
<a class="items-center justify-center box" href="{{ get_installation_path($github_app) }}">
|
||||
Install Repositories on GitHub
|
||||
<form wire:submit='submit'>
|
||||
<div class="flex items-center gap-2">
|
||||
<h1>GitHub App</h1>
|
||||
<div class="flex gap-2">
|
||||
@if (data_get($github_app, 'installation_id'))
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
<a href="{{ get_installation_path($github_app) }}">
|
||||
<x-forms.button>
|
||||
Update Repositories
|
||||
<x-external-link />
|
||||
</x-forms.button>
|
||||
</a>
|
||||
@else
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input id="github_app.name" label="App Name" disabled />
|
||||
<x-forms.input id="github_app.organization" label="Organization" disabled
|
||||
placeholder="If empty, personal user will be used" />
|
||||
</div>
|
||||
@if (!isCloud())
|
||||
<div class="w-48">
|
||||
<x-forms.checkbox label="System Wide?"
|
||||
helper="If checked, this GitHub App will be available for everyone in this Coolify instance."
|
||||
instantSave id="github_app.is_system_wide" />
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input id="github_app.html_url" label="HTML Url" disabled />
|
||||
<x-forms.input id="github_app.api_url" label="API Url" disabled />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
@if ($github_app->html_url === 'https://github.com')
|
||||
<x-forms.input id="github_app.custom_user" label="User" disabled />
|
||||
<x-forms.input type="number" id="github_app.custom_port" label="Port" disabled />
|
||||
@else
|
||||
<x-forms.input id="github_app.custom_user" label="User" required />
|
||||
<x-forms.input type="number" id="github_app.custom_port" label="Port" required />
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input type="number" id="github_app.app_id" label="App Id" disabled />
|
||||
<x-forms.input type="number" id="github_app.installation_id" label="Installation Id"
|
||||
disabled />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input id="github_app.client_id" label="Client Id" type="password" disabled />
|
||||
<x-forms.input id="github_app.client_secret" label="Client Secret" type="password" />
|
||||
<x-forms.input id="github_app.webhook_secret" label="Webhook Secret" type="password" />
|
||||
</div>
|
||||
<div class="flex items-end gap-2 ">
|
||||
<h2 class="pt-4">Permissions</h2>
|
||||
<x-forms.button wire:click.prevent="checkPermissions">Refetch</x-forms.button>
|
||||
<a href="{{ get_permissions_path($github_app) }}">
|
||||
<x-forms.button>
|
||||
Update
|
||||
<x-external-link />
|
||||
</x-forms.button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input id="github_app.contents" helper="read - mandatory." label="Content" readonly
|
||||
placeholder="N/A" />
|
||||
<x-forms.input id="github_app.metadata" helper="read - mandatory." label="Metadata" readonly
|
||||
placeholder="N/A" />
|
||||
{{-- <x-forms.input id="github_app.administration"
|
||||
@endif
|
||||
<x-new-modal isErrorButton buttonTitle="Delete">
|
||||
This source will be deleted. It is not reversible. <br>Please think again.
|
||||
</x-new-modal>
|
||||
</div>
|
||||
</div>
|
||||
<div class="subtitle">Your Private GitHub App for private repositories.</div>
|
||||
@if (!data_get($github_app, 'installation_id'))
|
||||
<div class="mb-10 rounded alert alert-warning">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
<span>You must complete this step before you can use this source!</span>
|
||||
</div>
|
||||
<a class="items-center justify-center box" href="{{ get_installation_path($github_app) }}">
|
||||
Install Repositories on GitHub
|
||||
</a>
|
||||
@else
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input id="github_app.name" label="App Name" disabled />
|
||||
<x-forms.input id="github_app.organization" label="Organization" disabled placeholder="If empty, personal user will be used" />
|
||||
</div>
|
||||
@if (!isCloud())
|
||||
<div class="w-48">
|
||||
<x-forms.checkbox label="System Wide?" helper="If checked, this GitHub App will be available for everyone in this Coolify instance." instantSave id="github_app.is_system_wide" />
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input id="github_app.html_url" label="HTML Url" disabled />
|
||||
<x-forms.input id="github_app.api_url" label="API Url" disabled />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
@if ($github_app->html_url === 'https://github.com')
|
||||
<x-forms.input id="github_app.custom_user" label="User" disabled />
|
||||
<x-forms.input type="number" id="github_app.custom_port" label="Port" disabled />
|
||||
@else
|
||||
<x-forms.input id="github_app.custom_user" label="User" required />
|
||||
<x-forms.input type="number" id="github_app.custom_port" label="Port" required />
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input type="number" id="github_app.app_id" label="App Id" disabled />
|
||||
<x-forms.input type="number" id="github_app.installation_id" label="Installation Id" disabled />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input id="github_app.client_id" label="Client Id" type="password" disabled />
|
||||
<x-forms.input id="github_app.client_secret" label="Client Secret" type="password" />
|
||||
<x-forms.input id="github_app.webhook_secret" label="Webhook Secret" type="password" />
|
||||
</div>
|
||||
<div class="flex items-end gap-2 ">
|
||||
<h2 class="pt-4">Permissions</h2>
|
||||
<x-forms.button wire:click.prevent="checkPermissions">Refetch</x-forms.button>
|
||||
<a href="{{ get_permissions_path($github_app) }}">
|
||||
<x-forms.button>
|
||||
Update
|
||||
<x-external-link />
|
||||
</x-forms.button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input id="github_app.contents" helper="read - mandatory." label="Content" readonly placeholder="N/A" />
|
||||
<x-forms.input id="github_app.metadata" helper="read - mandatory." label="Metadata" readonly placeholder="N/A" />
|
||||
{{-- <x-forms.input id="github_app.administration"
|
||||
helper="read:write access needed to setup servers as GitHub Runner." label="Administration"
|
||||
readonly placeholder="N/A" /> --}}
|
||||
<x-forms.input id="github_app.pull_requests"
|
||||
helper="write access needed to use deployment status update in previews."
|
||||
label="Pull Request" readonly placeholder="N/A" />
|
||||
</div>
|
||||
<x-forms.input id="github_app.pull_requests" helper="write access needed to use deployment status update in previews." label="Pull Request" readonly placeholder="N/A" />
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
<div class="w-full pt-10">
|
||||
<div class="h-full">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
<h2>Resources</h2>
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
<div class="w-full pt-10">
|
||||
<div class="h-full">
|
||||
<div class="pb-4 title">Here you can find all resources that are used by this source.</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
<h2>Resources</h2>
|
||||
</div>
|
||||
<div class="pb-4 title">Here you can find all resources that are used by this source.</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
<div class="overflow-x-auto">
|
||||
<div class="inline-block min-w-full">
|
||||
<div class="overflow-hidden">
|
||||
<table class="min-w-full divide-y divide-coolgray-400">
|
||||
<thead>
|
||||
<tr class="text-neutral-500">
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Project
|
||||
</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">
|
||||
Environment</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Name</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-coolgray-400">
|
||||
@forelse ($applications->sortBy('name',SORT_NATURAL) as $resource)
|
||||
<tr class="text-white bg-coolblack hover:bg-coolgray-100">
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
{{ data_get($resource->project(), 'name') }}
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
{{ data_get($resource, 'environment.name') }}
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap"><a class=""
|
||||
href="{{ $resource->link() }}">{{ $resource->name }}
|
||||
<x-internal-link /></a>
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
{{ str($resource->type())->headline() }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<div class="inline-block min-w-full">
|
||||
<div class="overflow-hidden">
|
||||
<table class="min-w-full divide-y divide-coolgray-400">
|
||||
<thead>
|
||||
<tr class="text-neutral-500">
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Project
|
||||
</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">
|
||||
Environment</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Name</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-coolgray-400">
|
||||
@forelse ($applications->sortBy('name',SORT_NATURAL) as $resource)
|
||||
<tr class="text-white bg-coolblack hover:bg-coolgray-100">
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
{{ data_get($resource->project(), 'name') }}
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
{{ data_get($resource, 'environment.name') }}
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap"><a class="" href="{{ $resource->link() }}">{{ $resource->name }}
|
||||
<x-internal-link /></a>
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
{{ str($resource->type())->headline() }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex items-center gap-2 pb-4">
|
||||
<h1>GitHub App</h1>
|
||||
<div class="flex gap-2">
|
||||
<x-new-modal isErrorButton buttonTitle="Delete">
|
||||
This source will be deleted. It is not reversible. <br>Please think again.
|
||||
</x-new-modal>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 pb-4">
|
||||
<h1>GitHub App</h1>
|
||||
<div class="flex gap-2">
|
||||
<x-new-modal isErrorButton buttonTitle="Delete">
|
||||
This source will be deleted. It is not reversible. <br>Please think again.
|
||||
</x-new-modal>
|
||||
</div>
|
||||
<div class="mb-10 rounded alert alert-warning">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
<span>You must complete this step before you can use this source!</span>
|
||||
</div>
|
||||
<div class="mb-10 rounded alert alert-warning">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
<span>You must complete this step before you can use this source!</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
<h2>Register a GitHub App</h2>
|
||||
<x-forms.button class="bg-coollabs hover:bg-coollabs-100" x-on:click.prevent="createGithubApp('{{ $webhook_endpoint }}','{{ $preview_deployment_permissions }}',{{ $administration }})">
|
||||
Register Now
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
<h2>Register a GitHub App</h2>
|
||||
<x-forms.button class="bg-coollabs hover:bg-coollabs-100"
|
||||
x-on:click.prevent="createGithubApp('{{ $webhook_endpoint }}','{{ $preview_deployment_permissions }}',{{ $administration }})">
|
||||
Register Now
|
||||
</x-forms.button>
|
||||
<div>You need to register a GitHub App before using this source.</div>
|
||||
<div class="py-10">
|
||||
@if (!isCloud() || isDev())
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.select wire:model.live='webhook_endpoint' label="Webhook Endpoint" helper="All Git webhooks will be sent to this endpoint. <br><br>If you would like to use domain instead of IP address, set your Last Hour Cloud instance's FQDN in the Settings menu.">
|
||||
@if ($ipv4)
|
||||
<option value="{{ $ipv4 }}">Use {{ $ipv4 }}</option>
|
||||
@endif
|
||||
@if ($ipv6)
|
||||
<option value="{{ $ipv6 }}">Use {{ $ipv6 }}</option>
|
||||
@endif
|
||||
@if ($fqdn)
|
||||
<option value="{{ $fqdn }}">Use {{ $fqdn }}</option>
|
||||
@endif
|
||||
@if (config('app.url'))
|
||||
<option value="{{ config('app.url') }}">Use {{ config('app.url') }}</option>
|
||||
@endif
|
||||
</x-forms.select>
|
||||
</div>
|
||||
<div>You need to register a GitHub App before using this source.</div>
|
||||
<div class="py-10">
|
||||
@if (!isCloud() || isDev())
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.select wire:model.live='webhook_endpoint' label="Webhook Endpoint"
|
||||
helper="All Git webhooks will be sent to this endpoint. <br><br>If you would like to use domain instead of IP address, set your Coolify instance's FQDN in the Settings menu.">
|
||||
@if ($ipv4)
|
||||
<option value="{{ $ipv4 }}">Use {{ $ipv4 }}</option>
|
||||
@endif
|
||||
@if ($ipv6)
|
||||
<option value="{{ $ipv6 }}">Use {{ $ipv6 }}</option>
|
||||
@endif
|
||||
@if ($fqdn)
|
||||
<option value="{{ $fqdn }}">Use {{ $fqdn }}</option>
|
||||
@endif
|
||||
@if (config('app.url'))
|
||||
<option value="{{ config('app.url') }}">Use {{ config('app.url') }}</option>
|
||||
@endif
|
||||
</x-forms.select>
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex flex-col gap-2 pt-4 w-96">
|
||||
<x-forms.checkbox disabled instantSave id="default_permissions" label="Mandatory"
|
||||
helper="Contents: read<br>Metadata: read<br>Email: read" />
|
||||
<x-forms.checkbox instantSave id="preview_deployment_permissions" label="Preview Deployments "
|
||||
helper="Necessary for updating pull requests with useful comments (deployment status, links, etc.)<br><br>Pull Request: read & write" />
|
||||
{{-- <x-forms.checkbox instantSave id="administration" label="Administration (for Github Runners)"
|
||||
@endif
|
||||
<div class="flex flex-col gap-2 pt-4 w-96">
|
||||
<x-forms.checkbox disabled instantSave id="default_permissions" label="Mandatory" helper="Contents: read<br>Metadata: read<br>Email: read" />
|
||||
<x-forms.checkbox instantSave id="preview_deployment_permissions" label="Preview Deployments " helper="Necessary for updating pull requests with useful comments (deployment status, links, etc.)<br><br>Pull Request: read & write" />
|
||||
{{-- <x-forms.checkbox instantSave id="administration" label="Administration (for Github Runners)"
|
||||
helper="Necessary for adding Github Runners to repositories.<br><br>Administration: read & write" /> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function createGithubApp(webhook_endpoint, preview_deployment_permissions, administration) {
|
||||
const {
|
||||
organization,
|
||||
uuid,
|
||||
html_url
|
||||
} = @json($github_app);
|
||||
let baseUrl = webhook_endpoint;
|
||||
const name = @js($name);
|
||||
const isDev = @js(config('app.env')) ===
|
||||
'local';
|
||||
const devWebhook = @js(config('coolify.dev_webhook'));
|
||||
if (isDev && devWebhook) {
|
||||
baseUrl = devWebhook;
|
||||
}
|
||||
const webhookBaseUrl = `${baseUrl}/webhooks`;
|
||||
const path = organization ? `organizations/${organization}/settings/apps/new` : 'settings/apps/new';
|
||||
const default_permissions = {
|
||||
contents: 'read',
|
||||
metadata: 'read',
|
||||
emails: 'read',
|
||||
administration: 'read'
|
||||
};
|
||||
if (preview_deployment_permissions) {
|
||||
default_permissions.pull_requests = 'write';
|
||||
}
|
||||
if (administration) {
|
||||
default_permissions.administration = 'write';
|
||||
}
|
||||
const data = {
|
||||
name,
|
||||
url: baseUrl,
|
||||
hook_attributes: {
|
||||
url: `${webhookBaseUrl}/source/github/events`,
|
||||
active: true,
|
||||
},
|
||||
redirect_url: `${webhookBaseUrl}/source/github/redirect`,
|
||||
callback_urls: [`${baseUrl}/login/github/app`],
|
||||
public: false,
|
||||
request_oauth_on_install: false,
|
||||
setup_url: `${webhookBaseUrl}/source/github/install?source=${uuid}`,
|
||||
setup_on_update: true,
|
||||
default_permissions,
|
||||
default_events: ['pull_request', 'push']
|
||||
};
|
||||
const form = document.createElement('form');
|
||||
form.setAttribute('method', 'post');
|
||||
form.setAttribute('action', `${html_url}/${path}?state=${uuid}`);
|
||||
const input = document.createElement('input');
|
||||
input.setAttribute('id', 'manifest');
|
||||
input.setAttribute('name', 'manifest');
|
||||
input.setAttribute('type', 'hidden');
|
||||
input.setAttribute('value', JSON.stringify(data));
|
||||
form.appendChild(input);
|
||||
document.getElementsByTagName('body')[0].appendChild(form);
|
||||
form.submit();
|
||||
</div>
|
||||
<script>
|
||||
function createGithubApp(webhook_endpoint, preview_deployment_permissions, administration) {
|
||||
const {
|
||||
organization,
|
||||
uuid,
|
||||
html_url
|
||||
} = @json($github_app);
|
||||
let baseUrl = webhook_endpoint;
|
||||
const name = @js($name);
|
||||
const isDev = @js(config('app.env')) ===
|
||||
'local';
|
||||
const devWebhook = @js(config('coolify.dev_webhook'));
|
||||
if (isDev && devWebhook) {
|
||||
baseUrl = devWebhook;
|
||||
}
|
||||
</script>
|
||||
const webhookBaseUrl = `${baseUrl}/webhooks`;
|
||||
const path = organization ? `organizations/${organization}/settings/apps/new` : 'settings/apps/new';
|
||||
const default_permissions = {
|
||||
contents: 'read',
|
||||
metadata: 'read',
|
||||
emails: 'read',
|
||||
administration: 'read'
|
||||
};
|
||||
if (preview_deployment_permissions) {
|
||||
default_permissions.pull_requests = 'write';
|
||||
}
|
||||
if (administration) {
|
||||
default_permissions.administration = 'write';
|
||||
}
|
||||
const data = {
|
||||
name,
|
||||
url: baseUrl,
|
||||
hook_attributes: {
|
||||
url: `${webhookBaseUrl}/source/github/events`,
|
||||
active: true,
|
||||
},
|
||||
redirect_url: `${webhookBaseUrl}/source/github/redirect`,
|
||||
callback_urls: [`${baseUrl}/login/github/app`],
|
||||
public: false,
|
||||
request_oauth_on_install: false,
|
||||
setup_url: `${webhookBaseUrl}/source/github/install?source=${uuid}`,
|
||||
setup_on_update: true,
|
||||
default_permissions,
|
||||
default_events: ['pull_request', 'push']
|
||||
};
|
||||
const form = document.createElement('form');
|
||||
form.setAttribute('method', 'post');
|
||||
form.setAttribute('action', `${html_url}/${path}?state=${uuid}`);
|
||||
const input = document.createElement('input');
|
||||
input.setAttribute('id', 'manifest');
|
||||
input.setAttribute('name', 'manifest');
|
||||
input.setAttribute('type', 'hidden');
|
||||
input.setAttribute('value', JSON.stringify(data));
|
||||
form.appendChild(input);
|
||||
document.getElementsByTagName('body')[0].appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
</script>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
@ -40,8 +40,8 @@ class="text-warning">{{ session('currentTeam.name') }}</span></span>
|
||||
<span>Currently active team: <span class="text-warning">{{ session('currentTeam.name') }}</span></span>
|
||||
</div>
|
||||
<div>You are not an admin or have been removed from this team. If this does not make sense, please <span
|
||||
class="text-white underline cursor-pointer" wire:click="help" onclick="help.showModal()">contact
|
||||
us</span>.</div>
|
||||
class="text-white underline">contact
|
||||
us at support@lasthourhosting.org</span>.</div>
|
||||
</div>
|
||||
@endif
|
||||
@else
|
||||
|
@ -13,7 +13,7 @@ class="font-normal text-white normal-case border-none rounded btn btn-primary bt
|
||||
</x-slide-over>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 pb-4">You can use these variables anywhere with <span class="text-warning">@{{team.VARIABLENAME}}</span> <x-helper
|
||||
helper="More info <a class='text-white underline' href='https://coolify.io/docs/environment-variables#shared-variables' target='_blank'>here</a>."></x-helper>
|
||||
helper="More info in upstream docs<a class='text-white underline' href='https://coolify.io/docs/environment-variables#shared-variables' target='_blank'>here</a>."></x-helper>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="w-96 min-w-fit">
|
||||
<div class="flex flex-col items-center pb-8">
|
||||
<a href="{{ route('dashboard') }}">
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Coolify</div>
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Last Hour Cloud</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex items-center justify-center pb-4 text-center">
|
||||
|