diff --git a/.env.dev b/.env.dev new file mode 100644 index 0000000..8864d32 --- /dev/null +++ b/.env.dev @@ -0,0 +1,17 @@ +#=============================================== +# Development Environment +#=============================================== + +BACKEND_PORT=8080 +FRONTEND_PORT=3000 +BASE_URL=http://localhost:3000 +API_URL=http://localhost:8080/service + +# Logto Authentication Configuration +LOGTO_ENDPOINT=https://auth.muchen.fan +LOGTO_APP_ID=nm3btt4j9v26rtt82t64e +LOGTO_APP_SECRET=2no3Gml080KbIGqAihfc0G8uRtk0DVQv +LOGTO_REDIRECT_URI=http://localhost:3000/service/auth/callback +LOGTO_POST_SIGN_OUT_REDIRECT_URI=http://localhost:3000 +COOKIE_SECRET=2QEzOcjnHej7wLMlbh57Hkhnzaqcddx8 + diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..1f75098 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,35 @@ +FROM golang:1.23-alpine AS builder + +WORKDIR /app + +# Copy go.mod and go.sum files +COPY go.mod go.sum ./ + +# Download dependencies +RUN go mod download + +# Copy the source code +COPY . . + +# Build the application +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o server main.go + +# Use a small alpine image for the final stage +FROM alpine:latest + +RUN apk --no-cache add ca-certificates + +WORKDIR /app + +# Copy the binary from the builder stage +COPY --from=builder /app/server . + +# Expose the application port +EXPOSE 8080 + +# Set environment variables +ENV PORT=8080 +ENV GIN_MODE=release + +# Run the application +CMD ["./server"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index f4c5218..f3eeef2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,7 +5,7 @@ services: dockerfile: Dockerfile restart: unless-stopped ports: - - "${BACKEND_PORT}:8000" + - "${BACKEND_PORT}:8080" environment: - BACKEND_PORT=${BACKEND_PORT} networks: diff --git a/frontend/next.config.ts b/frontend/next.config.ts index e9ffa30..8c8b6ff 100644 --- a/frontend/next.config.ts +++ b/frontend/next.config.ts @@ -2,6 +2,18 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { /* config options here */ + async rewrites() { + // Only apply proxy in development environment + if (process.env.NODE_ENV === "development") { + return [ + { + source: "/service/:path*", + destination: "http://localhost:8080/service/:path*", // assuming Go backend runs on port 8080 + }, + ]; + } + return []; + }, }; export default nextConfig; diff --git a/frontend/src/app/components/HealthStatus.tsx b/frontend/src/app/components/HealthStatus.tsx new file mode 100644 index 0000000..e0d60ac --- /dev/null +++ b/frontend/src/app/components/HealthStatus.tsx @@ -0,0 +1,75 @@ +"use client"; +import { useState, useEffect } from "react"; + +export default function HealthStatus() { + const [health, setHealth] = useState<{ status?: string }>({}); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(""); + + useEffect(() => { + const checkHealth = async () => { + try { + setLoading(true); + const response = await fetch("/service/health"); + + if (!response.ok) { + throw new Error(`Server responded with status: ${response.status}`); + } + + const data = await response.json(); + setHealth(data); + } catch (err) { + setError( + err instanceof Error ? err.message : "Failed to check health status" + ); + } finally { + setLoading(false); + } + }; + + checkHealth(); + }, []); + + return ( +
+

Backend Health Status

+ {loading ? ( +

Checking backend status...

+ ) : error ? ( +
+

Error: {error}

+
+ ) : ( +
+

+ Status:{" "} + + {health.status || "unknown"} + +

+
+ )} + +
+ ); +} diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index ed14f4e..56ed191 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -1,17 +1,6 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); - export const metadata: Metadata = { title: "Webapp Starter", description: "Created by FMC", diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 8364553..cbda622 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -1,3 +1,21 @@ +"use client"; +import HealthStatus from "./components/HealthStatus"; + export default function Home() { - return
Hello, world!
; + return ( +
+

Welcome to Starter App

+ + +
+ ); } diff --git a/sh/dev.sh b/sh/dev.sh index 5cc0a5e..5680ff2 100755 --- a/sh/dev.sh +++ b/sh/dev.sh @@ -21,6 +21,31 @@ fi SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="$SCRIPT_DIR/.." +# Cleanup function to kill backend server on script exit +cleanup() { + echo -e "\n${BLUE}Stopping backend server...${NC}" + if [ -n "$BACKEND_PID" ]; then + kill $BACKEND_PID 2>/dev/null || true + echo -e "${GREEN}Backend server stopped.${NC}" + fi + exit 0 +} + +# Register the cleanup function for script termination +trap cleanup INT TERM EXIT + +# Source the .env.dev file to get environment variables +if [ -f "$REPO_ROOT/.env.dev" ]; then + echo -e "${BLUE}Loading environment variables from .env.dev...${NC}" + set -a # automatically export all variables + source "$REPO_ROOT/.env.dev" + set +a + echo -e "${GREEN}Development environment variables loaded.${NC}" +else + echo -e "${RED}Error:${NC} .env.dev file not found in repository root!" + exit 1 +fi + # Start the backend server cd "$REPO_ROOT/backend" || exit 1 echo -e "${BLUE}Starting backend server...${NC}" @@ -42,5 +67,16 @@ else fi # Run dev server -echo -e "${BLUE}Starting dev server...${NC}" -npm run dev \ No newline at end of file +echo -e "${BLUE}Starting frontend dev server...${NC}" +npm run dev & +FRONTEND_PID=$! +echo -e "${GREEN}Frontend dev server started with PID $FRONTEND_PID.${NC}" + +# Keep script running until explicitly terminated +echo -e "${BLUE}Development environment running. Press Ctrl+C to stop all servers.${NC}" +wait $BACKEND_PID +echo -e "${YELLOW}Backend server exited. Frontend server may still be running.${NC}" +wait $FRONTEND_PID +echo -e "${YELLOW}Frontend server exited. Press Ctrl+C to exit the script.${NC}" +# Wait indefinitely +tail -f /dev/null \ No newline at end of file