Document Nextcloud S3 Storage
This commit is contained in:
parent
98371bdfba
commit
2981b493b8
2 changed files with 192 additions and 0 deletions
192
2024-03-28_Nextcloud-S3-Migration.md
Normal file
192
2024-03-28_Nextcloud-S3-Migration.md
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
---
|
||||||
|
date: 2024-03-28
|
||||||
|
title: Migrating Nextcloud from Local Storage to S3
|
||||||
|
tags:
|
||||||
|
- homelab
|
||||||
|
- s3
|
||||||
|
- Nextcloud
|
||||||
|
---
|
||||||
|
|
||||||
|
As I continue to investigate [migration from Unraid to XCP-ng](https://blog.mcknight.tech/2024/01/30/Compute_Setup/)
|
||||||
|
(or maybe Proxmox), I am taking a closer look at what storage resources my containers are still using on my Unraid
|
||||||
|
system. Unsurprisingly, Nextcloud is using a significant amount of persistent storage and I found that moving that
|
||||||
|
data to a remote share is difficult due to Nextcloud's file permission requirements. Looking for a solution, I found
|
||||||
|
that Nextcloud supports S3 storage and, while not officially supported, there are ways to move from local storage to
|
||||||
|
S3 without having to start over from scratch. I will admit that much of this was heacily inspired by other guides
|
||||||
|
which I've link below, but there were a few gotchas related to doing this with containers in Unraid that I'll highlight.
|
||||||
|
|
||||||
|
## Why to migrate storage
|
||||||
|
As I mentioned, my primary reason for migrating from local to S3 storage is to simplify running Nextcloud in a
|
||||||
|
container with primary storage residing on a different system. This is also a fun project for me to learn a
|
||||||
|
little more about how S3 works (this is my first application using S3 storage 🎉). I'm using MinIO on TrueNAS
|
||||||
|
which was practically a one-click deployment; I followed
|
||||||
|
[this video from Lawrence Systems](https://youtu.be/uIm41PhGEgQ?si=0X1FZgsNfZisnaKw).
|
||||||
|
|
||||||
|
## Preparing for migration
|
||||||
|
Fist things first, configure a bucket for Nextcloud (and only Nextcloud) to use; I've named mine "nextcloud".
|
||||||
|
I only have a few users on my Nextcloud instance and I'm the only one who uses it regularly, so I was able to
|
||||||
|
prevent any changes during the migration by closing any desktop applications that sync and not taking any
|
||||||
|
photos on my phone. If you have more users or activity, I would recommend putting Nextcloud into maintenance
|
||||||
|
mode before migrating things (`occ maintenance:mode --on`).
|
||||||
|
|
||||||
|
## Migrating from local to S3
|
||||||
|
Other guides I found made some assumptions about Nextcloud and SQL running in the same environment, which
|
||||||
|
isn't true in my case where they're in containers. They also assumed the `aws` cli could be used where
|
||||||
|
Nextcloud is running which is also not true in my case since Unraid doesn't have that package available.
|
||||||
|
The code snippets below have been modified from other examples to fit my use case.
|
||||||
|
|
||||||
|
### Get files from SQL
|
||||||
|
My Nextcloud setup uses MariaDb, so the first step is to export the list of files, along with some identifiers
|
||||||
|
Nextcloud uses, to be uploaded. My database is called `nextcloud` and the `/config` directory is mounted to the
|
||||||
|
host. `/mnt/user/Nextcloud` on the host system is mounted to `/data` in the Nextcloud container.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
mysql -p -B --disable-column-names -D nextcloud << EOF > /config/meta_file_list
|
||||||
|
select concat('urn:oid:', fileid, ' ', substring(id from 8), path)
|
||||||
|
from oc_filecache
|
||||||
|
join oc_storages
|
||||||
|
on storage = numeric_id
|
||||||
|
where id like 'local::%'
|
||||||
|
order by id;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
mysql -p -B --disable-column-names -D nextcloud << EOF > /config/user_file_list
|
||||||
|
select concat('urn:oid:', fileid, ' ', '/mnt/user/Nextcloud/',
|
||||||
|
substring(id from 7), '/', path)
|
||||||
|
from oc_filecache
|
||||||
|
join oc_storages
|
||||||
|
on storage = numeric_id
|
||||||
|
where id like 'home::%'
|
||||||
|
order by id;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sed -i -e "s| /data/| /mnt/user/Nextcloud/|g" meta_file_list
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that `user_file_list` paths are updated in the `mysql` command and the `meta_file_list` is updated
|
||||||
|
by the `sed` command to be accessible on the host.
|
||||||
|
|
||||||
|
### Move files to upload directory
|
||||||
|
Since I will be mounting the upload directory to a virtual machine, I opted to copy files rather than
|
||||||
|
create symlinks like the example I used as reference. It doesn't particularly matter where on the host
|
||||||
|
system the files to upload are copied to, but I used `/mnt/user/Nextcloud` which was my existing share
|
||||||
|
for Nextcloud data. I copied `user_file_list` and `meta_file_list` from the previous step to that path.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd /mnt/user/Nextcloud
|
||||||
|
mkdir s3_files
|
||||||
|
cd s3_files
|
||||||
|
|
||||||
|
while read target source ; do
|
||||||
|
if [ -f "$source" ] ;
|
||||||
|
then
|
||||||
|
cp "$source" "$target"
|
||||||
|
fi
|
||||||
|
done < ../user_file_list
|
||||||
|
|
||||||
|
while read target source ; do
|
||||||
|
if [ -f "$source" ] ;
|
||||||
|
then
|
||||||
|
cp "$source" "$target"
|
||||||
|
fi
|
||||||
|
done < ../meta_file_list
|
||||||
|
```
|
||||||
|
|
||||||
|
At this point, all of the files are named and placed in the `s3_files` directory, ready to be uploaded
|
||||||
|
to S3. Note that since the filenames contain `:`, this directory will NOT be accessible via an SMB share.
|
||||||
|
I exported it as an NFS share, but if I could install `awscli` on the host system then it wouldn't have
|
||||||
|
been a concern.
|
||||||
|
|
||||||
|
On my VM where I actually uploaded everything to a bucket named `nextcloud`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo mount <SERVER_ADDR>:/mnt/user/Nextcloud /home/$USER/Nextcloud
|
||||||
|
cd ~/Nextcloud
|
||||||
|
aws --endpoint-url <S3_URL> s3 sync s3_files s3://nextcloud
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nextcloud config updates
|
||||||
|
With all of the files uploaded to S3, Nextcloud needs to be updated to point at the new data source. So,
|
||||||
|
time to put Nextcloud into maintenance mode and start breaking things 🙂. From here on out, we are making
|
||||||
|
potentially destructive changes, so make backups, have a recovery plan, and don't continue
|
||||||
|
until reading to the end first.
|
||||||
|
|
||||||
|
In the Docker container:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
occ maintenance:mode --on
|
||||||
|
nano /config/www/nextcloud/config/config.php
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the following to the Nextcloud config (`/config/www/nextcloud/config/config.php`):
|
||||||
|
|
||||||
|
```php
|
||||||
|
'objectstore' =>
|
||||||
|
array (
|
||||||
|
'class' => 'OC\\Files\\ObjectStore\\S3',
|
||||||
|
'arguments' =>
|
||||||
|
array (
|
||||||
|
'bucket' => 'nextcloud',
|
||||||
|
'autocreate' => true,
|
||||||
|
'key' => '<MY_AWS_KEY>',
|
||||||
|
'secret' => '<MY_AWS_SECRET>',
|
||||||
|
'hostname' => '<S3_ADDRESS>',
|
||||||
|
'port' => 443,
|
||||||
|
'use_ssl' => true,
|
||||||
|
'region' => 'home',
|
||||||
|
'use_path_style' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
```
|
||||||
|
> Make sure this is before the closing `);` at the end of the file
|
||||||
|
|
||||||
|
`use_path_style` was required for MinIO, but I read that this may be false for other providers.
|
||||||
|
|
||||||
|
### SQL database updates
|
||||||
|
The SQL database at this point still contains local file references, so those will need to be
|
||||||
|
updated to the uploaded resources. In the SQL container:
|
||||||
|
```shell
|
||||||
|
mariadb -p -D nextcloud -e "update oc_storages set id = concat('object::user:', substring(id from 7)) where id like 'home::%';"
|
||||||
|
mariadb -p -D nextcloud -e "update oc_storages set id = 'object::store:amazon::nextcloud' where id like 'local::%';"
|
||||||
|
mariadb -p -D nextcloud -e "update oc_mounts set mount_provider_class = 'OC\\\Files\\\Mount\\\ObjectHomeMountProvider' where mount_provider_class like '%LocalHomeMountProvider%';"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Validating Changes
|
||||||
|
With configuration and database changes completed, its time to take Nextcloud out of maintenance mode
|
||||||
|
and validate changes. In the Nextcloud container:
|
||||||
|
```shell
|
||||||
|
occ maintenance:mode --off
|
||||||
|
```
|
||||||
|
|
||||||
|
> I also restarted the Nextcloud container here for good measure, but it may not be necessary.
|
||||||
|
|
||||||
|
Load up Nextcloud in a browser and make sure the page loads, user login works, and most importantly
|
||||||
|
user files are accessible. If this all works, then the migration is complete!
|
||||||
|
|
||||||
|
## Cleanup local files
|
||||||
|
With migration completed, I chose to remove the `data` container mount since the directory only needs
|
||||||
|
the `.ocdata` file and should only contain logs. On the host system:
|
||||||
|
```shell
|
||||||
|
cp /mnt/user/Nextcloud/.oc_data /mnt/user/appdata/nextcloud/data/
|
||||||
|
chmod 770 /mnt/user/appdata/nextcloud/data/
|
||||||
|
chown nobody:users /mnt/user/appdata/nextcloud/data/
|
||||||
|
```
|
||||||
|
> Note that the ownership is specific to Unraid, but Nextcloud requires permissions `770`.
|
||||||
|
|
||||||
|
Then, modify Nextcloud's `config.php`:
|
||||||
|
```php
|
||||||
|
'datadirectory' => '/config/data',
|
||||||
|
```
|
||||||
|
|
||||||
|
Then the `/data` mount can be removed from the Docker container and the container restarted. At this point,
|
||||||
|
the old data share can be removed completely (I'll archive mine as a backup).
|
||||||
|
|
||||||
|
## Wrap up
|
||||||
|
I have been using my Nextcloud with S3 storage for a few days now and haven't noticed any difference compared
|
||||||
|
to local storage. I like that the storage is accessible via HTTP so I don't have to worry about
|
||||||
|
managing permissions and access from the Nextcloud container to my storage server.
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [mrAceT migration scripts](https://github.com/mrAceT/nextcloud-S3-local-S3-migration)
|
||||||
|
- [Nextcloud issue with guide](https://github.com/nextcloud/server/issues/25781)
|
||||||
|
- [Nextcloud forum thread](https://help.nextcloud.com/t/migrate-from-local-storage-to-s3/138042)
|
Loading…
Reference in a new issue