I switched from Nextcloud to Opencloud.
Nextcloud worked great for me, but to be honest, it is overpowered for just a single user like me.
Some words why I switched and a bit of comparison
So a few weeks ago I read about Opencloud: It comes with an integrated markdown editor and when integrating Radicale (CalDAV/ CardDAV server) I can also host my calendar and contacts with it, like I did with Nextcloud.
But right now some features are still missing: You can not see or edit your calendar and contacts in the opencloud webpanel (which I’m okay with) and it also does not send notifications, if you have reminders set for calendar events. You would need to manage this with external apps.
And right now there are not many apps for Opencloud itself, but it’s a quite young project, so it might change in the future.
Like there is no eMail integration like Nextcloud has. And there are dozens or so of apps you can install and use with Nextcloud, like 2FA, Talk, whiteboard etc. pp. But I don’t need this for my self-hosted cloud setup ![]()
You can integrate collabora into Opencloud tho, and create workspaces. And there is also a roadmap for Openclouds future, the file-download-on-demand feature is right around the corner.
Opencloud is written in Golang, so it has a webserver integrated, It does not need PHP nor a database, everything is file-based. So you can just manipulate the files on your SBC without the need to refresh a database. Same goes for the calendar and contact data, everything in Radicale is stored as vcf or ics files.
Before we start a quick note:
You can not run Opencloud on a subpath, like example.org/opencloud, it will not work.
I tried to make it work, but somewhere in the code they trim the URL that you specify in the config file. So maybe you could change the code and try to run it on a subpath, but a lot of stuff is relying on that URL and will likely have unwanted side effects and break the app.
Now I think it’s a smart move to stay consistent through out the whole app with this canonical URL.
As it must run on the “root” of the domain, you can create just a subdomain, like cloud.example.org or just run it on the second-level-domain example.org if you like.
I use a DynDNS domain which has already a sub-domain in it (like domain.ddns.net, so I just created a new one for opencloud, which also points to my public IP.
How I installed opencloud & radicale bare-metal (including systemd services):
Install opencloud
- Download the binary from github: Releases · opencloud-eu/opencloud · GitHub
- copy it to
/opt/opencloud/opencloud - create a system user
opencloudand a directory for it, tweak permissions:
useradd --system --no-create-home --shell /usr/sbin/nologin opencloud
mkdir /mnt/dietpi_userdata/opencloud
chown -R opencloud:opencloud /mnt/dietpi_userdata/opencloud
chmod 700 /mnt/dietpi_userdata/opencloud
- Create the config and data directory and config file
cd /mnt/dietpi_userdata/opencloud
sudo -u opencloud mkdir ./config ./data
sudo -u opencloud touch ./config/config.env
content for config.env:
OC_CONFIG_DIR=/mnt/dietpi_userdata/opencloud/config/
OC_BASE_DATA_PATH=/mnt/dietpi_userdata/opencloud/data
OC_URL=http://<LAN_IP>:9200
PROXY_LOG_LEVEL=info
Replace <LAN_IP> with the IP of your device (like http://192.168.0.1:9200), we will test after the init if the service is running.
We will then later change it to the actual domain.
(I set PROXY_LOG_LEVEL to info to be able to create a filter for fail2ban)
Opencloud will create a yaml file inside ./config on first start, it contains keys, tokens and passworts, for example the admin passwort you need for the logging into the web panel.
- Then we create a systemd service:
nano/etc/systemd/system/opencloud.service
with the contents:
[Unit]
Description=OpenCloud Service
After=network.target
[Service]
Type=simple
User=opencloud
Group=opencloud
WorkingDirectory=/opt/opencloud
EnvironmentFile=/mnt/dietpi_userdata/opencloud/config/config.env
ExecStart=/opt/opencloud/opencloud server
Restart=on-failure
RestartSec=5
Environment=PATH=/usr/bin:/usr/local/bin
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Don’t start the service yet!
First we need to initialize opencloud, it also needs to use our .env file for the init to create the files in the correct places.
sudo -u opencloud env $(cat /mnt/dietpi_userdata/opencloud/config/config.env | xargs) /opt/opencloud/opencloud init
A prompt should appear:
Do you want to configure OpenCloud with certificate checking disabled?
If you use a self-signed certificate (if you use DynDNS and certbot / letsencrypt), choose yes.
If you know what you are doing, choose no.
We’ll config SSL within the reverse proxy and Opencloud (running on port 9200) will not be accessible directly from public internet, so this is fine.
It will also show you the admin passwort you need for login into the web panel. There should be now also a new file in /mnt/dietpi_userdata/opencloud/config called opencloud.yaml, it cointains also the password.
Now enable and start the service
systemctl daemon-reload
systemctl enable --now opencloud.service
You should now be able to reach it on port 9200 via http.
Proxy config
Is use nginx for the proxy, you can use this as a blueprint for lighty or apache I guess
- create the file:
nano /etc/nginx/sites-available/opencloud
(Replacecloud.example.orgwith your domain. It also contains already the proxy config for Radicale / CalDAV)
If you don’t want to use radicale, please delete the corresponding blocks from the nginx config!
/etc/nginx/sites-available/opencloud
server {
server_name cloud.example.org
listen 443 ssl;
http2 on;
ssl_certificate /etc/letsencrypt/live/cloud.example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.example.org/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
http2_max_concurrent_streams 512;
location / {
proxy_pass https://127.0.0.1:9200;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_ssl_verify off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Accept-Encoding "";
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
keepalive_timeout 3600s;
keepalive_requests 100000;
proxy_next_upstream off;
client_max_body_size 10M;
}
# ----------------------------
# RADICALE CalDAV
# ----------------------------
location /caldav/ {
proxy_pass http://127.0.0.1:5232/;
proxy_set_header X-Script-Name /caldav;
proxy_set_header X-Remote-User $http_x_remote_user;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_buffering off;
}
location = /.well-known/caldav {
return 301 /caldav/;
}
# ----------------------------
# RADICALE CardDAV
# ----------------------------
location /carddav/ {
proxy_pass http://127.0.0.1:5232/;
proxy_set_header X-Script-Name /carddav;
proxy_set_header X-Remote-User $http_x_remote_user;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_buffering off;
}
location = /.well-known/carddav {
return 301 /carddav/;
}
}
I guess you can also use QUIC/HTTP3, but in NGINX only one directive is allowed for QUIC for the whole config!
QUIC runs on UDP and is stateless, so it makes no sense to define it in multiple server blocks. If you already have QUIC set up in your default config it should be fine.
- link the config and reload nginx
ln -s /etc/nginx/sites-available/opencloud /etc/nginx/sites-enabled
- Now it’s also time to change
OC_URLinside/mnt/dietpi_userdata/opencloud/config/config.envto you actual domain, it should look like
OC_URL=https://cloud.example.org
- Now restart nginx and opencloud
systemctl daemon-reload
systemctl reload nginx.service
systemctl restart opencloud.service
You are now able to reach opencloud via your domain.
Install Radicale
(If you don’t want to use radicale, please delete the corresponding blocks from the nginx config)
Radicale is availble in the Debian repo, so we can just install it via apt
apt install radicale
It creates a systemd service file we can overwrite with
systemctl edit radicale.service
At the top of the file is an area marked, where we can insert our overwrites.
We add:
[Service]
User=radicale
Group=radicale
ExecStart=
ExecStart=/usr/bin/radicale --config /mnt/dietpi_userdata/radicale/radicale.conf
ReadWritePaths=
ReadWritePaths=/mnt/dietpi_userdata/radicale/
Before we restart we need to create the corresponding paths and the config file:
mkdir -p /mnt/dietpi_userdata/radicale/collections
chown -R radicale:radicale /mnt/dietpi_userdata/radicale
chmod 700 /mnt/dietpi_userdata/radicale
sudo -u radicale nano /mnt/dietpi_userdata/radicale/radicale.conf
content of the radicale.conf
[server]
hosts = 127.0.0.1:5232
max_connections = 20
timeout = 30
[auth]
type = http_x_remote_user
[rights]
type = owner_only
[storage]
filesystem_folder = /mnt/dietpi_userdata/radicale/collections
predefined_collections = {
"def-addressbook": {
"D:displayname": "Personal Address Book",
"tag": "VADDRESSBOOK"
},
"def-calendar": {
"C:supported-calendar-component-set": "VEVENT,VJOURNAL,VTODO",
"D:displayname": "Personal Calendar",
"tag": "VCALENDAR"
}
}
[web]
type = none
[logging]
level = warning
- Now restart everything
systemctl daemon-reload
systemctl restart radicale.service
systemctl restart opencloud.service
If you browse now the /caldav or /carddav endpoint you should see the message Radicale works!.
Also in the opencloud webpanel, click in the top right corner on the user icon, then on settings.
In the menu on the left side choose Calendar, you should see now some info about your radicale integration on this page.
To access it externally, you can use the username “admin” and as passwort you need to create an app token. You can do this from the menu on the left as well.
I hope I did not forget something, I wrote all of this from memory. The 1000 lines of history in bash were not enough to save everything I did when I was testing ![]()
References:
Radicale:
https://radicale.org/v3.html#documentation-1
Opencloud:
https://docs.opencloud.eu/docs/next/dev/server/configuration/config-system
https://docs.opencloud.eu/docs/next/admin/configuration/radicale-integration
https://github.com/opencloud-eu/opencloud
https://github.com/opencloud-eu/opencloud-compose/blob/3bddb65c8bf357285b8b47246351936aae3b75dc/config/radicale/config