HestiaCP + Nextcloud + Roundcube Mail App

HestiaCP version: v1.8.12
Host: Ubuntu 22.04

I’m honestly not sure if this is a HestiaCP question but thought I’d start here.

After installing Nextcloud through the Quick Install App menu, I wanted to setup the Roundcube Mail Nextcloud App to use Hestia’s install of Roundcube.

I was just wondering if anyone has gotten this to work as Hestia’s Apache, PHP, and Nginx configs aren’t exactly standard. Thus, following along with the setup guide for the app doesn’t work out of the box.

I was following this section of the guide for Roundcube installs which exist on the same web server but use a different domain:

https://github.com/rotdrop/nextcloud-roundcube/?tab=readme-ov-file#different-domains-but-same-web-server

I’ve created new Hestia templates for the Nextcloud site to use (apache and nginx) however, everything I try just leads to more problems.

I’m currently trying to point the Roundcube Mail App to /var/lib/roundcube and making Roundcube accessible externally via https://mynextcloud.com/roundcube.

Here’s my nextcloud.stpl apache template:

#=========================================================================#
# Default Web Domain Template                                             #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
# https://hestiacp.com/docs/server-administration/web-templates.html      #
#=========================================================================#

<VirtualHost %ip%:%web_ssl_port%>

    ServerName %domain_idn%
    %alias_string%
    ServerAdmin %email%
    DocumentRoot %sdocroot%
    ScriptAlias /cgi-bin/ %home%/%user%/web/%domain%/cgi-bin/
    Alias /vstats/ %home%/%user%/web/%domain%/stats/
    Alias /error/ %home%/%user%/web/%domain%/document_errors/
    #INCLUDES ROUNDCUBE
    Alias /roundcube /var/lib/roundcube/
    #SuexecUserGroup %user% %group%
    CustomLog /var/log/%web_system%/domains/%domain%.bytes bytes
    CustomLog /var/log/%web_system%/domains/%domain%.log combined
    ErrorLog /var/log/%web_system%/domains/%domain%.error.log
    <Directory %home%/%user%/web/%domain%/stats>
        AllowOverride All
    </Directory>
    <Directory %sdocroot%>
        AllowOverride All
        SSLRequireSSL
        Options +Includes -Indexes +ExecCGI
        </Directory>
    <Directory /var/lib/roundcube/>
        AllowOverride All
    </Directory>
    SSLEngine on
    SSLVerifyClient none
    SSLCertificateFile %ssl_crt%
    SSLCertificateKeyFile %ssl_key%
    %ssl_ca_str%SSLCertificateChainFile %ssl_ca%

    <FilesMatch \.php$>
        SetHandler "proxy:%backend_lsnr%|fcgi://localhost"
    </FilesMatch>
    SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

    IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.ssl.conf_*
    IncludeOptional /etc/apache2/conf.d/*.inc
</VirtualHost>

And here’s my nextcloud.stpl nginx template:

#=========================================================================#
# Default Web Domain Template                                             #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
# https://hestiacp.com/docs/server-administration/web-templates.html      #
#=========================================================================#

server {
        listen      %ip%:%proxy_ssl_port% ssl;
        server_name %domain_idn% %alias_idn%;
        error_log   /var/log/%web_system%/domains/%domain%.error.log error;

        ssl_certificate     %ssl_pem%;
        ssl_certificate_key %ssl_key%;
        ssl_stapling        on;
        ssl_stapling_verify on;

        # TLS 1.3 0-RTT anti-replay
        if ($anti_replay = 307) { return 307 https://$host$request_uri; }
        if ($anti_replay = 425) { return 425; }

        include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*;

        location ~ /\.(?!well-known\/|file) {
                deny all;
                return 404;
        }

        location / {
                proxy_pass https://%ip%:%web_ssl_port%;

                proxy_cache %domain%;
                proxy_cache_valid 200 5m;
                proxy_cache_valid 301 302 10m;
                proxy_cache_valid 404 10m;
                proxy_cache_bypass $no_cache $cookie_session $http_x_update;
                proxy_no_cache $no_cache;

                set $no_cache 0;

                if ($request_uri ~* "/wp-admin/|/wp-json/|wp-.*.php|xmlrpc.php|/store.*|/cart.*|/my-account.*|/checkout.*|/user/|/admin/|/administrator/|/manager/|index.php") {
                        set $no_cache 1;
                }

                if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash|PHPSESSID") {
                        set $no_cache 1;
                }

                if ($http_cookie ~ SESS) {
                        set $no_cache 1;
                }

                location ~* ^.+\.(%proxy_extensions%)$ {
                        try_files   $uri @fallback;

                        root        %sdocroot%;
                        access_log  /var/log/%web_system%/domains/%domain%.log combined;
                        access_log  /var/log/%web_system%/domains/%domain%.bytes bytes;

                        expires     max;

                        proxy_cache off;
                }
        }

        location /roundcube/ {
                alias /var/lib/roundcube/;
                index index.php;

                location ~ \.php$ {
                        fastcgi_split_path_info ^(.+\.php)(/.+)$;
                        set $path_info $fastcgi_path_info;

                        try_files $fastcgi_script_name =404;
                        fastcgi_param SCRIPT_FILENAME $request_filename;
                        include fastcgi_params;
                        fastcgi_param PATH_INFO $path_info;
                        fastcgi_param HTTPS on;
                        fastcgi_pass %backend_lsnr%;

                        # The following lines might be optional depending on your setup:
                        #fastcgi_param modHeadersAvailable true;         # Avoid sending the security headers twice
                        #fastcgi_param front_controller_active true;     # Enable pretty urls
                        #fastcgi_intercept_errors on;
                        #fastcgi_request_buffering off;
                }

                # Handle static assets
                location ~ ^/roundcube/(.+)$ {
                        try_files /$1 =404;
                }
        }

        location @fallback {
                proxy_pass https://%ip%:%web_ssl_port%;
        }

        location /error/ {
                alias %home%/%user%/web/%domain%/document_errors/;
        }

        proxy_hide_header Upgrade;

        include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}

The current error I’m getting is from Roundcube itself I believe:

2024/11/06 22:51:25 [error] 1580333#1580333: *5865 FastCGI sent in stderr: "PHP message: PHP Warning:  realpath(): open_basedir restriction in effect. File(/var/lib/roundcube/program/lib) is not within the allowed path(s): (/home/MYUSER/.composer:/home/MYUSER/web/MYDOMAIN/public_html:/home/MYUSER/web/MYDOMAIN/private:/home/MYUSER/web/MYDOMAIN/public_shtml:/home/MYUSER/tmp:/tmp:/var/www/html:/bin:/usr/bin:/usr/local/bin:/usr/share:/opt) in /var/lib/roundcube/program/lib/Roundcube/bootstrap.php on line 90; PHP message: PHP Warning:  is_readable(): open_basedir restriction in effect. File(/var/lib/roundcube/program/include/rcmail.php) is not within the allowed path(s): (/home/MYUSER/.composer:/home/MYUSER/web/MYDOMAIN/public_html:/home/MYUSER/web/MYDOMAIN/private:/home/MYUSER/web/MYDOMAIN/public_shtml:/home/MYUSER/tmp:/tmp:/var/www/html:/bin:/usr/bin:/usr/local/bin:/usr/share:/opt) in /var/lib/roundcube/program/include/iniset.php on line 96; PHP message: PHP Fatal error:  Uncaught Error: Class "rcmail" not found in /var/lib/roundcube/index.php:43
Stack trace:
#0 {main}
  thrown in /var/lib/roundcube/index.php on line 43; PHP message: PHP Warning:  file_get_contents(): open_basedir restriction in effect. File(/var/lib/roundcube/program/resources/error.html) is not within the allowed path(s): (/home/MYUSER/.composer:/home/MYUSER/web/MYDOMAIN/public_html:/home/MYUSER/web/MYDOMAIN/private:/home/MYUSER/web/MYDOMAIN/public_shtml:/home/MYUSER/tmp:/tmp:/var/www/html:/bin:/usr/bin:/usr/local/bin:/usr/share:/opt) in /var/lib/roundcube/program/include/iniset.php on line 135; PHP message: PHP Warning:  file_get_contents(/var/lib/roundcube/program/resources/error.html): Failed to open stream: Operation not permitted in /var/lib/roundcube/program/include/iniset.php on line 135" while reading response header from upstream, client: CLIENTIP, server: MYDOMAIN, request: "GET /roundcube/index.php HTTP/2.0", upstream: "fastcgi://unix:/run/php/php8.2-fpm

I’m just not really sure where to go from here as I’m not super familiar with PHP and how Roundcube works on a technical level. Any help or advice appreciated.

Use email clients embed in nextcloud, search in nextcloud store.
Roundcube should be accessible in hestia by webmail.yourdomain.com, if it setup correctly in mail and dns.

As @viorelp said, connect as if the IMAP server was a remote server and everything will run smoothly.

1 Like