mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-03 06:56:15 +00:00
reverse proxy basics (#609)
This commit is contained in:
@ -13,6 +13,7 @@
|
|||||||
use App\Notifications\SiteInstallationSucceed;
|
use App\Notifications\SiteInstallationSucceed;
|
||||||
use App\ValidationRules\DomainRule;
|
use App\ValidationRules\DomainRule;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@ -38,6 +39,7 @@ public function create(Server $server, array $input): Site
|
|||||||
'type' => $input['type'],
|
'type' => $input['type'],
|
||||||
'domain' => $input['domain'],
|
'domain' => $input['domain'],
|
||||||
'aliases' => $input['aliases'] ?? [],
|
'aliases' => $input['aliases'] ?? [],
|
||||||
|
'port' => $input['port'] ?? null,
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
'path' => '/home/'.$user.'/'.$input['domain'],
|
'path' => '/home/'.$user.'/'.$input['domain'],
|
||||||
'status' => SiteStatus::INSTALLING,
|
'status' => SiteStatus::INSTALLING,
|
||||||
@ -132,6 +134,14 @@ public static function rules(Server $server, array $input): array
|
|||||||
Rule::unique('sites', 'user')->where('server_id', $server->id),
|
Rule::unique('sites', 'user')->where('server_id', $server->id),
|
||||||
Rule::notIn($server->getSshUsers()),
|
Rule::notIn($server->getSshUsers()),
|
||||||
],
|
],
|
||||||
|
'port' => [
|
||||||
|
'nullable',
|
||||||
|
'integer',
|
||||||
|
'min:1',
|
||||||
|
'max:65535',
|
||||||
|
Rule::unique('sites', 'port')
|
||||||
|
->where(fn (Builder $query) => $query->where('server_id', $server->id)),
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
return array_merge($rules, self::typeRules($server, $input));
|
return array_merge($rules, self::typeRules($server, $input));
|
||||||
|
30
app/Http/Controllers/SearchController.php
Normal file
30
app/Http/Controllers/SearchController.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Spatie\RouteAttributes\Attributes\Get;
|
||||||
|
use Spatie\RouteAttributes\Attributes\Middleware;
|
||||||
|
use Spatie\RouteAttributes\Attributes\Prefix;
|
||||||
|
|
||||||
|
#[Prefix('search')]
|
||||||
|
#[Middleware(['auth'])]
|
||||||
|
class SearchController extends Controller
|
||||||
|
{
|
||||||
|
#[Get('/', name: 'search')]
|
||||||
|
public function search(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$this->validate($request, [
|
||||||
|
'query' => 'required|string|min:3',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$query = $request->input('query');
|
||||||
|
|
||||||
|
$results = [
|
||||||
|
'data' => [], // Replace with actual search results
|
||||||
|
];
|
||||||
|
|
||||||
|
return response()->json($results);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, C
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { CommandIcon, SearchIcon } from 'lucide-react';
|
import { CommandIcon, SearchIcon } from 'lucide-react';
|
||||||
|
import CreateServer from '@/pages/servers/components/create-server';
|
||||||
|
|
||||||
export default function AppCommand() {
|
export default function AppCommand() {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
@ -33,7 +34,9 @@ export default function AppCommand() {
|
|||||||
<CommandList>
|
<CommandList>
|
||||||
<CommandEmpty>No results found.</CommandEmpty>
|
<CommandEmpty>No results found.</CommandEmpty>
|
||||||
<CommandGroup heading="Suggestions">
|
<CommandGroup heading="Suggestions">
|
||||||
<CommandItem>Create server</CommandItem>
|
<CreateServer>
|
||||||
|
<CommandItem>Create server</CommandItem>
|
||||||
|
</CreateServer>
|
||||||
<CommandItem>Create project</CommandItem>
|
<CommandItem>Create project</CommandItem>
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
</CommandList>
|
</CommandList>
|
||||||
|
@ -47,7 +47,7 @@ function SheetContent({
|
|||||||
<SheetPrimitive.Content
|
<SheetPrimitive.Content
|
||||||
data-slot="sheet-content"
|
data-slot="sheet-content"
|
||||||
className={cn(
|
className={cn(
|
||||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col overflow-y-auto shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
||||||
side === 'right' &&
|
side === 'right' &&
|
||||||
'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
|
'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
|
||||||
side === 'left' &&
|
side === 'left' &&
|
||||||
|
@ -25,6 +25,7 @@ type CreateSiteForm = {
|
|||||||
php_version: string;
|
php_version: string;
|
||||||
source_control: string;
|
source_control: string;
|
||||||
user: string;
|
user: string;
|
||||||
|
port: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function CreateSite({ server, children }: { server?: Server; children: ReactNode }) {
|
export default function CreateSite({ server, children }: { server?: Server; children: ReactNode }) {
|
||||||
@ -39,6 +40,7 @@ export default function CreateSite({ server, children }: { server?: Server; chil
|
|||||||
php_version: '',
|
php_version: '',
|
||||||
source_control: '',
|
source_control: '',
|
||||||
user: '',
|
user: '',
|
||||||
|
port: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const submit: FormEventHandler = (e) => {
|
const submit: FormEventHandler = (e) => {
|
||||||
@ -154,6 +156,15 @@ export default function CreateSite({ server, children }: { server?: Server; chil
|
|||||||
<InputError message={form.errors.aliases} />
|
<InputError message={form.errors.aliases} />
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
|
<FormField>
|
||||||
|
<Label htmlFor="port">Reverse proxy port</Label>
|
||||||
|
<Input id="port" type="text" value={form.data.port} onChange={(e) => form.setData('port', e.target.value)} placeholder="3000" />
|
||||||
|
<p className="text-muted-foreground text-xs">
|
||||||
|
This port will be used for reverse proxying the site. It should be unique across all sites on the server.
|
||||||
|
</p>
|
||||||
|
<InputError message={form.errors.port} />
|
||||||
|
</FormField>
|
||||||
|
|
||||||
{page.props.configs.site_types_custom_fields[form.data.type].map((config) => getFormField(config))}
|
{page.props.configs.site_types_custom_fields[form.data.type].map((config) => getFormField(config))}
|
||||||
|
|
||||||
<FormField>
|
<FormField>
|
||||||
|
@ -8,17 +8,21 @@
|
|||||||
import access_log {{ $site->domain }}
|
import access_log {{ $site->domain }}
|
||||||
import compression
|
import compression
|
||||||
import security_headers
|
import security_headers
|
||||||
@if ($site->type()->language() === 'php')
|
@if ($site->port)
|
||||||
root * {{ $site->getWebDirectoryPath() }}
|
reverse_proxy 127.0.0.1:{{ $site->port }}
|
||||||
@php
|
@else
|
||||||
$phpSocket = "unix//var/run/php/php{$site->php_version}-fpm.sock";
|
@if ($site->type()->language() === 'php')
|
||||||
if ($site->isIsolated()) {
|
root * {{ $site->getWebDirectoryPath() }}
|
||||||
$phpSocket = "unix//run/php/php{$site->php_version}-fpm-{$site->user}.sock";
|
@php
|
||||||
}
|
$phpSocket = "unix//var/run/php/php{$site->php_version}-fpm.sock";
|
||||||
@endphp
|
if ($site->isIsolated()) {
|
||||||
try_files {path} {path}/ /index.php?{query}
|
$phpSocket = "unix//run/php/php{$site->php_version}-fpm-{$site->user}.sock";
|
||||||
php_fastcgi {{ $phpSocket }}
|
}
|
||||||
file_server
|
@endphp
|
||||||
|
try_files {path} {path}/ /index.php?{query}
|
||||||
|
php_fastcgi {{ $phpSocket }}
|
||||||
|
file_server
|
||||||
|
@endif
|
||||||
@endif
|
@endif
|
||||||
@if ($site->type === \App\Enums\SiteType::LOAD_BALANCER)
|
@if ($site->type === \App\Enums\SiteType::LOAD_BALANCER)
|
||||||
reverse_proxy {
|
reverse_proxy {
|
||||||
@ -44,4 +48,4 @@
|
|||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
@include('ssh.services.webserver.caddy.redirects', ['site' => $site])
|
@include('ssh.services.webserver.caddy.redirects', ['site' => $site])
|
||||||
}
|
}
|
||||||
|
@ -51,31 +51,41 @@
|
|||||||
|
|
||||||
charset utf-8;
|
charset utf-8;
|
||||||
|
|
||||||
@if ($site->type()->language() === 'php')
|
@if ($site->port)
|
||||||
@php
|
|
||||||
$phpSocket = "unix:/var/run/php/php{$site->php_version}-fpm.sock";
|
|
||||||
if ($site->isIsolated()) {
|
|
||||||
$phpSocket = "unix:/run/php/php{$site->php_version}-fpm-{$site->user}.sock";
|
|
||||||
}
|
|
||||||
@endphp
|
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /index.php?$query_string;
|
proxy_pass http://127.0.0.1:{{ $site->port }};
|
||||||
}
|
proxy_set_header Host $host;
|
||||||
location ~ \.php$ {
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
fastcgi_pass {{ $phpSocket }};
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
include fastcgi_params;
|
|
||||||
fastcgi_hide_header X-Powered-By;
|
|
||||||
}
|
}
|
||||||
|
@else
|
||||||
|
@if ($site->type()->language() === 'php')
|
||||||
|
@php
|
||||||
|
$phpSocket = "unix:/var/run/php/php{$site->php_version}-fpm.sock";
|
||||||
|
if ($site->isIsolated()) {
|
||||||
|
$phpSocket = "unix:/run/php/php{$site->php_version}-fpm-{$site->user}.sock";
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_pass {{ $phpSocket }};
|
||||||
|
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_hide_header X-Powered-By;
|
||||||
|
}
|
||||||
|
@endif
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($site->type === \App\Enums\SiteType::LOAD_BALANCER)
|
@if ($site->type === \App\Enums\SiteType::LOAD_BALANCER)
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://{{ $backendName }}$request_uri;
|
proxy_pass http://{{ $backendName }}$request_uri;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user