Skip to content

Commit 809753f

Browse files
BoodyaIlia BeliakovtechbuzzzCopilot
authored
Dockerfile: build backend and frontend into container (#40)
* Create an auto-deploy file * feat: Add frontend static serving to backend * Full stack docker provision file * fix: Remove invalid placeholder keys from GitHub Actions workflow * fix: Use correct Dockerfile with static file serving for deployment * remove unused files * Update cmd/server/main.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Dockerfile Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Ilia Beliakov <ilia.beliakov@sefe.eu> Co-authored-by: Victor Buzin <buzin.victor@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 95b01b4 commit 809753f

2 files changed

Lines changed: 47 additions & 4 deletions

File tree

Dockerfile

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,23 @@
1-
FROM golang:1.24-alpine AS builder
1+
# Stage 1: Build Frontend (Vue.js)
2+
FROM node:18-alpine AS frontend-builder
3+
4+
WORKDIR /app
5+
6+
# Copy frontend package files
7+
COPY web/package*.json ./
8+
RUN npm install
9+
10+
# Copy frontend source
11+
COPY web/ ./
12+
13+
# Build frontend for production
14+
RUN npm run build
15+
16+
# Verify build output
17+
RUN test -d /app/dist || (echo "ERROR: dist not found!" && exit 1)
18+
19+
# Stage 2: Build Backend (Go)
20+
FROM golang:1.24-alpine AS backend-builder
221

322
WORKDIR /app
423

@@ -12,12 +31,13 @@ COPY . .
1231
# Build
1332
RUN CGO_ENABLED=0 GOOS=linux go build -o /mcp-server ./cmd/server
1433

34+
# Stage 3: Final production image
1535
FROM alpine:latest
1636

1737
WORKDIR /app
1838

19-
# Copy binary
20-
COPY --from=builder /mcp-server .
39+
# Copy backend binary
40+
COPY --from=backend-builder /mcp-server .
2141

2242
# Copy migrations
2343
COPY migrations ./migrations
@@ -26,6 +46,9 @@ COPY migrations ./migrations
2646
COPY *.md ./
2747
COPY docs ./docs
2848

49+
# Copy frontend build (static files)
50+
COPY --from=frontend-builder /app/dist ./web/dist
51+
2952
EXPOSE 8080
3053

3154
CMD ["./mcp-server"]

cmd/server/main.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,27 @@ func main() {
143143
// WebSocket
144144
r.HandleFunc("/ws", wsHandler.HandleWebSocket)
145145

146-
// MCP Protocol endpoint (root level for VS Code)
146+
// Serve static files from web/dist (if exists) - BEFORE catch-all routes
147+
distDir := "./web/dist"
148+
if _, err := os.Stat(distDir); err == nil {
149+
log.Println("Serving frontend from ./web/dist")
150+
fs := http.FileServer(http.Dir(distDir))
151+
r.PathPrefix("/").Handler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
152+
// Try to serve the requested file
153+
path := distDir + req.URL.Path
154+
if _, err := os.Stat(path); os.IsNotExist(err) {
155+
// File doesn't exist, serve index.html for SPA routing
156+
http.ServeFile(w, req, distDir+"/index.html")
157+
return
158+
}
159+
// File exists, serve it
160+
fs.ServeHTTP(w, req)
161+
}))
162+
} else {
163+
log.Println("Frontend not found at ./web/dist - serving backend only")
164+
}
165+
166+
// MCP Protocol endpoint (root level for VS Code) - AFTER static files
147167
r.HandleFunc("/", mcpHandler.HandleMCP).Methods("GET", "POST", "OPTIONS")
148168
r.HandleFunc("/mcp", mcpHandler.HandleMCP).Methods("GET", "POST", "OPTIONS")
149169
r.HandleFunc("/mcp/message", mcpHandler.HandleMCP).Methods("POST", "OPTIONS")

0 commit comments

Comments
 (0)