Skip to main content
  1. Posts/
  2. Nextcloud/

Nextcloud in Proxmox: A Full Installation in an LXC without Docker

··2124 words·10 mins· loading · loading · ·
Stilicho2011
Author
Stilicho2011
Writing about homelab, self-hosting, automation and open-source solutions
Table of Contents
Nextcloud - This article is part of a series.
Part : This Article

Installing a Full Nextcloud in an LXC Container in Proxmox
#

If you enjoyed this article, you can support the author by becoming a sponsor on Boosty (link in the contacts section).


In this video I’ll show you how to install Nextcloud from scratch - without Docker, on a full Apache, MariaDB, and PHP stack. Safe and stable, stylish and modern. The setup I’ll show you today can handle the load of even a small-to-medium office, let alone home use.

But first, I want to thank my sponsors on Boosty. Guys, a huge thank you for helping this channel grow. This channel runs entirely thanks to your support. And your support goes entirely toward growing this channel. For those who don’t know, on Boosty, sponsors get videos early - up to a month before they go public - so if you enjoy the content on this channel, want to support its growth, or maybe just want to watch something ahead of time, the link to Boosty and all my other contacts - Telegram, backup channels on domestic platforms - will be in the description.

I already have two videos on my YouTube channel covering the specifics of installing Nextcloud AIO and Nextcloud in Docker. There are also videos about installing and integrating OnlyOffice with Nextcloud, as well as the Memories gallery. This video will be the final one in the series. But that’s not guaranteed.

Links to Other Installation Options#

In this video we’ll set up a full-featured Nextcloud, but with a few particular twists. First, though, as tradition demands, I need to explain to newcomers what Nextcloud actually is. Nextcloud is an open-source cloud service that lets you store, sync, and share files, and extend its functionality with built-in apps: calendars, video calls, notes, document editors, and so on. So whenever you hear someone say Nextcloud is a replacement for commercial cloud storage, look at them with a bit of pity - like, “oh, you’re still young, you don’t get it yet, rookie.” Nextcloud crossed the line from “just a cloud storage” a long time ago. Today it’s a genuine competitor to solutions like Google Workspace and similar platforms.

Now let’s talk about what’s special about today’s installation. There are only two official Nextcloud builds. That’s the one we’ll install today, and Nextcloud AIO (which, as far as I know, is maintained by essentially one person). Everything else is the work of the community. In videos about installing full Nextcloud, you usually see people setting everything up in a VM, then installing certbot, installing nginx or ngrok, issuing an SSL certificate. We’re not going to do any of that. Why? We already have our own reverse proxy, and that’s what we’ll use. We’ll install everything in an LXC container. Now, the hardcore admins out there are probably yelling at me - “what are you doing, you can’t do that.” You can’t - in production. At home, you can. Why LXC? Because we can pass through the integrated GPU on the CPU, and at the same time still use that same GPU in other containers. To see how GPU passthrough works, check out the video on my channel.

I already have an LXC container created, and my reverse proxy is set up to issue a certificate for the IP address our container lives on, on port 80. I’m assuming you know how to configure your particular reverse proxy. That wraps up the intro.

Let’s get started.

Step 1: Update the System
#

  1. Update packages and configure the locale:
sudo su
apt update && apt upgrade -y
dpkg-reconfigure locales

Step 2: Install Apache2 and PHP Modules
#

  1. Install Apache2:
apt install apache2 -y
  1. Install the dependencies:
apt install php php-common libapache2-mod-php php-bz2 php-gd php-mysql php-curl php-mbstring php-imagick php-zip php-common php-curl php-xml php-json php-bcmath php-xml php-intl php-gmp zip unzip wget smbclient libmagickcore-6.q16-7-extra ffmpeg intel-media-va-driver-non-free ffmpeg va-driver-all ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools -y
  1. Enable the necessary Apache modules:
a2enmod env rewrite dir mime headers setenvif ssl
  1. Restart, enable, and check Apache’s status.
systemctl restart apache2
systemctl enable apache2
systemctl status apache2
  1. Check which Apache modules are loaded:
apache2ctl -M

Step 3: Install and Configure the MariaDB Server
#

  1. Install the mariadb-server package:
apt install mariadb-server -y
  1. Log into MariaDB:
mysql
  1. Create a database and user for Nextcloud and grant the user the necessary privileges:
CREATE USER 'ncloud'@'localhost' IDENTIFIED BY 'admin123';
CREATE DATABASE ncloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES ON ncloud.* TO 'ncloud'@'localhost';
FLUSH PRIVILEGES;
quit;
  1. Restart and enable MariaDB:
systemctl restart mariadb
systemctl enable mariadb
  1. Check that MariaDB is running:
systemctl status mariadb

Step 4: Download, Extract, and Set Permissions for Nextcloud
#

  1. Download and extract into the /var/www/html folder:
cd /var/www/html
wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip
  1. Remove the archive, since we don’t need it anymore:
rm -rf latest.zip
  1. Set the folder permissions:
chown -R www-data:www-data /var/www/html/nextcloud/

Step 5: Install Nextcloud from the Command Line
#

  1. Run the command below to install Nextcloud (of course, fill in your own values):
cd /var/www/html/nextcloud
sudo -E -u www-data php occ maintenance:install --database \
"mysql" --database-name "ncloud"  --database-user "ncloud" --database-pass \
'admin123' --admin-user "admin" --admin-pass "password"
  1. Nextcloud only allows access from localhost by default, which can lead to an “Access through untrusted domain” error. We need to allow access to Nextcloud using the IP address or domain name.
sudo nano /var/www/html/nextcloud/config/config.php

  'trusted_domains' =>
  array (
    0 => 'localhost',
    1 => 'nextcloud.your_domain.ru',   // we Included the Sub Domain
  ),
  'overwritehost' => 'nextcloud.your_domain.ru',
  'overwriteprotocol' => 'https',
  'overwrite.cli.url' => 'https://nextcloud.your_domain.ru',
  'trusted_proxies' => 
  array (
    0 => '192.168.0.0/16',
    1 => '172.16.0.0/12',
    2 => '10.0.0.0/8',
    3 => 'fc00::/7',
    4 => 'fe80::/10',
    5 => '2001:db8::/32',
   ),
  'default_phone_region' => 'RU',
  'allow_local_remote_servers' => true,
  
  1. Configure Apache to serve Nextcloud from the /var/www/html/nextcloud folder:
nano /etc/apache2/sites-enabled/000-default.conf

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/nextcloud
        
        <Directory /var/www/html/nextcloud>
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
       
 ServerName nextcloud.your_domain.ru
        <IfModule mod_headers.c>
            Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
        </IfModule>
        
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
  1. Restart Apache:
systemctl restart apache2
  1. Now go to your browser and enter http://[the IP or full domain name] of the server. You should see the Nextcloud login page shown below.

Step 6: Install and Configure PHP-FPM with Apache
#

  1. Install PHP-FPM (PHP 8.3 is used throughout below - check the currently supported version before installing; at the time of writing, Nextcloud supports PHP 8.2-8.5):
apt install php8.3-fpm 
  1. Check whether PHP-FPM is running, its version, and whether the socket has been created:
service php8.3-fpm status
php-fpm8.3 -v
ls -la /var/run/php/php8.3-fpm.sock
  1. Disable mod_php and the prefork module:
a2dismod php8.3
a2dismod mpm_prefork
  1. Enable PHP-FPM:
a2enmod mpm_event proxy_fcgi setenvif
a2enconf php8.3-fpm
  1. Restart Apache to reload all modules and configurations:
systemctl restart apache2

Now, to configure the upload size and performance, we need to change a few php.ini settings listed below, in the /etc/php/8.3/fpm/php.ini file. You can set your own values depending on your environment.

upload_max_filesize = 64M
post_max_size = 96M
memory_limit = 512M
max_execution_time = 600
max_input_vars = 3000
max_input_time = 1000
  1. Check the current value:
grep -E "upload_max_filesize|post_max_size|memory_limit|max_execution_time|max_input_vars|max_input_time" /etc/php/8.3/fpm/php.ini
  1. Instead of making the changes manually, you can run the following command to apply them immediately. This will save time.
sed -i 's/^upload_max_filesize.*/upload_max_filesize = 64M/; s/^post_max_size.*/post_max_size = 96M/; s/^memory_limit.*/memory_limit = 512M/; s/^max_execution_time.*/max_execution_time = 600/; s/^;max_input_vars.*/max_input_vars = 3000/; s/^max_input_time.*/max_input_time = 1000/' /etc/php/8.3/fpm/php.ini

or

sed -i 's/^upload_max_filesize.*/upload_max_filesize = 16G/; s/^post_max_size.*/post_max_size = 16G/; s/^memory_limit.*/memory_limit = 2048M/; s/^max_execution_time.*/max_execution_time = 3600/; s/^;max_input_vars.*/max_input_vars = 3600/; s/^max_input_time.*/max_input_time = 3600/' /etc/php/8.3/fpm/php.ini

Now we need to update the PHP-FPM pool configuration in /etc/php/8.3/fpm/pool.d/ www.conf. Below are some reasonable default values, but you should set your own.

pm.max_children = 64
pm.start_servers = 16
pm.min_spare_servers = 16
pm.max_spare_servers = 32
  1. Let’s check the current values:
grep -E "pm.max_children|pm.start_servers|pm.min_spare_servers|pm.max_spare_servers" /etc/php/8.3/fpm/pool.d/www.conf
  1. Change all values at once with the following command:
sed -i 's/^pm.max_children = .*/pm.max_children = 64/; s/^pm.start_servers = .*/pm.start_servers = 16/; s/^pm.min_spare_servers = .*/pm.min_spare_servers = 16/; s/^pm.max_spare_servers = .*/pm.max_spare_servers = 32/' /etc/php/8.3/fpm/pool.d/www.conf

or

sed -i 's/^pm.max_children = .*/pm.max_children = 70/; s/^pm.start_servers = .*/pm.start_servers = 20/; s/^pm.min_spare_servers = .*/pm.min_spare_servers = 20/; s/^pm.max_spare_servers = .*/pm.max_spare_servers = 60/' /etc/php/8.3/fpm/pool.d/www.conf
  1. Now restart PHP-FPM to apply all the changes:
service php8.3-fpm restart

Now paste the code below into the default Apache site configuration file /etc/apache2/sites-enabled/000-default.conf; it tells Apache to hand off PHP file processing to PHP-FPM.

    <FilesMatch ".php$">
         SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost/"
    </FilesMatch>

  1. After adding this code, the default Apache site configuration will look like this:
nano /etc/apache2/sites-enabled/000-default.conf 
<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/nextcloud

        <Directory /var/www/html/nextcloud>
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
           
        <FilesMatch ".php$"> 
            SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost/"
        </FilesMatch>   
            
        ServerName nextcloud.your_domain.ru
        <IfModule mod_headers.c>
            Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
        </IfModule>

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>
  1. Now restart Apache for the changes to take effect:
systemctl restart apache2

Step 7: Create an info.php Page to Test PHP Features (optional - remove the file once you’re done testing)
#

Create an info.php page - it’ll show us whether PHP-FPM, OPCache, and APCu are enabled in PHP.

cd /var/www/html/nextcloud
nano info.php
<?php phpinfo(); ?>

Now go to [URL]/info.php. If PHP-FPM is enabled in PHP, it will show “Server API FPM/FastCGI”.

Step 8: Enable OPCache in PHP
#

  1. Enable OPCache in PHP: Check whether it’s running using the [URL]/info.php file we created earlier.

Opcache’s JIT (Just-In-Time) compilation is an important feature. JIT compilation improves PHP performance by compiling code to machine language at runtime instead of interpreting it on every run. This can significantly boost performance for resource-intensive tasks. So enabling it will be very effective for improving Nextcloud’s performance.

nano /etc/php/8.3/fpm/conf.d/10-opcache.ini

zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=12000
opcache.memory_consumption=512
opcache.save_comments=1
opcache.revalidate_freq=60
opcache.jit = 1255
opcache.jit_buffer_size = 256M
  1. Restart PHP-FPM for the changes to take effect:
service php8.3-fpm restart

Step 9: Enable APCu in PHP
#

  1. Enable APCu in PHP:
apt install php8.3-apcu
nano /etc/php/8.3/fpm/conf.d/20-apcu.ini
extension=apcu.so
apc.enable_cli=1

Now restart PHP-FPM and Apache.

systemctl restart php8.3-fpm
systemctl restart apache2

Now check [URL]/info.php again - it will show “APCu support Enabled”.

  1. Configure Nextcloud to use APCu for memory caching:
nano /var/www/html/nextcloud/config/config.php
'memcache.local' => '\OC\Memcache\APCu',

Step 10: Install and Configure Redis Cache
#

  1. Install and configure Redis Cache. In Nextcloud, Redis is used for local and distributed caching, as well as for transactional file locking. For local caching we used APCu, which is faster than Redis. Redis will be used for file locking. Nextcloud’s transactional file locking mechanism locks files to prevent corruption during normal operation.

  2. Install the Redis server and the Redis PHP extension.

apt install redis-server php-redis -y
  1. Start and enable the Redis service.
systemctl start redis-server
systemctl enable redis-server
systemctl status redis-server
  1. Configure Redis to use a Unix socket instead of ports.
nano /etc/redis/redis.conf
port 0
unixsocket /var/run/redis/redis.sock
unixsocketperm 770
  1. Add the Apache user to the Redis group.
usermod -a -G redis www-data
  1. Configure Nextcloud to use Redis for file locking.
nano /var/www/html/nextcloud/config/config.php
'filelocking.enabled' => 'true',
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' => [
     'host'     => '/var/run/redis/redis.sock',
     'port'     => 0,
     'dbindex'  => 0,
     'password' => '',
     'timeout'  => 1.5,
],
  1. Enable Redis session locking in PHP.
nano /etc/php/8.3/fpm/php.ini
redis.session.locking_enabled=1
redis.session.lock_retries=-1
redis.session.lock_wait_time=10000
  1. Restart Redis, PHP-FPM, and Apache.
systemctl restart redis-server
systemctl restart php8.3-fpm
systemctl restart apache2
  1. You can check whether the features are enabled in PHP.
nextcloud-ubuntu-24.04-redis
Redis is Installed for Nextcloud

https://help.nextcloud.com/t/installing-redis-for-memcache/162599/6

  1. I’m assuming you’re using Traefik as your reverse proxy and don’t need certbot. So we’ve added the relevant values to /etc/apache2/sites-enabled/000-default.conf.

  2. Enable Pretty URLs:

nano /var/www/html/nextcloud/config/config.php
'htaccess.RewriteBase' => '/',

This command will update the .htaccess file for redirection.

sudo -E -u www-data php -d apc.enable_cli=1 /var/www/html/nextcloud/occ maintenance:update:htaccess
  1. Other useful commands:
sudo -E -u www-data php /var/www/html/nextcloud/occ maintenance:repair --include-expensive
sudo -E -u www-data php /var/www/html/nextcloud/occ db:add-missing-indices
sudo -E -u www-data php /var/www/html/nextcloud/occ config:system:set maintenance_window_start --type=integer --value=1
sudo crontab -u www-data -e
*/5  *  *  *  * php -f /var/www/html/nextcloud/cron.php
sudo -E -u www-data php /var/www/html/nextcloud/occ files:scan --all
sudo -E -u www-data php /var/www/html/nextcloud/occ app:update --all
Nextcloud - This article is part of a series.
Part : This Article

Related