nextcloud / server

☁️ Nextcloud server, a safe home for all your data
https://nextcloud.com
GNU Affero General Public License v3.0
27.5k stars 4.08k forks source link

Maintenance mode does not invalidate OPcache #37557

Open Martin555 opened 1 year ago

Martin555 commented 1 year ago

⚠️ This issue respects the following points: ⚠️

Bug description

When the maintenance mode gets activated, Nextcloud does not invalidate the OPcache of php. Hence, if the option opcache.validate_timestamps is set to 0, as advised by the official Server tuning manual, the web interface will continue to to be served, instead of the maintenance page.

Steps to reproduce

  1. Set the option opcache.validate_timestamps to 0 via the php configuration
  2. Start or restart the php interpreter (OPcache is populated)
  3. Open the webinterface and log in via any user
  4. Enable the maintenance mode via OCC command or perform a maintenance task, that automatically enables it
  5. Go back to the web interface and navigate around (everything will act like normal, but changes to the DB will of course fail)

Expected behavior

As the software does with changes to the configuration or other php files, enabling the maintenance mode should also invalidate the respective cached code, so the maintenance page is served to the user, the next time he loads a web interface page.

Installation method

Community Docker image

Nextcloud Server version

25

Operating system

Debian/Ubuntu

PHP engine version

PHP 8.0

Web server

Nginx

Database engine version

MySQL

Is this bug present after an update or on a fresh install?

Updated from a minor version (ex. 22.2.3 to 22.2.4)

Are you using the Nextcloud Server Encryption module?

Encryption is Disabled

What user-backends are you using?

Configuration report

{
    "system": {
        "simpleSignUpLink.shown": false,
        "memcache.local": "\\OC\\Memcache\\APCu",
        "apps_paths": [{
                "path": "\/var\/www\/html\/apps",
                "url": "\/apps",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/custom_apps",
                "url": "\/custom_apps",
                "writable": true
            }
        ],
        "loglevel": 2,
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "***REMOVED SENSITIVE VALUE***"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "mysql",
        "version": "24.0.4.1",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbport": "",
        "dbtableprefix": "oc_",
        "mysql.utf8mb4": true,
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "default_language": "de",
        "default_locale": "de",
        "default_phone_region": "DE",
        "mail_smtpmode": "smtp",
        "mail_smtpauthtype": "LOGIN",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "templatedirectory": "\/var\/www\/html\/core\/skeleton\/Templates\/",
        "enabledPreviewProviders": [
            "OC\\Preview\\PNG",
            "OC\\Preview\\JPEG",
            "OC\\Preview\\GIF",
            "OC\\Preview\\BMP",
            "OC\\Preview\\XBitmap",
            "OC\\Preview\\MP3",
            "OC\\Preview\\TXT",
            "OC\\Preview\\MarkDown",
            "OC\\Preview\\OpenDocument",
            "OC\\Preview\\Krita",
            "OC\\Preview\\HEIC"
        ],
        "redis": {
            "host": "***REMOVED SENSITIVE VALUE***",
            "port": "6379",
            "timeout": "1.5",
            "dbindex": "0"
        },
        "memcache.locking": "\\OC\\Memcache\\Redis",
        "memcache.distributed": "\\OC\\Memcache\\Redis"
    }
}

List of activated Apps

Enabled:
  - accessibility: 1.10.0
  - activity: 2.16.0
  - circles: 24.0.1
  - cloud_federation_api: 1.7.0
  - comments: 1.14.0
  - contactsinteraction: 1.5.0
  - dashboard: 7.4.0
  - dav: 1.22.0
  - federatedfilesharing: 1.14.0
  - federation: 1.14.0
  - files: 1.19.0
  - files_pdfviewer: 2.5.0
  - files_rightclick: 1.3.0
  - files_sharing: 1.16.2
  - files_trashbin: 1.14.0
  - files_versions: 1.17.0
  - files_videoplayer: 1.13.0
  - firstrunwizard: 2.13.0
  - logreader: 2.9.0
  - lookup_server_connector: 1.12.0
  - nextcloud_announcements: 1.13.0
  - notifications: 2.12.0
  - notify_push: 0.4.0
  - oauth2: 1.12.0
  - password_policy: 1.14.0
  - photos: 1.6.0
  - privacy: 1.8.0
  - provisioning_api: 1.14.0
  - recommendations: 1.3.0
  - serverinfo: 1.14.0
  - settings: 1.6.0
  - sharebymail: 1.14.0
  - support: 1.7.0
  - survey_client: 1.12.0
  - systemtags: 1.14.0
  - text: 3.5.1
  - twofactor_backupcodes: 1.13.0
  - updatenotification: 1.14.0
  - user_status: 1.4.0
  - viewer: 1.8.0
  - weather_status: 1.4.0
  - workflowengine: 2.6.0
Disabled:
  - admin_audit
  - encryption
  - files_external
  - theming: 1.15.0

Nextcloud Signing status

No errors have been found.

Nextcloud Logs

No response

Additional info

No response

solracsf commented 1 year ago

Well, it is also specified that:

Any change to config.php will then require either restarting PHP, manually clearing the cache, or invalidating this particular script.

This includes enabling maintenance mode. As well as updating apps trough the web interface, etc.

jww-sh commented 1 year ago

why not address the issue with opcache.blacklist_filename and add the path to config.php?

https://www.php.net/manual/en/opcache.configuration.php#:~:text=opcache.blacklist_filename%20string,www/*%2Dbroken.php

joshtrichards commented 1 year ago

The docs are a bit ambiguous, but I'm not sure setting opcache.validate_timestamps = 0 is advised in the Server Tuning section. More just... overly casually mentioned. :-)

I agree though some clarification in the docs is probably in order - particularly maybe about implications for occ maintenance:mode perhaps (PRs welcome - click on "Edit on GitHub" when viewing the docs or head over to https://github.com/nextcloud/documentation).

Anyhow we can't invalidate the opcache from the CLI directly AFAIK. I guess if we had to, we'd have to create some sort of out-of-bound way to have the CLI tell the web app to clear the cache.

If you set opcache.validate_timestamps = 1 and then set opcache.revalidate_freq = X where X is something sane like 2 or 60 then wait X seconds after initiating the maintenance command you'll be golden (and still get the performance benefits).

@jww-sh That's an interesting idea, but I'm not sure the performance implications of never caching a file we refer to quite a lot would be. Someone would need to test that out. That, and keep in mind that just setting opcache.revalidate_freq = 2 (the default in PHP incidentally) would likely achieve near the same result for most people today without much downside.

MichaIng commented 1 year ago

Right, this also affects occ config:set. And the cache cannot be invalidated since CLI and web UI are different PHP instances which have no access to each others OPcache. The CLI by default has no OPcache at all.