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:
@@ -8,7 +8,7 @@ RUN apk add --no-cache \
|
|||||||
python3 \
|
python3 \
|
||||||
py3-pip \
|
py3-pip \
|
||||||
ffmpeg \
|
ffmpeg \
|
||||||
&& pip3 install --no-cache-dir yt-dlp
|
&& pip3 install --no-cache-dir --break-system-packages yt-dlp
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ export default defineConfig({
|
|||||||
adapter: node({
|
adapter: node({
|
||||||
mode: 'standalone'
|
mode: 'standalone'
|
||||||
}),
|
}),
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 4321
|
||||||
|
},
|
||||||
i18n: {
|
i18n: {
|
||||||
defaultLocale: 'de',
|
defaultLocale: 'de',
|
||||||
locales: ['de', 'en'],
|
locales: ['de', 'en'],
|
||||||
@@ -20,4 +24,3 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { t } from "../lib/i18n";
|
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">
|
<div class="container mx-auto px-4 py-8 max-w-2xl">
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ interface Props {
|
|||||||
const { title } = Astro.props;
|
const { title } = Astro.props;
|
||||||
const loginEnabled = isLoginEnabled();
|
const loginEnabled = isLoginEnabled();
|
||||||
const session = await getSession(Astro.request);
|
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);
|
const locale = getLocale(Astro);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const translations: Record<string, Translations> = {
|
|||||||
*/
|
*/
|
||||||
export function getLocale(astro: AstroGlobal): string {
|
export function getLocale(astro: AstroGlobal): string {
|
||||||
// Check environment variable first (for Docker/container environments)
|
// 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')) {
|
if (envLocale && (envLocale === 'de' || envLocale === 'en')) {
|
||||||
return envLocale;
|
return envLocale;
|
||||||
}
|
}
|
||||||
@@ -26,7 +26,7 @@ export function getLocale(astro: AstroGlobal): string {
|
|||||||
*/
|
*/
|
||||||
export function getLocaleFromRequest(request: Request): string {
|
export function getLocaleFromRequest(request: Request): string {
|
||||||
// Check environment variable first (for Docker/container environments)
|
// 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')) {
|
if (envLocale && (envLocale === 'de' || envLocale === 'en')) {
|
||||||
return envLocale;
|
return envLocale;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { Request } from 'astro';
|
import type { Request } from 'astro';
|
||||||
|
|
||||||
const SESSION_COOKIE = 'session';
|
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 {
|
export interface Session {
|
||||||
username: string;
|
username: string;
|
||||||
@@ -13,7 +13,7 @@ export interface Session {
|
|||||||
* Wenn LOGIN=false oder nicht gesetzt, ist Login deaktiviert
|
* Wenn LOGIN=false oder nicht gesetzt, ist Login deaktiviert
|
||||||
*/
|
*/
|
||||||
export function isLoginEnabled(): boolean {
|
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
|
// Wenn LOGIN explizit auf "false" gesetzt ist, ist Login deaktiviert
|
||||||
// Ansonsten ist Login aktiviert (Standard-Verhalten)
|
// Ansonsten ist Login aktiviert (Standard-Verhalten)
|
||||||
return loginEnabled !== "false";
|
return loginEnabled !== "false";
|
||||||
@@ -52,4 +52,3 @@ export function createSessionCookie(session: Session): string {
|
|||||||
export function clearSessionCookie(): string {
|
export function clearSessionCookie(): string {
|
||||||
return `${SESSION_COOKIE}=; HttpOnly; Path=/; Max-Age=0; SameSite=Lax`;
|
return `${SESSION_COOKIE}=; HttpOnly; Path=/; Max-Age=0; SameSite=Lax`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const GET: APIRoute = async ({ request }) => {
|
|||||||
|
|
||||||
// Download-Verzeichnis aus Environment-Variable
|
// Download-Verzeichnis aus Environment-Variable
|
||||||
const downloadDir =
|
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);
|
const filePath = path.join(downloadDir, fileName);
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export const POST: APIRoute = async ({ request }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prüfe ob Stream-Modus aktiviert ist
|
// 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
|
// yt-dlp-wrap Instanz erstellen
|
||||||
const ytDlpWrap = new YTDlpWrap();
|
const ytDlpWrap = new YTDlpWrap();
|
||||||
@@ -154,7 +154,7 @@ export const POST: APIRoute = async ({ request }) => {
|
|||||||
} else {
|
} else {
|
||||||
// NORMALER MODUS: Datei speichern wie bisher
|
// NORMALER MODUS: Datei speichern wie bisher
|
||||||
const downloadDir =
|
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
|
// Verzeichnis erstellen falls nicht vorhanden
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const GET: APIRoute = async ({ request }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prüfe ob Stream-Modus aktiviert ist
|
// Prüfe ob Stream-Modus aktiviert ist
|
||||||
const streamOnly = import.meta.env.STREAM_ONLY === "true";
|
const streamOnly = process.env.STREAM_ONLY === "true";
|
||||||
if (streamOnly) {
|
if (streamOnly) {
|
||||||
return new Response(
|
return new Response(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@@ -36,7 +36,7 @@ export const GET: APIRoute = async ({ request }) => {
|
|||||||
try {
|
try {
|
||||||
// Download-Verzeichnis aus Environment-Variable
|
// Download-Verzeichnis aus Environment-Variable
|
||||||
const downloadDir =
|
const downloadDir =
|
||||||
import.meta.env.DOWNLOAD_DIR || path.join(process.cwd(), "downloaded");
|
process.env.DOWNLOAD_DIR || path.join(process.cwd(), "downloaded");
|
||||||
|
|
||||||
if (!existsSync(downloadDir)) {
|
if (!existsSync(downloadDir)) {
|
||||||
return new Response(JSON.stringify({ files: [] }), {
|
return new Response(JSON.stringify({ files: [] }), {
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ export const POST: APIRoute = async ({ request }) => {
|
|||||||
const password = formData.get('password')?.toString();
|
const password = formData.get('password')?.toString();
|
||||||
|
|
||||||
// Credentials aus Environment-Variablen
|
// Credentials aus Environment-Variablen
|
||||||
const envUsername = import.meta.env.LOGIN_USERNAME;
|
const envUsername = process.env.LOGIN_USERNAME;
|
||||||
const envPassword = import.meta.env.LOGIN_PASSWORD;
|
const envPassword = process.env.LOGIN_PASSWORD;
|
||||||
|
|
||||||
// Prüfe ob Credentials konfiguriert sind
|
// Prüfe ob Credentials konfiguriert sind
|
||||||
if (!envUsername || !envPassword) {
|
if (!envUsername || !envPassword) {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ if (loginEnabled && !session) {
|
|||||||
return Astro.redirect('/');
|
return Astro.redirect('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
const streamOnly = import.meta.env.STREAM_ONLY === "true";
|
const streamOnly = process.env.STREAM_ONLY === "true";
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={t(Astro, "files.title")}>
|
<Layout title={t(Astro, "files.title")}>
|
||||||
|
|||||||
Reference in New Issue
Block a user