shaarli / Shaarli

The personal, minimalist, super-fast, database free, bookmarking service - community repo
https://shaarli.readthedocs.io/
Other
3.38k stars 287 forks source link

Show an error page (instead of the /install page) when data/cache directories are not writable #2090

Open xnum opened 2 months ago

xnum commented 2 months ago

When I moved the data of Shaarli, which is deployed with docker-compose, I sometimes encountered directory/file permission issues that needed fixing. Before I could address these issues, Shaarli would expose the installation page with a status code of 200. This behavior suggests there might be room for improvement.

  1. If an existing directory/file is detected or if it appears to be an incomplete deployment, Shaarli could display an error page with a status code of 5xx. This would allow automatic monitoring systems to recognize that an issue has occurred.
  2. Under the Nginx configuration, we can add HTTP basic authorization to the /install pages to prevent unauthorized access.

Additionally, I am willing to help create a PR if the core developers favor these features.

nodiscc commented 2 months ago

Hi,

Shaarli could display an error page with a status code of 5xx

Which exact cases should trigger this behavior (instead of showing the usual installation/initial setup page)?

xnum commented 2 months ago

For example I restored the site from a backup. Here is the steps to reproduce, presented as bash shell script:

#!/usr/bin/env bash

# Create a dir to save files of docker compose
mkdir shaarli-docker
cd shaarli-docker

# Create volumes mounted into shaarli
mkdir {cache,data}

# shaarli will access these dirs from UID 1000.
# But sometimes we broke the site and restore it from backup,
# the dir owner becomes root.
# The content inside dir isn't aware in this case.
chown root:root cache data

cat << EOF > docker-compose.yaml
version: '3'

services:
  shaarli:
    container_name: shaarli-docker
    image: ghcr.io/shaarli/shaarli:latest
    restart: unless-stopped
    ports:
      - 5433:80
    volumes:
      - ./cache:/var/www/shaarli/cache
      - ./data:/var/www/shaarli/data
EOF

if command -v docker-compose; then
        docker-compose up -d
else
        docker compose up -d
fi

# Wait for the container ready.
sleep 3

curl -L -s -v -b cookie.txt -c cookie.txt http://localhost:5433 >/dev/null

if command -v docker-compose; then
        docker-compose down
else
        docker compose down
fi

The output looks like:

*   Trying 127.0.0.1:5433...
* Connected to localhost (127.0.0.1) port 5433 (#0)
> GET / HTTP/1.1
> Host: localhost:5433
> User-Agent: curl/7.88.1
> Accept: */*
> Cookie: shaarli=tvq81i50rduc4b8dg436js3hpb
> 
< HTTP/1.1 302 Found
< Server: nginx/1.24.0
< Date: Sun, 09 Jun 2024 10:16:44 GMT
< Content-Type: text/html; charset=UTF-8
< Content-Length: 0
< Connection: keep-alive
< X-Powered-By: PHP/8.2.16
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Last-Modified: Sun, 09 Jun 2024 10:16:44 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Cache-Control: post-check=0, pre-check=0
< Pragma: no-cache
< Location: /install
< 
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:5433/install'
* Found bundle for host: 0x64887c066920 [serially]
* Can not multiplex, even if we wanted to
* Re-using existing connection #0 with host localhost
> GET /install HTTP/1.1
> Host: localhost:5433
> User-Agent: curl/7.88.1
> Accept: */*
> Cookie: shaarli=tvq81i50rduc4b8dg436js3hpb
> 
< HTTP/1.1 200 OK
< Server: nginx/1.24.0
< Date: Sun, 09 Jun 2024 10:16:44 GMT
< Content-Type: text/html; charset=UTF-8
< Content-Length: 107967
< Connection: keep-alive
< X-Powered-By: PHP/8.2.16
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Last-Modified: Sun, 09 Jun 2024 10:16:44 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Cache-Control: post-check=0, pre-check=0
< Pragma: no-cache
< 
{ [32446 bytes data]
* Connection #0 to host localhost left intact

The website content has an error:

Server requirements
Permissions

There are permissions that need to be fixed.

"cache" directory is not writable
"data" directory is not writable

So, there was an existing datastore with improper permission setting. Some application such as database, would crash and forbid to serve. But shaarli redirects to /install and returns 200, which would be detected as operational in monitoring system.

nodiscc commented 2 months ago

Got it.

Related https://github.com/shaarli/Shaarli/issues/2073

I don't know which behavior would be correct, we should check in the code which condition led to the 302 redirect in the first place... if this is caused by the cache/date directories being detected as unwritable, these are the possible behavior we should consider:

Another possibility is to add a /status page/API endpoint indicating the instance status and returning 50x for anything else than a fully configured, working instance (installed=200, permission-error=500, unconfigured=500 ...)

xnum commented 2 months ago

I'd like to vote for an error page.

Considering a public site, we usually see a lean error page when the site is down. On the contrary, showing an install page may be weird. Actually, I've hosted one, and it was a bit awkward to show the install page for days until I found out it was not working.

A status page is also a good idea. We could enable the health check function in Docker to check status promptly.