You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes环境下部署Rails+Unicorn+Nginx应用无法加载静态资源

Hey there, let's dig into why your Rails app's static assets aren't loading on Kubernetes—this is a super common gotcha when moving from Docker Compose to K8s, so let's break down targeted fixes and checks:

1. First, Confirm Rails Asset Precompilation is Working

Rails doesn't serve static assets in production mode by default—you need to precompile them first, and make sure that step is baked into your Docker image.

  • Double-check your Dockerfile includes this command (after installing gems and copying app code):
    RUN RAILS_ENV=production bundle exec rails assets:precompile
    
  • Verify your Deployment sets the production environment via env vars:
    env:
      - name: RAILS_ENV
        value: "production"
    
  • You can also exec into a running pod to check if assets exist:
    kubectl exec -it <your-app-pod-name> -- ls public/assets
    
    You should see hashed files like application-abc123.css—if not, precompilation failed.

2. Make Sure Your Web Server is Serving Static Assets

Your choice of server (Unicorn, Passenger, Nginx) dictates how assets are handled:

  • Unicorn: By default, Unicorn won't serve static assets. You can either:
    • Enable it temporarily in config/environments/production.rb (not ideal for performance):
      config.serve_static_assets = true
      # Or for Rails 5+, use:
      config.public_file_server.enabled = true
      
    • Or add an Nginx sidecar or combine Nginx with Unicorn in your image to serve assets directly (this is the production-grade approach).
  • Combined Rails + Nginx Image: If you went this route, ensure your Nginx config has a block to serve assets:
    location ~ ^/assets/ {
      root /app/public;
      expires 1y;
      add_header Cache-Control public;
      add_header ETag "";
    }
    
  • Passenger: It should handle static assets automatically, but confirm config.public_file_server.enabled = true is set in your production config.

3. Tweak Your Ingress Configuration (The Likely Culprit)

Your existing tweaks might have missed a few key details:

  • Ditch the ingress.kubernetes.io/add-base-url annotation unless your app is hosted under a subpath (like yourdomain.com/appx). This annotation can rewrite asset paths incorrectly.
  • Use pathType: Prefix for your root path to ensure all requests (including assets) are forwarded to your service:
    spec:
      rules:
      - host: your-app-domain.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: appX-cluster-ip-service
                port:
                  number: 80
    
  • Check your ingress controller logs for 404s related to assets:
    kubectl logs -n kube-system <your-ingress-controller-pod> | grep assets
    

4. Debug Pod-to-Service Connectivity

Rule out issues inside your cluster:

  • Exec into your app pod and test if assets load locally:
    kubectl exec -it <your-app-pod> -- curl localhost:<container-port>/assets/application-<hash>.css
    
    If this returns the asset content, the problem is in your Ingress or Service. If not, the issue is inside the pod (web server config or missing assets).
  • Confirm your Service is targeting the correct container port (e.g., Unicorn usually listens on 8080, Nginx on 80).

5. Use Browser Dev Tools to Diagnose Request Issues

Open your browser's dev tools (F12) and check the Network tab:

  • Look for asset requests with 404/403 status codes. If the URL is something like yourdomain.com/assets/application.css (no hash), that means Rails isn't generating the hashed asset path correctly—double-check precompilation and RAILS_ENV.
  • If the URL has the hash but returns 404, your server isn't routing the request to the correct asset file.

Quick Stable Setup Example (Rails + Unicorn + Nginx)

If you want a reliable baseline, here's a simplified Dockerfile to combine both servers:

FROM ruby:2.5.5-slim

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
  build-essential nginx \
  && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Install gems
COPY Gemfile Gemfile.lock ./
RUN bundle install --without development test --deployment

# Copy app code
COPY . .

# Precompile assets
RUN RAILS_ENV=production bundle exec rails assets:precompile

# Copy Nginx config
COPY nginx.conf /etc/nginx/nginx.conf

# Start both servers
CMD ["bash", "-c", "bundle exec unicorn -c config/unicorn.rb & nginx -g 'daemon off;'"]

And a basic nginx.conf:

events {
  worker_connections 1024;
}

http {
  server {
    listen 80;
    root /app/public;

    # Serve static assets directly
    location ~ ^/assets/ {
      expires 1y;
      add_header Cache-Control public;
    }

    # Forward dynamic requests to Unicorn
    location / {
      proxy_pass http://localhost:8080;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}

内容的提问来源于stack exchange,提问作者Alejandro Roble Gutiérrez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:41:44