mawoka-myblock / ClassQuiz

ClassQuiz is a quiz-application like Kahoot!, but open-source.
https://classquiz.de
Mozilla Public License 2.0
457 stars 83 forks source link

redis.exceptions.ConnectionError #214

Closed MrNonoss closed 1 year ago

MrNonoss commented 1 year ago

Which component is affected?

Redis

Did the issue occur at ClassQuiz.de, or on a self-hosted instance?

On a self-hosted instance

How can the issue be reproduced?

Hi all,

I'm trying to create a self hosting instance to provide some local quizzes, for some "no internet" training rooms. Every containers are starting normally, but I cannot log or create a new account. Each time I try I get an error in the api container:

redis.exceptions.ConnectionError: Error connecting to localhost:6379. Multiple exceptions: [Errno 111] Connection refused, [Errno 99] Cannot assign requested address.

Since the docker-compose file seems to be different from the doc as it does no longer input "STORAGE_BACKEND" options, I added them manually, but not sure it is the right way to do so.

Also, since it is intended to be played locally only, I tried to remove the GitHub and google authentification mechanism from the environment statements, but for back to defaults as it is not working.

Except for the local storage, everything looks as it should be in the docs, and other containers do not show errors in their logs, even redis.

The full api container logs are:

2023-03-01 18:34:42 Checking for script in /app/prestart.sh
2023-03-01 18:34:42 Running script /app/prestart.sh
2023-03-01 18:34:47 {"loglevel": "info", "workers": 1, "bind": "0.0.0.0:80", "graceful_timeout": 120, "timeout": 120, "keepalive": 5, "errorlog": "-", "accesslog": "-", "workers_per_core": 1.0, "use_max_workers": 1, "host": "0.0.0.0", "port": "80"}
2023-03-01 18:34:47 Creating MeiliSearch Index
2023-03-01 18:34:47 Finished MeiliSearch synchronisation
2023-03-01 18:34:47 172.22.0.5:33514 - "GET /socket.io/?EIO=4&transport=polling&t=OQUFQDO HTTP/1.1" 200
2023-03-01 18:34:47 172.22.0.5:33514 - "POST /socket.io/?EIO=4&transport=polling&t=OQUFQoi&sid=3fGH0rMVdtIs9Lv2AAAA HTTP/1.1" 200
2023-03-01 18:34:47 172.22.0.5:33514 - "GET /socket.io/?EIO=4&transport=polling&t=OQUFQoj&sid=3fGH0rMVdtIs9Lv2AAAA HTTP/1.1" 200
2023-03-01 18:34:47 172.22.0.5:33514 - "GET /socket.io/?EIO=4&transport=polling&t=OQUFQou&sid=3fGH0rMVdtIs9Lv2AAAA HTTP/1.1" 200
2023-03-01 18:36:15 172.22.0.5:49108 - "POST /api/v1/login/start HTTP/1.1" 200
2023-03-01 18:34:44 INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
2023-03-01 18:34:44 INFO  [alembic.runtime.migration] Will assume transactional DDL.
2023-03-01 18:34:44 [2023-03-01 17:34:44 +0000] [1] [INFO] Starting gunicorn 20.1.0
2023-03-01 18:34:44 [2023-03-01 17:34:44 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
2023-03-01 18:34:44 [2023-03-01 17:34:44 +0000] [1] [INFO] Using worker: uvicorn.workers.UvicornWorker
2023-03-01 18:34:44 [2023-03-01 17:34:44 +0000] [8] [INFO] Booting worker with pid: 8
2023-03-01 18:34:46 [2023-03-01 17:34:46 +0000] [8] [INFO] Started server process [8]
2023-03-01 18:34:46 [2023-03-01 17:34:46 +0000] [8] [INFO] Waiting for application startup.
2023-03-01 18:34:47 [2023-03-01 17:34:47 +0000] [8] [INFO] Application startup complete.
2023-03-01 18:34:47 [2023-03-01 17:34:47 +0000] [8] [INFO] ('172.22.0.5', 60774) - "WebSocket /socket.io/?EIO=4&transport=websocket&sid=3fGH0rMVdtIs9Lv2AAAA" [accepted]
2023-03-01 18:34:47 [2023-03-01 17:34:47 +0000] [8] [INFO] connection open
2023-03-01 18:35:44 [2023-03-01 17:35:44 +0000] [8] [INFO] connection closed
2023-03-01 18:36:21 [2023-03-01 17:36:21 +0000] [8] [ERROR] Exception in ASGI application
2023-03-01 18:36:21 Traceback (most recent call last):
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/anyio/streams/memory.py", line 94, in receive
2023-03-01 18:36:21     return self.receive_nowait()
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/anyio/streams/memory.py", line 89, in receive_nowait
2023-03-01 18:36:21     raise WouldBlock
2023-03-01 18:36:21 anyio.WouldBlock
2023-03-01 18:36:21 
2023-03-01 18:36:21 During handling of the above exception, another exception occurred:
2023-03-01 18:36:21 
2023-03-01 18:36:21 Traceback (most recent call last):
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 77, in call_next
2023-03-01 18:36:21     message = await recv_stream.receive()
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/anyio/streams/memory.py", line 114, in receive
2023-03-01 18:36:21     raise EndOfStream
2023-03-01 18:36:21 anyio.EndOfStream
2023-03-01 18:36:21 
2023-03-01 18:36:21 During handling of the above exception, another exception occurred:
2023-03-01 18:36:21 
2023-03-01 18:36:21 Traceback (most recent call last):
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 419, in run_asgi
2023-03-01 18:36:21     result = await app(  # type: ignore[func-returns-value]
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
2023-03-01 18:36:21     return await self.app(scope, receive, send)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/fastapi/applications.py", line 270, in __call__
2023-03-01 18:36:21     await super().__call__(scope, receive, send)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/applications.py", line 124, in __call__
2023-03-01 18:36:21 172.22.0.5:56580 - "POST /api/v1/login/step/1?session_id=0dd555cc6b6db8930dd3139f87224ccc HTTP/1.1" 500
2023-03-01 18:36:21     await self.middleware_stack(scope, receive, send)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
2023-03-01 18:36:21     raise exc
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
2023-03-01 18:36:21     await self.app(scope, receive, _send)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/sessions.py", line 86, in __call__
2023-03-01 18:36:21     await self.app(scope, receive, send_wrapper)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 106, in __call__
2023-03-01 18:36:21     response = await self.dispatch_func(request, call_next)
2023-03-01 18:36:21   File "/app/classquiz/__init__.py", line 85, in auth_middleware_wrapper
2023-03-01 18:36:21     return await rememberme_middleware(request, call_next)
2023-03-01 18:36:21   File "/app/classquiz/oauth/__init__.py", line 88, in rememberme_middleware
2023-03-01 18:36:21     response: Response = await call_next(request)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 80, in call_next
2023-03-01 18:36:21     raise app_exc
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 69, in coro
2023-03-01 18:36:21     await self.app(scope, receive_or_disconnect, send_no_error)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 106, in __call__
2023-03-01 18:36:21     response = await self.dispatch_func(request, call_next)
2023-03-01 18:36:21   File "/app/classquiz/__init__.py", line 56, in sentry_exception
2023-03-01 18:36:21     raise e
2023-03-01 18:36:21   File "/app/classquiz/__init__.py", line 50, in sentry_exception
2023-03-01 18:36:21     response = await call_next(request)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 80, in call_next
2023-03-01 18:36:21     raise app_exc
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 69, in coro
2023-03-01 18:36:21     await self.app(scope, receive_or_disconnect, send_no_error)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
2023-03-01 18:36:21     raise exc
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
2023-03-01 18:36:21     await self.app(scope, receive, sender)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
2023-03-01 18:36:21     raise e
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
2023-03-01 18:36:21     await self.app(scope, receive, send)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 706, in __call__
2023-03-01 18:36:21     await route.handle(scope, receive, send)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle
2023-03-01 18:36:21     await self.app(scope, receive, send)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 66, in app
2023-03-01 18:36:21     response = await func(request)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/fastapi/routing.py", line 237, in app
2023-03-01 18:36:21     raw_response = await run_endpoint_function(
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/fastapi/routing.py", line 163, in run_endpoint_function
2023-03-01 18:36:21     return await dependant.call(**values)
2023-03-01 18:36:21   File "/app/classquiz/routers/login.py", line 155, in step_1
2023-03-01 18:36:21     redis_res = await redis.get(f"login_session:{session_id}")
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/redis/asyncio/client.py", line 502, in execute_command
2023-03-01 18:36:21     conn = self.connection or await pool.get_connection(command_name, **options)
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/redis/asyncio/connection.py", line 1396, in get_connection
2023-03-01 18:36:21     await connection.connect()
2023-03-01 18:36:21   File "/usr/local/lib/python3.10/site-packages/redis/asyncio/connection.py", line 608, in connect
2023-03-01 18:36:21     raise ConnectionError(self._error_message(e))
2023-03-01 18:36:21 redis.exceptions.ConnectionError: Error connecting to localhost:6379. Multiple exceptions: [Errno 111] Connection refused, [Errno 99] Cannot assign requested address.

docker-compose environment part are:

    environment:
      DB_URL: "postgresql://postgres:classquiz@db:5432/classquiz"
      MAIL_ADDRESS: "test@test.fr"
      MAIL_PASSWORD: "password"
      MAIL_USERNAME: "test"
      MAIL_SERVER: "smtp.gmail.com"
      MAX_WORKERS: "1" # Very important
      MAIL_PORT: "587"
      SECRET_KEY: "xxxxx73731b6dbf41b0f37a4a323df2567bbccf20fb34db6d6e25faf3xxxxx"
      ACCESS_TOKEN_EXPIRE_MINUTES: 30
      SKIP_EMAIL_VERIFICATION: True
      HCAPTCHA_KEY: "xx0412xx-a71x-xxx8-xx10-35xxxxxa26861"
      MEILISEARCH_URL: "http://meilisearch:7700"
      STORAGE_BACKEND: "local"
      STORAGE_PATH: "/tmp"

frontend/Dockerfile top part is:

# pull the Node.js Docker image
FROM node:19-bullseye as builder
# ENV API_URL=http://api:80
ENV API_URL=https://mawoka.eu
#Ah, I've noticed that!!!
ENV REDIS_URL=redis://localhost:6379
# ENV VITE_MAPBOX_ACCESS_TOKEN=
# This Mapbox-token is restricted to the following urls: classquiz.de, classquiz.mawoka.eu, test.com
ENV VITE_HCAPTCHA=xx0412xx-a71x-xxx8-xx10-35xxxxxa26861
# ENV VITE_SENTRY=https://75cb4ef1be624d8f81bbaf864b722f8a@glitch.mawoka.eu/2
ENV VITE_GOOGLE_AUTH_ENABLED=true
ENV VITE_GITHUB_AUTH_ENABLED=true
ENV VITE_CAPTCHA_ENABLED=true
#ENV VITE_PLAUSIBLE_DATA_URL=
# change working directory
WORKDIR /usr/src/app

If something attract your eyes, I'm willing for inputs. Many thanks for your help.

Describe the bug (with screenshots if possible)

Cannot log in to create account

Device

Desktop

Operating System

iOS

Browser

Safari

mawoka-myblock commented 1 year ago

Thank for your report! Your setup looks fine, except the STORAGE_PATH. I think that it should end with a slash, but that isn't the cause of the problem. The error tells us that the Api-Container can't communicate with the redis-container. I'll do a quick local test. You could run "docker compose ps" in the meantime and check if the redis-container is "up and healthy".

MrNonoss commented 1 year ago

Many thanks for your fast lookup. I can confirm all the containers are up and healthy.

mawoka-myblock commented 1 year ago

That's strange. How familiar are you with docker and Linux?

MrNonoss commented 1 year ago

Quite familiar. I usually am able to troubleshoot myself. However not so comfortable with redis and web development. I will try the same setup on a linux device instead of this Mac.

mawoka-myblock commented 1 year ago

You could try that. You could also go into the api-container bz entering sth like "docker compose exec api /bin/bash" and try pinging a host called "redis". If that doesn't work, try pinging "frontend".

MrNonoss commented 1 year ago

Pinging the host redis or frontend is working fine from the api container

mawoka-myblock commented 1 year ago

Another day, another look at the error. You forgot to set the redis uri. Add the following to the environment section:

REDIS: "redis://redis:6379/0?decode_responses=True"

Sorry for being kinda stupid and not seeing that.

MrNonoss commented 1 year ago

Wooo many thanks. It is working fine. Now I need to understand how to create quiz and select correct answer :)

mawoka-myblock commented 1 year ago

Is that difficult?