Skip to content

Commit 5ed8547

Browse files
authored
Merge pull request #364 from Paraphraser/20210612-nextcloud-master
Nextcloud - consistent service definition - master - 1 of 3
2 parents a8a37cf + d2d00f4 commit 5ed8547

File tree

7 files changed

+297
-56
lines changed

7 files changed

+297
-56
lines changed

.templates/nextcloud/service.yml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
nextcloud:
2-
image: nextcloud
32
container_name: nextcloud
3+
image: nextcloud
4+
restart: unless-stopped
5+
environment:
6+
- MYSQL_HOST=nextcloud_db
7+
- MYSQL_PASSWORD=%randomMySqlPassword%
8+
- MYSQL_DATABASE=nextcloud
9+
- MYSQL_USER=nextcloud
410
ports:
511
- "9321:80"
612
volumes:
7-
- ./volumes/nextcloud/html:/var/www/html:rw
8-
restart: unless-stopped
9-
depends_on:
10-
- nextcloud_db
11-
links:
13+
- ./volumes/nextcloud/html:/var/www/html
14+
depends_on:
1215
- nextcloud_db
1316
networks:
1417
- iotstack_nw
1518
- nextcloud_internal
16-
environment:
17-
- MYSQL_HOST=nextcloud_db
18-
- MYSQL_PASSWORD=%randomMySqlPassword%
19-
- MYSQL_DATABASE=nextcloud
20-
- MYSQL_USER=nextcloud
2119

2220
nextcloud_db:
23-
image: linuxserver/mariadb
2421
container_name: nextcloud_db
25-
volumes:
26-
- ./volumes/nextcloud/db:/config
22+
image: ghcr.io/linuxserver/mariadb
23+
restart: unless-stopped
2724
environment:
25+
- TZ=Etc/UTC
26+
- PUID=1000
27+
- PGID=1000
2828
- MYSQL_ROOT_PASSWORD=%randomPassword%
2929
- MYSQL_PASSWORD=%randomMySqlPassword%
3030
- MYSQL_DATABASE=nextcloud
3131
- MYSQL_USER=nextcloud
32-
restart: unless-stopped
32+
volumes:
33+
- ./volumes/nextcloud/db:/config
3334
networks:
3435
- nextcloud_internal
35-

docs/Containers/NextCloud.md

Lines changed: 281 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,304 @@
1-
# Next Cloud
2-
## DO NOT EXPOSE PORT 80 TO THE WEB
1+
# Nextcloud
32

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>
54

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:
76

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
923

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+
```
1139
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.
1341
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.
1543

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:
1745

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+
![Create Administrator Account](./images/nextcloud-createadminaccount.png)
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+
![Mal-formed URL](./images/nextcloud-malformedurl.png)
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+
![Recommended Apps](./images/nextcloud-recommendedapps.png)
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+
![Post-initialisation](./images/nextcloud-postinitialisation.png)
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+
![Dashboard](./images/nextcloud-dashboard.png)
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).
29185

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:
40253

41254
```
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.
42265

43-
The port is 9321
266+
> This is also true for [Paraphraser/IOTstackBackup](https://github.com/Paraphraser/IOTstackBackup).
44267

45-
![image](https://user-images.githubusercontent.com/46672225/69730546-f2ede200-1130-11ea-97f4-0f4f81d08fad.png)
268+
If you want to take a backup, something like the following will get the job done:
46269

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+
```
48279

49-
![image](https://user-images.githubusercontent.com/46672225/69731273-46acfb00-1132-11ea-9b10-579bb8b3dd9a.png)
280+
Note:
50281

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.
52283

53-
![image](https://user-images.githubusercontent.com/46672225/69732101-b1ab0180-1133-11ea-95dc-8a2e6fb80536.png)
284+
To restore, you first need to identify the name of the backup file by looking in the `backups` directory. Then:
54285

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+
```
56295

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:
58297

59298
![image](https://user-images.githubusercontent.com/46672225/69873297-a3d6b700-12c0-11ea-98c9-40f358137b77.png)
60299

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:
62303

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.
878 KB
Loading
389 KB
Loading
46.2 KB
Loading
408 KB
Loading
862 KB
Loading

0 commit comments

Comments
 (0)