• We value your experience with Plesk during 2024
    Plesk strives to perform even better in 2025. To help us improve further, please answer a few questions about your experience with Plesk Obsidian 2024.
    Please take this short survey:

    https://pt-research.typeform.com/to/AmZvSXkx
  • The Horde webmail has been deprecated. Its complete removal is scheduled for April 2025. For details and recommended actions, see the Feature and Deprecation Plan.
  • We’re working on enhancing the Monitoring feature in Plesk, and we could really use your expertise! If you’re open to sharing your experiences with server and website monitoring or providing feedback, we’d love to have a one-hour online meeting with you.

Input How to run Magento 2 on Plesk Obsidian 18 without Docker

davidon

New Pleskian
Server operating system version
Debian 11
Plesk version and microupdate number
Plesk Obsidian Version 18.0.50
This guide is about how to install and run Magento 2.4x on Plesk without Docker.
Our example domain will be "example-magento.com" make sure you replace this detail to the domain where you would like to set-up the magneto site.
We won't cover the installation of the required components, by request I can add some details.

Pre-requirements:
Plesk Obsidian - Version 18.0.50
Mariadb 10.5.18
Php 7.4 (for now)
Nginx
Composer 2
Memcached
Opcache
Redis 6
Elasticsearch 7.9.x

In our experience running Magento systems with Plesk it is recommended to create a custom vhost template.
Create the directory /opt/psa/admin/conf/templates/custom/domain copy the nginxDomainVirtualHost.php from /opt/psa/admin/conf/templates/default/domain to this directory.
Open the the copied file in your prefered editor /opt/psa/admin/conf/templates/custom/domain/nginxDomainVirtualHost.php
@line 217 replace
PHP:
        <?php if ($VAR->domain->physicalHosting->directoryIndex && !$VAR->domain->physicalHosting->proxySettings['nginxProxyMode']): ?>
        index <?=$VAR->quote($VAR->domain->physicalHosting->directoryIndex)?>;
        <?php endif ?>
with
PHP:
        <?php if ($VAR->domain->physicalHosting->directoryIndex): ?>
            location ~ /$ {
            index index.php index.cgi index.pl index.html index.xhtml index.htm index.shtml;
            try_files $uri $uri/ /index.php$is_args$args;
        }      
     #   index <?=$VAR->quote($VAR->domain->physicalHosting->directoryIndex)?>;
        <?php endif ?>

Web Hosting Access​

Create the domain and allow "Access to the server over SSH" and the usage of bin/bash

Hosting Settings​

- Document root "httpdocs/pub"
- Enable "Permanent SEO-safe 301 redirect from HTTP to HTTPS" !
- Php version 7.4x
- FPM application served by Nginx (Use dedicated if you understand how it works)

1676885184005.png

Apache & nginx Settings​

Index files (we have a custom maintenance page what runs from the index.html)
Code:
index.php index.html

Additional headers for development:
Code:
Cache-Control: public
Strict-Transport-Security: max-age=-1
X-Frame-Options: SAMEORIGIN

Additional headers for production:
Code:
Cache-Control: public
Strict-Transport-Security: max-age=63072000
X-Frame-Options: SAMEORIGIN



Additional Apache directives both HTTP and HTTPS
Code:
<IfModule mod_security2.c>
    SecResponseBodyLimit 546870912
</IfModule>
Optionally you can add the following directives:
Code:
<Directory /var/www/vhosts/example-magento.com>
    Options +ExecCGI +FollowSymlinks
</Directory>


nginx settings
Proxy mode enabled
Smart static files processing enabled
Serve static files directly by nginx enabled

Maximum allowed HTTP request body size
128MB

Enable nginx caching
Cache size
64MB
Cache timeout
5 seconds


Additional nginx directives

Code:
set $MAGE_ROOT "/var/www/vhosts/example-magento.com/httpdocs/pub";

location ~ ^/setup {
    root $MAGE_ROOT;
    location ~ ^/setup/index.php(/.*)?$ {
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ ^/setup/(?!pub/). {
        deny all;
    }

    location ~ ^/setup/pub/ {
        add_header X-Frame-Options "SAMEORIGIN";
    }
}
# PHP entry point for update application
location ~ ^/update {
    root $MAGE_ROOT;
    location ~ ^/update/index.php(/.*)?$ {
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    # Deny everything but index.php
    location ~ ^/update/(?!pub/). {
        deny all;
    }

    location ~ ^/update/pub/ {
        add_header X-Frame-Options "SAMEORIGIN";
    }
    if (!-e $request_filename){ rewrite ^(/.*)(/.+)$ /index.php$is_args$args last; }
}
location @fallback {
    return 404;
}

#location / { try_files $uri $uri/ /index.php$is_args$args; }

location /pub/ {
    location ~ ^/pub/media/(downloadable|customer|import|custom_options|theme_customization/.*\.xml) {
        deny all;
    }
    alias $MAGE_ROOT/pub/;
    add_header X-Frame-Options "SAMEORIGIN";
}

location /static/ {
    # Uncomment the following line in production mode
    # expires max;

    # Remove signature of the static files that is used to overcome the browser cache
    location ~ ^/static/version {
        rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
    }

    location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|html|json)$ {
        add_header Cache-Control "public";
        add_header X-Frame-Options "SAMEORIGIN";
        expires +1y;

        if (!-f $request_filename) {
            rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
        }
    }
    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        add_header X-Frame-Options "SAMEORIGIN";
        expires    off;

        if (!-f $request_filename) {
            rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
        }
    }
    if (!-f $request_filename) {
        rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
    }
    add_header X-Frame-Options "SAMEORIGIN";
}

location /media/ {
    try_files $uri $uri/ /get.php$is_args$args;

    location ~ ^/media/theme_customization/.*\.xml { deny all; }

    location ~ ^/(.*\.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json))$ {
        add_header Cache-Control "public";
        add_header X-Frame-Options "SAMEORIGIN";
        expires +1y;
        log_not_found off;
        access_log off;
        add_header ETag "";
        add_header Access-Control-Allow-Origin "www.example-magento.com, example-magento.com";

        try_files $uri $uri/ /get.php$is_args$args;
    }
    location ~ ^/(.*\.(zip|gz|gzip|bz2|csv|xml))$ {
        add_header Cache-Control "no-store";
        add_header X-Frame-Options "SAMEORIGIN";
        expires off;
        log_not_found off;
        access_log off;
        add_header ETag "";
        add_header Access-Control-Allow-Origin "www.example-magento.com,example-magento.com";

        try_files $uri $uri/ /get.php$is_args$args;
    }
    add_header X-Frame-Options "SAMEORIGIN";
}

location /media/customer/ { deny all; }

location /media/downloadable/ { deny all; }

location /media/import/ { deny all; }

location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {

    try_files $uri =404;

    add_header X-Processing-Time $request_time always;
    add_header X-Request-ID $request_id always;
    add_header X-UA-Compatible 'IE=Edge,chrome=1';
    add_header Link "<$scheme://$http_host$request_uri>; rel=\"canonical\"" always;
}

location ~ /$ {
    if (!-e $request_filename){ rewrite ^(/.*)([^/]+/)$ /index.php$is_args$args last; }
}
gzip on;
gzip_disable "MSIE [1-6]\\.(?!.*SV1)";
gzip_proxied any;
gzip_comp_level 5;
gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/bmp image/svg+xml;
gzip_vary on;
fastcgi_buffers         16  16k;
fastcgi_buffer_size         32k;
fastcgi_read_timeout 600s;
fastcgi_connect_timeout 600s;
proxy_buffer_size          128k;
proxy_buffers            4 256k;
proxy_busy_buffers_size    256k;

PHP Settings​

(adjust these settings to your own needs)
memory_limit
2048M
max_execution_time
180
max_execution_time
180
post_max_size
64M
upload_max_filesize
64M

The following settings are required and recommended:

opcache.enable
On
include_path
.
short_open_tag
On

PHP-FPM settings:

pm.max_children
20
pm.max_requests
500

Additional directives:
max_input_vars = 18000

1676886985577.png


Login via ssh and create the .bashrc file at the /var/www/vhosts/example-magento.com location (domain service root), make sure this file has the proper web-space owner permissions!
Code:
alias php="/opt/plesk/php/7.4/bin/php -c /var/www/vhosts/system/example-magento.com/etc/php.ini -d memory_limit=4G -d max_execution_time=360000"
alias composer="/opt/plesk/php/7.4/bin/php -c /var/www/vhosts/system/example-magento.com/etc/php.ini -d memory_limit=4G -d max_execution_time=360000 /usr/lib64/plesk-9.0/composer.phar"
export PATH="$PATH:/opt/plesk/php/7.4/bin:/var/www/vhosts/example-magento.com/.rbenv/shims:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/var/www/vhosts/example-magento.com/httpdocs";

With this solution you can create a php.ini specific for the site's php CLI to enable some services or raise timeouts, memory limits etc.
I hope it's understandable and I haven't missed anything, enjoy and I will gladly help if something is not clear.
 
Thank you for compiling and sharing! Could you also post this to the resources section? Thats where guide like these are usually shared and can easily be found.
 
also works under VServer with Debian 11, Plesk 18.0.52, PHP 8.1.x (before installing Plesk, install MySQL 8 and Elasticsearch 7.17.x)
 
Thanks for sharing, I have followed the instruction, however, I can access the landing page but all other URLs on the page redirect to the 404 error page including the admin page. Can you help? many thanks
 
Hi davidon,

this instruction is really great and helped me a lot to get forward - thank you for this! However, I am still struggling a bit:

My task is to move a fully working Magento installation to a Plesk server (18.0.55 with PHP 8.1). I had the issue that all other pages but the homepage were not working. What helped a bit was replacing

Code:
location ~ /$ {
        if (!-e $request_filename){ rewrite ^(/.*)([^/]+/)$ /index.php$is_args$args last; }
    }

with

Code:
if (!-e $request_filename){ rewrite ^(/.*)([^/]+/)$ /index.php$is_args$args last; }

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

(Source: Question - Magento 2 with only nginx rewrite rule)

Now all pages coming from the CMS are being displayed, I can also reach the backend. However, I still get 404's for the shop related pages, no matter if they have rewritten URLs or end on .html.

Would you have any idea how to solve this?

Best,
Udo
 
I'm using required services for Magento 2 in Dockers.


 
Thanks for the detailed post - do you know if it's possible to run M2.4 with just nginx (no Apache)? Or should I just give that up as an impossibility?

From what I've read, M2 is faster on nginx, but by how much I don't know and I'm not sure I can be bothered to waste more of my life on trying to make it work...
 
Back
Top