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;
  }

}
sctgraham
  • 33
  • 1
  • 4
  • 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
  • Just rereading your question, your Assets URL should match your assets path. If i'm reading your config right, BasePath would be /srv/craft/public. I would guess your URLs are coming out like whatever.com/images/ when they should be coming out like whatever.com/uploads/images. – RitterKnight Jan 14 '16 at 22:15
  • @RitterKnight you are right, my folder location is outside the Nginx root path. It's actually under /srv/craft/uploads/ and not /srv/craft/public. I wanted to keep those files separate for version control reasons. So that's more than likely the issue, I'm off to test this now. However, one quick question : would the solution be as simple as adding "root /srv/craft/uploads/" to the media location or will this potentially interfere with any other Craft media files ? Thanks a mil for you time and help. – sctgraham Jan 14 '16 at 22:16
  • Craft's static assets from the CP get served by PHP so you should be good there. Yeh if you make new location /images block, the root you mention would serve it out of that directory and nginx would use files in that location when it encounters something from whatever.com/images/. – RitterKnight Jan 14 '16 at 22:33

4 Answers4

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.)

medoingthings
  • 949
  • 9
  • 16
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.

RitterKnight
  • 6,582
  • 14
  • 24
  • 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
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.

andrew.welch
  • 11,551
  • 22
  • 31
0

I replaced some of my Nginx configuration with the ones from here:

[https://github.com/nystudio107/nginx-craft/blob/master/sites-available/basic_localdev.com.conf][1]

I believe this line is what resolved it for me

location / { try_files $uri/index.html $uri $uri/ /index.php?$query_string; }