3

I have the following issue which I can't seem to wrap my head around.

All images assets uploaded to Craft return a 404 not found on the front-end. Everything works fine in the admin CP though (uploading, renaming, thumbnails, etc.). Any template with getUrl() outputs the correct URL but the resource returns a 404 status code. When I navigate directly to the asset's URL, Craft returns a 404 template instead of the image.

These are the things I have checked so far :

  • Files permissions seem OK (775 on folder and 664 on files) on the "craft" user;
  • The assets paths is {basePath}uploads/images/
  • The assets URL is {siteUrl}images/
  • Both {basePath} and {siteUrl} are correctly set as environment variables in general.php
  • I'm running Nginx with a config similar to this answer

Any thoughts ? This is really bugging me.

Thanks.

Edit

These are my two nginx configuration files :

# nginx.conf

user craft craft;
worker_processes auto;
worker_rlimit_nofile 8192;
events {
    worker_connections 8000;
}

error_log /var/log/nginx/error.log debug; # not for production
pid /var/run/nginx.pid;


http {

    disable_symlinks off;
    proxy_buffering on;
    proxy_buffer_size 8k;
    proxy_buffers 2048 8k;
    proxy_connect_timeout  600s;
    proxy_send_timeout  600s;
    proxy_read_timeout  600s;
    fastcgi_send_timeout 600s;
    fastcgi_read_timeout 600s;

    rewrite_log on;
    access_log /var/log/nginx/access.log;

    server_tokens off;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    keepalive_timeout   65;
    sendfile            on;
    tcp_nopush          on;
    gzip                on;
    gzip_comp_level     5;
    gzip_min_length     256;
    gzip_proxied        any;
    gzip_vary           on;
    gzip_disable        "msie6";

    include /etc/nginx/sites-enabled/*;
}

and

# site.conf

# -------------------------------------------------
# General server configuration

server {

  listen 80 default_server;
  server_name example.com;
  root /srv/craft/public;
  index index.php index.html index.htm;
  charset utf-8;
  error_page 404 /index.php;
  error_log /var/log/nginx/example.com.error.log debug;
  access_log /var/log/nginx/example.com.access.log;

  # -------------------------------------------------
  # Some locations to help during dev, remove for production

  location = /phpinfo {
    try_files $uri $uri/ /phpinfo.php$is_args$args;
  }

  location = /status {
     access_log off;
     allow all;
     include fastcgi_params;
     fastcgi_param SCRIPT_FILENAME /status;
     fastcgi_pass unix:/var/run/php-fpm.sock;
  }

  location = /ping {
     access_log off;
     allow all;
     include fastcgi_params;
     fastcgi_param SCRIPT_FILENAME /ping;
     fastcgi_pass unix:/var/run/php-fpm.sock;
  }

  # -------------------------------------------------
  # Static assets (css, js, fonts, etc.) location

  location /src {
      root /srv/craft/public/src;
      expires 1y;
      access_log off;
      add_header Pragma public;
      add_header Cache-Control "public";
  }

  # -------------------------------------------------
  # Craft application locations

  location / {
    try_files $uri $uri/ @rewrites;
  }

  location @rewrites {
    rewrite ^(.*) /index.php?p=$1 last;
  }

  location ~ \.php$ {
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }

  # cache.appcache, your document html and data
  location ~* \.(?:manifest|appcache|html?|xml|json)$ {
      try_files $uri /index.php?$query_string;
      expires -1;
  }

  # Feed
  location ~* \.(?:rss|atom)$ {
      try_files $uri /index.php?$query_string;
      expires 1h;
      add_header Cache-Control "public";
  }

  # Media: images, icons, video, audio, HTC
  location ~* \.(?:jpg|jpeg|gif|png|pdf|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
      try_files $uri /index.php?$query_string;
      expires 1M;
      add_header Pragma public;
      add_header Cache-Control "public";
  }

  # CSS and Javascript
  location ~* \.(?:css|js)$ {
      try_files $uri /index.php?$query_string;
      expires 1y;
      add_header Pragma public;
      add_header Cache-Control "public";
  }

  # -------------------------------------------------
  # Other static ressources

  # Favicons
  location = /favicon.ico {
      access_log off;
      log_not_found off;
  }

  # Robots.txt
  location = /robots.txt {
      access_log off;
      log_not_found off;
  }

  # Humans.txt
  location = /humans.txt {
      access_log off;
      log_not_found off;
  }

  # Prevent clients from accessing hidden files (starting with a dot)
  # This is particularly important if you store .htpasswd files in the site hierarchy
  location ~* (?:^|/)\. {
      deny all;
  }
  # Prevent clients from accessing to backup/config/source files
  location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ {
      deny all;
  }

}
  • 1
    Can you post your nginx config? It sounds like one of the rules dealing with static files isn't being followed. That could be for number of reasons. As a general rule, when processing a config, nginx looks for more exact rules first and then down to less and less specific. – RitterKnight Jan 14 '16 at 18:10
  • Shouldn't the assets URL be {siteUrl}uploads/images? – megatrond Jan 14 '16 at 19:00
  • @RitterKnight I've added the Nginx files, you'll see a /src location which is working fine to serve static ressources (JS, CSS, fonts and UI images) not managed by craft. Maybe something is wrong with the media location further down the file. – sctgraham Jan 14 '16 at 21:38
  • @megatrond No, I want the images to be served from example.com/images/ but I don't think the folder path should necessarily match that url fragment for this to work. At least I hope not ! – sctgraham Jan 14 '16 at 21:43
  • It appears like nginx is setup correctly what what I can tell. I would double check your asset source's location. Where are the images that craft maintains stored? I would guess under /images/? Those have to be some folder under /public as well unless you have a nginx rule that rewrites them. – RitterKnight Jan 14 '16 at 21:56
1

It appears nginx is setup correctly. In Craft, your Assets URL can be different than your assets path, which I think is where some confusion is coming in.

If Craft's file upload path is outside nginx root (otherwise known as the DocumentRoot directive in Apache), you could either move your asset storage so it's under the document root—and thus "public" or "virtually move" the root folder so nginx will serve from that directory instead of the actual "images" folder.

location /images/ {
  /root /srv/craft/uploads
}

As with great power comes great responsibility. If you use the virtual rewriting option, be careful to always specify a default document root, and only override the root inside a location unless you have to as noted in nginx docs, or nothing will match and you'll pull your hair out as to why nothing matches.

|improve this answer|||||
  • 1
    OK I've updated my Nginx configuration with the advice you have provided, and it works. Thanks again. – sctgraham Jan 15 '16 at 13:08
3

Just had a similar issue with a colleague. Double check your folder permissions. It might be the case that Craft isn’t allowed to write the transformed files to your assets folder.

Something like chmod -R 777 public/assets might do the trick.

(You might want set this to something other than 777 if it worked out. Look at the docs for details.)

|improve this answer|||||
  • Thank you for this! I needed to change my upload directory to use 777 permissions to get things working. – Anna_MediaGirl Feb 6 at 23:19
1

Not a direct answer to your question, but I keep a pretty up to date Nginx config for Craft here: Nginx-Craft that may be useful to you at some point.

Glad you got it sorted.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.