diff --git a/.dockerignore b/.dockerignore index aae7ec5..8ca8992 100644 --- a/.dockerignore +++ b/.dockerignore @@ -45,3 +45,7 @@ coverage .DS_Store *.log *.tmp + +# Exclude wyoming-piper directory (should not be in aitherboard image) +wyoming-piper/ +piper-data/ diff --git a/Dockerfile b/Dockerfile index 2b10ce6..5f0894e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,6 +23,9 @@ RUN npm ci --only=production && npm cache clean --force # Copy built application from builder stage COPY --from=builder /app/build ./build +# Copy public directory (for static assets like changelog.yaml, healthz.json) +COPY --from=builder /app/public ./public + # Copy entrypoint script COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/docker-entrypoint.sh diff --git a/docker-compose.yml b/docker-compose.yml index 9cfffbe..93bb24e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,16 @@ services: aitherboard: container_name: aitherboard - build: - context: . - # Optional: override defaults from config.ts if needed - # Uncomment and modify if you want custom values: - # args: - # VITE_DEFAULT_RELAYS: "wss://theforest.nostr1.com,wss://nostr21.com,wss://nostr.land" - # VITE_THREAD_TIMEOUT_DAYS: "30" + # Using pre-built image (recommended for production) + image: silberengel/aitherboard:latest + # Alternative: Build from source (for development) + # build: + # context: . + # # Optional: override defaults from config.ts if needed + # # Uncomment and modify if you want custom values: + # # args: + # # VITE_DEFAULT_RELAYS: "wss://theforest.nostr1.com,wss://nostr21.com,wss://nostr.land" + # # VITE_THREAD_TIMEOUT_DAYS: "30" ports: - "9876:9876" environment: @@ -24,12 +27,20 @@ services: piper-tts: container_name: piper-tts - # Using official Wyoming Piper from source - # To build locally: git clone https://github.com/rhasspy/wyoming-piper.git wyoming-piper - # Then change build.context to ./wyoming-piper - build: - context: ./wyoming-piper - dockerfile: Dockerfile + # Option 1: Use pre-built image (recommended for production) + # Build and push the image first: + # 1. git clone https://github.com/rhasspy/wyoming-piper.git wyoming-piper + # 2. cd wyoming-piper + # 3. docker build -t your-registry/wyoming-piper:latest . + # 4. docker push your-registry/wyoming-piper:latest + # Then uncomment the image line below and update with your registry/image name + image: silberengel/wyoming-piper:latest + + # Option 2: Build from source (for development or if no registry) + # Uncomment the build section below and comment out the image line above + #build: + #context: ./wyoming-piper + #dockerfile: Dockerfile # Port 10200 is only used internally by aitherboard container # No need to expose it to the host expose: diff --git a/package-lock.json b/package-lock.json index 10ace07..c07e2aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,6 +42,7 @@ "@sveltejs/adapter-node": "^5.5.2", "@sveltejs/adapter-static": "^3.0.0", "@types/dompurify": "^3.0.5", + "@types/js-yaml": "^4.0.9", "@types/marked": "^6.0.0", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", @@ -3554,6 +3555,13 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", diff --git a/package.json b/package.json index 2f3519c..dc633b9 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@sveltejs/adapter-node": "^5.5.2", "@sveltejs/adapter-static": "^3.0.0", "@types/dompurify": "^3.0.5", + "@types/js-yaml": "^4.0.9", "@types/marked": "^6.0.0", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", diff --git a/src/routes/changelog.yaml/+server.ts b/src/routes/changelog.yaml/+server.ts new file mode 100644 index 0000000..5f5e66c --- /dev/null +++ b/src/routes/changelog.yaml/+server.ts @@ -0,0 +1,50 @@ +import { readFileSync } from 'fs'; +import { join } from 'path'; +import type { RequestHandler } from '@sveltejs/kit'; + +export const GET: RequestHandler = async () => { + try { + // Try multiple possible locations for changelog.yaml + // 1. In public directory (development) + // 2. In build/client (production - where SvelteKit copies public files) + // 3. In the copied public directory (Docker) + const possiblePaths = [ + join(process.cwd(), 'public', 'changelog.yaml'), + join(process.cwd(), 'build', 'client', 'changelog.yaml'), + join(process.cwd(), '..', 'public', 'changelog.yaml'), + '/app/public/changelog.yaml' // Docker container path + ]; + + let changelogContent: string | null = null; + for (const path of possiblePaths) { + try { + changelogContent = readFileSync(path, 'utf-8'); + break; // Found it, stop trying + } catch { + // Try next path + continue; + } + } + + if (!changelogContent) { + throw new Error('changelog.yaml not found in any expected location'); + } + + return new Response(changelogContent, { + headers: { + 'Content-Type': 'application/x-yaml', + 'Cache-Control': 'public, max-age=3600' // Cache for 1 hour + } + }); + } catch (error) { + console.error('Failed to read changelog.yaml:', error); + // Return empty changelog on error + const emptyChangelog = 'versions:\n'; + return new Response(emptyChangelog, { + status: 404, + headers: { + 'Content-Type': 'application/x-yaml' + } + }); + } +};