Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
xnum opened this issue Jun 9, 2024 · 4 comments

Comments

@xnum
Copy link

xnum commented Jun 9, 2024

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
Copy link
Member

nodiscc commented Jun 9, 2024

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
Copy link
Author

xnum commented Jun 9, 2024

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
Copy link
Member

nodiscc commented Jun 9, 2024

Got it.

Related #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:

  • current: redirect to the /install page indicating the permission problems with HTTP code 200 (somehow misleading to automated monitoring, the instance is in fact not fully working)
  • same as above, but with HTTP code 50x. Somehow it feels "wrong" to display to a "working" install page but serve a 50x
  • display an error page (not the /install page) indicating the permission problems, asking to fix these before anything else (with code 50x)

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 ...)

@nodiscc nodiscc added this to the backlog to the future milestone Jun 9, 2024
@xnum
Copy link
Author

xnum commented Jun 9, 2024

I'd like to vote for an error page.

  • If application cache/data isn't writable or its content is corrupted, an error page will be shown to describe the reason.
  • If not and can be identified as a fresh state, redirects to the install page.
  • Otherwise, leads to landing 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.

@nodiscc nodiscc removed the discussion label Jun 9, 2024
@nodiscc nodiscc changed the title Protect installation page when an existing datastore is available Show an error page (instead of the /install page) when data/cache directories are not writable Jun 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants