Skip to content

Strukturpiloten/nextcloud

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nextcloud

A Nextcloud container solution using Free and Open Source (FOSS) tools 🤝

This project is being tested againt Podman as container runtime with docker/compose as compose engine.

Future goals are to also support Kubernetes.

Note

🚧🚧🚧

This project is still under heavy development. Do not use in production setups! There will be breaking changes in the near future.

🚧🚧🚧

Index

Support by Strukturpiloten

Strukturpiloten is a German consulting crew specializing in process optimization, automation, Linux, network engineering, and DevOps.
We build scalable, open, and human-centered IT systems — from containers to culture.

Need mission control for your next project?
👉 Get in touch

Powered by curiosity. Guided by structure.

Motivation

We at Strukturpiloten love Free and Open Source Software (FOSS) and therefore also want to use FOSS software as underlay. When it comes to container runtimes we prefer Podman (Website) over Docker due to its daemonless architecture and improved security model.

There are already official and community backed Nextcloud Docker containers available, but none of them support Podman out of the box. This project aims to provide an easy to use Nextcloud setup using Podman as container runtime in the first step. Furthermore we intend to provide a Kubernetes setup that can be derived from this Podman project in the near future.

Other Projects

All other projects that we know of use Docker as container runtime. The official Nextcloud container even needs a docker.sock bind mount to work.

Nextcloud All-in-One

Official Nextcloud All-in-One Docker project. To run this project root access to the docker.sock is required.

Nextcloud Docker Container

Community backed Nextcloud Docker container. Can be used as stand-alone container that accesses other services (database, etc.) or can be used with a compose.yaml file.

Linuxserver Nextcloud

The LinuxServer.io project also has a Nextcloud docker container. Can be used as stand-alone container that accesses other services (database, etc.) or can be used with a compose.yaml file.

Prerequisites

Podman Setup

Podman requires a proper setup for non-root users. Please follow the official Podman installation instructions.

The following packages need to be installed, but package names may differ depending on your Linux distribution:

  • podman
  • docker-compose - not to be confused with podman-compose!

Sadly this project is not compatible with podman-compose as podman-compose lacks several fundamental features that are already implemented in docker-compose 😢

Podman Quadlets have not been implemented by this project as many people using Docker and docker/compose don't know about Quadlets yet. Therefore we stick to the more common docker/compose way of doing things.

It is also recommended to set up IPv4 and IPv6 (dual-stack) on your system.

User Setup

There's a whole example setup with commands at the end of this chapter.

Create a username and group for running the containers, e.g.:

  • User: podman
  • Group: podman

Make your user services reboot persistent by enabling linger for your podman user. Run this command as root user:

loginctl enable-linger podman

Also add the podman.sock systemd socket for non-root users. Run this command with your podman user:

systemctl --user enable --now podman.socket

The whole setup looks like this:

username=podman
groupadd ${username}
useradd -g ${username} -m ${username}
loginctl enable-linger ${username}
sudo -u ${username} systemctl --user enable --now podman.socket

You can access the podman user with another account with sudo rights:

sudo -i -u podman

Allow Non-Root Users to Bind to Privileged Ports

Allow non-root users to bind to privileged ports <1024.

Run these commands as root to allow non-root users to bind to privileged ports starting from port 0. The second command will make it persistent across reboots:

Caution

This change impacts the whole system and allow also non-root users to bind to privileged ports. Make sure that you understand the security implications of this change.

echo 'net.ipv4.ip_unprivileged_port_start=0' >> /etc/sysctl.conf
sysctl -p

Firewall

Make sure that the following ports and protocols are open in your firewall:

  • 80/tcp: HTTP/1.1, HTTP/2
  • 80/udp: HTTP/3
  • 443/tcp: HTTP/1.1 with TLS/SSL, HTTP/2 with TLS
  • 443/udp: HTTP/3 with TLS

Installation

This section will show a step-by-step example installation.

The setup differentiates between these directories:

  • This repository is only used for the logic and not your (user) data and configs
  • data: Store your (user) files in one or multiple data directories
  • configs: Store your config files in one or multiple config directories

Therefore these directories will be used for this example setup:

  • /mnt/nextcloud: Parent working directory (pwd)
  • /mnt/nextcloud/configs: Your config files
  • /mnt/nextcloud/data: Your (user) files
  • /mnt/nextcloud/nextcloud: This repository

Preparation

So let's start:

cd /mnt/nextcloud
mkdir data
mkdir configs

Clone the repository to your local machine:

git clone https://github.com/Strukturpiloten/nextcloud.git

There are now three directories in /mnt/nextcloud:

  • configs
  • data
  • nextcloud

Environment Variables

Copy the example environment file and edit it to your needs:

cd /mnt/nextcloud
cp nextcloud/.env.example configs/.env

Check if UID and GID variables are set for your podman user. You can get the values with these commands:

echo "$UID"
echo "$GID"

If they are not set you can get the values:

id -u
id -g

Edit the configs/.env file and set at least the following variables:

  • PODMAN_NAMESPACE: E.g. customername, yourcompanyname
  • PODMAN_STAGE: E.g. test, prod
  • Change PODMAN_UID and PODMAN_GID if needed
  • All variables containing the following values:
    • /your/absolute/path/to/: Set the absolute paths to your data and config directories
    • a_secure_password: Use a separate secure password for each variable
    • domain.example.com: Your domain name
  • NEXTCLOUD_SMTP_, NEXTCLOUD_MAIL_ and NEXTCLOUD_DEFAULT_ variables

The following variables will not be changed for this example setup, because we will use the default config files where possible. These are the default values that are also present in our .env file. The configs path refers to /mnt/nextcloud/nextcloud/configs and not /mnt/nextcloud/configs as the environment variables are consumed be podman compose in the nextcloud directory. The default values are relative and not absolute paths:

PODMAN_PHPFPM_CONF_FILE_HOST=configs/phpfpm/conf/zzz-www.conf
# PODMAN_PHPFPM_CONF_FILE_HOST=/your/absolute/path/to/configs/phpfpm/conf/zzz-www.conf

PODMAN_PHPFPM_INI_FILE_HOST=configs/phpfpm/ini/nextcloud.ini
# PODMAN_PHPFPM_INI_FILE_HOST=/your/absolute/path/to/configs/phpfpm/ini/nextcloud.ini

PODMAN_MANAGER_CRON_ROOT_FILE_HOST=configs/phpfpm/cron/cron_root
# PODMAN_MANAGER_CRON_ROOT_FILE_HOST=/your/absolute/path/to/configs/phpfpm/cron/cron_root

That leads us to the following changes in the configs/.env file for this example:

# namespace and stage
PODMAN_NAMESPACE=examplecompany
PODMAN_STAGE=prod

# PODMAN_UID=${UID}
# PODMAN_GID=${GID}
PODMAN_UID=2000
PODMAN_GID=2000

# databases
PODMAN_SQL_DATABASE=postgres
PODMAN_KEY_VALUE_DATABASE=valkey

# data paths
PODMAN_SSL_DIR_HOST=/mnt/nextcloud/configs/ssl
PODMAN_NGINX_CONF_DIR_HOST=/mnt/nextcloud/configs/nginx/conf
PODMAN_CLAMAV_DATA_DIR_HOST=/mnt/nextcloud/data/clamav
PODMAN_POSTGRES_DATA_DIR_HOST=/mnt/nextcloud/data/postgres
PODMAN_VALKEY_DATA_DIR_HOST=/mnt/nextcloud/data/valkey
PODMAN_NEXTCLOUD_DATA_DIR_HOST=/mnt/nextcloud/data/nextcloud
PODMAN_NEXTCLOUD_USER_DATA_DIR_HOST=/mnt/nextcloud/data/nextcloud_data

# secrets - do not use these example secrets for your setup!
POSTGRES_PASSWORD=doNotUseThisSecretForPostgres
WHITEBOARD_JWT_SECRET_KEY=doNotUseThisSecretForWhiteboard
VALKEY_PASSWORD=doNotUseThisSecretForValkey
NEXTCLOUD_ADMIN_PASSWORD=doNotUseThisSecretForNextcloudAdminUser

NEXTCLOUD_DOMAIN=nextcloud.example.com
NEXTCLOUD_TRUSTED_DOMAINS="localhost nextcloud.example.com"

NEXTCLOUD_SMTP_HOST=nix
NEXTCLOUD_SMTP_SECURE=nix
NEXTCLOUD_SMTP_PORT=nix
NEXTCLOUD_SMTP_AUTHTYPE=nix
NEXTCLOUD_SMTP_NAME=nix
NEXTCLOUD_MAIL_FROM_ADDRESS=nix
NEXTCLOUD_MAIL_DOMAIN=nix

NEXTCLOUD_DEFAULT_LANGUAGE=de_DE
NEXTCLOUD_DEFAULT_PHONE_REGION=DE
NEXTCLOUD_DEFAULT_TIMEZONE=Europe/Berlin

Configs

Now we need to create the config directories and files. As bare minimum the Nginx config file needs to be changed, check the Minimal Example Setup for further details. Depending on your needs you can also copy/create all config files and edit them to your needs, check the All Configs section.

Minimal Example Setup

For your example setup we only need to edit the Nginx config file. Therefore we will only create the required directories and copy the default config files into our configs directory.

cd /mnt/nextcloud
mkdir -p configs/nginx/conf

Copy the default file into the directory:

cp nextcloud/configs/nginx/conf/nextcloud_default.conf configs/nginx/conf/nextcloud.conf

You need to edit the Nginx nextcloud.conf file as it contains the default domain cloud.example.com that needs to be changed to your domain like this:

sed -i 's/cloud.example.com/yourdomain.example.com/g'  configs/nginx/conf/nextcloud.conf

All other config files use some default values that can be used out of the box for a small setups.

All Configs

If you need to change all service configs you need to create the following directories:

cd /mnt/nextcloud
mkdir -p configs/nginx/conf
mkdir -p configs/phpfpm/conf
mkdir -p configs/phpfpm/ini

#  SQL database (choose your fighter)
mkdir -p configs/mariadb
mkdir -p configs/mysql
mkdir -p configs/postgres

# key-value database
mkdir -p configs/valkey

# Key-value database
mkdir -p configs/valkey

# Nextcloud scripts for the "manager" container
mkdir -p configs/manager

Copy all default files into the directories:

# nginx
cp nextcloud/configs/nginx/conf/nextcloud_default.conf configs/nginx/conf/nextcloud.conf

# phpfpm
cp nextcloud/configs/phpfpm/conf/zzz-www_default.conf configs/phpfpm/conf/zzz-www.conf
cp nextcloud/configs/phpfpm/ini/nextcloud_default.ini configs/phpfpm/ini/nextcloud.ini

# manager
cp nextcloud/configs/manager/nextcloud_config_default.php configs/manager/nextcloud_config.php
cp nextcloud/configs/manager/nextcloud_setup_default.sh configs/manager/

There are no default config files for MariaDB, MySQL, Postgres and Valkey, so you need to create them on your own if needed. Also check the environment variables containing path values in configs/.env that need to be uncommented and set accordingly. The path variable names end with _FILE_HOST and _DIR_HOST.

You need to edit the Nginx nextcloud.conf file as it contains the default domain cloud.example.com that needs to be changed to your domain like this:

sed -i 's/cloud.example.com/yourdomain.example.com/g'  configs/nginx/conf/nextcloud.conf

All other config files use some default values that can be used out of the box for a small setups.

SSL Certificates

Depending on your needs and your other setups you may or may not want to use a separate SSL directory. In this case we will use it as it's a simple way to move forward with this example setup:

cd /mnt/nextcloud
mkdir -p configs/ssl

The path /mnt/nextcloud/configs/ssl has also been set for the environment variable PODMAN_SSL_DIR_HOST.

You need to put your SSL certificate and key into the configs/ssl directory. The default Nginx config nextcloud_default.conf references these file names:

ssl_certificate.crt
ssl_certificate_key.key

Creating Self-Signed SSL Certificates

If you don't have SSL certificates yet, you can create self-signed certificates for testing purposes:

cd /mnt/nextcloud
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname" \
-keyout configs/ssl/ssl_certificate_key.key -out configs/ssl/ssl_certificate.crt

First Start

We chose Postgres as SQL database for this example setup. Therefore we will use the postgres profile when starting the containers. You can use one of these profile names for the SQL database:

  • mariadb
  • mysql
  • postgres

These profiles are available for the key-value database:

  • valkey
  • redis
cd /mnt/nextcloud
cd nextcloud

Build the containers:

podman compose --env-file "../configs/.env" --profile "postgres" --profile "valkey" build

Start the containers:

podman compose --env-file "../configs/.env" --profile "postgres" --profile "valkey" up -d

Check their status:

podman ps

The output will look like this:

CONTAINER ID  IMAGE                           COMMAND               CREATED         STATUS                   PORTS                  NAMES
29d755bf2a4d  docker.io/library/tempcloud...                        34 minutes ago  Up 34 minutes            6379/tcp               tempcloud2-nextcloud-prod-valkey-1
31e6257367e1  docker.io/clamav/clamav:1.5...                        34 minutes ago  Up 34 minutes            3310/tcp, 7357/tcp     tempcloud2-nextcloud-prod-clamav-1
dd227375136e  ghcr.io/nextcloud-releases/...                        34 minutes ago  Up 34 minutes (healthy)  3002/tcp               tempcloud2-nextcloud-prod-whiteboard-1
2da070fd3166  docker.io/library/postgres:...  postgres              34 minutes ago  Up 34 minutes            5432/tcp               tempcloud2-nextcloud-prod-postgres-1
343ec463b816  docker.io/library/nginx:1.2...  nginx -g daemon o...  34 minutes ago  Up 34 minutes            0.0.0.0:80->80/tcp...  tempcloud2-nextcloud-prod-nginx-1
d3fa28c652c6  docker.io/library/tempcloud...  php-fpm               34 minutes ago  Up 34 minutes            9000/tcp               tempcloud2-nextcloud-prod-phpfpm-1
ecc2cd2b5032  docker.io/library/tempcloud...  sh /etc/entrypoin...  34 minutes ago  Up 34 minutes            9000/tcp               tempcloud2-nextcloud-prod-manager-1

The first startup may take some time. You can check the logs of the startup with:

podman logs -f tempcloud2-nextcloud-prod-manager-1

The installation and configuration will be finished when these log lines appear:

Nextcloud configuration: completed
Nextcloud maintenance: mode off
Maintenance mode already disabled
Manager script: Setup completed successfully
Nextcloud script: Completed
Service: Starting cron
 1/1 [============================] 100%time="2025-12-03T09:34:13Z" level=warning msg="process reaping disabled, not pid 1"
time="2025-12-03T09:34:13Z" level=info msg="read crontab: /etc/crontabs/root"

Open your browser and enter your domain name. You should see the Nextcloud login page. You can now log in with the admin user and the password you set for the variable NEXTCLOUD_ADMIN_PASSWORD in the configs/.env file.

Note

Sometimes you need to login twice at the very first startup.

Systemd Configuration

To make sure that your Nextcloud starts automatically after a system reboot, you can create a systemd service file. The following parameters need to be adapted:

  • Description
  • WorkingDirectory
  • ExecStart
  • ExecStop

Create the systemd service file podman-examplecompany-nextcloud-prod.service under ~/.config/systemd/user with the following content:

Description=Podman examplecompany-nextcloud-prod
After=network.target
After=systemd-user-sessions.service
After=network-online.target
After=podman.socket
Requires=podman.socket

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/mnt/nextcloud
ExecStart=/usr/bin/env podman compose --env-file "../configs/.env" --profile "postgres" --profile "valkey" start
ExecStop=/usr/bin/env podman compose --env-file "../configs/.env" --profile "postgres" --profile "valkey" stop

[Install]
WantedBy=default.target

Stop your containers:

cd /mnt/nextcloud
podman compose --env-file "../configs/.env" --profile "postgres" --profile "valkey" stop

Enable and start the systemd service:

Note

Systemd linger needs to be enabled for the podman user as described in the User Setup section.

systemctl --user enable --now examplecompany-nextcloud-prod.service

Check the container status:

podman ps

If the server gets rebooted the containers will be started automatically. If the containers don't get started check the service status:

systemctl --user status examplecompany-nextcloud-prod.service

If the service didn't get started check that your podman user exists under the Systemd linger directory:

ls -l /var/lib/systemd/linger

Also check the current boot log as the podman or root user depending on the current state:

journalctl -b 0

Resources

Overview of the used documentations, projects and containers.

PHP-FPM

Nginx

Whiteboard

TURN

Use an external TURN server or use our Coturn project for Podman (coming soon™️).

HPB

Recording

External Issues affecting this Project

Nextcloud Server

Contribution

Contributions are very welcome! If you find any issues or have ideas for improvements, please open an issue and a pull request. Feel free to open a discussion for general questions or suggestions.

Thank you for your support! ❤️

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published