Vue前端基于Nginx、Docker部署对接后端并迁移至K8s集群方案咨询
Hey Hashan, let's walk through this step by step—you're dealing with a common setup for Vue apps in Docker/Kubernetes, and we'll fix that backend communication issue while getting everything deployed properly.
Right now, your API_URL is hardcoded to http://localhost:8084—this won't work in Docker or Kubernetes because localhost inside a container refers to the container itself, not your host machine or backend pods. We need a flexible approach:
Option 1: Use Environment Variables (Recommended)
- Create a
.env.productionfile in your Vue project root:VUE_APP_API_URL=/api - Update your Axios code to use this environment variable (fallback to localhost for local development):
import axios from 'axios' const API_URL = process.env.VUE_APP_API_URL || 'http://localhost:8084' class NotificationDataService { retrieveAllNotifications() { return axios.get(`${API_URL}/notification/getall`); } } export default new NotificationDataService()
This way, your frontend will send API requests to /api in production, and we'll use Nginx to forward those to your backend.
Option 2: Hardcode Backend Service Name (For K8s Only)
If you skip Nginx reverse proxy, you can directly use the Kubernetes service name (we'll define this later) as your API URL:
const API_URL = process.env.VUE_APP_API_URL || 'http://backend-service:8084'
But this bypasses Nginx and can lead to CORS issues if your frontend is exposed externally.
We'll use a multi-stage Docker build to first compile your Vue app, then serve it with Nginx (which will handle API proxying).
1. Create a Dockerfile
# Build stage: Compile Vue app FROM node:18-alpine as builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . # Build with production environment variables RUN npm run build # Run stage: Serve with Nginx FROM nginx:alpine # Copy custom Nginx config COPY nginx.conf /etc/nginx/conf.d/default.conf # Copy compiled Vue files from build stage COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 # Start Nginx in foreground CMD ["nginx", "-g", "daemon off;"]
2. Create an Nginx Config (nginx.conf)
This config serves your static Vue files and proxies API requests to the backend:
server { listen 80; server_name localhost; # Serve Vue static files root /usr/share/nginx/html; index index.html index.htm; # Handle Vue Router history mode (if you use it) location / { try_files $uri $uri/ /index.html; } # Proxy API requests to backend location /api/ { # For local Docker testing: Use host.docker.internal (Windows/macOS) or your host IP (Linux) # proxy_pass http://host.docker.internal:8084/; # For Kubernetes: Use the backend service name (we'll define this next) proxy_pass http://backend-service:8084/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
3. Build & Test Locally
- Build the Docker image:
docker build -t vue-frontend:v1 . - Run the container (test with your local backend):
docker run -p 8080:80 vue-frontend:v1
Visit http://localhost:8080—your frontend should load, and API requests should be forwarded to your local backend at 8084.
Now we'll deploy both frontend and backend to Kubernetes. First, make sure your backend is containerized (we'll assume you have a backend Docker image called backend-image:v1).
3.1 Deploy the Backend
Create two YAML files for the backend:
backend-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: backend-deployment spec: replicas: 2 selector: matchLabels: app: backend template: metadata: labels: app: backend spec: containers: - name: backend image: backend-image:v1 # Replace with your actual backend image ports: - containerPort: 8084 resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "200m" memory: "256Mi"
backend-service.yaml
This creates a stable DNS name for your backend pods:
apiVersion: v1 kind: Service metadata: name: backend-service spec: selector: app: backend ports: - port: 8084 targetPort: 8084 type: ClusterIP # Only accessible inside the Kubernetes cluster
Apply these resources:
kubectl apply -f backend-deployment.yaml -f backend-service.yaml
3.2 Deploy the Frontend
First, update the proxy_pass in your nginx.conf to use http://backend-service:8084/ (this is the DNS name of the backend service we just created), then rebuild your frontend Docker image and push it to a container registry (like Docker Hub or a private registry).
Create frontend deployment and service files:
frontend-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: frontend-deployment spec: replicas: 2 selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: containers: - name: frontend image: vue-frontend:v1 # Replace with your pushed frontend image ports: - containerPort: 80 resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "200m" memory: "256Mi"
frontend-service.yaml
Expose the frontend to external traffic:
apiVersion: v1 kind: Service metadata: name: frontend-service spec: selector: app: frontend ports: - port: 80 targetPort: 80 type: LoadBalancer # Cloud K8s will assign an external IP; use NodePort for local clusters
Apply these resources:
kubectl apply -f frontend-deployment.yaml -f frontend-service.yaml
3.3 Verify Communication
Check if frontend pods can reach the backend:
# Get a frontend pod name kubectl get pods -l app=frontend # Exec into the pod and test the backend kubectl exec -it <frontend-pod-name> -- curl http://backend-service:8084/notification/getall
You should get a valid response from your backend API.
- Docker: Packages your frontend + Nginx into a portable image that runs consistently across environments.
- Nginx: Serves static Vue files and proxies API requests to avoid CORS issues and keep backend URLs hidden from clients.
- Kubernetes Services: The
backend-service(ClusterIP) provides a stable DNS name for backend pods, so frontend pods don't have to track individual backend pod IPs. - Environment Variables: Avoid hardcoding URLs—use them to adapt your app to dev, staging, and production environments easily.
内容的提问来源于stack exchange,提问作者HashanR

