Fix Docker deployment and runtime environment variables

- Add --break-system-packages flag to pip install for Alpine Linux 3.12+ compatibility
- Configure Astro server to bind to 0.0.0.0 for Docker container accessibility
- Replace import.meta.env with process.env for runtime environment variable access in SSR
- Enable dynamic LOGIN configuration at runtime

Co-Authored-By: Warp <agent@warp.dev>
This commit is contained in:
root
2025-12-22 12:41:22 +01:00
parent 4fd9d3f400
commit eb32dd1064
11 changed files with 19 additions and 17 deletions

View File

@@ -8,7 +8,7 @@ RUN apk add --no-cache \
python3 \
py3-pip \
ffmpeg \
&& pip3 install --no-cache-dir yt-dlp
&& pip3 install --no-cache-dir --break-system-packages yt-dlp
WORKDIR /app

View File

@@ -12,6 +12,10 @@ export default defineConfig({
adapter: node({
mode: 'standalone'
}),
server: {
host: '0.0.0.0',
port: 4321
},
i18n: {
defaultLocale: 'de',
locales: ['de', 'en'],
@@ -20,4 +24,3 @@ export default defineConfig({
}
}
});

View File

@@ -1,7 +1,7 @@
---
import { t } from "../lib/i18n";
const streamOnly = import.meta.env.STREAM_ONLY === "true";
const streamOnly = process.env.STREAM_ONLY === "true";
---
<div class="container mx-auto px-4 py-8 max-w-2xl">

View File

@@ -10,7 +10,7 @@ interface Props {
const { title } = Astro.props;
const loginEnabled = isLoginEnabled();
const session = await getSession(Astro.request);
const streamOnly = import.meta.env.STREAM_ONLY === "true";
const streamOnly = process.env.STREAM_ONLY === "true";
const locale = getLocale(Astro);
---

View File

@@ -14,7 +14,7 @@ const translations: Record<string, Translations> = {
*/
export function getLocale(astro: AstroGlobal): string {
// Check environment variable first (for Docker/container environments)
const envLocale = import.meta.env.LOCALE;
const envLocale = process.env.LOCALE;
if (envLocale && (envLocale === 'de' || envLocale === 'en')) {
return envLocale;
}
@@ -26,7 +26,7 @@ export function getLocale(astro: AstroGlobal): string {
*/
export function getLocaleFromRequest(request: Request): string {
// Check environment variable first (for Docker/container environments)
const envLocale = import.meta.env.LOCALE;
const envLocale = process.env.LOCALE;
if (envLocale && (envLocale === 'de' || envLocale === 'en')) {
return envLocale;
}

View File

@@ -1,7 +1,7 @@
import type { Request } from 'astro';
const SESSION_COOKIE = 'session';
const SESSION_SECRET = import.meta.env.SESSION_SECRET || 'default-secret-change-in-production';
const SESSION_SECRET = process.env.SESSION_SECRET || 'default-secret-change-in-production';
export interface Session {
username: string;
@@ -13,7 +13,7 @@ export interface Session {
* Wenn LOGIN=false oder nicht gesetzt, ist Login deaktiviert
*/
export function isLoginEnabled(): boolean {
const loginEnabled = import.meta.env.LOGIN;
const loginEnabled = process.env.LOGIN;
// Wenn LOGIN explizit auf "false" gesetzt ist, ist Login deaktiviert
// Ansonsten ist Login aktiviert (Standard-Verhalten)
return loginEnabled !== "false";
@@ -52,4 +52,3 @@ export function createSessionCookie(session: Session): string {
export function clearSessionCookie(): string {
return `${SESSION_COOKIE}=; HttpOnly; Path=/; Max-Age=0; SameSite=Lax`;
}

View File

@@ -25,7 +25,7 @@ export const GET: APIRoute = async ({ request }) => {
// Download-Verzeichnis aus Environment-Variable
const downloadDir =
import.meta.env.DOWNLOAD_DIR || path.join(process.cwd(), "downloaded");
process.env.DOWNLOAD_DIR || path.join(process.cwd(), "downloaded");
const filePath = path.join(downloadDir, fileName);

View File

@@ -48,7 +48,7 @@ export const POST: APIRoute = async ({ request }) => {
}
// Prüfe ob Stream-Modus aktiviert ist
const streamOnly = import.meta.env.STREAM_ONLY === "true";
const streamOnly = process.env.STREAM_ONLY === "true";
// yt-dlp-wrap Instanz erstellen
const ytDlpWrap = new YTDlpWrap();
@@ -154,7 +154,7 @@ export const POST: APIRoute = async ({ request }) => {
} else {
// NORMALER MODUS: Datei speichern wie bisher
const downloadDir =
import.meta.env.DOWNLOAD_DIR || path.join(process.cwd(), "downloaded");
process.env.DOWNLOAD_DIR || path.join(process.cwd(), "downloaded");
// Verzeichnis erstellen falls nicht vorhanden
try {

View File

@@ -19,7 +19,7 @@ export const GET: APIRoute = async ({ request }) => {
}
// Prüfe ob Stream-Modus aktiviert ist
const streamOnly = import.meta.env.STREAM_ONLY === "true";
const streamOnly = process.env.STREAM_ONLY === "true";
if (streamOnly) {
return new Response(
JSON.stringify({
@@ -36,7 +36,7 @@ export const GET: APIRoute = async ({ request }) => {
try {
// Download-Verzeichnis aus Environment-Variable
const downloadDir =
import.meta.env.DOWNLOAD_DIR || path.join(process.cwd(), "downloaded");
process.env.DOWNLOAD_DIR || path.join(process.cwd(), "downloaded");
if (!existsSync(downloadDir)) {
return new Response(JSON.stringify({ files: [] }), {

View File

@@ -16,8 +16,8 @@ export const POST: APIRoute = async ({ request }) => {
const password = formData.get('password')?.toString();
// Credentials aus Environment-Variablen
const envUsername = import.meta.env.LOGIN_USERNAME;
const envPassword = import.meta.env.LOGIN_PASSWORD;
const envUsername = process.env.LOGIN_USERNAME;
const envPassword = process.env.LOGIN_PASSWORD;
// Prüfe ob Credentials konfiguriert sind
if (!envUsername || !envPassword) {

View File

@@ -11,7 +11,7 @@ if (loginEnabled && !session) {
return Astro.redirect('/');
}
const streamOnly = import.meta.env.STREAM_ONLY === "true";
const streamOnly = process.env.STREAM_ONLY === "true";
---
<Layout title={t(Astro, "files.title")}>