How to Fix Nginx 404 Not Found on Google Cloud Run
-
The Root Cause On Google Cloud Run, an Nginx 404 often indicates that Nginx is running within the container but cannot locate the requested files at its configured
rootdirectory. This usually stems from a mismatch between Nginx’srootdirective and the actual path where application static files or web content are placed within the Docker image during the build process. -
Quick Fix (CLI) After correcting your
nginx.conforDockerfilelocally, you need to rebuild and redeploy your service.# 1. Set variables for your project and service PROJECT_ID=$(gcloud config get-value project) SERVICE_NAME="your-cloud-run-service-name" # Replace with your Cloud Run service name REGION="us-central1" # Replace with your Cloud Run service region # 2. Build the new Docker image (assuming Dockerfile is in the current directory) IMAGE_NAME="gcr.io/${PROJECT_ID}/${SERVICE_NAME}:latest" docker build -t ${IMAGE_NAME} . # 3. Push the new image to Google Container Registry docker push ${IMAGE_NAME} # 4. Deploy the updated service on Cloud Run gcloud run deploy ${SERVICE_NAME} --image ${IMAGE_NAME} \ --platform managed --region ${REGION} \ --allow-unauthenticated # Add or remove --allow-unauthenticated as per your service's requirements -
Configuration Check The primary configuration to check is your
nginx.conffile and yourDockerfile.-
File to edit:
nginx.conf(typically found at/etc/nginx/nginx.confor/etc/nginx/conf.d/default.confinside the container). -
Key lines to change/verify:
# In your 'server' block within nginx.conf server { listen ${PORT:-8080}; # Cloud Run injects the PORT environment variable; fall back to 8080 root /app/public; # <-- CRITICAL: This path MUST be the absolute path where your static files are # actually located inside the container. Common paths include /app, /app/build, or /usr/share/nginx/html. index index.html index.htm; # Specify your index file(s) location / { try_files $uri $uri/ =404; # Ensures Nginx correctly attempts to find files and serves a 404 if not found } # Add other necessary location blocks for API routes, etc., if any # For example, if you have a backend API running on another port in the same container: # location /api/ { # proxy_pass http://localhost:8081; # Assuming your backend is on port 8081 # proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; # } } -
Also check your
Dockerfile: Ensure that your static assets are copied to the exactrootdirectory specified innginx.conf.# Example Dockerfile snippet # ... # Copy your custom Nginx configuration file COPY ./nginx.conf /etc/nginx/nginx.conf # Copy your static web content (e.g., built frontend assets) # The destination path MUST match the 'root' directive in your nginx.conf COPY ./dist /app/public # <-- This '/app/public' should match 'root /app/public;' in nginx.conf # Expose the port Nginx will listen on (often 8080 for Cloud Run) ENV PORT 8080 EXPOSE ${PORT} # Command to start Nginx, ensuring it stays in the foreground CMD ["nginx", "-g", "daemon off;"]
-
-
Verification After the deployment is complete, verify the fix by accessing your service URL.
# 1. Obtain your Cloud Run service URL SERVICE_URL=$(gcloud run services describe ${SERVICE_NAME} \ --platform managed --region ${REGION} \ --format 'value(status.url)') # 2. Use curl to request the root path or a known static file curl -v "${SERVICE_URL}" # Alternatively, for a specific static file (e.g., index.html): # curl -v "${SERVICE_URL}/index.html" # Look for an HTTP/1.1 200 OK status code in the curl output. # A 404 response (or any other non-2xx status code) indicates the issue persists.