{"id":483,"date":"2015-05-15T22:44:32","date_gmt":"2015-05-15T22:44:32","guid":{"rendered":"https:\/\/wecodepixels.com\/?p=483"},"modified":"2022-01-07T13:07:23","modified_gmt":"2022-01-07T13:07:23","slug":"nginx-configuration-for-sylius","status":"publish","type":"post","link":"https:\/\/wecodepixels.com\/nginx-configuration-for-sylius\/","title":{"rendered":"Nginx configuration for Sylius"},"content":{"rendered":"<p>Recently we started using the increasingly popular Sylius platform for one of our e-commerce projects. Sylius is based on Symfony2, the leading PHP framework which <a href=\"https:\/\/wecodepixels.com\/web-development\/\">we have worked with on our photography website<\/a>. Even though we use WooCommerce for smaller projects, Sylius provides a more modern and powerful solution that we believe is definitely better suited for more ambitious e-commerce websites.<\/p>\n<p>A problem that we initially struggled with was getting Sylius to work properly on our Nginx + PHP-FPM + Ubuntu 14.04 web server. We started with a <a href=\"http:\/\/symfony.com\/doc\/current\/cookbook\/configuration\/web_server_configuration.html#nginx\">standard Symfony2 configuration file<\/a> plus some optimizations, but could not get any product thumbnails to work. Turns out that <a href=\"http:\/\/symfony.com\/doc\/current\/bundles\/LiipImagineBundle\/index.html\">LiipImagineBundle<\/a> is used to generate thumbnails on-the-fly, and this was interfering with our cache expiry rule-set, resulting in 404s for any image thumbnails that we tried to display.<\/p>\n<p>Here is what we were incorrectly using to set an expiry date of 1 year in the future for static files:<\/p>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Nginx\" data-shcb-language-slug=\"nginx\"><div><code class=\"hljs language-nginx shcb-code-table shcb-line-numbers shcb-wrap-lines\"><span class='shcb-loc'><span><span class=\"hljs-attribute\">location<\/span> <span class=\"hljs-regexp\">~ \\.(js|css|png|jpeg|jpg|gif|ico|swf|flv|pdf|zip)$<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\"># Set expiry date to 1 year in the future.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">expires<\/span> <span class=\"hljs-number\">365d<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/div><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Nginx<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">nginx<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>While this normally works without a problem, it also means that any URL ending with one of those extensions will completely bypass the app.php file, whether or not the actual image file exists. Since thumbnails in Sylius are created on-the-fly upon a URL request, this completely breaks thumbnail creation.<\/p>\n\n\n\n<p>The fix is very straightforward: We only set the expiry date for requested files that actually exist. Otherwise, we rewrite them to the app.php file, as usual. Here is the final Nginx configuration file that we used:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Nginx\" data-shcb-language-slug=\"nginx\"><div><code class=\"hljs language-nginx shcb-code-table shcb-line-numbers shcb-wrap-lines\"><span class='shcb-loc'><span><span class=\"hljs-section\">server<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">server_name<\/span> example.com;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">root<\/span> \/var\/www\/example.com\/web;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">location<\/span> \/ {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">try_files<\/span> <span class=\"hljs-variable\">$uri<\/span> <span class=\"hljs-variable\">@rewriteapp<\/span>; <span class=\"hljs-comment\"># Redirect to app.php if the requested file does not exist.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\"># Development rule-set.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\"># This rule should only be placed on your development environment.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\"># In production, don't include this and don't deploy app_dev.php or config.php.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">location<\/span> <span class=\"hljs-regexp\">~ ^\/(app_dev|config)\\.php(\/|$)<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">fastcgi_pass<\/span> unix:\/var\/run\/php5-fpm.sock;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">fastcgi_split_path_info<\/span><span class=\"hljs-regexp\"> ^(.+\\.php)(\/.*)$<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">include<\/span> fastcgi_params;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">fastcgi_param<\/span> SCRIPT_FILENAME <span class=\"hljs-variable\">$document_root<\/span><span class=\"hljs-variable\">$fastcgi_script_name<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">fastcgi_param<\/span> HTTPS <span class=\"hljs-literal\">off<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>    \n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\"># Production rule-set.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">location<\/span> <span class=\"hljs-regexp\">~ ^\/app\\.php(\/|$)<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">fastcgi_pass<\/span> unix:\/var\/run\/php5-fpm.sock;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">fastcgi_split_path_info<\/span><span class=\"hljs-regexp\"> ^(.+\\.php)(\/.*)$<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">include<\/span> fastcgi_params;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">fastcgi_param<\/span> SCRIPT_FILENAME <span class=\"hljs-variable\">$document_root<\/span><span class=\"hljs-variable\">$fastcgi_script_name<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">fastcgi_param<\/span> HTTPS <span class=\"hljs-literal\">off<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>        \n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-comment\"># Prevents URIs that include the front controller. This will 404:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-comment\"># http:\/\/domain.tld\/app.php\/some-path<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-comment\"># Remove the internal directive to allow URIs like this.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        internal;\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\"># Static files rule-set.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">location<\/span> <span class=\"hljs-regexp\">~ \\.(js|css|png|jpeg|jpg|gif|ico|swf|flv|pdf|zip)$<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-comment\"># Set rules only if the file actually exists.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">if<\/span> (-f <span class=\"hljs-variable\">$request_filename<\/span>) {\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-comment\"># Set expiry date to 1 year in the future.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-attribute\">expires<\/span> <span class=\"hljs-number\">365d<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-comment\"># Further optimize by not logging access to these files.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-attribute\">access_log<\/span> <span class=\"hljs-literal\">off<\/span>; \n<\/span><\/span><span class='shcb-loc'><span>        }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-comment\"># Rewrite to app.php if the requested file does not exist.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">try_files<\/span> <span class=\"hljs-variable\">$uri<\/span> <span class=\"hljs-variable\">@rewriteapp<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\"># Rewrite rule for PHP files.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">location<\/span> <span class=\"hljs-variable\">@rewriteapp<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attribute\">rewrite<\/span><span class=\"hljs-regexp\"> ^(.*)$<\/span> \/app.php\/<span class=\"hljs-variable\">$1<\/span> <span class=\"hljs-literal\">last<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">error_log<\/span> \/var\/log\/nginx\/example.com_error.log;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">access_log<\/span> \/var\/log\/nginx\/example.com_access.log;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/div><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Nginx<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">nginx<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>That&#8217;s it. The thumbnails are now being properly generated on-the-fly, while the existing images are also using proper expiry headers. Let us know if this worked for you, or if you used a different approach. Happy coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently we started using the increasingly popular <a href=\"http:\/\/sylius.org\/\">Sylius<\/a> platform for one of our e-commerce projects. Sylius is based on <a href=\"http:\/\/symfony.com\/\">Symfony2<\/a>, the leading PHP framework which <a href=\"\">we have worked with in the past<\/a>. Although we also use WooCommerce for smaller projects, Sylius provides a more modern and powerful solution that we believe is definitely better suited for more ambitious e-commerce projects.<\/p>\n<p>A problem that we initially struggled with was getting Sylius to work properly on our Nginx + PHP-FPM + Ubuntu 14.04 web server. We started with a <a href=\"http:\/\/symfony.com\/doc\/current\/cookbook\/configuration\/web_server_configuration.html\">standard Symfony2 configuration file<\/a> plus some optimizations, but could not get any product thumbnails to work. Turns out that LiipImagineBundle is used to generate thumbnails on-the-fly, and this was interfering with our cache expiry rule-set, resulting in 404s for any image thumbnails that we tried to display.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"acf":[],"_links":{"self":[{"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/posts\/483"}],"collection":[{"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/comments?post=483"}],"version-history":[{"count":31,"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/posts\/483\/revisions"}],"predecessor-version":[{"id":3972,"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/posts\/483\/revisions\/3972"}],"wp:attachment":[{"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/media?parent=483"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/categories?post=483"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wecodepixels.com\/wp-json\/wp\/v2\/tags?post=483"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}