|
1 |
| -# Next Cloud |
2 |
| -## DO NOT EXPOSE PORT 80 TO THE WEB |
| 1 | +# Nextcloud |
3 | 2 |
|
4 |
| -It is a very bad idea to expose unencrypted traffic to the web. You will need to use a reverse-proxy to ensure your password is not stolen and your account hacked. |
| 3 | +## <a name="serviceDefinition"> Service definition </a> |
5 | 4 |
|
6 |
| -I'm still working on getting a good encrypted reverse proxy working. However in the interim you can use a VPN tunnel like OpenVPN or Zerotier to securely connect to your private cloud |
| 5 | +This is the **core** of the IOTstack Nextcloud service definition: |
7 | 6 |
|
8 |
| -## Backups |
| 7 | +```yml |
| 8 | +nextcloud: |
| 9 | + container_name: nextcloud |
| 10 | + image: nextcloud |
| 11 | + restart: unless-stopped |
| 12 | + environment: |
| 13 | + - MYSQL_HOST=nextcloud_db |
| 14 | + - MYSQL_PASSWORD=«user_password» |
| 15 | + - MYSQL_DATABASE=nextcloud |
| 16 | + - MYSQL_USER=nextcloud |
| 17 | + ports: |
| 18 | + - "9321:80" |
| 19 | + volumes: |
| 20 | + - ./volumes/nextcloud/html:/var/www/html |
| 21 | + depends_on: |
| 22 | + - nextcloud_db |
9 | 23 |
|
10 |
| -Nextcloud has been excluded from the docker_backup script due to its potential size. Once I've found a better way of backing it up I will add a dedicated script for it. |
| 24 | +nextcloud_db: |
| 25 | + container_name: nextcloud_db |
| 26 | + image: ghcr.io/linuxserver/mariadb |
| 27 | + restart: unless-stopped |
| 28 | + environment: |
| 29 | + - TZ=Etc/UTC |
| 30 | + - PUID=1000 |
| 31 | + - PGID=1000 |
| 32 | + - MYSQL_ROOT_PASSWORD=«root_password» |
| 33 | + - MYSQL_PASSWORD=«user_password» |
| 34 | + - MYSQL_DATABASE=nextcloud |
| 35 | + - MYSQL_USER=nextcloud |
| 36 | + volumes: |
| 37 | + - ./volumes/nextcloud/db:/config |
| 38 | +``` |
11 | 39 |
|
12 |
| -## Setup |
| 40 | +There are two containers, one for the cloud service itself, and the other for the database. Both containers share the same persistent storage area in the volumes subdirectory so they are treated as a unit. This will not interfere with any other MariaDB containers you might wish to run. |
13 | 41 |
|
14 |
| -Next-Cloud recommends using MySQL/MariaDB for the accounts and file list. The alternative is to use SQLite however they strongly discourage using it |
| 42 | +Depending on the IOTstack branch you are running, there may also be `networks:` directives. Other than to note that new menu dedicates a network to inter-container communications, those directives make no difference for this discussion. |
15 | 43 |
|
16 |
| -This is the service yml. Notice that there are in fact two containers, one for the db and the other for the cloud itself. You will need to change the passwords **before** starting the stack (remember to change the docker-compose.yml and ./services/nextcloud/service.yml), if you dont you will need to delete the volume directory and start again. |
| 44 | +Under old-menu, you are responsible for setting passwords. The passwords are "internal use only" and it is unlikely that you will need them unless you plan to go ferreting-about in the database using SQL. The rules are: |
17 | 45 |
|
18 |
| -```yml |
19 |
| - nextcloud: |
20 |
| - image: nextcloud |
21 |
| - container_name: nextcloud |
22 |
| - ports: |
23 |
| - - 9321:80 |
24 |
| - volumes: |
25 |
| - - ./volumes/nextcloud/html:/var/www/html |
26 |
| - restart: unless-stopped |
27 |
| - depends_on: |
28 |
| - - nextcloud_db |
| 46 | +* The two instances of `«user_password»` **must** be the same. |
| 47 | +* The instance of `«root_password»` *should* be different from `«user_password»`. |
| 48 | + |
| 49 | +Under new-menu, the menu can generate random passwords for you. You can either use that feature or roll your own using the old-menu approach by replacing: |
| 50 | + |
| 51 | +* Two instances of `%randomMySqlPassword%` (the `«user_password»`) |
| 52 | +* One instance of `%randomPassword%` (the `«root_password»`) |
| 53 | + |
| 54 | +The passwords need to be set before you bring up the Nextcloud service for the first time but the following initialisation steps assume you might not have done that and always start over from a clean slate. |
| 55 | + |
| 56 | +## <a name="initialisation"> Initialising Nextcloud </a> |
| 57 | + |
| 58 | +1. Be in the correct directory: |
| 59 | + |
| 60 | + ``` |
| 61 | + $ cd ~/IOTstack |
| 62 | + ``` |
| 63 | + |
| 64 | +2. If the stack is running, take it down: |
| 65 | + |
| 66 | + ``` |
| 67 | + $ docker-compose down |
| 68 | + ``` |
| 69 | + |
| 70 | +3. Erase the persistent storage area for Nextcloud (double-check the command *before* you hit return): |
| 71 | + |
| 72 | + ``` |
| 73 | + $ sudo rm -rf ./volumes/nextcloud |
| 74 | + ``` |
| 75 | + |
| 76 | + This is done to force re-initialisation. In particular, it gives you assurance that the passwords in your `docker-compose.yml` are the ones that are actually in effect. |
| 77 | + |
| 78 | +4. Bring up the stack: |
| 79 | + |
| 80 | + ``` |
| 81 | + $ docker-compose up -d |
| 82 | + ``` |
| 83 | + |
| 84 | +5. Check for errors: |
| 85 | + |
| 86 | + Repeat the following command two or three times at 10-second intervals: |
| 87 | + |
| 88 | + ``` |
| 89 | + $ docker ps |
| 90 | + ``` |
| 91 | + |
| 92 | + You are looking for evidence that the `nextcloud` and `nextcloud_db` containers are up, stable, and not restarting. If you see any evidence of restarts, try to figure out why using: |
| 93 | + |
| 94 | + ``` |
| 95 | + $ docker logs nextcloud |
| 96 | + ``` |
| 97 | + |
| 98 | +6. If you want to be sure Nextcloud gets set up correctly, it is best to perform the remaining steps from a **different** computer. |
| 99 | + |
| 100 | + That means you need to decide how that **other** computer will refer to your Raspberry Pi running Nextcloud. Your choices are: |
| 101 | + |
| 102 | + * the IP address of your Raspberry Pi – eg `192.168.203.200` |
| 103 | + * your Raspberry Pi's fully-qualified domain name – eg `myrpi.mydomain.com` |
| 104 | + * your Raspberry Pi's host name – eg `myrpi` |
| 105 | + |
| 106 | + Key points: |
| 107 | + |
| 108 | + * You **can't** use a multicast domain name (eg `myrpi.local`). An mDNS name will not work until Nextcloud has been initialised! |
| 109 | + * Once you have picked a connection method, **STICK TO IT**. |
| 110 | + * You are only stuck with this restriction until Nextcloud has been initialised. You **can** (and should) fix it later by completing the steps in ["Access through untrusted domain"](#untrustedDomain). |
| 111 | + |
| 112 | +7. On a computer that is **not** the Raspberry Pi running Nextcloud, launch a browser and point to the Raspberry Pi running Nextcloud using your chosen connection method. Examples: |
| 113 | + |
| 114 | + - If you are using an IP address: |
| 115 | + |
| 116 | + ``` |
| 117 | + http://192.168.203.200:9321 |
| 118 | + ``` |
| 119 | + |
| 120 | + - If you are using a domain name: |
| 121 | + |
| 122 | + ``` |
| 123 | + http://myrpi.mydomain.com:9321 |
| 124 | + ``` |
| 125 | + |
| 126 | + - If you are using a host name in `/etc/hosts`: |
| 127 | + |
| 128 | + ``` |
| 129 | + http://myrpi:9321 |
| 130 | + ``` |
| 131 | + |
| 132 | + The expected result is: |
| 133 | + |
| 134 | +  |
| 135 | + |
| 136 | +8. Create an administrator account and then click "Finish Setup". |
| 137 | + |
| 138 | +9. There is a long delay. And then you get an error: |
| 139 | + |
| 140 | +  |
| 141 | + |
| 142 | + If you examine the contents of your browser's URL bar, you will find: |
| 143 | + |
| 144 | + ``` |
| 145 | + http://localhost/index.php/core/apps/recommended |
| 146 | + ``` |
| 147 | + |
| 148 | + That is **clearly** wrong and it is probably a bug in Nextcloud. |
| 149 | +10. Edit the URL to replace `localhost` with what it *should* be, which will be **one** of the following patterns, depending on which method you chose to access Nextcloud: |
| 150 | + |
| 151 | + * `http://192.168.203.200:9321/index.php/core/apps/recommended` |
| 152 | + * `http://myrpi.mydomain.com:9321/index.php/core/apps/recommended` |
| 153 | + * `http://myrpi:9321/index.php/core/apps/recommended` |
| 154 | + |
| 155 | + Note: |
| 156 | + |
| 157 | + * This seems to be the only time Nextcloud misbehaves and forces `localhost` into a URL. |
| 158 | + |
| 159 | +11. After a delay, you will see the "Recommended apps" screen with a spinner moving down the list of apps as they are loaded: |
| 160 | + |
| 161 | +  |
| 162 | + |
| 163 | + Wait for the loading to complete. |
| 164 | + |
| 165 | +12. Eventually, the dashboard will appear. Then the dashboard will be obscured by the "Nextcloud Hub" floating window: |
| 166 | + |
| 167 | +  |
| 168 | + |
| 169 | + Hover your mouse to the right of the floating window and keep clicking on the right-arrow button until you reach the last screen, then click "Start using Nextcloud". |
| 170 | + |
| 171 | +13. Congratulations. Your IOTstack implementation of Nextcloud is ready to roll: |
| 172 | + |
| 173 | +  |
| 174 | + |
| 175 | +## <a name="untrustedDomain">"Access through untrusted domain"</a> |
| 176 | + |
| 177 | +During Nextcloud initialisation you had to choose between an IP address, a domain name or a host name. Now that Nextcloud is running, you have the opportunity to expand your connection options. |
| 178 | + |
| 179 | +> If you are reading this because you are staring at an "access through untrusted domain" message then you have come to the right place. |
| 180 | + |
| 181 | +Let's assume the following: |
| 182 | + |
| 183 | +* You used `raspi-config` to give your Raspberry Pi the name "myrpi". |
| 184 | +* Your Raspberry Pi has the fixed IP address "192.168.203.200" (via either a static binding in your DHCP server or a static IP address on your Raspberry Pi). |
29 | 185 |
|
30 |
| - nextcloud_db: |
31 |
| - image: linuxserver/mariadb |
32 |
| - container_name: nextcloud_db |
33 |
| - volumes: |
34 |
| - - ./volumes/nextcloud/db:/config |
35 |
| - environment: |
36 |
| - - MYSQL_ROOT_PASSWORD=stronger_password |
37 |
| - - MYSQL_PASSWORD=strong_password |
38 |
| - - MYSQL_DATABASE=nextcloud |
39 |
| - - MYSQL_USER=nextcloud |
| 186 | +Out of the box, a Raspberry Pi participates in multicast DNS so it will also have the mDNS name: |
| 187 | + |
| 188 | +* "myrpi.local" |
| 189 | + |
| 190 | +Let's also assume you have a local Domain Name System server where your Raspberry Pi: |
| 191 | + |
| 192 | +* has the canonical name (A record) "myrpi.mydomain.com"; plus |
| 193 | +* an alias (CNAME record) of "nextcloud.mydomain.com". |
| 194 | + |
| 195 | +Rolling all that together, you would expect your Nextcloud service to be reachable at any of the following URLs: |
| 196 | + |
| 197 | +* `http://192.168.203.200:9321` |
| 198 | +* `http://myrpi.local:9321` |
| 199 | +* `http://myrpi.mydomain.com:9321` |
| 200 | +* `http://nextcloud.mydomain.com:9321` |
| 201 | + |
| 202 | +To tell Nextcloud that all of those URLs are valid, you need to use `sudo` and your favourite text editor to edit this file: |
| 203 | + |
| 204 | +``` |
| 205 | +~/IOTstack/volumes/nextcloud/html/config/config.php |
| 206 | +``` |
| 207 | + |
| 208 | +Hint: |
| 209 | + |
| 210 | +* It is a good idea to make a backup of any file before you edit it. For example: |
| 211 | + |
| 212 | + ``` |
| 213 | + $ cd ~/IOTstack/volumes/nextcloud/html/config/ |
| 214 | + $ sudo cp config.php config.php.bak |
| 215 | + ``` |
| 216 | + |
| 217 | +Search for "trusted_domains". To tell Nextcloud to trust **all** of the URLs above, edit the array structure like this: |
| 218 | + |
| 219 | +``` |
| 220 | + 'trusted_domains' => |
| 221 | + array ( |
| 222 | + 0 => '192.168.203.200:9321', |
| 223 | + 1 => 'myrpi.local:9321', |
| 224 | + 2 => 'myrpi.mydomain.com:9321', |
| 225 | + 3 => 'nextcloud.mydomain.com:9321', |
| 226 | + ), |
| 227 | +``` |
| 228 | + |
| 229 | +> Note: *all* the trailing commas are intentional! |
| 230 | + |
| 231 | +Once you have finished editing the file, save your work then restart Nextcloud: |
| 232 | + |
| 233 | +``` |
| 234 | +$ cd ~/IOTstack |
| 235 | +$ docker-compose restart nextcloud |
| 236 | +``` |
| 237 | + |
| 238 | +Use `docker ps` to check that the container has restarted properly and hasn't gone into a restart loop. |
| 239 | + |
| 240 | +See also: |
| 241 | + |
| 242 | +* [Nextcloud documentation - trusted domains](https://docs.nextcloud.com/server/21/admin_manual/installation/installation_wizard.html#trusted-domains). |
| 243 | + |
| 244 | +### <a name="dnsAlias"> Using a DNS alias for your Nextcloud service </a> |
| 245 | + |
| 246 | +The examples above include using a DNS alias (a CNAME record) for your Nextcloud service. If you decide to do that, you may see this warning in the log: |
| 247 | + |
| 248 | +``` |
| 249 | +Could not reliably determine the server's fully qualified domain name |
| 250 | +``` |
| 251 | + |
| 252 | +You can silence the warning by editing the Nextcloud service definition in `docker-compose.yml` to add your fully-qualified DNS alias to at `hostname` directive. For example: |
40 | 253 |
|
41 | 254 | ```
|
| 255 | + hostname: nextcloud.mydomain.com |
| 256 | +``` |
| 257 | + |
| 258 | +## <a name="security"> Security considerations</a> |
| 259 | + |
| 260 | +Nextcloud traffic is not encrypted. Do **not** expose it to the web by opening a port on your home router. Instead, use a VPN like Wireguard to provide secure access to your home network, and let your remote clients access Nextcloud over the VPN tunnel. |
| 261 | + |
| 262 | +## <a name="backups"> Backups </a> |
| 263 | + |
| 264 | +Nextcloud is currently excluded from the IOTstack-supplied backup scripts due to its potential size. |
42 | 265 |
|
43 |
| -The port is 9321 |
| 266 | +> This is also true for [Paraphraser/IOTstackBackup](https://github.com/Paraphraser/IOTstackBackup). |
44 | 267 |
|
45 |
| - |
| 268 | +If you want to take a backup, something like the following will get the job done: |
46 | 269 |
|
47 |
| -click on the storage options, select maraiadb/mysql and fill in the details as follows |
| 270 | +``` |
| 271 | +$ cd ~/IOTstack |
| 272 | +$ BACKUP_TAR_GZ=$PWD/backups/$(date +"%Y-%m-%d_%H%M").$HOSTNAME.nextcloud-backup.tar.gz |
| 273 | +$ touch "$BACKUP_TAR_GZ" |
| 274 | +$ docker-compose stop nextcloud nextcloud_db |
| 275 | +$ docker-compose rm -f nextcloud nextcloud_db |
| 276 | +$ sudo tar -czf "$BACKUP_TAR_GZ" -C "./volumes/nextcloud" . |
| 277 | +$ docker-compose up -d |
| 278 | +``` |
48 | 279 |
|
49 |
| - |
| 280 | +Note: |
50 | 281 |
|
51 |
| -Note that you data will be stored in `./volumes/nextcloud/html/data/{account}` |
| 282 | +* A *baseline* backup takes over 400MB and about 2 minutes. Once you start adding your own data, it will take even more time and storage. |
52 | 283 |
|
53 |
| - |
| 284 | +To restore, you first need to identify the name of the backup file by looking in the `backups` directory. Then: |
54 | 285 |
|
55 |
| -Also note that file permissions are "www-data" so you cant simply copy data into this folder directly, you should use the web interface or the app. |
| 286 | +``` |
| 287 | +$ cd ~/IOTstack |
| 288 | +$ RESTORE_TAR_GZ=$PWD/backups/2021-06-12_1321.sec-dev.nextcloud-backup.tar.gz |
| 289 | +$ docker-compose stop nextcloud nextcloud_db |
| 290 | +$ docker-compose rm -f nextcloud nextcloud_db |
| 291 | +$ sudo rm -rf ./volumes/nextcloud/* |
| 292 | +$ sudo tar -x --same-owner -z -f "$RESTORE_TAR_GZ" -C "./volumes/nextcloud" |
| 293 | +$ docker-compose up -d |
| 294 | +``` |
56 | 295 |
|
57 |
| -It would be a good idea to mount an external drive to store the data in rather than on your sd card. details to follow shortly. Something like: |
| 296 | +If you are running from an SD card, it would be a good idea to mount an external drive to store the data. Something like: |
58 | 297 |
|
59 | 298 | 
|
60 | 299 |
|
61 |
| -The external drive will have to be an ext4 formatted drive because smb, fat32 and NTFS can't handle linux file permissions. If the permissions aren't set to "www-data" then the container wont be able to write to the disk. |
| 300 | +The external drive will have to be an ext4 formatted drive because smb, fat32 and NTFS can't handle Linux file permissions. If the permissions aren't set to "www-data" then the container won't be able to write to the disk. |
| 301 | + |
| 302 | +Finally, a warning: |
62 | 303 |
|
63 |
| -Just a warning: If your database gets corrupted then your nextcloud is pretty much stuffed |
| 304 | +* If your database gets corrupted then your Nextcloud is pretty much stuffed. |
0 commit comments