Restore backup to docker installation

Nextcloud version: 20.0.12 (official nextcloud image)
Operating system and version: docker-compose 1.29.1, apache image
Proxy version: Traefik 2.2.1
PHP version: 7.4.22

The issue:
404 page not found, the containers have the right network settings and the config file has the corresponding IP for the trusted proxy.
This was a working installation on Nextcloud version 17 with Traefik 1.7.16 before the server burned.
No backup of the Nextcloud 17 image or container thus no upgrade possible !
The backup is restored to the data folder and the config.php file of the Nextcloud volume same for the DB, the tables are populated:

MariaDB [nextcloud]> show tables;
±-------------------------------+
| Tables_in_nextcloud |
±-------------------------------+
| oc_accounts |
| oc_activity |
| oc_activity_mq |
| oc_addressbookchanges |
| oc_addressbooks |
| oc_appconfig |
| oc_audioplayer_albums |
| oc_audioplayer_artists |
| oc_audioplayer_genre |
| oc_audioplayer_playlist_tracks |
| oc_audioplayer_playlists |
| oc_audioplayer_stats |
| oc_audioplayer_streams |
| oc_audioplayer_tracks |
| oc_authtoken |
| oc_bookmarks |
| oc_bookmarks_folders |
| oc_bookmarks_folders_bookmarks |
| oc_bookmarks_tags |
| oc_bruteforce_attempts |
| oc_calendar_invitations |
| oc_calendar_reminders |
| oc_calendar_resources |
| oc_calendar_resources_md |
| oc_calendar_rooms |
| oc_calendar_rooms_md |
| oc_calendarchanges |
| oc_calendarobjects |
| oc_calendarobjects_props |
| oc_calendars |
| oc_calendarsubscriptions |
| oc_cards |
| oc_cards_properties |
| oc_carnet_metadata |
| oc_collres_accesscache |
| oc_collres_collections |
| oc_collres_resources |
| oc_comments |
| oc_comments_read_markers |
| oc_credentials |
| oc_dav_cal_proxy |
| oc_dav_shares |
| oc_directlink |
| oc_federated_reshares |
| oc_file_locks |
| oc_filecache |
| oc_filecache_extended |
| oc_files_trash |
| oc_flow_checks |
| oc_flow_operations |
| oc_group_admin |
| oc_group_user |
| oc_groups |
| oc_jobs |
| oc_login_flow_v2 |
| oc_migrations |
| oc_mimetypes |
| oc_mounts |
| oc_notifications |
| oc_notifications_pushtokens |
| oc_oauth2_access_tokens |
| oc_oauth2_clients |
| oc_preferences |
| oc_privacy_admins |
| oc_properties |
| oc_richdocuments_assets |
| oc_richdocuments_direct |
| oc_richdocuments_wopi |
| oc_schedulingobjects |
| oc_share |
| oc_share_external |
| oc_storages |
| oc_systemtag |
| oc_systemtag_group |
| oc_systemtag_object_mapping |
| oc_talk_commands |
| oc_talk_guests |
| oc_talk_participants |
| oc_talk_rooms |
| oc_talk_signaling |
| oc_text_documents |
| oc_text_sessions |
| oc_text_steps |
| oc_trusted_servers |
| oc_twofactor_backupcodes |
| oc_twofactor_providers |
| oc_twofactor_totp_secrets |
| oc_users |
| oc_vcategory |
| oc_vcategory_to_object |
| oc_whats_new |
±-------------------------------+
91 rows in set (0.001 sec)

Nextcloud config/config.php

‘’<?php
$CONFIG = array (
‘htaccess.RewriteBase’ => ‘/’,
‘memcache.local’ => ‘\OC\Memcache\APCu’,
‘apps_paths’ =>
array (
0 =>
array (
‘path’ => ‘/var/www/html/apps’,
‘url’ => ‘/apps’,
‘writable’ => false,
),
1 =>
array (
‘path’ => ‘/var/www/html/custom_apps’,
‘url’ => ‘/custom_apps’,
‘writable’ => true,
),
),
‘instanceid’ => ‘xxx’,
‘passwordsalt’ => ‘xxx’,
‘secret’ => ‘xxx’,
‘trusted_domains’ =>
array (
0 => ‘xxx’,
),
‘trusted_proxies’ =>
array (
0 => ‘172.25.0.2’,
),
‘datadirectory’ => ‘/var/www/html/data’,
‘dbtype’ => ‘mysql’,
‘version’ => ‘20.0.12’,
‘overwrite.cli.url’ => ‘https://xxx.domain’,
‘overwriteprotocol’ => ‘https’,
‘dbname’ => ‘xxx’,
‘dbhost’ => ‘172.26.0.2:3306’,
‘dbport’ => ‘’,
‘dbtableprefix’ => ‘oc_’,
‘mysql.utf8mb4’ => true,
‘dbuser’ => ‘xxx’,
‘dbpassword’ => ‘xxx’,
‘installed’ => true,
‘twofactor_enforced’ => ‘true’,
‘twofactor_enforced_groups’ =>
array (
0 => ‘admin’,
),
‘twofactor_enforced_excluded_groups’ =>
array (
),
‘mail_smtpmode’ => ‘smtp’,
‘mail_smtpsecure’ => ‘ssl’,
‘mail_sendmailmode’ => ‘smtp’,
‘mail_from_address’ => ‘xxx’,
‘mail_domain’ => ‘xxx’,
‘mail_smtpauthtype’ => ‘LOGIN’,
‘mail_smtpauth’ => 1,
‘mail_smtphost’ => ‘ssl0.ovh.net’,
‘mail_smtpport’ => ‘465’,
‘mail_smtpname’ => ‘xxx’,
‘mail_smtppassword’ => ‘xxx’,
‘has_rebuilt_cache’ => true,
‘maintenance’ => true,
‘theme’ => ‘’,
‘loglevel’ => 2,
);
‘’
Can’t see anything wrong in the db logs:

$ sudo docker logs nxt_db | tail
2021-08-12 10:00:07 0 [Note] mysqld (mysqld 10.5.9-MariaDB-1:10.5.9+maria~focal) starting as process 1 

2021-08-12 10:00:07 0 [Warning] You need to use --log-bin to make --binlog-format work.
2021-08-12 10:00:07 0 [Note] InnoDB: Uses event mutexes
2021-08-12 10:00:07 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2021-08-12 10:00:07 0 [Note] InnoDB: Number of pools: 1
2021-08-12 10:00:07 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
2021-08-12 10:00:07 0 [Note] mysqld: O_TMPFILE is not supported on /tmp (disabling future attempts)
2021-08-12 10:00:07 0 [Note] InnoDB: Using Linux native AIO
2021-08-12 10:00:07 0 [Note] InnoDB: Initializing buffer pool, total size = 134217728, chunk size = 134217728
2021-08-12 10:00:07 0 [Note] InnoDB: Completed initialization of buffer pool
2021-08-12 10:00:07 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2021-08-12 10:00:07 0 [Note] InnoDB: 128 rollback segments are active.
2021-08-12 10:00:07 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2021-08-12 10:00:07 0 [Note] InnoDB: Setting file ‘./ibtmp1’ size to 12 MB. Physically writing the file full; Please wait 

2021-08-12 10:00:07 0 [Note] InnoDB: File ‘./ibtmp1’ size is now 12 MB.
2021-08-12 10:00:07 0 [Note] InnoDB: 10.5.9 started; log sequence number 45190; transaction id 20
2021-08-12 10:00:07 0 [Note] Plugin ‘FEEDBACK’ is disabled.
2021-08-12 10:00:07 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2021-08-12 10:00:07 0 [Note] InnoDB: Buffer pool(s) load completed at 210812 10:00:07
2021-08-12 10:00:07 0 [Note] Server socket created on IP: ‘::’.
2021-08-12 10:00:07 0 [Warning] ‘proxies_priv’ entry ‘@% root@4237f408438f’ ignored in --skip-name-resolve mode.
2021-08-12 10:00:07 0 [Note] Reading of all Master_info entries succeeded
2021-08-12 10:00:07 0 [Note] Added new Master_info ‘’ to hash table
2021-08-12 10:00:07 0 [Note] mysqld: ready for connections.
Version: ‘10.5.9-MariaDB-1:10.5.9+maria~focal’ socket: ‘/run/mysqld/mysqld.sock’ port: 3306 mariadb.org binary distribution
2021-08-10 20:51:22+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.
2021-08-10 20:51:23+00:00 [Note] [Entrypoint]: Switching to dedicated user ‘mysql’
2021-08-10 20:51:23+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.
2021-08-12 09:28:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.
2021-08-12 09:28:36+00:00 [Note] [Entrypoint]: Switching to dedicated user ‘mysql’
2021-08-12 09:28:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.
2021-08-12 09:48:25+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.
2021-08-12 09:48:25+00:00 [Note] [Entrypoint]: Switching to dedicated user ‘mysql’
2021-08-12 09:48:25+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.
2021-08-12 10:00:07+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.
2021-08-12 10:00:07+00:00 [Note] [Entrypoint]: Switching to dedicated user ‘mysql’
2021-08-12 10:00:07+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.

Tested with both version 1 & 2 of Traefik and also Nextcloud 19 image, always 404 page not found !
The Traefik dashboard works, no warnings or errors and can’t see anything useful in its logs:

$ sudo docker logs traefik | tail -10
time=“2021-07-23T10:14:18-04:00” level=debug msg=“Adding tracing to middleware” entryPointName=https routerName=traefik-rtr@docker middlewareName=middlewares-secure-headers@file
time=“2021-07-23T10:14:18-04:00” level=debug msg=“Creating middleware” entryPointName=https routerName=traefik-rtr@docker middlewareName=middlewares-rate-limit@file middlewareType=RateLimiterType
time=“2021-07-23T10:14:18-04:00” level=debug msg=“Using IPStrategy” entryPointName=https routerName=traefik-rtr@docker middlewareName=middlewares-rate-limit@file middlewareType=RateLimiterType
time=“2021-07-23T10:14:18-04:00” level=debug msg=“Adding tracing to middleware” middlewareName=middlewares-rate-limit@file entryPointName=https routerName=traefik-rtr@docker
time=“2021-07-23T10:14:18-04:00” level=debug msg=“Creating middleware” entryPointName=https middlewareType=Recovery middlewareName=traefik-internal-recovery
time=“2021-07-23T10:14:18-04:00” level=debug msg=“Creating TCP server 0 at 172.26.0.3:443” routerName=nextcloud-tcp@docker serviceName=nextcloud-tcp-svc serverName=0 entryPointName=https
time=“2021-07-23T10:14:18-04:00” level=debug msg=“Adding route nextcloud.opensolutions.ovh on TCP” entryPointName=https routerName=nextcloud-tcp@docker
time=“2021-07-23T10:14:20-04:00” level=debug msg=“Authentication succeeded” middlewareType=BasicAuth middlewareName=middlewares-basic-auth@file
time=“2021-07-23T10:14:25-04:00” level=debug msg=“Authentication succeeded” middlewareName=middlewares-basic-auth@file middlewareType=BasicAuth
time=“2021-07-23T10:14:30-04:00” level=debug msg=“Authentication succeeded” middlewareName=middlewares-basic-auth@file middlewareType=BasicAuth

Cannot interpret nextcloud log:

$ sudo docker logs nxt | tail -30
AH00558: apache2: Could not reliably determine the server’s fully qualified domain name, using 172.26.0.3. Set the ‘ServerName’ directive globally to suppress this message
[Thu Aug 12 10:00:13.897608 2021] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) PHP/7.4.22 configured – resuming normal operations
[Thu Aug 12 10:00:13.897921 2021] [core:notice] [pid 1] AH00094: Command line: ‘apache2 -D FOREGROUND’
#3 /var/www/html/3rdparty/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php(206): OC\DB\Connection->executeQuery(‘SELECT * FROM `
’, Array, Array)
#4 /var/www/html/lib/private/DB/QueryBuilder/QueryBuilder.php(248): Doctrine\DBAL\Query\QueryBuilder->execute()
#5 /var/www/html/lib/private/AppConfig.php(345): OC\DB\QueryBuilder\QueryBuilder->execute()
#6 /var/www/html/lib/private/AppConfig.php(110): OC\AppConfig->loadConfigValues()
#7 /var/www/html/lib/private/AppConfig.php(301): OC\AppConfig->getApps()
#8 /var/www/html/lib/private/legacy/OC_App.php(957): OC\AppConfig->getValues(false, ‘installed_versi
’)
#9 /var/www/html/lib/private/Server.php(668): OC_App::getAppVersions()
#10 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(155): OC\Server->OC{closure}(Object(OC\Server))
#11 /var/www/html/3rdparty/pimple/pimple/src/Pimple/Container.php(118): OC\AppFramework\Utility\SimpleContainer->OC\AppFramework\Utility{closure}(Object(Pimple\Container))
#12 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(122): Pimple\Container->offsetGet(‘OC\Memcache\Fac
’)
#13 /var/www/html/lib/private/ServerContainer.php(156): OC\AppFramework\Utility\SimpleContainer->query(‘OC\Memcache\Fac
’, true)
#14 /var/www/html/lib/private/Server.php(1677): OC\ServerContainer->query(‘OC\Memcache\Fac
’)
#15 /var/www/html/lib/private/Server.php(1017): OC\Server->getMemCacheFactory()
#16 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(155): OC\Server->OC{closure}(Object(OC\Server))
#17 /var/www/html/3rdparty/pimple/pimple/src/Pimple/Container.php(118): OC\AppFramework\Utility\SimpleContainer->OC\AppFramework\Utility{closure}(Object(Pimple\Container))
#18 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(122): Pimple\Container->offsetGet(‘OCP\Lock\ILocki
’)
#19 /var/www/html/lib/private/ServerContainer.php(156): OC\AppFramework\Utility\SimpleContainer->query(‘OCP\Lock\ILocki
’, true)
#20 /var/www/html/lib/private/Server.php(1977): OC\ServerContainer->query(‘OCP\Lock\ILocki
’)
#21 /var/www/html/lib/private/Files/View.php(118): OC\Server->getLockingProvider()
#22 /var/www/html/lib/private/Server.php(395): OC\Files\View->__construct()
#23 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(155): OC\Server->OC{closure}(Object(OC\Server))
#24 /var/www/html/3rdparty/pimple/pimple/src/Pimple/Container.php(118): OC\AppFramework\Utility\SimpleContainer->OC\AppFramework\Utility{closure}(Object(Pimple\Container))
#25 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(122): Pimple\Container->offsetGet(‘OC\Files\Node\H
’)
#26 /var/www/html/lib/private/ServerContainer.php(156): OC\AppFramework\Utility\SimpleContainer->query(‘OC\Files\Node\H
’, true)
#27 /var/www/html/lib/private/Server.php(1324): OC\ServerContainer->query(‘OC\Files\Node\H
’)
#28 /var/www/html/lib/base.php(595): OC\Server->boot()
#29 /var/www/html/lib/base.php(1091): OC::init()
#30 /var/www/html/console.php(49): require_once(’/var/www/html/l
’)
#31 /var/www/html/occ(11): require_once(’/var/www/html/c
’)

docker-compose-t2.yml

version: ‘3.7’

########################### NETWORKS
networks:
t2_proxy:
external:
name: t2_proxy
default:
driver: bridge

########################### SERVICES
services:
# All services / apps go below this line

traefik:
hostname: traefik
image: traefik:2.2.1
container_name: traefik
restart: unless-stopped
domainname: ${DOMAINNAME}
command: # CLI arguments
- --global.checkNewVersion=true
- --global.sendAnonymousUsage=true
- --entryPoints.http.address=:80
- --entryPoints.https.address=:443
- --entryPoints.traefik.address=:8080
- --api=true
- --api.insecure=true
# - --serversTransport.insecureSkipVerify=true
- --log=true
- --log.level=DEBUG # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
- --accessLog=true
- --accessLog.filePath=/traefik.log
- --accessLog.bufferingSize=100 # Configuring a buffer of 100 lines
- --accessLog.filters.statusCodes=400-499
- --providers.docker=true
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.defaultrule=Host({{ index .Labels "com.docker.compose.service" }}.$DOMAINNAME)
- --providers.docker.exposedByDefault=false
- --providers.docker.network=t2_proxy
- --providers.docker.swarmMode=false
- --providers.file.directory=/rules # Load dynamic configuration from one or more .toml or .yml files in a directory.
# - --providers.file.filename=/path/to/file # Load dynamic configuration from a file.
- --providers.file.watch=true # Only works on top level files in the rules folder
# - --certificatesResolvers.dns-ovh.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing
- --certificatesResolvers.dns-ovh.acme.email=$OVH_EMAIL
- --certificatesResolvers.dns-ovh.acme.storage=/acme.json
- --certificatesResolvers.dns-ovh.acme.dnsChallenge.provider=ovh
networks:
- t2_proxy
security_opt:
- no-new-privileges:true
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
- target: 8080
published: 8080
protocol: tcp
mode: host
volumes:
- $DOCKERDIR/traefik2/rules:/rules
- /var/run/docker.sock:/var/run/docker.sock:ro
- $DOCKERDIR/traefik2/acme/acme.json:/acme.json
- $DOCKERDIR/traefik2/traefik.log:/traefik.log
- $DOCKERDIR/shared:/shared
env_file:
- .env
# secrets:
# - ovh_app_key
# - ovh_key
# - ovh_app_secret
environment:
- OVH_API_EMAIL=${OVH_EMAIL}
- OVH_ENDPOINT=ovh-eu
- OVH_APPLICATION_KEY=XXX
- OVH_APPLICATION_SECRET=XXX
- OVH_CONSUMER_KEY=XXX
labels:
- “traefik.enable=true”
# HTTP-to-HTTPS Redirect
- “traefik.http.routers.http-catchall.entrypoints=http”
- “traefik.http.routers.http-catchall.rule=HostRegexp({host:.+})”
- “traefik.http.routers.http-catchall.middlewares=redirect-to-https”
- “traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https”
# HTTP Routers
- “traefik.http.routers.traefik-rtr.entrypoints=https”
- “traefik.http.routers.traefik-rtr.rule=Host(traefik.$DOMAINNAME)”
- “traefik.http.routers.traefik-rtr.tls=true”
# - “traefik.http.routers.traefik-rtr.tls.certresolver=dns-ovh” # Comment out this line after first run of traefik to force the use of wildcard certs
- “traefik.http.routers.traefik-rtr.tls.domains[0].main=*.$DOMAINNAME”
- “traefik.http.routers.traefik-rtr.tls.domains[0].sans=$DOMAINNAME”
## Services - API
- “traefik.http.routers.traefik-rtr.service=api@internal”
## Middlewares
- “traefik.http.routers.traefik-rtr.middlewares=chain-basic-auth@file”

db:
image: mariadb
container_name: nxt_db
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
restart: always
volumes:
# - /var/lib/docker/volumes/nextcloud_db/_data:/var/lib/mysql:rw
# - $DOCKERDIR/db/data/mysql:/var/lib/mysql:rw
- db:/var/lib/mysql
secrets:
- os_secret
environment:
- MYSQL_ROOT_PASSWORD=xxxxxx
# networks:
# default:
# ipv4_address: ‘172.20.0.3’

nextcloud:
container_name: nxt
image: nextcloud:20-apache
restart: always
depends_on:
- db
networks:
- t2_proxy
- default
# ports:
# - “443:443”
security_opt:
- no-new-privileges:true
volumes:
# - $DOCKERDIR/nxt:/config
# - $DOCKERDIR/nxt/data:/var/www/html:rw
- nextcloud:/var/www/html
environment:
- NODE_ENV=production
- MYSQL_HOST=db
labels:
- “traefik.enable=true”
- “traefik.docker.network=traefik_proxy”
## TCP Routers
- “traefik.tcp.routers.nextcloud-tcp.entrypoints=https”
- “traefik.tcp.routers.nextcloud-tcp.rule=HostSNI(nextcloud.$DOMAINNAME)”
- “traefik.tcp.routers.nextcloud-tcp.tls.certresolver=ovh-eu”
- “traefik.tcp.routers.nextcloud-tcp.tls.passthrough=true”
## TCP Services
- “traefik.tcp.routers.nextcloud-tcp.service=nextcloud-tcp-svc”
- “traefik.tcp.services.nextcloud-tcp-svc.loadbalancer.server.port=443”

volumes:
db:
nextcloud:

secrets:
os_secret:
file: $SECRETSDIR/mysql_pwd

pull the nc17 image. make the restore. and update to nc18/19/20.

direct restore to a nc20 image is possible, but i doubt that you got it right. anyhow it would be a downgrade to nc17.

1 Like

Hello,

Thanks for your prompt reply, that’s what I wanted to do but couldn’t see the tag for the image so I presumed I couldn’t pull :frowning:
Just done it but I still get 404 page not found. Going to try with original docker compose file and traefik1.7

You mention it’s possible without upgrade, can you give me any pointers?

here: Docker

the nc version is also stored in config.php if you backuped this file. (which is a good idea to do.)

misunderstanding.

the database dump correlates to a nc version. you now can run docker-compose and pull the nc20 image. this will install nc20 to /var/www/html which is normally bound to a local volume/path on your host. ( -v nextcloud:/var/www/html

to restore you have to overwrite this volume with your backup. and that would be the downgarde. got it?

Hello,
Thanks for the link to docker hub.
There was no misunderstanding, I used wrong wording, meant downgrade with direct restore from nc20 image, sorry.
Using nc17 image the container keeps restarting, no luck there

Using nc20 image keep receiving 404 page not found, changed the version to 17.0.10 in config.php, in case, to no avail !
The containers are properly networked, I can access db and logs don’t show anything new.
I’m almost at my wits’ end, it seems the only way forward is with downgrade, since you mentioned that you doubted I got it right can you give me any advice ?

did you look at the entrypoint.sh skript of the nc image? the “installation” of nextcloud happens at the start of container.

https://github.com/nextcloud/docker/blob/master/21/apache/entrypoint.sh#L80

the key line is rsync ... /usr/src/nextcloud/ /var/www/html/

this “installs” nextcloud at the start of the container. normally (e.g. mariadb, postgres) this would be done in a Dockerfile when you build the image.

it installs the nc version only if the present one (in /var/www/html/) is older. that’s how you get an update.

so. if you launch all images needed to run nextcloud on an “empty host” you’ll get a fresh nextcloud installation. “ready to login”.

this “stack” you have to shutdown. stop all container.

now you have to do a restore:

  • restore the nextcloud data folder
  • restore the database
  • restore the nextcloud “code” folder (in the container /var/www/html/)

the last step will “downgrade” nextcloud. because you copy your nc version into the “code” folder.

so now on startup the entrypoint.sh script will update your nc. to my knowledge you can’t update from nc17 to nc20 direct. you have to do it step by step. nc17 → nc18 → nc19 → nc20.

1 Like