feat(picture): migrate web app from Netlify to Docker/Mac Mini deployment

Switch from adapter-netlify to adapter-node for self-hosted Docker deployment.
Add missing Button and Card UI components, remove Netlify config files,
and add picture-backend + picture-web services to docker-compose and
Cloudflare tunnel routing (picture.mana.how).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-20 20:50:12 +01:00
parent 1ffcfa0e5c
commit 3ac976f600
7 changed files with 77 additions and 37 deletions

View file

@ -1 +0,0 @@
/* /index.html 200

View file

@ -1,30 +0,0 @@
[build]
# Build command for the web app in monorepo
command = "cd ../.. && pnpm install --no-frozen-lockfile && pnpm --filter @picture/web... build"
# Directory where the build output is located
publish = ".svelte-kit/netlify"
[build.environment]
# Node version
NODE_VERSION = "20"
# Use pnpm
NPM_FLAGS = "--version"
# Headers for security and performance
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
X-XSS-Protection = "1; mode=block"
Referrer-Policy = "strict-origin-when-cross-origin"
[[headers]]
for = "/*.js"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
[[headers]]
for = "/*.css"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"

View file

@ -41,7 +41,7 @@
"@eslint/js": "^9.36.0",
"@manacore/shared-pwa": "workspace:*",
"@manacore/shared-vite-config": "workspace:*",
"@sveltejs/adapter-netlify": "^5.2.3",
"@sveltejs/adapter-node": "^5.4.0",
"@sveltejs/kit": "^2.47.1",
"@sveltejs/vite-plugin-svelte": "^6.2.0",
"@tailwindcss/forms": "^0.5.10",

View file

@ -0,0 +1,43 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import type { HTMLButtonAttributes } from 'svelte/elements';
interface Props extends HTMLButtonAttributes {
variant?: 'primary' | 'secondary' | 'danger';
loading?: boolean;
children?: Snippet;
}
let {
variant = 'primary',
loading = false,
disabled,
children,
class: className,
...rest
}: Props = $props();
const variantClasses: Record<string, string> = {
primary: 'bg-blue-600 text-white hover:bg-blue-700 disabled:bg-blue-300',
secondary:
'bg-gray-100 text-gray-700 hover:bg-gray-200 disabled:bg-gray-50 disabled:text-gray-400',
danger: 'bg-red-600 text-white hover:bg-red-700 disabled:bg-red-300',
};
</script>
<button
class="inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed {variantClasses[
variant
]} {className ?? ''}"
disabled={disabled || loading}
{...rest}
>
{#if loading}
<div
class="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current border-r-transparent"
></div>
{/if}
{#if children}
{@render children()}
{/if}
</button>

View file

@ -0,0 +1,16 @@
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
class?: string;
children?: Snippet;
}
let { class: className, children }: Props = $props();
</script>
<div class="rounded-lg border border-gray-200 bg-white shadow-sm {className ?? ''}">
{#if children}
{@render children()}
{/if}
</div>

View file

@ -1,12 +1,15 @@
import adapter from '@sveltejs/adapter-netlify';
import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://svelte.dev/docs/kit/integrations
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: { adapter: adapter() },
kit: {
adapter: adapter({
out: 'build',
}),
},
};
export default config;

11
pnpm-lock.yaml generated
View file

@ -3960,7 +3960,7 @@ importers:
specifier: workspace:*
version: link:../../../../packages/shared-vite-config
'@sveltejs/adapter-node':
specifier: ^5.2.12
specifier: ^5.4.0
version: 5.4.0(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.44.0)(vite@7.2.4(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.1)))(svelte@5.44.0)(vite@7.2.4(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.1)))
'@sveltejs/kit':
specifier: ^2.47.1
@ -5950,6 +5950,15 @@ importers:
specifier: ^5.3.0
version: 5.9.3
games/whopixels:
dependencies:
dotenv:
specifier: ^16.4.7
version: 16.6.1
node-fetch:
specifier: ^2.7.0
version: 2.7.0(encoding@0.1.13)
packages/bot-services:
dependencies:
'@nestjs/common':