diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..6b2961f79 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +FROM node:22-alpine AS builder + +WORKDIR /app + +COPY package*.json ./ +RUN npm ci + +COPY . . + +ARG TELEGRAM_API_ID +ARG TELEGRAM_API_HASH +ARG BASE_URL=/ + +ENV TELEGRAM_API_ID=$TELEGRAM_API_ID +ENV TELEGRAM_API_HASH=$TELEGRAM_API_HASH +ENV BASE_URL=$BASE_URL +ENV NODE_ENV=production + +RUN npm run build:production + +# --- + +FROM nginx:alpine + +COPY --from=builder /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..4246b1804 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +services: + telegram-tt: + build: + context: . + args: + TELEGRAM_API_ID: ${TELEGRAM_API_ID} + TELEGRAM_API_HASH: ${TELEGRAM_API_HASH} + BASE_URL: ${BASE_URL:-/} + restart: unless-stopped + ports: + - "${PORT:-8080}:80" diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 000000000..96f5430ff --- /dev/null +++ b/nginx.conf @@ -0,0 +1,33 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # WASM needs correct MIME type + types { + application/wasm wasm; + } + + # SharedArrayBuffer requires these headers (used by audio/video workers) + add_header Cross-Origin-Opener-Policy "same-origin"; + add_header Cross-Origin-Embedder-Policy "require-corp"; + + # SPA fallback + location / { + try_files $uri $uri/ /index.html; + } + + # Cache static assets aggressively (content-hashed filenames) + location ~* \.(js|css|wasm|woff2|woff|ttf|png|jpg|webp|svg|ico)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header Cross-Origin-Opener-Policy "same-origin"; + add_header Cross-Origin-Embedder-Policy "require-corp"; + } + + gzip on; + gzip_types text/plain text/css application/javascript application/json application/wasm; + gzip_min_length 1024; +}