24

EDIT

It turns out that I was barking up the wrong tree trying to edit .htaccess, as nginx doesn't use it. What I apparently need to do is edit my .conf file. Before I read this, my_app.conf looked like this:

upstream backend {
    server unix:/u/apps/my_app/tmp/php.sock;
}

server {

    listen 80 default;
    root /u/apps/my_app/www;
    index index.php;

    access_log /u/apps/my_app/logs/access.log;
    error_log /u/apps/my_app/logs/error.log;

    location / {
        try_files $uri $uri/ /index.php;
    }

    # This location block matches anything ending in .php and sends it to
    # our PHP-FPM socket, defined in the upstream block above.
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass backend;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /u/apps/my_app/www$fastcgi_script_name;
        include fastcgi_params;
    }

    # This location block is used to view PHP-FPM stats
    location ~ ^/(php_status|php_ping)$ {
        fastcgi_pass backend;
        fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
        include fastcgi_params;
        allow 127.0.0.1;
        deny all;
    }

    # This location block is used to view nginx stats
    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

Now it looks like this, and it's still not working:

upstream backend {
    server unix:/u/apps/my_app/tmp/php.sock;
}

server {

    listen 80 default;
    root /u/apps/my_app/www;
    index index.php;

    access_log /u/apps/my_app/logs/access.log;
    error_log /u/apps/my_app/logs/error.log;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location /wordpress/ {
        try_files $uri $uri/ /index.php?$args;
    }

    rewrite /wp-admin$ $scheme://$host$uri/ permanent;

    location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2    |doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
       access_log off; log_not_found off; expires max;
    }

    # Uncomment one of the lines below for the appropriate caching plugin (if used).
    #include global/wordpress-wp-super-cache.conf;
    #include global/wordpress-w3-total-cache.conf;

    # This location block matches anything ending in .php and sends it to
    # our PHP-FPM socket, defined in the upstream block above.
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass backend;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /u/apps/my_app/www$fastcgi_script_name;
        include fastcgi_params;
    }

    # This location block is used to view PHP-FPM stats
    location ~ ^/(php_status|php_ping)$ {
        fastcgi_pass backend;
        fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
        include fastcgi_params;
        allow 127.0.0.1;
        deny all;
    }

    # This location block is used to view nginx stats
    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

Anyone know what I'm doing wrong?

END EDIT

I have changed my permalinks from the default to /%postname%/, and now the links within WordPress's Admin panel give me 404 errors - Not WordPress 404 pages, nginx 404 pages. Looking up why this is told me that this should be editing my .htaccess file or telling me WordPress can't rewrite .htaccess - the .htaccess file is nonexistant, and WordPress isn't giving any errors when I change permalinks.

I've tried creating a blank .htaccess file in my wordpress folder, giving it 666 permissions, changing the user and group to www-data and then changing the permalinks- that didn't work. I then changed it to this before changing the permalinks:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

When that didn't work, I changed RewriteBase to /wordpress/ before changing permalinks again - still nothing.

I've also gone into my site's .conf file and changed try_files $uri $uri/ /index.php; to the following, restarting nginx and php5-fpm each time;

try_files $uri $uri/ /index.php?$query_string;

try_files $uri $uri/ /index.php?q=$request_uri;

try_files $uri $uri/ /index.php?$args;

I'm running a home server with nginx. Any ideas about what's going on here?

6 Answers 6

15

Those are Apache .htaccess rewrite rules, but you have stated that you are on an Nginx server. Nginx does not use an .htaccess-like directory level file, much less does it use the .htaccess file itself.. You need to edit the server configuration itself. The Codex has a detail sample:

# WordPress single blog rules.
# Designed to be included in any server {} block.

# This order might seem weird - this is attempted to match last if rules below fail.
# http://wiki.nginx.org/HttpCoreModule
location / {
    try_files $uri $uri/ /index.php?$args;
}

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

# Directives to send expires headers and turn off 404 error logging.
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
       access_log off; log_not_found off; expires max;
}

# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-wp-super-cache.conf;
#include global/wordpress-w3-total-cache.conf;

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    if (!-f $document_root$fastcgi_script_name) {
        return 404;
    }
    # This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default)

    include fastcgi.conf;
    fastcgi_index index.php;
#   fastcgi_intercept_errors on;
    fastcgi_pass php;
}
3
  • Thanks, I'd vote this up if I had the reputation. I'm having a little trouble implementing this into my .conf file seeing as it was already changed significantly from the default, but at least I'm not fiddling around with .htaccess any more. May 21, 2015 at 19:32
  • @s_ha_dum, I used thies configuration until yesterday when I updated to wordpress 4.8 and now I am getting 404s on permalinks custom structure....tried debugging it since yesterday but nothing worx, any ideas??
    – Jadeye
    Jul 4, 2017 at 14:32
  • I had to change the last line ot read "fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;" to work on Ubuntu 18.04 but it works and saved my sanity
    – Rob
    Dec 17, 2018 at 3:24
30

I'm using wordpress multisite with custom permalink setting: /%category%/%postname%/

/etc/nginx/site-available/domain.conf

On server{

location / {
    try_files $uri $uri/ /index.php?q=$uri$args;
}

If your root wordpress is not the webroot but http://domain.com/wordpress/:

location /wordpress/ {
    try_files $uri $uri/ /wordpress/index.php?q=$uri$args;
}

If you are using old wordpress with blogs.dir, add: location ^~ /blogs.dir { internal; alias /var/www/wordpress/wp-content/blogs.dir; access_log off; log_not_found off; expires max; }

Check the nginx configuration: sudo nginx -t

Reload nginx: sudo service nginx reload

Also try change permalink settings.

3
  • 6
    This is the best answer for anyone who wants to manually move a WordPress installation to a subdirectory under a new domain name! THANK YOU SO MUCH! This should be the accepted answer. Jan 24, 2017 at 13:25
  • 1
    The path: /etc/nginx/site-available/ should read: /etc/nginx/sites-available/
    – Grant
    Feb 20, 2018 at 10:14
  • 1
    The second option works for me as my site was in a sub directory
    – Arunendra
    Oct 19, 2020 at 2:37
10

Had to add this piece of code to both the /sites-available/your-settings-file and /sites-enabled/your-settings-file:

server {
[...]

if (!-e $request_filename) {
    rewrite ^.*$ /index.php last;
}

[...]
}

It's working for me now.

6
  • 1
    This is the simple answer I was looking for, thanks
    – ThEBiShOp
    Jun 28, 2017 at 19:15
  • 1
    This worked! Could you please explain what it does? (esp the "last" part...)
    – Sidd
    Aug 12, 2018 at 18:50
  • This code still work! Sep 16, 2020 at 17:34
  • 1
    sites-enabled/ files are symlinked from sites-available/, so basically you are editing the file inside sites-available/ and changes will be reflected in the other folder automatically. Just a clarification. Jan 15, 2021 at 18:39
  • Can confirm this still works like a charm!
    – terryeah
    Apr 2, 2022 at 2:11
1

I had to set the root path to wordpressś installed directory: root /var/www/html/wp;

I dont like it because I have more applications installed on this machine but creating more virtual hosts should be enough.

0

Step 1. Edit /etc/nginx/site-available/example.com

location / {
try_files $uri $uri/ /index.php?q=$uri$args;
}

step 2 : login to server step 3. Run this

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

step 4. Test configuration

sudo nginx -t

step 5. Restart Nginx server

sudo systemctl restart nginx

step 6. Save the permalink from wordpress admin dashboard ***** Happy browsing ****

More details http://toihid.com/wordpress-permalink-in-nginx-server/

0

@Angelo's answer solved the issue for me. I'd upvote but lack reputation so posting an answer.

Just for Clarity the following

server {
        server_name xxx.xxxx.com;
        
        root /var/www/wordpress;

        listen 80;
        listen [::]:80;

        index index.php;

        location / {
                try_files $uri $uri/ =404;
        }

        location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        }
}

became

server {
        server_name xxx.xxxx.com;
        
        root /var/www/wordpress;

        listen 80;
        listen [::]:80;

        index index.php;

        location / {
                try_files $uri $uri/ =404;
        }

        if (!-e $request_filename) {
                rewrite ^.*$ /index.php last;
        }

        location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        }
}

Notice the extra


        if (!-e $request_filename) {
                rewrite ^.*$ /index.php last;
        }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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