Search code examples
nginxsymlink

Nginx root directory with nested symlinks


Our website (laravel) project directory is like this:

/home/user/project/{app,route,public_html,storage,...} 

New releases are placed in:

/home/user/releases/v1

For some reason we have to link public_html directory for every release, so:

/home/user/releases/v1/public_html > /home/user/project/public_html

Nginx root diretory is:

/home/user/www/site/public_html  

Which:

/home/user/www/site > /home/user/releases/v1

Since NGINX will follow symlinks, final root directory would be:

/home/user/project/public_html

Is there a way to fix this situation?


Solution

  • Since the root of your virtual host is /home/user/www/site/public_html and since /home/user/www/site/public_html is a symlink to /home/user/project/public_html and since /home/user/project/public_html is a symlink to your latest release - nginX location blocks will actually search inside /home/user/releases/v1/public_html.


    Here is an example. Let's say we have a folder /my_releases. Everytime I publish/deploy a new release I will create a new subfolder inside /my_releases with the version of the release (/my_releases/v1, then /my_releases/v2 and so on). All assets of the release will be inside the corresponding subfolder - so I will have

    /my_releases
      |
      +---- /v1
      |      |
      |      +--- /css
      |      |      |
      |      |      +--- /home.a120cd8.css
      |      |
      |      +--- /img
      |      |      |
      |      |      +--- /logo.7f40c3a.svg
      |      |
      |      +--- /js
      |      |     |
      |      |     +--- /main.ba4de98.js
      |      |
      |      +--- /api
      |      |      |
      |      |      +--- /index.php
      |      |      |
      |      |      +--- /routes
      |      |              |
      |      |              +--- /login.php
      |      +--- /index.html
      |
      +---- /v2
      |      |
      |      +--- /css
      |      |      |
      |      |      +--- /home.7845c7.css
      |      |
      |      +--- /img
      |      |      |
      |      |      +--- /logo.23038ad.svg
      |      |
      |      +--- /js
      |      |     |
      |      |     +--- /main.acb33f1.js
      |      |
      |      +--- /api
      |      |      |
      |      |      +--- /index.php
      |      |      |
      |      |      +--- /routes
      |      |              |
      |      |              +--- /login.php
      |      +--- /index.html
    
    ........ next releases until the end of the world
    

    My nginX is configured in such a way, that my virtual host has

    server {
      server_name my.personal.web.site;
      root /var/www/public_html;
      .....
    }
    

    Before starting nginX, I have run the following 2 commands:

    ln -s -f -n /my_releases/current /my_releases/v1
    ln -s -f -n /var/www/public_html /my_releases/current
    

    Then I started nginX - service nginx start. It will now serve v1 of my web site/application.

    Now, any time I deploy a new release, I run the following command (replace v2 with the relevant revision)

    ln -s -f -n /my_releases/current /my_releases/v2
    

    Don't forget to set the proper filesystem permissions and ownership.