mirror of
https://github.com/tiennm99/coolify.git
synced 2026-08-21 06:26:22 +00:00
fix(dev): support configurable hosts and light-mode surfaces
Add configurable bind addresses and Vite protocols for development networking, and improve light-mode styling for logs and unsaved-change controls.
This commit is contained in:
@@ -13,7 +13,7 @@ services:
|
||||
- COOLIFY_CLI_VERSION=${COOLIFY_CLI_VERSION:-nightly}
|
||||
- COOLIFY_CLI_CHECKSUM=${COOLIFY_CLI_CHECKSUM:-unknown}
|
||||
ports:
|
||||
- "${APP_PORT:-8000}:8080"
|
||||
- "${DEV_BIND_ADDRESS:-0.0.0.0}:${APP_PORT:-8000}:8080"
|
||||
- "${FORWARD_FLUX_PORT:-6443}:6443"
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
@@ -82,8 +82,8 @@ services:
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "${FORWARD_SOKETI_PORT:-6001}:6001"
|
||||
- "6002:6002"
|
||||
- "${DEV_BIND_ADDRESS:-0.0.0.0}:${FORWARD_SOKETI_PORT:-6001}:6001"
|
||||
- "${DEV_BIND_ADDRESS:-0.0.0.0}:6002:6002"
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
volumes:
|
||||
@@ -111,8 +111,9 @@ services:
|
||||
# Set VITE_HOST in .env to a browser-reachable IP/hostname for LAN/Tailscale access
|
||||
VITE_HOST: "${VITE_HOST:-localhost}"
|
||||
VITE_PORT: "${VITE_PORT:-5173}"
|
||||
VITE_PROTOCOL: "${VITE_PROTOCOL:-http}"
|
||||
ports:
|
||||
- "${VITE_PORT:-5173}:${VITE_PORT:-5173}"
|
||||
- "${DEV_BIND_ADDRESS:-0.0.0.0}:${VITE_PORT:-5173}:${VITE_PORT:-5173}"
|
||||
volumes:
|
||||
- .:/var/www/html/:cached
|
||||
command: sh -c "npm install && npm run dev"
|
||||
|
||||
+12
-2
@@ -2673,6 +2673,16 @@ input[type="search"]::-webkit-search-results-decoration {
|
||||
|
||||
/* Shared logs viewer (deployment + runtime) — mobile-first toolbar
|
||||
Mobile stacks: search → meta → full-width actions (no side-by-side overlap). */
|
||||
.logs-viewer {
|
||||
background: #fff;
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.dark .logs-viewer {
|
||||
background: var(--color-log);
|
||||
color: #f5f5f5;
|
||||
}
|
||||
|
||||
.logs-viewer-toolbar {
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid var(--color-neutral-200);
|
||||
@@ -2934,7 +2944,7 @@ html[data-theme="custom"] .logs-viewer-timestamp {
|
||||
|
||||
.logs-viewer-viewport {
|
||||
min-width: 0;
|
||||
padding: 0.5rem 0.75rem;
|
||||
padding: 0.5rem 0.75rem 2rem;
|
||||
}
|
||||
|
||||
.logs-viewer-line {
|
||||
@@ -3024,7 +3034,7 @@ html[data-theme="custom"] .logs-viewer-timestamp {
|
||||
}
|
||||
|
||||
.logs-viewer-viewport {
|
||||
padding: 0.5rem 1rem;
|
||||
padding: 0.5rem 1rem 2rem;
|
||||
}
|
||||
|
||||
.logs-viewer-line {
|
||||
|
||||
@@ -56,18 +56,18 @@
|
||||
}
|
||||
"
|
||||
@if ($targets) wire:target="{{ $targets }}" @endif
|
||||
class="pointer-events-none fixed inset-x-3 bottom-[calc(var(--keyboard-inset,0px)+max(1.5rem,env(safe-area-inset-bottom,0px)+0.75rem))] z-[1000] flex max-w-full translate-y-6 flex-col items-stretch gap-2 rounded-2xl border border-white/10 bg-surface py-2.5 pr-2.5 pl-4 opacity-0 shadow-modal transition-[opacity,transform] duration-200 ease-out delay-0 [&.is-dirty]:pointer-events-auto [&.is-dirty]:translate-y-0 [&.is-dirty]:opacity-100 [&.is-dirty]:delay-300 sm:inset-x-auto sm:left-1/2 sm:bottom-6 sm:w-max sm:max-w-none sm:-translate-x-1/2 sm:flex-row sm:items-center sm:gap-8 sm:py-2 sm:pl-5 sm:pr-2">
|
||||
<span class="text-[13px] font-semibold leading-snug text-fg sm:whitespace-nowrap">{{ $label }}</span>
|
||||
class="pointer-events-none fixed inset-x-3 bottom-[calc(var(--keyboard-inset,0px)+max(1.5rem,env(safe-area-inset-bottom,0px)+0.75rem))] z-[1000] flex max-w-full translate-y-6 flex-col items-stretch gap-2 rounded-2xl border border-neutral-200 bg-white py-2.5 pr-2.5 pl-4 opacity-0 shadow-modal transition-[opacity,transform] duration-200 ease-out delay-0 dark:border-white/10 dark:bg-surface [&.is-dirty]:pointer-events-auto [&.is-dirty]:translate-y-0 [&.is-dirty]:opacity-100 [&.is-dirty]:delay-300 sm:inset-x-auto sm:left-1/2 sm:bottom-6 sm:w-max sm:max-w-none sm:-translate-x-1/2 sm:flex-row sm:items-center sm:gap-8 sm:py-2 sm:pl-5 sm:pr-2">
|
||||
<span class="text-[13px] font-semibold leading-snug text-neutral-800 dark:text-fg sm:whitespace-nowrap">{{ $label }}</span>
|
||||
<div class="flex shrink-0 items-center justify-end gap-2">
|
||||
<button type="button" onclick="window.location.reload()"
|
||||
class="h-8 rounded-lg bg-white/[0.07] px-3.5 text-[13px] font-medium text-fg transition-colors hover:bg-white/[0.12]">
|
||||
class="h-8 rounded-lg bg-neutral-100 px-3.5 text-[13px] font-medium text-neutral-700 transition-colors hover:bg-neutral-200 dark:bg-white/[0.07] dark:text-fg dark:hover:bg-white/[0.12]">
|
||||
Reset
|
||||
</button>
|
||||
<button type="button" wire:click="{{ $action }}" wire:loading.attr="disabled"
|
||||
class="button-highlighted flex h-8 items-center gap-2 rounded-lg px-4 text-[13px] font-semibold transition-[transform,background-color] active:scale-[0.98]">
|
||||
<span>Save changes</span>
|
||||
<kbd
|
||||
class="rounded border border-white/20 bg-white/10 px-1.5 py-0.5 text-[10px] leading-none font-medium text-white/75">Enter</kbd>
|
||||
class="rounded border border-coollabs/20 bg-coollabs/10 px-1.5 py-0.5 text-[10px] leading-none font-medium text-coollabs-200 dark:border-white/20 dark:bg-white/10 dark:text-white/75">Enter</kbd>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,11 +11,15 @@ test('active deployment log controls use a coollabs background and white icon',
|
||||
|
||||
test('deployment logs use light surfaces in light mode and dark surfaces in dark mode', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/project/application/deployment/show.blade.php'));
|
||||
$styles = file_get_contents(resource_path('css/app.css'));
|
||||
|
||||
expect($view)
|
||||
->toContain('bg-white text-neutral-800')
|
||||
->toContain('dark:bg-[#0d0d0d] dark:text-neutral-100')
|
||||
->toContain('border-neutral-200 shadow-sm dark:border-neutral-800')
|
||||
->toContain('dark:bg-log dark:text-neutral-100')
|
||||
->toContain('border-neutral-200 shadow-sm dark:border-coolgray-200')
|
||||
->toContain('border-neutral-200! bg-white!')
|
||||
->toContain('dark:border-white/[0.08]! dark:bg-white/[0.05]!');
|
||||
->toContain('dark:border-white/[0.08]! dark:bg-white/[0.05]!')
|
||||
->and($styles)
|
||||
->toMatch('/\.logs-viewer\s*\{[^}]*background:\s*#fff;[^}]*color:\s*#262626;/s')
|
||||
->toMatch('/\.dark \.logs-viewer\s*\{[^}]*background:\s*var\(--color-log\);/s');
|
||||
});
|
||||
|
||||
@@ -117,6 +117,8 @@ it('uses a mobile-friendly stacked logs toolbar markup', function () {
|
||||
->toContain('.logs-viewer-actions')
|
||||
->toContain('.logs-viewer-deployment-actions')
|
||||
->toContain('.logs-settings-section')
|
||||
->toContain('padding: 0.5rem 0.75rem 2rem;')
|
||||
->toContain('padding: 0.5rem 1rem 2rem;')
|
||||
->toContain('flex-direction: column')
|
||||
->toContain('@media (min-width: 640px)');
|
||||
|
||||
|
||||
@@ -47,6 +47,25 @@ test('unsaved bar saves with enter and shows the shortcut on the save button', f
|
||||
->toContain('Enter</kbd>');
|
||||
});
|
||||
|
||||
test('unsaved bar keyboard shortcut remains visible in light mode', function () {
|
||||
$contents = file_get_contents(resource_path('views/components/unsaved-bar.blade.php'));
|
||||
|
||||
expect($contents)
|
||||
->toContain('border-coollabs/20 bg-coollabs/10')
|
||||
->toContain('text-coollabs-200')
|
||||
->toContain('dark:border-white/20 dark:bg-white/10 dark:text-white/75');
|
||||
});
|
||||
|
||||
test('unsaved bar uses a light surface in light mode', function () {
|
||||
$contents = file_get_contents(resource_path('views/components/unsaved-bar.blade.php'));
|
||||
|
||||
expect($contents)
|
||||
->toContain('border-neutral-200 bg-white')
|
||||
->toContain('text-neutral-800 dark:text-fg')
|
||||
->toContain('bg-neutral-100')
|
||||
->toContain('dark:bg-white/[0.07]');
|
||||
});
|
||||
|
||||
test('unsaved bar stays above floating notifications so save actions remain accessible', function () {
|
||||
$unsavedBar = file_get_contents(resource_path('views/components/unsaved-bar.blade.php'));
|
||||
$popup = file_get_contents(resource_path('views/components/popup-small.blade.php'));
|
||||
|
||||
+7
-1
@@ -16,6 +16,11 @@ export default defineConfig(({ mode }) => {
|
||||
viteHost
|
||||
).trim();
|
||||
const vitePort = Number(process.env.VITE_PORT || env.VITE_PORT || 5173);
|
||||
const viteProtocol = (
|
||||
process.env.VITE_PROTOCOL ||
|
||||
env.VITE_PROTOCOL ||
|
||||
"http"
|
||||
).trim();
|
||||
|
||||
return {
|
||||
resolve: {
|
||||
@@ -34,10 +39,11 @@ export default defineConfig(({ mode }) => {
|
||||
allowedHosts: true,
|
||||
// App (:8000) and Vite (:5173) are different origins; allow any host in dev
|
||||
cors: true,
|
||||
origin: `http://${viteHost}:${vitePort}`,
|
||||
origin: `${viteProtocol}://${viteHost}:${vitePort}`,
|
||||
hmr: {
|
||||
host: viteHmrHost,
|
||||
clientPort: vitePort,
|
||||
protocol: viteProtocol === "https" ? "wss" : "ws",
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
|
||||
Reference in New Issue
Block a user