update docker
This commit is contained in:
22
Dockerfile
22
Dockerfile
@@ -10,20 +10,10 @@ WORKDIR /app
|
|||||||
COPY package.json package-lock.json ./
|
COPY package.json package-lock.json ./
|
||||||
RUN npm ci
|
RUN npm ci
|
||||||
|
|
||||||
# Copy source
|
# Copy source and build — no VITE_* args needed at build time.
|
||||||
|
# Supabase keys are injected at runtime via docker/entrypoint.sh → window.__ENV__
|
||||||
COPY . .
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
# VITE_* vars are Supabase public keys — safe for browser, baked into bundle at build time.
|
|
||||||
# Using ARG only (no ENV) so values don't persist as image-layer env vars.
|
|
||||||
ARG VITE_SUPABASE_URL
|
|
||||||
ARG VITE_SUPABASE_ANON_KEY
|
|
||||||
ARG VITE_SUPABASE_PUBLISHABLE_KEY
|
|
||||||
|
|
||||||
# Pass vars inline so they're scoped to this RUN layer only
|
|
||||||
RUN VITE_SUPABASE_URL="$VITE_SUPABASE_URL" \
|
|
||||||
VITE_SUPABASE_ANON_KEY="$VITE_SUPABASE_ANON_KEY" \
|
|
||||||
VITE_SUPABASE_PUBLISHABLE_KEY="$VITE_SUPABASE_PUBLISHABLE_KEY" \
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# Stage 2 — Serve
|
# Stage 2 — Serve
|
||||||
@@ -37,6 +27,10 @@ COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|||||||
# Copy built static files from builder
|
# Copy built static files from builder
|
||||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Entrypoint generates env.js from runtime env vars before starting nginx
|
||||||
|
COPY docker/entrypoint.sh /entrypoint.sh
|
||||||
|
RUN chmod +x /entrypoint.sh
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
CMD ["/entrypoint.sh"]
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
|
||||||
VITE_SUPABASE_URL: ${VITE_SUPABASE_URL}
|
|
||||||
VITE_SUPABASE_ANON_KEY: ${VITE_SUPABASE_ANON_KEY}
|
|
||||||
VITE_SUPABASE_PUBLISHABLE_KEY: ${VITE_SUPABASE_PUBLISHABLE_KEY}
|
|
||||||
image: renolation/english-toeic:latest
|
image: renolation/english-toeic:latest
|
||||||
|
environment:
|
||||||
|
- VITE_SUPABASE_URL=${VITE_SUPABASE_URL}
|
||||||
|
- VITE_SUPABASE_ANON_KEY=${VITE_SUPABASE_ANON_KEY}
|
||||||
|
- VITE_SUPABASE_PUBLISHABLE_KEY=${VITE_SUPABASE_PUBLISHABLE_KEY}
|
||||||
ports:
|
ports:
|
||||||
- "${APP_PORT:-3000}:80"
|
- "${APP_PORT:-3000}:80"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
10
docker/entrypoint.sh
Normal file
10
docker/entrypoint.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Generate runtime env.js from container environment variables
|
||||||
|
cat > /usr/share/nginx/html/env.js <<EOF
|
||||||
|
window.__ENV__ = {
|
||||||
|
VITE_SUPABASE_URL: "${VITE_SUPABASE_URL}",
|
||||||
|
VITE_SUPABASE_ANON_KEY: "${VITE_SUPABASE_ANON_KEY}",
|
||||||
|
VITE_SUPABASE_PUBLISHABLE_KEY: "${VITE_SUPABASE_PUBLISHABLE_KEY}"
|
||||||
|
};
|
||||||
|
EOF
|
||||||
|
exec nginx -g 'daemon off;'
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
<html lang="vi">
|
<html lang="vi">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
<script src="/env.js"></script>
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>EnglishAI — Luyện TOEIC thông minh</title>
|
<title>EnglishAI — Luyện TOEIC thông minh</title>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ server {
|
|||||||
|
|
||||||
# Health check endpoint
|
# Health check endpoint
|
||||||
location /health {
|
location /health {
|
||||||
|
access_log off;
|
||||||
return 200 "ok";
|
return 200 "ok";
|
||||||
add_header Content-Type text/plain;
|
add_header Content-Type text/plain;
|
||||||
}
|
}
|
||||||
|
|||||||
1
public/env.js
Normal file
1
public/env.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
window.__ENV__ = {};
|
||||||
@@ -114,7 +114,7 @@ export function useWritingCheck() {
|
|||||||
const feedback = await callEdgeFunction(content, onChunk)
|
const feedback = await callEdgeFunction(content, onChunk)
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
saveWritingSubmission(user.id, content, feedback)
|
await saveWritingSubmission(user.id, content, feedback)
|
||||||
queryClient.invalidateQueries({ queryKey: ["writing-history"] })
|
queryClient.invalidateQueries({ queryKey: ["writing-history"] })
|
||||||
} else {
|
} else {
|
||||||
recordWritingCheckUsage()
|
recordWritingCheckUsage()
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
import { createClient } from "@supabase/supabase-js"
|
import { createClient } from "@supabase/supabase-js"
|
||||||
|
|
||||||
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
|
// Runtime env (injected by docker/entrypoint.sh) takes priority over build-time vars
|
||||||
// Supports both key name conventions
|
const runtimeEnv = (window as unknown as { __ENV__?: Record<string, string> }).__ENV__ ?? {}
|
||||||
|
|
||||||
|
const supabaseUrl =
|
||||||
|
runtimeEnv.VITE_SUPABASE_URL ||
|
||||||
|
import.meta.env.VITE_SUPABASE_URL
|
||||||
|
|
||||||
const supabaseAnonKey =
|
const supabaseAnonKey =
|
||||||
|
runtimeEnv.VITE_SUPABASE_ANON_KEY ||
|
||||||
|
runtimeEnv.VITE_SUPABASE_PUBLISHABLE_KEY ||
|
||||||
import.meta.env.VITE_SUPABASE_ANON_KEY ||
|
import.meta.env.VITE_SUPABASE_ANON_KEY ||
|
||||||
import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
|
import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user