mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-05-21 10:50:10 +00:00
Compare commits
11 Commits
7598f6534d
...
copilot/ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eea59927f8 | ||
|
|
c962fcc10c | ||
|
|
2a2e69f047 | ||
|
|
e5aaacf07e | ||
|
|
f41fe58455 | ||
|
|
8727df147d | ||
|
|
a747ab1c5e | ||
|
|
f28d94c30c | ||
|
|
6dc1cd6ebd | ||
|
|
670e38969c | ||
|
|
ae5a21eadf |
@@ -46,7 +46,8 @@ RUN set -ex; \
|
||||
sudo \
|
||||
netcat-openbsd \
|
||||
curl \
|
||||
grep; \
|
||||
grep \
|
||||
cosign; \
|
||||
\
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
autoconf \
|
||||
|
||||
@@ -61,7 +61,8 @@ flowchart TD
|
||||
|
||||
## How to use this?
|
||||
Starting with v11 of AIO, the management of Community Containers is done via the AIO interface (it is the last section in the AIO interface, so only visible if you scroll down).
|
||||
⚠️⚠️⚠️ Please review the folder for documentation on each of the containers before adding them! Not reviewing the documentation for each of them first might break starting the AIO containers because e.g. fail2ban only works on Linux and not on Docker Desktop! **Hint:** If the containers where running already, in order to actually start the added container, you need to click on `Stop containers` and the `Update and start containers` in order to actually start it.
|
||||
|
||||
⚠️⚠️⚠️ Please review the folder for documentation on each of the containers before adding them! Not reviewing the documentation for each of them first might break starting the AIO containers because some containers are not compatible with each other and more.
|
||||
|
||||
## How to add containers?
|
||||
Simply submit a PR by creating a new folder in this directory: https://github.com/nextcloud/all-in-one/tree/main/community-containers with the name of your container. It must include a json file with the same name and with correct syntax and a readme.md with additional information. You might get inspired by caddy, fail2ban, local-ai, libretranslate, plex, pi-hole or vaultwarden (subfolders in this directory). For a full-blown example of the json file, see https://github.com/nextcloud/all-in-one/blob/main/php/containers.json. The json-schema that it validates against can be found here: https://github.com/nextcloud/all-in-one/blob/main/php/containers-schema.json.
|
||||
|
||||
@@ -3,15 +3,23 @@ It is possible due to several reasons that you do not want or cannot open Nextcl
|
||||
|
||||
### Content
|
||||
- [1. Tailscale](#1-tailscale)
|
||||
- [2. The normal way](#2-the-normal-way)
|
||||
- [3. Use the ACME DNS-challenge](#3-use-the-acme-dns-challenge)
|
||||
- [4. Use Cloudflare](#4-use-cloudflare)
|
||||
- [5. Buy a certificate and use that](#5-buy-a-certificate-and-use-that)
|
||||
- [2. Pangolin](#2-pangolin)
|
||||
- [3. The normal way](#3-the-normal-way)
|
||||
- [4. Use the ACME DNS-challenge](#4-use-the-acme-dns-challenge)
|
||||
- [5. Use Cloudflare](#5-use-cloudflare)
|
||||
- [6. Buy a certificate and use that](#6-buy-a-certificate-and-use-that)
|
||||
|
||||
## 1. Tailscale
|
||||
This is the recommended way. For a reverse proxy example guide for Tailscale, see this guide by [@Perseus333](https://github.com/Perseus333): https://github.com/nextcloud/all-in-one/discussions/6817
|
||||
|
||||
## 2. The normal way
|
||||
## 2. Pangolin
|
||||
[Pangolin](https://pangolin.net/) is an open-source, WireGuard-based remote access platform similar in concept to Tailscale. It uses the **Newt** connector to create outbound-only encrypted tunnels — no inbound ports need to be opened on your firewall. Pangolin handles TLS automatically, providing a valid certificate for your Nextcloud domain.
|
||||
|
||||
You can use either [Pangolin Cloud](https://app.pangolin.net/) (free tier available) or [self-host your own Pangolin server](https://docs.pangolin.net/self-host/quick-install) on a VPS. For private/local-only access, self-hosting Pangolin on a machine within your local network means that Nextcloud never needs to be exposed to the public internet.
|
||||
|
||||
For the reverse proxy configuration details and a step-by-step setup guide, see the [Pangolin section in the reverse proxy documentation](./reverse-proxy.md#pangolin).
|
||||
|
||||
## 3. The normal way
|
||||
The normal way is the following:
|
||||
1. Set up your domain correctly to point to your home network
|
||||
1. Set up a reverse proxy by following the [reverse proxy documentation](./reverse-proxy.md) but only open port 80 (which is needed for the ACME challenge to work - however no real traffic will use this port).
|
||||
@@ -21,12 +29,12 @@ The normal way is the following:
|
||||
|
||||
**Hint:** You may have a look at [this video](https://youtu.be/zk-y2wVkY4c) for a more complete but possibly outdated example.
|
||||
|
||||
## 3. Use the ACME DNS-challenge
|
||||
## 4. Use the ACME DNS-challenge
|
||||
You can alternatively use the ACME DNS-challenge to get a valid certificate for Nextcloud. Here is described how to set it up using an external caddy reverse proxy: https://github.com/nextcloud/all-in-one#how-to-get-nextcloud-running-using-the-acme-dns-challenge
|
||||
|
||||
## 4. Use Cloudflare
|
||||
## 5. Use Cloudflare
|
||||
If you do not have any control over the network, you may think about using Cloudflare Tunnel to get a valid certificate for your Nextcloud. However it will be opened to the public internet then. See https://github.com/nextcloud/all-in-one#how-to-run-nextcloud-behind-a-cloudflare-tunnel how to set this up.
|
||||
|
||||
## 5. Buy a certificate and use that
|
||||
## 6. Buy a certificate and use that
|
||||
If none of the above ways work for you, you may simply buy a certificate from an issuer for your domain. You then download the certificate onto your server, configure AIO in [reverse proxy mode](./reverse-proxy.md) and use the certificate for your domain in your reverse proxy config.
|
||||
|
||||
|
||||
128
migration.md
128
migration.md
@@ -3,7 +3,7 @@
|
||||
There are basically three ways how to migrate from an already existing Nextcloud installation to Nextcloud AIO (if you ran AIO on the former installation already, you can follow [these steps](https://github.com/nextcloud/all-in-one#how-to-migrate-from-aio-to-aio)):
|
||||
|
||||
1. Migrate only the files which is the easiest way (this excludes all calendar data for example)
|
||||
1. Migrate the files and the database which is much more complicated (and doesn't work on former snap installations)
|
||||
1. Migrate the files and the database which is much more complicated (with special handling required for former snap installations, see [below](#migrating-from-a-snap-installation))
|
||||
1. Use the user_migration app that allows to migrate some of the user's data from a former instance to a new instance but needs to be done manually for each user
|
||||
|
||||
## Migrate only the files
|
||||
@@ -21,7 +21,7 @@ The procedure for migrating only the files works like this:
|
||||
1. If the restored data is older than any clients you want to continue to sync, for example if the server was down for a period of time during migration, you may want to take a look at [Synchronising with clients after migration](/migration.md#synchronising-with-clients-after-migration) below.
|
||||
|
||||
## Migrate the files and the database
|
||||
**Please note**: this is much more complicated than migrating only the files and also not as failproof so be warned! Also, this will not work on former snap installations as the snap is read-only and thus you cannot install the necessary `pdo_pgsql` PHP extension. So if migrating from snap, you will need to use one of the other methods. However you could try to ask if the snaps maintainer could add this one small PHP extension to the snap here: https://github.com/nextcloud-snap/nextcloud-snap/issues which would allow for an easy migration.
|
||||
**Please note**: this is much more complicated than migrating only the files and also not as failproof so be warned! If you are migrating from a snap installation, please first follow the [dedicated snap migration steps](#migrating-from-a-snap-installation) below, which show you how to perform the database conversion using a temporary Docker container. Once done, you can continue from step 5 of this guide.
|
||||
|
||||
The procedure for migrating the files and the database works like this:
|
||||
1. Make sure that your old instance is on exactly the same version like the version used in Nextcloud AIO. (e.g. 23.0.0) You can find the used version here: [click here](https://github.com/nextcloud/all-in-one/search?l=Dockerfile&q=NEXTCLOUD_VERSION&type=). If not, simply upgrade your former installation to that version or wait until the version used in Nextcloud AIO got updated to the same version of your former installation or the other way around.
|
||||
@@ -87,6 +87,130 @@ If not, feel free to restore the AIO instance from backup and start at step 8 ag
|
||||
|
||||
If the restored data is older than any clients you want to continue to sync, for example if the server was down for a period of time during migration, you may want to take a look at [Synchronising with clients after migration](/migration.md#synchronising-with-clients-after-migration) below.
|
||||
|
||||
### Migrating from a snap installation
|
||||
|
||||
**Disclaimer:** it might be possible that the guide below is not working 100% correctly, yet. Improvements to it are very welcome!
|
||||
|
||||
Since the Nextcloud snap is read-only, it is not possible to install the `pdo_pgsql` PHP extension inside the snap to perform the MySQL-to-PostgreSQL database conversion required by AIO. As a workaround, a temporary [nextcloud/docker](https://github.com/nextcloud/docker) container can be used as an intermediate environment that already includes `pdo_pgsql` and can convert the snap's MySQL database to PostgreSQL for you.
|
||||
|
||||
This procedure covers steps 1–3 of the regular migration above (version matching, app updates, and database conversion) and also produces the `database-dump.sql` needed for step 4. Once finished, continue from step 5 of the [Migrate the files and the database](#migrate-the-files-and-the-database) procedure above.
|
||||
|
||||
1. **Create a backup of the snap before doing anything else**, so you can restore the snap to its current state if anything goes wrong:
|
||||
```
|
||||
sudo snap save nextcloud
|
||||
```
|
||||
This creates a snapshot that can be restored later with `sudo snap restore <snapshot-id>`. The snapshot ID is shown in the output of `snap save`. You can also list existing snapshots with `snap saved`.
|
||||
1. Note the exact Nextcloud version of your snap installation:
|
||||
```
|
||||
sudo nextcloud.occ -V
|
||||
```
|
||||
1. Make sure that this version matches exactly the version used in Nextcloud AIO. You can find the AIO version here: [click here](https://github.com/nextcloud/all-in-one/search?l=Dockerfile&q=NEXTCLOUD_VERSION&type=). If they do not match, upgrade your snap with `sudo snap refresh nextcloud --channel=<major-version>/stable` or wait for AIO to be updated to the same version.
|
||||
1. Update all installed Nextcloud apps to their latest versions:
|
||||
```
|
||||
sudo nextcloud.occ app:update --all
|
||||
```
|
||||
1. Retrieve the necessary configuration values from the snap using `nextcloud.occ` and store them in environment variables. Do this **before** stopping the snap, as `nextcloud.occ` requires the snap services to be running:
|
||||
```
|
||||
export INSTANCEID=$(sudo nextcloud.occ config:system:get instanceid)
|
||||
export PASSWORDSALT=$(sudo nextcloud.occ config:system:get passwordsalt)
|
||||
export SECRET=$(sudo nextcloud.occ config:system:get secret)
|
||||
export TABLE_PREFIX=$(sudo nextcloud.occ config:system:get dbtableprefix || echo "oc_")
|
||||
export SNAP_DATA=$(sudo nextcloud.occ config:system:get datadirectory)
|
||||
# Note down SNAP_DATA — you will need it later when copying files
|
||||
echo "Snap data directory: $SNAP_DATA"
|
||||
```
|
||||
1. Export a dump of the snap's MySQL database:
|
||||
```
|
||||
sudo nextcloud.mysqldump > ~/mysql-dump.sql
|
||||
```
|
||||
1. Stop the snap to prevent further writes during the migration:
|
||||
```
|
||||
sudo snap stop nextcloud
|
||||
```
|
||||
1. Set up environment variables for the temporary containers (adjust the version and passwords as needed):
|
||||
```
|
||||
export NEXTCLOUD_VERSION="29.0.0" # Replace with the exact version from step 2
|
||||
export MYSQL_PASSWORD="mysql-temp-password"
|
||||
export PG_USER="ncadmin"
|
||||
export PG_PASSWORD="my-temporary-pg-password"
|
||||
export PG_DATABASE="nextcloud_db"
|
||||
```
|
||||
1. Create a Docker network for the temporary migration containers:
|
||||
```
|
||||
docker network create nextcloud-migration
|
||||
```
|
||||
1. Start a temporary MySQL container and import the snap database dump into it:
|
||||
```
|
||||
docker run -d \
|
||||
--name mysql-migration \
|
||||
--network nextcloud-migration \
|
||||
-e MYSQL_ROOT_PASSWORD="mysql-root-temp" \
|
||||
-e MYSQL_DATABASE="nextcloud" \
|
||||
-e MYSQL_USER="nextcloud" \
|
||||
-e MYSQL_PASSWORD="$MYSQL_PASSWORD" \
|
||||
mysql:8
|
||||
# Wait for MySQL to finish starting up before importing
|
||||
until docker exec mysql-migration mysqladmin ping -h localhost --silent 2>/dev/null; do sleep 1; done
|
||||
docker exec -i mysql-migration mysql -u nextcloud -p"$MYSQL_PASSWORD" nextcloud < ~/mysql-dump.sql
|
||||
```
|
||||
1. Start a temporary PostgreSQL container as the migration target:
|
||||
```
|
||||
docker run -d \
|
||||
--name postgres-migration \
|
||||
--network nextcloud-migration \
|
||||
-e POSTGRES_USER="$PG_USER" \
|
||||
-e POSTGRES_PASSWORD="$PG_PASSWORD" \
|
||||
-e POSTGRES_DB="$PG_DATABASE" \
|
||||
postgres:16
|
||||
```
|
||||
1. Create a temporary config file for the migration container using the values retrieved in step 5:
|
||||
```
|
||||
cat > /tmp/migration-config.php << EOF
|
||||
<?php
|
||||
\$CONFIG = array(
|
||||
'instanceid' => '$INSTANCEID',
|
||||
'passwordsalt' => '$PASSWORDSALT',
|
||||
'secret' => '$SECRET',
|
||||
'dbtype' => 'mysql',
|
||||
'dbname' => 'nextcloud',
|
||||
'dbhost' => 'mysql-migration',
|
||||
'dbport' => '',
|
||||
'dbtableprefix' => '$TABLE_PREFIX',
|
||||
'dbuser' => 'nextcloud',
|
||||
'dbpassword' => '$MYSQL_PASSWORD',
|
||||
'datadirectory' => '$SNAP_DATA',
|
||||
'installed' => true,
|
||||
);
|
||||
EOF
|
||||
```
|
||||
1. Run a temporary nextcloud/docker container to convert the MySQL database to PostgreSQL. Note that the container image version must match the Nextcloud version you noted in step 2, and that `pdo_pgsql` is already included in the `nextcloud` Docker image:
|
||||
```
|
||||
docker run --rm \
|
||||
--network nextcloud-migration \
|
||||
--entrypoint bash \
|
||||
-v /tmp/migration-config.php:/var/www/html/config/config.php:rw \
|
||||
-v "${SNAP_DATA}:${SNAP_DATA}:ro" \
|
||||
nextcloud:${NEXTCLOUD_VERSION}-apache \
|
||||
-c "php /var/www/html/occ db:convert-type --all-apps --password '$PG_PASSWORD' pgsql '$PG_USER' postgres-migration '$PG_DATABASE'"
|
||||
```
|
||||
**Please note:** The `occ` command may print a warning about being run as root — this can be safely ignored for this migration step.
|
||||
1. Export the converted PostgreSQL database:
|
||||
```
|
||||
docker exec postgres-migration pg_dump -U "$PG_USER" "$PG_DATABASE" > ~/database-dump.sql
|
||||
```
|
||||
**Please note:** The exact name of the database export file is important! (`database-dump.sql`)
|
||||
1. Clean up the temporary containers and network:
|
||||
```
|
||||
docker rm -f mysql-migration postgres-migration
|
||||
docker network rm nextcloud-migration
|
||||
```
|
||||
1. You now have a `~/database-dump.sql`. Continue from step 5 of the [Migrate the files and the database](#migrate-the-files-and-the-database) procedure above. When those steps ask for your old data directory path, use the `$SNAP_DATA` value noted in step 5 (typically `/var/snap/nextcloud/common`). If you have opened a new shell session since then, you can retrieve it again with `sudo nextcloud.occ config:system:get datadirectory` (requires the snap to be running) or read it directly from `/var/snap/nextcloud/current/nextcloud/config/config.php`.
|
||||
1. Once you have verified that the migration to AIO was successful and everything is working correctly, you can permanently remove the Nextcloud snap from your system:
|
||||
```
|
||||
sudo snap remove --purge nextcloud
|
||||
```
|
||||
The `--purge` flag removes the snap along with all its saved snapshots and data. Omit it if you want to keep the snap snapshots as a fallback. **Only do this after you are fully satisfied that your AIO instance is working correctly**, as this action cannot be undone.
|
||||
|
||||
## Use the user_migration app
|
||||
A new way since the Nextcloud update to 24 is to use the new [user_migration app](https://apps.nextcloud.com/apps/user_migration#app-gallery). It allows to export the most important data on one instance and import it on a different Nextcloud instance. For that, you need to install and enable the user_migration app on your old instance, trigger the export for the user, create the user on the new instance, log in with that user and import the archive that was created during the export. This then needs to be done for each user that you want to migrate.
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ $app->get('/containers', function (Request $request, Response $response, array $
|
||||
$bypass_mastercontainer_update = isset($params['bypass_mastercontainer_update']);
|
||||
$bypass_container_update = isset($params['bypass_container_update']);
|
||||
$skip_domain_validation = isset($params['skip_domain_validation']);
|
||||
$skip_cosign_check = isset($params['skip_cosign_check']);
|
||||
|
||||
return $view->render($response, 'containers.twig', [
|
||||
'domain' => $configurationManager->domain,
|
||||
@@ -180,6 +181,7 @@ $app->get('/containers', function (Request $request, Response $response, array $
|
||||
'community_containers' => $configurationManager->listAvailableCommunityContainers(),
|
||||
'community_containers_enabled' => $configurationManager->aioCommunityContainers,
|
||||
'bypass_container_update' => $bypass_container_update,
|
||||
'skip_cosign_check' => $skip_cosign_check,
|
||||
]);
|
||||
})->setName('profile');
|
||||
$app->get('/login', function (Request $request, Response $response, array $args) use ($container) {
|
||||
|
||||
@@ -273,14 +273,18 @@ readonly class DockerController {
|
||||
$nonbufResp = $this->startStreamingResponse($response);
|
||||
$addToStreamingResponseBody = $this->getAddToStreamingResponseBody($nonbufResp);
|
||||
|
||||
$this->startWatchtower($addToStreamingResponseBody);
|
||||
// Allow temporarily skipping the cosign check via a POST body parameter
|
||||
$skipCosignCheck = isset($request->getParsedBody()['skip_cosign_check']);
|
||||
|
||||
$this->startWatchtower($addToStreamingResponseBody, $skipCosignCheck);
|
||||
|
||||
// End streaming response
|
||||
$this->finalizeStreamingResponse($nonbufResp);
|
||||
return $nonbufResp;
|
||||
}
|
||||
|
||||
public function startWatchtower(?\Closure $addToStreamingResponseBody = null) : void {
|
||||
public function startWatchtower(?\Closure $addToStreamingResponseBody = null, bool $skipCosignCheck = false) : void {
|
||||
$this->dockerActionManager->verifyMastercontainerImageSignature($skipCosignCheck);
|
||||
$id = 'nextcloud-aio-watchtower';
|
||||
|
||||
$this->PerformRecursiveContainerStart($id, true, $addToStreamingResponseBody);
|
||||
|
||||
@@ -523,6 +523,7 @@ readonly class DockerActionManager {
|
||||
}
|
||||
|
||||
$imageName = $this->BuildImageName($container);
|
||||
$this->verifyImageSignature($imageName);
|
||||
$encodedImageName = urlencode($imageName);
|
||||
$url = $this->BuildApiUrl(sprintf('images/create?fromImage=%s', $encodedImageName));
|
||||
$imageIsThere = true;
|
||||
@@ -557,6 +558,58 @@ readonly class DockerActionManager {
|
||||
}
|
||||
}
|
||||
|
||||
private function verifyImageSignature(string $imageName): void {
|
||||
// Only verify images from the nextcloud-releases ghcr.io registry or
|
||||
// the nextcloud/all-in-one Docker Hub image, as those are the images
|
||||
// signed via the CI workflows in PR #97.
|
||||
if (!str_starts_with($imageName, 'ghcr.io/nextcloud-releases/') && !str_starts_with($imageName, 'nextcloud/all-in-one')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$command = [
|
||||
'cosign',
|
||||
'verify',
|
||||
'--certificate-identity-regexp',
|
||||
'^https://github\\.com/nextcloud-releases/all-in-one/\\.github/workflows/',
|
||||
'--certificate-oidc-issuer',
|
||||
'https://token.actions.githubusercontent.com',
|
||||
$imageName,
|
||||
];
|
||||
|
||||
$process = proc_open(
|
||||
$command,
|
||||
[
|
||||
0 => ['file', '/dev/null', 'r'],
|
||||
1 => ['file', '/dev/null', 'w'],
|
||||
2 => ['pipe', 'w'],
|
||||
],
|
||||
$pipes
|
||||
);
|
||||
|
||||
if (!is_resource($process)) {
|
||||
throw new \Exception('Could not execute cosign command to verify image ' . $imageName . '. Ensure cosign is installed and accessible.');
|
||||
}
|
||||
|
||||
$stderr = stream_get_contents($pipes[2]);
|
||||
fclose($pipes[2]);
|
||||
$exitCode = proc_close($process);
|
||||
|
||||
if ($exitCode !== 0) {
|
||||
$stderrOutput = $stderr !== false ? $stderr : '';
|
||||
error_log('cosign verification output for ' . $imageName . ': ' . $stderrOutput);
|
||||
throw new \Exception('Image signature verification failed for ' . $imageName . '. The image may not be correctly signed.');
|
||||
}
|
||||
}
|
||||
|
||||
public function verifyMastercontainerImageSignature(bool $skipCosignCheck = false): void {
|
||||
if ($skipCosignCheck) {
|
||||
error_log('WARNING: Skipping cosign signature verification for mastercontainer image. This should only be done temporarily.');
|
||||
return;
|
||||
}
|
||||
$imageName = $this->GetCurrentImageName() . ':' . $this->GetCurrentChannel();
|
||||
$this->verifyImageSignature($imageName);
|
||||
}
|
||||
|
||||
private function isContainerUpdateAvailable(string $id): string {
|
||||
$container = $this->containerDefinitionFetcher->GetContainerById($id);
|
||||
|
||||
|
||||
@@ -93,6 +93,9 @@
|
||||
<form method="POST" action="api/docker/watchtower" target="overlay-log">
|
||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||
{% if skip_cosign_check == true %}
|
||||
<input type="hidden" name="skip_cosign_check" value="true">
|
||||
{% endif %}
|
||||
<input type="submit" value="Update mastercontainer" />
|
||||
</form>
|
||||
{% else %}
|
||||
@@ -335,6 +338,9 @@
|
||||
<form method="POST" action="api/docker/watchtower" target="overlay-log">
|
||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||
{% if skip_cosign_check == true %}
|
||||
<input type="hidden" name="skip_cosign_check" value="true">
|
||||
{% endif %}
|
||||
<input type="submit" value="Update mastercontainer" />
|
||||
</form>
|
||||
{% else %}
|
||||
|
||||
28
readme.md
28
readme.md
@@ -231,6 +231,9 @@ sudo docker run \
|
||||
> [!NOTE]
|
||||
> For production usage (and ease of upgrades and changes), we suggest using the example [Compose file](https://github.com/nextcloud/all-in-one/blob/main/compose.yaml) rather than `docker run`.
|
||||
|
||||
> [!TIP]
|
||||
> You can optionally verify the cryptographic signature of the mastercontainer image before running it. See [How to verify the image signature?](#how-to-verify-the-image-signature)
|
||||
|
||||
4. After the initial startup, open the Nextcloud AIO interface on port 8080 of this server **by IP address**, for example:
|
||||
```txt
|
||||
https://192.168.5.5:8080
|
||||
@@ -357,6 +360,7 @@ https://your-domain-that-points-to-this-server.tld:8443
|
||||
- [Update policy](#update-policy)
|
||||
- [How often are update notifications sent?](#how-often-are-update-notifications-sent)
|
||||
- [Huge docker logs](#huge-docker-logs)
|
||||
- [How to verify the image signature?](#how-to-verify-the-image-signature)
|
||||
|
||||
### Where can I find additional documentation?
|
||||
Some of the documentation is available on [GitHub Discussions](https://github.com/nextcloud/all-in-one/discussions/categories/wiki).
|
||||
@@ -1285,6 +1289,30 @@ AIO ships its own update notifications implementation. It checks if container up
|
||||
### Huge docker logs
|
||||
If you should run into issues with huge docker logs, you can adjust the log size by following https://docs.docker.com/config/containers/logging/local/#usage. However for the included AIO containers, this should usually not be needed because almost all of them have the log level set to warn so they should not produce many logs.
|
||||
|
||||
### How to verify the image signature?
|
||||
All AIO images published to `ghcr.io/nextcloud-releases/` and the `nextcloud/all-in-one` Docker Hub image are signed using [cosign](https://github.com/sigstore/cosign) with keyless signing via GitHub Actions (Sigstore). You can verify the signature of the mastercontainer image before running it by installing cosign and executing one of the following commands depending on which registry you use:
|
||||
|
||||
For `ghcr.io/nextcloud-releases/all-in-one` (GitHub Container Registry):
|
||||
```sh
|
||||
cosign verify \
|
||||
--certificate-identity-regexp '^https://github\.com/nextcloud-releases/all-in-one/\.github/workflows/' \
|
||||
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
|
||||
ghcr.io/nextcloud-releases/all-in-one:latest
|
||||
```
|
||||
|
||||
For `nextcloud/all-in-one` (Docker Hub):
|
||||
```sh
|
||||
cosign verify \
|
||||
--certificate-identity-regexp '^https://github\.com/nextcloud-releases/all-in-one/\.github/workflows/' \
|
||||
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
|
||||
nextcloud/all-in-one:latest
|
||||
```
|
||||
|
||||
Replace `latest` with the tag you intend to run (e.g. `beta`). A successful verification prints the signing certificate details and exits with code 0. Any non-zero exit code means the signature could not be verified and you should **not** run that image.
|
||||
|
||||
> [!NOTE]
|
||||
> AIO itself automatically verifies the cosign signature of every image it pulls from `ghcr.io/nextcloud-releases/` or `nextcloud/all-in-one` (Docker Hub) and refuses to pull images that fail verification. The manual command above lets you perform the same check independently before the initial `docker run`.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Badges</summary>
|
||||
|
||||
@@ -6,7 +6,7 @@ This guide explains how to connect to Nextcloud AIO securely via HTTPS (TLS) usi
|
||||
|
||||
- **Integrated**: AIO's built-in reverse proxy with automatic HTTPS
|
||||
- **External**: An external reverse proxy (such as Caddy or Nginx or Cloudflare Proxy)
|
||||
- **Secure tunnel**: Tunneling services for private network access or public access without port forwarding (such as Tailscale Serve or Cloudflare Tunnel)
|
||||
- **Secure tunnel**: Tunneling services for private network access or public access without port forwarding (such as Tailscale Serve, Cloudflare Tunnel, or Pangolin)
|
||||
|
||||
## Choosing Your Approach
|
||||
|
||||
@@ -23,6 +23,7 @@ This guide explains how to connect to Nextcloud AIO securely via HTTPS (TLS) usi
|
||||
| **Integrated** | Simple setups, single service on port 443 | Public IP, dedicated port 443 | Yes (443) |
|
||||
| **External Reverse Proxy** (including Cloudflare Proxy) | Multiple services, existing web server, or users wanting DDoS protection | Existing reverse proxy, willingness to set one up, or Cloudflare account | Yes (443) |
|
||||
| **Cloudflare Tunnel** | No port forwarding possible/desired, public access | Cloudflare account | No |
|
||||
| **Pangolin** | No port forwarding possible/desired, public or private access, self-hostable tunnel | Pangolin Cloud account or self-hosted Pangolin server | No |
|
||||
| **Tailscale Serve** | Private access (tailnet only) | Tailscale account | No |
|
||||
| **Tailscale Funnel** | Public access via Tailscale | Tailscale account | No |
|
||||
|
||||
@@ -68,29 +69,32 @@ Using an existing external reverse proxy is required in particular if port `443/
|
||||
> [!NOTE]
|
||||
> An external reverse proxy can also facilitate other routing approaches, but Nextcloud AIO only supports having its own dedicated hostname (e.g., `cloud.example.com`). You cannot run it in a subfolder like `example.com/nextcloud/`.[^shared]
|
||||
|
||||
### Secure tunnel: Using AIO with a secure tunneling service (*Tailscale, Cloudflare*)
|
||||
### Secure tunnel: Using AIO with a secure tunneling service (*Tailscale, Cloudflare, Pangolin*)
|
||||
|
||||
Cloudflare and Tailscale offer secure tunneling services that let you access your Nextcloud without opening ports on your firewall.
|
||||
Cloudflare, Tailscale, and Pangolin offer secure tunneling services that let you access your Nextcloud without opening ports on your firewall.
|
||||
|
||||
#### Private network access
|
||||
|
||||
For Nextcloud AIO, you can use:
|
||||
- **Cloudflare Tunnel (`cloudflared`)** - Secure outbound-only tunnels that don't require exposing ports
|
||||
- **Tailscale Serve** - Expose services privately on your Tailscale network (tailnet only)
|
||||
- **Pangolin** - WireGuard-based outbound tunnels using the Newt connector; can be used for both private and public access
|
||||
|
||||
Both options provide private network access to your Nextcloud AIO instance.
|
||||
All three options provide private network access to your Nextcloud AIO instance.
|
||||
|
||||
#### Public Internet access (without port forwarding)
|
||||
|
||||
To make your Nextcloud AIO instance accessible from the public Internet (not just your private network), you can use:
|
||||
- **Cloudflare Tunnel** with public routes enabled (which combines Cloudflare Tunnel with Cloudflare's proxy features)
|
||||
- **Tailscale Funnel** - Expose services to the public Internet via Tailscale's infrastructure
|
||||
- **Pangolin** - Expose services publicly via Pangolin Cloud or a self-hosted Pangolin server
|
||||
|
||||
**Comparison of Cloudflare and Tailscale options:**
|
||||
**Comparison of Cloudflare, Tailscale, and Pangolin options:**
|
||||
|
||||
| Feature | Access Scope | Inbound Ports Required | Use Case |
|
||||
|---------|--------------|----------------|----------|
|
||||
| **Cloudflare Tunnel** | Public Internet | None | Public access without port forwarding |
|
||||
| **Pangolin** | Public Internet or private | None | Public or private access; self-hostable |
|
||||
| **Tailscale Serve** | Your Tailscale network only | None | Private access for you and invited users |
|
||||
| **Tailscale Funnel** | Public Internet | None | Public access through Tailscale |
|
||||
|
||||
@@ -737,6 +741,48 @@ httpServer.on('upgrade', (req, socket, head) => {
|
||||
|
||||
</details>
|
||||
|
||||
##### Pangolin
|
||||
|
||||
<details>
|
||||
|
||||
<summary>click here to expand</summary>
|
||||
|
||||
[Pangolin](https://pangolin.net/) is an open-source, identity-based remote access platform built on WireGuard that enables secure connectivity to private resources without opening inbound firewall ports. It uses the **Newt** connector as an outbound-only WireGuard tunnel client that runs alongside AIO on your server and connects to a Pangolin server (either Pangolin Cloud or your own self-hosted instance). From AIO's perspective, Pangolin works like a reverse proxy: Pangolin handles TLS and routes public traffic through the tunnel to AIO.
|
||||
|
||||
**Requirements:**
|
||||
- A [Pangolin Cloud](https://app.pangolin.net/) account **or** a [self-hosted Pangolin server](https://docs.pangolin.net/self-host/quick-install)
|
||||
- No open inbound ports required
|
||||
|
||||
**Setup:**
|
||||
|
||||
1. **Set up Pangolin**: Either sign up for a free [Pangolin Cloud](https://app.pangolin.net/) account, or [self-host Pangolin](https://docs.pangolin.net/self-host/quick-install) on a VPS with a public IP address.
|
||||
|
||||
1. **Create a site**: In the Pangolin dashboard, create a new site for the machine that will run AIO. Follow the instructions to generate a **Newt ID** and **Newt secret** for the site.
|
||||
|
||||
1. **Deploy Newt on the AIO host**: Run the Newt connector on the same machine as AIO. You can deploy it as a Docker container alongside AIO:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
newt:
|
||||
image: fosrl/newt
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- PANGOLIN_ENDPOINT=https://app.pangolin.net # For Pangolin Cloud; replace with your self-hosted server URL if self-hosting
|
||||
- NEWT_ID=<your-newt-id>
|
||||
- NEWT_SECRET=<your-newt-secret>
|
||||
```
|
||||
|
||||
Or as a standalone binary — see the [Newt documentation](https://github.com/fosrl/newt) for details.
|
||||
|
||||
1. **Create a resource**: In the Pangolin dashboard, create a new resource for the site. Set the target to `http://private.ip.address.of.server:11000`.<br>
|
||||
⚠️ **Please note:** look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the port and address to match your `APACHE_PORT` and `APACHE_IP_BINDING` settings.
|
||||
|
||||
1. **Configure AIO**: When starting AIO, add `--env SKIP_DOMAIN_VALIDATION=true` to disable domain validation (domain validation is known to not work through Pangolin tunnels). Use the domain assigned by Pangolin as your Nextcloud domain when opening the AIO interface.
|
||||
|
||||
1. Now continue with [point 2](#2-use-this-startup-command).
|
||||
|
||||
</details>
|
||||
|
||||
##### Synology Reverse Proxy
|
||||
|
||||
<details>
|
||||
|
||||
Reference in New Issue
Block a user