1

I'm moving my wordpress blog from Apache to Nginx. I've tried multiple tutorials to get permalinks working but nothing is working for me. My website structure is like this:

main site -> www.localhost.com

wordpress blog -> www.localhost.com/blog

Website is in /var/www/html and wordpress is installed in /var/www/html/blog

I've read multiple articles and watched multiple videos but nothing seems to be working. Please let me know where I'm going wrong.

I've defined two server blocks in /etc/nginx/sites-available/default one for main site and one for the blog.

# Default server configuration
#
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # SSL configuration
    #
    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server;
    #
    # Note: You should disable gzip for SSL traffic.
    # See: https://bugs.debian.org/773332
    #
    # Read up on ssl_ciphers to ensure a secure configuration.
    # See: https://bugs.debian.org/765782
    #
    # Self signed certs generated by the ssl-cert package
    # Don't use them in a production server!
    #
    # include snippets/snakeoil.conf;

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;

    server_name _;

       charset utf-8;
       error_page 404 /404.php;

       location /article {
         rewrite ^/article.* / redirect;
       }

       #location / {
        # try_files $uri $uri/ /loadpage.php?$args; 
       #}

       location ~ \.html$ {
         try_files $uri /courses/index.php?$args;
       }





    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
    #
    #   # With php7.0-cgi alone:
    #   fastcgi_pass 127.0.0.1:9000;
        # With php7.0-fpm:
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                include fastcgi_params;

    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\.ht {
        deny all;
    }
}



server {
    listen 80;
    listen [::]:80;
    root /var/www/html/blog;
    index  index.php index.html index.htm;
    server_name  example.com www.example.com;

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


    location ~ \.php$ {
    fastcgi_split_path_info  ^(.+\.php)(/.+)$;
    fastcgi_index            index.php;
 #  fastcgi_pass             unix:/var/run/php/php7.1-fpm.sock; #Ubuntu 17.10
    fastcgi_pass             unix:/var/run/php/php7.0-fpm.sock; #Ubuntu 17.04
    include                  fastcgi_params;
    fastcgi_param   PATH_INFO       $fastcgi_path_info;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

}
4
  • For clarification, both your main site and WordPress are under the same domain? You cannot have multiple server blocks for the same domain (unless the ports are different, but that's not the case here).
    – Thomas
    Commented Apr 24, 2019 at 11:27
  • Yes, both are under the same domain. I'm testing it on my localhost. So it is like localhost for main site and localhost/blog for wordpress site.
    – Axel
    Commented Apr 24, 2019 at 11:31
  • @Thomas Man, you're a life saver! I was at this problem since last 6-7 hours, kept changing my config under the 2nd server block but didn't even think about the 2nd server block creating problem on its own. Permalinks working like charm now.
    – Axel
    Commented Apr 24, 2019 at 11:59
  • Please post the comment as an answer so that I can mark it as an answer.
    – Axel
    Commented Apr 24, 2019 at 12:01

2 Answers 2

1

By creating multiple server blocks for the same domain you are effectively creating a collision between the virtual servers. server blocks define what Nginx will listen for. If there are multiple virtual servers for a given port, the request will be passed on to a virtual server with the best matching server_name. By having multiple identical virtual servers, Nginx will have no way of telling where to pass it to.

Your main site and WordPress are under the same domain (and the same port) and thus should go in a single virtual server. You separate them using location blocks.

Take caution with the Nginx block selection algorithm, regular expression blocks are always evaluated before normal blocks. In your example everything ending with .html is send to your main site. This may interfere with WordPress when it tries to use URI's ending with .html as well. To prevent this, you can use nested location blocks. By moving the regular expression location block inside / it will only be evaluated when the parent location matches. When a request comes in for /blog, the /blog location block will be the best matching one and therefore will be selected over the / one. Because the regular expression block is now nested inside there, it won't be evaluated for requests to WordPress.

# Default server configuration
#
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # SSL configuration
    #
    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server;
    #
    # Note: You should disable gzip for SSL traffic.
    # See: https://bugs.debian.org/773332
    #
    # Read up on ssl_ciphers to ensure a secure configuration.
    # See: https://bugs.debian.org/765782
    #
    # Self signed certs generated by the ssl-cert package
    # Don't use them in a production server!
    #
    # include snippets/snakeoil.conf;

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;

    server_name _;

    charset utf-8;
    error_page 404 /404.php;

    location /article {
        rewrite ^/article.* / redirect;
    }

    location / {
        location ~ \.html$ {
            try_files $uri /courses/index.php?$args;
        }

        try_files $uri $uri/ /loadpage.php?$args;
    }

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

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
    #
    #   # With php7.0-cgi alone:
    #   fastcgi_pass 127.0.0.1:9000;
        # With php7.0-fpm:
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                include fastcgi_params;

    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\.ht {
        deny all;
    }
}
2
  • Done! Thanks for the answer but even more for the great explanation and not just posting the answer. You've cleared so many doubts of mine.
    – Axel
    Commented Apr 24, 2019 at 12:26
  • @Axel No problem, I'm glad I could help. If you run into any more issues with the migration process, feel free to ping me. ;)
    – Thomas
    Commented Apr 24, 2019 at 12:28
0

I know this is an old post but I faced the same problem and did not find the correct answer anywhere. This is not a problem with the .htaccess file or permissions to the folder structure. The problem is moving wordpress sites out of the default document root folder.

If you have multiple wordpress sites or a single site in a sub-folder of your document root folder, you have to "relax access to content" for each sub-folder in the apache2.conf or the httpd.conf files.

When this is added you will be able to use "Pretty Permalinks" instead of the almost pretty or plain permalinks.

/etc/apache2/apache2.conf
/etc/httpd/conf/httpd.conf

<Directory /var/www/>
  Options Indexes FollowSymLinks
  AllowOverride None
  Require all granted
</Directory>

# Added

<Directory /var/www/html/site1/>
  Options Indexes FollowSymLinks
  AllowOverride None
  Require all granted
</Directory>

<Directory /var/www/html/site2/>
  Options Indexes FollowSymLinks
  AllowOverride None
  Require all granted
</Directory>

# End added
1
  • Welcome to Super User! Please do not post the same answer to multiple questions. If the same information really answers both questions, then one question (usually the newer one) should be closed as a duplicate of the other. You can indicate this by voting to close it as a duplicate or, if you don't have enough reputation for that, raise a flag to indicate that it's a duplicate. Otherwise tailor your answer to this question and don't just paste the same answer in multiple places.
    – DavidPostill
    Commented May 7 at 20:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .