feat: Docker + Caddy production deployment setup

This commit is contained in:
2026-05-12 11:46:42 +03:00
parent bc73888355
commit 78b511e65d
5 changed files with 99 additions and 3 deletions
+8
View File
@@ -0,0 +1,8 @@
node_modules
dist
.env
.env.*
!.env.example
.git
.gitignore
*.log
+12 -3
View File
@@ -1,5 +1,14 @@
# Скопируйте этот файл в .env и укажите ваши данные от Telegram бота # Supabase
VITE_TG_BOT_TOKEN="ваш_токен_бота_от_botfather"
VITE_TG_CHAT_ID="ваш_chat_id_куда_отправлять_сообщения"
VITE_SUPABASE_URL=https://your-project.supabase.co VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key VITE_SUPABASE_ANON_KEY=your-anon-key
# Telegram bot (lead form on landing page)
VITE_TG_BOT_TOKEN=your-bot-token
VITE_TG_CHAT_ID=your-chat-id
# Web Push / VAPID (generate with the node command in .env)
VITE_VAPID_PUBLIC_KEY=your-vapid-public-key
# Deployment domain for Caddy (automatic HTTPS)
# Use "localhost" for local dev, set to real domain in production
DOMAIN=localhost
+23
View File
@@ -0,0 +1,23 @@
{$DOMAIN:localhost} {
root * /srv
# Gzip compression
encode gzip
# SPA fallback — all routes serve index.html
try_files {path} /index.html
# Cache static assets aggressively
@static {
path *.js *.css *.png *.jpg *.svg *.ico *.woff2 *.woff
}
header @static Cache-Control "public, max-age=31536000, immutable"
# Service worker must not be cached
@sw {
path /sw.js
}
header @sw Cache-Control "no-cache, no-store, must-revalidate"
file_server
}
+27
View File
@@ -0,0 +1,27 @@
# Stage 1: build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --prefer-offline
COPY . .
ARG VITE_SUPABASE_URL
ARG VITE_SUPABASE_ANON_KEY
ARG VITE_TG_BOT_TOKEN
ARG VITE_TG_CHAT_ID
ARG VITE_VAPID_PUBLIC_KEY
ENV VITE_SUPABASE_URL=$VITE_SUPABASE_URL
ENV VITE_SUPABASE_ANON_KEY=$VITE_SUPABASE_ANON_KEY
ENV VITE_TG_BOT_TOKEN=$VITE_TG_BOT_TOKEN
ENV VITE_TG_CHAT_ID=$VITE_TG_CHAT_ID
ENV VITE_VAPID_PUBLIC_KEY=$VITE_VAPID_PUBLIC_KEY
RUN npm run build
# Stage 2: serve with Caddy
FROM caddy:2-alpine
COPY --from=builder /app/dist /srv
COPY Caddyfile /etc/caddy/Caddyfile
+29
View File
@@ -0,0 +1,29 @@
services:
web:
build:
context: .
args:
VITE_SUPABASE_URL: ${VITE_SUPABASE_URL}
VITE_SUPABASE_ANON_KEY: ${VITE_SUPABASE_ANON_KEY}
VITE_TG_BOT_TOKEN: ${VITE_TG_BOT_TOKEN}
VITE_TG_CHAT_ID: ${VITE_TG_CHAT_ID}
VITE_VAPID_PUBLIC_KEY: ${VITE_VAPID_PUBLIC_KEY}
environment:
DOMAIN: ${DOMAIN:-localhost}
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3
volumes:
- caddy_data:/data # TLS certificates (persisted across restarts)
- caddy_config:/config # Caddy config cache
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:80"]
interval: 30s
timeout: 5s
retries: 3
volumes:
caddy_data:
caddy_config: