Self-hosting Nextcloud with Dokku and s3 compatible storage
For those who are not familiar with Dokku, I recommend you read the previous post first or the official site. In short, it's an awesome open source PaaS similar to Heroku (albeit limited to one server).
If you are not familiar with Nextcloud, it's an feature-rich open source platform for file sharing, syncing (with apps for most operating systems and devices) and collaboration. It offers the ability to install "apps" with which you can replicate many of the features you can have with paid solutions like Google Workspace. Learn more here.
I particularly like Nextcloud because by self hosting I don't have to worry about privacy as much as I would have for example with Google. Plus it can be much cheaper than paid options like Google or Dropbox (speaking of file sharing/syncing), depending on where and how you self host it.
Let's see how to deploy it using Dokku on a Linux server. In this post I'll show how you can use an s3 compatible object storage service as the primary storage for Nextcloud - I am testing this with Wasabi at the moment. It's an awesome option so you don't need a server with a ton of local storage if you need to store a lot of data.
Creating the app
dokku apps:create nextcloud
We'll want to deploy the official Docker image for Nextcloud, so to do that with Dokku we can run the following command:
dokku git:from-image nextcloud nextcloud:23.0.2-apache
At the time of this writing, the latest Nextcloud version is 23.0.2. Change the tag according to the version you want to install.
Mounting the local storage
First, create a directory where to store this configuration; Dokku by default uses `/var/lib/dokku/data/storage` as a container for directories to "mount" inside applications. So let's create a subdirectory for Nextcloud:
mkdir -p /var/lib/dokku/data/storage/nextcloud
Then, we need to mount this directory in the Nextcloud app:
dokku storage:mount nextcloud /var/lib/dokku/data/storage/nextcloud:/var/www/html
The command above mounts the directory we created as `/var/www/html` in the Nextcloud container, which is the expected location.
Supporting services
dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres dokku postgres:create nextcloud-postgres dokku postgres:link nextcloud-postgres nextcloud
We'll also use Redis for caching, to speed things up:
dokku plugin:install https://github.com/dokku/dokku-redis.git redis dokku redis:create nextcloud-redis dokku redis:link nextcloud-redis nextcloud
These commands will add the environment variables DATABASE_URL (for Postgres) and REDIS_URL (for Redis) to the Nextcloud application.
Next, we need to add some custom configuration to Nextcloud. Check which passwords and hosts Dokku has set for Postgres and Redis with the aforementioned environment variables, because Nextcloud expects different variables:
dokku config:show nextcloud
Then run:
dokku config:set nextcloud \ DOKKU_LETSENCRYPT_EMAIL=<your email address to issue a certificate with Let's Encrypt> \ POSTGRES_DB=nextcloud \ POSTGRES_USER=postgres \ POSTGRES_PASSWORD=<postgres password> \ POSTGRES_HOST=<the postgres host> \ REDIS_HOST=<redis host> \ REDIS_HOST_PASSWORD=<redis password> \ SMTP_HOST=<smtp host> \ SMTP_PORT=587 \ SMTP_SECURE=tls \ SMTP_AUTHTYPE=PLAIN \ SMTP_NAME=<smtp username> \ SMTP_PASSWORD=<smtp password> \ MAIL_FROM_ADDRESS=cloud \ # or whichever name you want to receive email notifications from; note that this should be set to the name part only of an email address MAIL_DOMAIN=<email domain> \ OVERWRITEPROTOCOL=https \ NEXTCLOUD_TRUSTED_DOMAINS=<your full nextcloud domain, e.g. cloud.mydomain.com> \ NEXTCLOUD_ADMIN_USER=<first admin username> \ NEXTCLOUD_ADMIN_PASSWORD=<first admin password> \ OBJECTSTORE_S3_BUCKET=true \ OBJECTSTORE_S3_SSL=true \ OBJECTSTORE_S3_USEPATH_STYLE=false \ OBJECTSTORE_S3_LEGACYAUTH=false \ OBJECTSTORE_S3_AUTOCREATE=false \ OBJECTSTORE_S3_BUCKET=<s3 bucket to use as primary storage> \ OBJECTSTORE_S3_KEY=<s3 access key> \ OBJECTSTORE_S3_SECRET=<s3 secret key> \ OBJECTSTORE_S3_REGION=<s3 region> \ OBJECTSTORE_S3_HOST=<s3 endpoint hostname> \ OBJECTSTORE_S3_PORT=443
The configuration above:
- ensures that we use the Postgres and Redis instances we created earlier
- configures an SMTP provider so we can have Nextcloud send us notifications when for example sharing files and folders; if you don't have a provider of choice, I recommend Mailplace since it's very cheap and reliable
- configures an s3 bucket as primary storage for user data; I recommend Wasabi for this since it only charges for the amount of data stored. Other providers charge for API requests too, and Nextcloud can make quite many of them
- creates the first admin user
The command above will restart the application; during this process, the necessary tables will be initialized in the database and some data will be written to the bucket with the demo files for the first admin user.
Certificate
dokku proxy:ports-set nextcloud http:80:80
Then add the domain to the application and request a certificate:
dokku domains:add nextcloud cloud.mydomain.com dokku letsencrypt:enable nextcloud
Increasing the max upload size for browser transfers
mkdir -p /home/dokku/nextcloud/nginx.conf.d/ echo 'client_max_body_size 5120m;' > /home/dokku/nextcloud/nginx.conf.d/upload.conf service nginx reload
The example above increases the max upload size to 5GB per file.
Done. Now open the Nextcloud domain in your browser and login as the first admin user to configure the rest.