How to Update Nextcloud in Docker (One Major Version at a Time)

In Docker you update Nextcloud by changing the image tag and recreating the container. The image runs the upgrade itself when it starts, but only one major version at a time, so go 33 to 34 to 35 after a backup, and never jump with latest.

Watch on YouTube · published Nov 3, 2026 · 6:26

In Docker you don't update Nextcloud from inside Nextcloud. You change the image, recreate the container, and the image's start-up script upgrades your data when the new container starts. The one rule: one major version at a time. Pull latest onto a server that is two versions behind and Nextcloud will not start at all.

We filmed every step on Nextcloud in Docker, installed fresh at 33.0.10 and taken to 35.0.2 with the official nextcloud image and PostgreSQL.

How do I update Nextcloud in Docker?

Back up first (below). Then, with docker compose, set the image line to the next major version and recreate the container:

# compose.yaml
services:
  app:
    image: nextcloud:34-apache    # was nextcloud:33-apache

docker compose pull
docker compose up -d
docker compose logs -f app      # watch it upgrade

The new container compares the version in your volume with the version in the image. If the image is newer, it copies in the new files and runs occ upgrade, then starts the web server. While that runs the site does not answer; reload until it does. In our test each step took about a minute on a nearly empty server. Then check Administration → Overview: the Version box shows the new number.

Not using compose? The image's README describes the same thing with plain Docker: pull the image, stop and remove the old container, and start the new one with exactly the same options, volumes and ports included.

Why won't Nextcloud start after I pulled the latest image?

Because latest skipped a major version. In our test, nextcloud:latest was 35.0.2. On the 33 server, the site stopped answering ("This site can't be reached") and the container log said:

Can't start Nextcloud because upgrading from 33.0.10.1 to 35.0.2.2 is not supported.
It is only possible to upgrade one major version at a time. For example, if you want
to upgrade from version 14 to 16, you will have to upgrade from version 14 to 15,
then from 15 to 16.

Nothing was damaged. That check runs before the image copies a single file, so the volume was still 33. We set the image to 34-apache, recreated the container, and it upgraded normally. The README's own example, docker pull nextcloud, pulls latest, which is why this catches people who follow it on an older server.

Why is there no update button?

The Docker image switches the web updater off. On 34.0.5 the Overview page said: "A new version is available: Nextcloud 35.0.2" and, beside it, "Web updater is disabled. Please use the command line updater or the appropriate update mechanism for your installation method (e.g. Docker pull) to update." The page tells you a version exists; the image is how you get it.

Can I go back to the old version?

Not by changing the tag back. With the 34 image on data that had reached 35, the container refused to start: "the version of the data (35.0.2.2) is higher than the docker image version (34.0.5.1) and downgrading is not supported." The only way back is a backup taken before the step. Before each one, stop Nextcloud and copy the volume and the database. For a compose setup with PostgreSQL that looks like this (adjust the service, volume and user names to yours):

docker compose stop app
docker compose exec db pg_dump -U nextcloud nextcloud > nextcloud-db.sql
docker run --rm -v nextcloud:/data -v "$PWD":/backup alpine \
  tar czf /backup/nextcloud-volume.tar.gz -C /data .
# MariaDB/MySQL: docker compose exec db mysqldump -u nextcloud -p nextcloud > nextcloud-db.sql

Our Nextcloud backup guide covers what a backup needs and how to restore it.

Should I use nextcloud:latest?

We wouldn't. Put the major version in the image line, for example nextcloud:34-apache (or 34-fpm). A pull then brings you the fixes for 34, and 35 only arrives when you change the number yourself, after a backup.

What should I check after each upgrade?

  • The start-up log. If an app has no version for the new release, the upgrade disables it, and the image prints "The following apps have been disabled:" followed by the list. Re-enable each one once it supports the new version.
  • Security & setup warnings on Administration → Overview. After 34 to 35 ours listed "Database missing indices". The fix is one command: docker compose exec -u www-data app php occ db:add-missing-indices. Our setup warnings guide covers the rest of that list.

Stuck in maintenance mode after an update?

If an upgrade was interrupted, the site can keep saying "This Nextcloud instance is currently in maintenance mode". Check the log for the error first, then: docker compose exec -u www-data app php occ maintenance:mode --off. If occ status then says the database still needs upgrading, run the upgrade by hand: docker compose exec -u www-data app php occ upgrade.

What about AIO, Snap and plain Linux installs?

  • Nextcloud All-in-One updates its containers from its own admin interface. Don't change the image tags of its containers by hand; follow AIO's own documentation.
  • Snap updates through snap's own refresh mechanism.
  • A plain Linux install uses the built-in updater (web or updater.phar) or replaced files plus occ upgrade. The one-major-version rule is Nextcloud's, not Docker's, so it applies there too.

Sources

More self-hosting guides →

Full video transcript

1
00:00:00,000 --> 00:00:04,028
To update Nextcloud in Docker,
you don't click an update button.

2
00:00:04,068 --> 00:00:09,367
You change the image, recreate the container,
and it upgrades itself when it starts.

3
00:00:09,407 --> 00:00:11,719
But only one major version at a time.

4
00:00:11,759 --> 00:00:16,613
Pull the latest image onto an older
server, and Nextcloud won't start at all.

5
00:00:16,653 --> 00:00:20,148
I'll show you that happening,
and the safe way through.

6
00:00:20,548 --> 00:00:26,028
This is Nextcloud thirty three. It runs in
Docker, on a Linux server I run myself.

7
00:00:26,068 --> 00:00:31,548
Nextcloud thirty five is already out, so
this server is two major versions behind.

8
00:00:31,588 --> 00:00:35,694
That's a common place to be,
and it's where updates go wrong.

9
00:00:36,947 --> 00:00:41,386
Administration, Overview. The
version box says thirty three.

10
00:00:42,611 --> 00:00:47,674
Just below, the update box says your
version is up to date. It isn't the newest.

11
00:00:47,714 --> 00:00:52,880
Thirty five is out. So this box won't
always tell you a new major version exists.

12
00:00:54,125 --> 00:00:59,042
So how do you update it? The Docker image
has its own instructions, on GitHub.

13
00:01:00,299 --> 00:01:03,927
Updating the Nextcloud container
is done by pulling the new image,

14
00:01:03,967 --> 00:01:07,134
throwing away the old container
and starting the new one.

15
00:01:08,368 --> 00:01:12,686
The startup script will check for the
version in your volume and the installed

16
00:01:12,726 --> 00:01:13,524
docker version.

17
00:01:13,564 --> 00:01:17,363
If it finds a mismatch, it automatically
starts the upgrade process.

18
00:01:18,598 --> 00:01:23,423
That's the big idea. In Docker, you don't
update Nextcloud from inside Nextcloud.

19
00:01:23,463 --> 00:01:24,564
You swap the image.

20
00:01:24,604 --> 00:01:29,069
When the new container starts, it sees
your files are older than the image,

21
00:01:29,109 --> 00:01:31,212
and it runs the upgrade on its own.

22
00:01:32,468 --> 00:01:37,306
And then, in bold. It is only possible
to upgrade one major version at a time.

23
00:01:37,346 --> 00:01:41,621
For example, if you want to upgrade
from version fourteen to sixteen,

24
00:01:41,661 --> 00:01:45,248
you will have to upgrade from
version fourteen to fifteen,

25
00:01:45,288 --> 00:01:47,103
then from fifteen to sixteen.

26
00:01:48,372 --> 00:01:49,450
Here's the trap.

27
00:01:49,490 --> 00:01:54,479
The example command on this page pulls
plain nextcloud, with no version.

28
00:01:54,519 --> 00:01:59,369
That means the latest tag. And today,
latest is Nextcloud thirty five.

29
00:01:59,409 --> 00:02:03,530
On a server running thirty
three, that's two jumps at once.

30
00:02:06,001 --> 00:02:11,358
So let's do exactly that. In the compose
file, the image line says nextcloud latest.

31
00:02:11,398 --> 00:02:14,442
Then docker compose pull,
and docker compose up.

32
00:02:14,482 --> 00:02:17,116
That's what I've just run on this server.

33
00:02:18,366 --> 00:02:20,186
Now back to Nextcloud.

34
00:02:21,394 --> 00:02:25,676
This site can't be reached.
Nextcloud isn't there at all.

35
00:02:25,716 --> 00:02:28,900
Not an error page from Nextcloud. Nothing.

36
00:02:30,136 --> 00:02:32,393
The reason is in the container's log.

37
00:02:32,433 --> 00:02:33,759
Can't start Nextcloud,

38
00:02:33,799 --> 00:02:37,981
because upgrading from thirty three
to thirty five is not supported.

39
00:02:38,021 --> 00:02:42,948
It is only possible to upgrade one major
version at a time. The container stops.

40
00:02:42,988 --> 00:02:47,832
If it's set to restart, Docker starts it
again, and it stops again, on a loop.

41
00:02:49,110 --> 00:02:52,057
The good news is that
nothing has changed yet.

42
00:02:52,097 --> 00:02:55,953
That check runs before the new
version copies a single file.

43
00:02:55,993 --> 00:03:00,303
Your server is still thirty three,
untouched. So the fix is simple.

44
00:03:00,343 --> 00:03:03,744
Set the image to the next
major version, thirty four,

45
00:03:03,784 --> 00:03:05,926
and recreate the container again.

46
00:03:08,403 --> 00:03:12,333
Done. This time, the log says
it's upgrading from thirty three.

47
00:03:12,373 --> 00:03:16,682
While the upgrade runs, the site
still doesn't answer. That's normal.

48
00:03:16,722 --> 00:03:19,306
Give it time, and reload until it's back.

49
00:03:20,906 --> 00:03:23,135
It's back. Sign in again.

50
00:03:27,881 --> 00:03:31,655
Then back to Administration,
Overview, to see what changed.

51
00:03:33,359 --> 00:03:36,351
Nextcloud thirty four
point zero point five.

52
00:03:36,391 --> 00:03:40,387
The upgrade ran by itself, when
the new container started.

53
00:03:41,633 --> 00:03:46,470
And look at the update box. A new version
is available, Nextcloud thirty five.

54
00:03:46,510 --> 00:03:49,283
And right beside it.
Web updater is disabled.

55
00:03:49,323 --> 00:03:54,262
Please use the update mechanism for your
installation, for example Docker pull.

56
00:03:55,530 --> 00:03:58,175
That's the same idea from the other side.

57
00:03:58,215 --> 00:04:01,122
In Docker, there's no
update button to press.

58
00:04:01,162 --> 00:04:06,334
At best, Nextcloud tells you a new version
exists. The image is how you get it.

59
00:04:07,589 --> 00:04:08,748
Now the next step.

60
00:04:08,788 --> 00:04:13,716
Change the image to thirty five, and
recreate the container one more time.

61
00:04:14,949 --> 00:04:18,796
Same as before. It upgrades,
and then it answers again.

62
00:04:20,396 --> 00:04:23,253
It's back again. Sign in.

63
00:04:27,304 --> 00:04:29,784
And the overview, one more time.

64
00:04:32,771 --> 00:04:38,761
Thirty five point zero point two. Two
major versions, taken one at a time.

65
00:04:38,801 --> 00:04:41,897
Same files, same database, same users.

66
00:04:43,148 --> 00:04:47,023
After each step, check two
things. First, the startup log.

67
00:04:47,063 --> 00:04:52,626
If an app you use doesn't support the new
version yet, the upgrade switches it off,

68
00:04:52,666 --> 00:04:54,044
and the log lists it.

69
00:04:54,084 --> 00:04:58,364
Second, the security and setup
warnings at the top of this page.

70
00:04:58,404 --> 00:05:04,074
After this upgrade, mine listed missing
database indices. One occ command adds them.

71
00:05:06,580 --> 00:05:11,347
One last test. Say an upgrade goes wrong,
and you want the old version back.

72
00:05:11,387 --> 00:05:14,612
I've put the thirty four
image back on this server.

73
00:05:15,828 --> 00:05:16,472
Gone again.

74
00:05:16,512 --> 00:05:20,325
The log says the version of the
data is higher than the image,

75
00:05:20,365 --> 00:05:22,376
and downgrading is not supported.

76
00:05:22,416 --> 00:05:26,789
Once a step has run, your files and
database belong to the new version.

77
00:05:26,829 --> 00:05:28,818
An older image won't touch them.

78
00:05:30,065 --> 00:05:32,200
So the only way back is a backup.

79
00:05:32,240 --> 00:05:36,023
Before each step, stop the
container, and copy two things.

80
00:05:36,063 --> 00:05:38,594
The Nextcloud volume, and the database.

81
00:05:38,634 --> 00:05:42,615
If a step goes wrong, you restore
both and run the old image.

82
00:05:42,655 --> 00:05:45,754
My video on Nextcloud
backups walks through it.

83
00:05:47,017 --> 00:05:50,294
And to stop this happening by
accident, don't use latest.

84
00:05:50,334 --> 00:05:54,833
Put the major version in the image line.
Thirty four dash apache, for example.

85
00:05:54,873 --> 00:05:57,452
Then a pull brings you
fixes for thirty four,

86
00:05:57,492 --> 00:06:01,974
and the next major version only arrives
when you change that number yourself.

87
00:06:03,842 --> 00:06:06,189
So. In Docker, the image is the update.

88
00:06:06,229 --> 00:06:10,657
Go up one major version at a time,
and check the version after each step.

89
00:06:10,697 --> 00:06:15,125
Back up the volume and the database
first, because there's no going back.

90
00:06:15,165 --> 00:06:18,369
Put the major version in
your image line, not latest.

91
00:06:18,409 --> 00:06:23,367
And check the warnings when it's done.
The commands are on the page linked below.


Related reading