docker icon indicating copy to clipboard operation
docker copied to clipboard

Why is my instance trying to install NextCloud after upgrade?

Open jakubgs opened this issue 3 years ago • 27 comments

I've just upgraded to nextcloud:23.0.0-apache and after first restart it worked fine, but after that every restart fails to start NextCloud.

When I check the status it appears as not installed:

 > docker exec -u 33 nextcloud-app php occ status
Nextcloud is not installed - only a limited number of commands are available
  - installed: false
  - version: 23.0.0.10
  - versionstring: 23.0.0
  - edition: 
  - maintenance: false
  - needsDbUpgrade: false
  - productname: Nextcloud
  - extendedSupport: false

But my database is in place and intact:

nextcloud=# SELECT count(*) FROM pg_catalog.pg_tables WHERE tableowner = 'oc_admin';
 count 
-------
   126
(1 row)

And my data is still there:

nextcloud=# SELECT count(*) FROM oc_users;
 count 
-------
    42
(1 row)

So what is happening?

jakubgs avatar Jan 25 '22 15:01 jakubgs

If I try to run php occ maintenance:install by hand it fails with:

Error while trying to initialise the database: An exception occurred while executing a query:
SQLSTATE[42P07]: Duplicate table: 7 ERROR:  relation "oc_migrations" already exists

So how is this supposed to work?

jakubgs avatar Jan 25 '22 15:01 jakubgs

I found the installation called by php occ maintenance:install is performed by this file: https://github.com/nextcloud/server/blob/v23.0.0/core/Command/Maintenance/Install.php

jakubgs avatar Jan 25 '22 16:01 jakubgs

But it appears the actual installation is performed here: https://github.com/nextcloud/server/blob/v23.0.0/lib/private/Setup.php#L278

jakubgs avatar Jan 25 '22 16:01 jakubgs

But what interests me is how the installed status is detected:

	'installed' => $this->config->getSystemValueBool('installed', false),

https://github.com/nextcloud/server/blob/0619207f13792250aea775a2c3133d41ab625980/core/Command/Status.php#L58

jakubgs avatar Jan 25 '22 16:01 jakubgs

Based on lines like this it just appears to be line in the PHP config:

cat > ./tests/autoconfig-pgsql.php <<DELIM
<?php
\$AUTOCONFIG = array (
  'installed' => false,
  'dbtype' => 'pgsql',

https://github.com/nextcloud/server/blob/0619207f13792250aea775a2c3133d41ab625980/tests/travis/install.sh#L72-L76

jakubgs avatar Jan 25 '22 16:01 jakubgs

As far as I can tell the /var/www/html/config/config.php file is generated at startup.

I tried creating a /usr/src/nextcloud/config/install.config.php file with contents like this:

<?php
$CONFIG = array (
  'installed' => true,
);

But that didn't change anything. This is very confusing.

jakubgs avatar Jan 25 '22 16:01 jakubgs

The installed value doesn't appear to be part of the config definition: https://github.com/nextcloud/server/blob/v23.0.0/lib/private/SystemConfig.php

jakubgs avatar Jan 25 '22 17:01 jakubgs

I don't get where $this->config->getSystemValueBool('installed', false) is supposed to come from...

jakubgs avatar Jan 25 '22 17:01 jakubgs

I found this, which shows how $AUTOCONFIG values from autoconfig.php are loaded:

	public function loadAutoConfig($post) {
		if (file_exists($this->autoConfigFile)) {
			\OCP\Util::writeLog('core', 'Autoconfig file found, setting up Nextcloud…', ILogger::INFO);
			$AUTOCONFIG = [];
			include $this->autoConfigFile;
			$post = array_merge($post, $AUTOCONFIG);
		}

https://github.com/nextcloud/server/blob/v23.0.0/core/Controller/SetupController.php#L130-L136

jakubgs avatar Jan 26 '22 17:01 jakubgs

I tried creating my own config.php based off of sample.config.php, but now I'm getting this:

It looks like you are trying to reinstall your Nextcloud.
However the file CAN_INSTALL is missing from your config directory. 
Please create the file CAN_INSTALL in your config folder to continue.

I do not want to install anything, I just want it to start. This is baffling behavior.

How can I stop it from trying to install things and just have it start.

jakubgs avatar Jan 26 '22 18:01 jakubgs

This page appears to be coming from core/templates/installation_forbidden.php which is used in displaySetupForbidden():

	private function displaySetupForbidden() {
		\OC_Template::printGuestPage('', 'installation_forbidden');
	}

https://github.com/nextcloud/server/blob/v23.0.0/core/Controller/SetupController.php#L89-L91

Which is used in every call to SetupController->run():

		if (!is_file(\OC::$configDir.'/CAN_INSTALL')) {
			$this->displaySetupForbidden();
			return;
		}

https://github.com/nextcloud/server/blob/v23.0.0/core/Controller/SetupController.php#L67-L70

jakubgs avatar Jan 26 '22 19:01 jakubgs

And it looks like the attempt to run setup is executed at every call to handleRequest():

	public static function handleRequest() {
		\OC::$server->getEventLogger()->start('handle_request', 'Handle request');
		$systemConfig = \OC::$server->getSystemConfig();

		// Check if Nextcloud is installed or in maintenance (update) mode
		if (!$systemConfig->getValue('installed', false)) {
			\OC::$server->getSession()->clear();
			$setupHelper = new OC\Setup(
				$systemConfig,
				\OC::$server->get(\bantu\IniGetWrapper\IniGetWrapper::class),
				\OC::$server->getL10N('lib'),
				\OC::$server->query(\OCP\Defaults::class),
				\OC::$server->get(\Psr\Log\LoggerInterface::class),
				\OC::$server->getSecureRandom(),
				\OC::$server->query(\OC\Installer::class)
			);
			$controller = new OC\Core\Controller\SetupController($setupHelper);
			$controller->run($_POST);
			exit();
		}

https://github.com/nextcloud/server/blob/v23.0.0/lib/base.php#L922-L941

And it looks like indeed the installed config value is checked to see if SetupController->run() should be called.

jakubgs avatar Jan 26 '22 19:01 jakubgs

It appears the secret sauce is the presence of these three values together:

  'version' => '23.0.0.10',
  'instanceid' => 'xyz',
  'installed' => true,

And then starting the container with apache2-foreground as entrypoint to avoid any installation/seeding steps.

jakubgs avatar Jan 26 '22 19:01 jakubgs

How are you running the container? It is likely you have run into some oddities with how this container operates.

It works like the following

  1. Container start
  2. Check /var/www/html/version.php
  3. See if /usr/src/nextcloud/version.php is equal or newer
  4. if this is a new version, copy /usr/src/nextcloud into /var/www/html
  5. continue with upgrade

If the /var/www/html isn't persisted with a volume mount, then weird/bad things will happen.

Yes, this is deeply weird/wrong.

especially-relative avatar Feb 09 '22 22:02 especially-relative

Completely agree, this behavior of copying stuff from /usr/src/nextcloud to /var/www/html is very dangerous and could easily lead to someone losing their encryption secret and rest of configuration.

This is why I've made apache2-foreground the entrypoint for the container and run Nginx in a separate container as running multiple services in a single container is quite the anti-pattern.

jakubgs avatar Feb 09 '22 22:02 jakubgs

Completely agree, this behavior of copying stuff from /usr/src/nextcloud to /var/www/html is very dangerous and could easily lead to someone losing their encryption secret and rest of configuration.

This is why I've made apache2-foreground the entrypoint for the container and run Nginx in a separate container as running multiple services in a single container is quite the anti-pattern.

Then you could fpm + nginx?

If your database /var/www/html/config /var/www/html/data /var/www/html/themes intact, you can deploy a new clean one with persistent, and bind mount / copy back the config,data,themes to new persistent root.

martadinata666 avatar Feb 10 '22 03:02 martadinata666

What? I already have it working, also, your suggestion is confusing.

jakubgs avatar Feb 10 '22 14:02 jakubgs

So here is the thing, i used to accidentally remove the persistent webroot or whatever you called, as i always backup that three folder i mentioned, in another accidental peristent webroot i can redeploy without missing anything, as the three folder will determine the nextcloud state

martadinata666 avatar Feb 10 '22 15:02 martadinata666

Yes, I already have it working. My point still stands. Copying things over is a dangerous way to do setup if the files include things like encryption keys.

jakubgs avatar Feb 11 '22 08:02 jakubgs

Well in this case there wouldn't be encryption keys; but it is still bad.

Containers shouldn't be copying their application files to a mounted volume before running it from the mounted volume! It is bad practice!

  1. It Adds a significant amount of time to upgrades.
  2. It complicates systems with multiple replicas.
  3. Potentially adds network overhead (many users have persistent volume mounts served by NFS/Ceph/Gluster/etc)
  4. Increases storage space needed for no advantage.
  5. Adds a unnecessary volume, complicating configuration for no benefit.
  6. if you skip the volume mount and run apache2-foreground it still copies (for no reason!) and utilizes local ephemeral storage.

Why is it like this? I can see two reasons why it was considered to be a good idea.

  1. php-fpm. A webservice(nginix) container needs the static application files, and rsyncing them to a volume is a way to achieve that.
  2. There is a single command run on the old install before the rsync: run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_before. This is generating a list of current addo-ons, so it can check them against add-ons after the rsync/update.

Howerver to these points:

  1. At the very least the non php-fpm images should not do this, like for the mod-php apache image. The rsync could be kept as a optional flag to support a nginix container. The better, more correct solution would be to release a nginix container, with the required Nextcloud static content as a separate tag.
  2. While this is nice, I am not sure it is required. A clean install shouldn't have a massive list of disabled add-ons. Just display the currently disabled add-ons at the end and it would be fine.

Proposed solution:

  1. Get rid of the copy at least for the apache container, but ideally for all of them.
  2. Consider adding a new container tag that runs nginix and has the Nextcloud static content that it needs to serve baked in.
  3. Check the version from config.php in the container.

especially-relative avatar Feb 11 '22 15:02 especially-relative

Well in this case there wouldn't be encryption keys; but it is still bad.

Yes there would, I almost lost mine because of this. I only recovered it because I still had old volumes available.

If I ran docker volume prune I would have been in a bad spot.

jakubgs avatar Feb 14 '22 08:02 jakubgs

There are encryption keys in /var/www/html !? If you're talking about keys in a custom apps directory then that should be its own volume for sure -- that vol will have to persist no matter what the deal is with /var/www/html due to how NC is designed.

especially-relative avatar Feb 14 '22 13:02 especially-relative

I had the same issue. I think the reason was a non-compatible addon when upgrading from v22 to v23 (also my instance has no internet access). After updating the addon manually and restarting, Nextcloud was displayed as installed again.

jaylinski avatar Apr 03 '22 20:04 jaylinski

@jakubgs I had the same issue, what I have done in my case is taking the containers down and removing them entirely with an exception to the volumes/data and then rebuilding using the latest release of NextCloud, I have gone to check why this is happening and from what I have noticed the config.php is messed up

The following environment variables are incorrect:

  • POSTGRES_USER
  • POSTGRES_PASSWORD
  • NEXTCLOUD_TRUSTED_DOMAINS

Those variables are not as configured in my docker-compose, rather as the following:

  • DB username is oc_administrator%
  • DB Password is something random

And I also suggest having an environment variable to state whether this is an existing installation where no reinstallation/installation should be triggered.

IbrahimS2 avatar Jul 10 '22 14:07 IbrahimS2

In my case, I found that something had replaced the instanceid value (and a bunch of other stuff) in the config.php on the persistent volume :facepalm:

Service was restored by re-instating a backup of my config.php file with the correct values.

rossigee avatar Jul 17 '22 01:07 rossigee

I am running into the same issue with It looks like you are trying to reinstall your Nextcloud. However the file CAN_INSTALL is missing from your config directory. Please create the file CAN_INSTALL in your config folder to continue.

Reason is my config.php got blown away, I don't have a backup because I stupidly rm -r /usr/local/www/nextcloud-old/ directory which has the config/config.php folder. 🤦

My current config.php file looks like this:

root@nextcloud:/ # cat /usr/local/www/nextcloud/config/config.php 
<?php
$CONFIG = array (
  'instanceid' => 'id value here, which I don't know how to verify...',
);

What are my choices to get my service back running?

petercdcn avatar Sep 07 '22 14:09 petercdcn

I am running into the same issue with It looks like you are trying to reinstall your Nextcloud. However the file CAN_INSTALL is missing from your config directory. Please create the file CAN_INSTALL in your config folder to continue.

Reason is my config.php got blown away, I don't have a backup because I stupidly rm -r /usr/local/www/nextcloud-old/ directory which has the config/config.php folder. 🤦

My current config.php file looks like this:

root@nextcloud:/ # cat /usr/local/www/nextcloud/config/config.php 
<?php
$CONFIG = array (
  'instanceid' => 'id value here, which I don't know how to verify...',
);

What are my choices to get my service back running?

Next cloud when using online updater provides back up for config.php by default. Thanks Nextcloud for doing this and it saved my butt. haha. Location is here:

cat /mnt/data/updater-snadfnes/backups/nextcloud-23.0.8.1-1662165509/config/config.php Modify the content to match your current install version and updater.secret change to 'updater.release.channel' => 'stable',

After making the change visit the website will prompt you to update. Click on the update button will fix the system.

petercdcn avatar Sep 07 '22 17:09 petercdcn

I am running into the same issue with It looks like you are trying to reinstall your Nextcloud. However the file CAN_INSTALL is missing from your config directory. Please create the file CAN_INSTALL in your config folder to continue. Reason is my config.php got blown away, I don't have a backup because I stupidly rm -r /usr/local/www/nextcloud-old/ directory which has the config/config.php folder. 🤦 My current config.php file looks like this:

root@nextcloud:/ # cat /usr/local/www/nextcloud/config/config.php 
<?php
$CONFIG = array (
  'instanceid' => 'id value here, which I don't know how to verify...',
);

What are my choices to get my service back running?

Next cloud when using online updater provides back up for config.php by default. Thanks Nextcloud for doing this and it saved my butt. haha. Location is here:

cat /mnt/data/updater-snadfnes/backups/nextcloud-23.0.8.1-1662165509/config/config.php Modify the content to match your current install version and updater.secret change to 'updater.release.channel' => 'stable',

After making the change visit the website will prompt you to update. Click on the update button will fix the system.

Thanks for this.

For the sake of generalisation: what you mentioned as /mnt/data is the path-to-nextcloud-data-folder. It was not the same to me.

Then, updater-snadfnes is actually different for everyone. In fact, "snadfness" is very likely your instanceid value.

Cheers,

diyoyo avatar Oct 14 '22 14:10 diyoyo