papermerge / papermerge-core

In this repository is the source code of Papermerge DMS backend core, REST API server, and frontend UI
https://papermerge.com
Apache License 2.0
293 stars 52 forks source link

How do I run Papermerge on a raspberry pi? #431

Open Urganot opened 1 month ago

Urganot commented 1 month ago

Hi I want to run papermerge in a raspberry pi. But as far as I can tell, there is no image that has the correct architecture/platform "linux/arm64". If I want to pack my own image for this, which repository would I use for this? "papermerge-core" or "papermerge" ?

Urganot commented 1 month ago

I am stuck. I managed to run the container on the raspberry. But now I have the issue that the FE wants to do something" and failes. Can you give me a point on what is wrong here?


2024/08/11 17:44:07 [error] 129#129: *7 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.178.27, server: _, request: "GET /api/users/me HTTP/1.1", upstream: "http://127.0.0.1:8000/users/me", host: "192.168.178.48:12000", referrer: "http://192.168.178.48:12000/"

192.168.178.27 - - [11/Aug/2024:17:44:07 +0000] "GET /api/tags/?page_size=999&page_number=1 HTTP/1.1" 502 559 "http://192.168.178.48:12000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"

192.168.178.27 - - [11/Aug/2024:17:44:07 +0000] "GET /api/users/me HTTP/1.1" 502 559 "http://192.168.178.48:12000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"

For context: "192.168.178.48" is the raspberry pi "port 12000" is the papermerge port "http://127.0.0.1:8000/tags/?page_size=999&page_number=1" is the endpoint the FE tries do something with

Urganot commented 1 month ago

This is the modified docker-compose.yml I am using:


x-backend: &common
  image: urganot/papermerge-raspberry:1.0.8
  environment:
    PAPERMERGE__SECURITY__SECRET_KEY: secret_key
    PAPERMERGE__AUTH__USERNAME: admin
    PAPERMERGE__AUTH__PASSWORD: password
    PAPERMERGE__DATABASE__URL: postgresql://papermerge:db_password@db:5432/papermerge
    PAPERMERGE__REDIS__URL: redis://redis:6379/0
  volumes:
    - index_db:/core_app/index_db
    - media:/core_app/media
  platform: linux/arm64
services:
  web:
    <<: *common
    ports:
     - "12000:80"
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
  worker:
    <<: *common
    command: worker
  redis:
    image: redis:6
    platform: linux/arm64
    healthcheck:
      test: redis-cli --raw incr ping
      interval: 5s
      timeout: 10s
      retries: 5
      start_period: 10s
  db:
    image: postgres:16.4
    platform: linux/arm/v5
    ports:
     - "12001:5432"
     - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      POSTGRES_PASSWORD: db_password
      POSTGRES_DB: papermerge
      POSTGRES_USER: papermerge
    healthcheck:
      test: pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB
      interval: 5s
      timeout: 10s
      retries: 5
      start_period: 10s
volumes:
  postgres_data:
  index_db:
  media:
ciur commented 1 month ago

I can't help here. I am not using raspberry pi.

Urganot commented 1 month ago

Could you help me with the functionality? I get this exception:

Exception in ASGI application
Traceback (most recent call last):
  File "/auth_server_app/.venv/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 428, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/uvicorn/middleware/message_logger.py", line 86, in __call__
    raise exc from None
  File "/auth_server_app/.venv/lib/python3.11/site-packages/uvicorn/middleware/message_logger.py", line 82, in __call__
    await self.app(scope, inner_receive, inner_send)
  File "/auth_server_app/.venv/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/auth_server_app/.venv/lib/python3.11/site-packages/starlette/applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/auth_server_app/.venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/auth_server_app/.venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/auth_server_app/.venv/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/auth_server_app/.venv/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/auth_server_app/.venv/lib/python3.11/site-packages/starlette/routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "/auth_server_app/.venv/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/auth_server_app/.venv/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
               ^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/fastapi/routing.py", line 299, in app
    raise e
  File "/auth_server_app/.venv/lib/python3.11/site-packages/fastapi/routing.py", line 294, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/auth_server/main.py", line 48, in token_endpoint
    user_or_token: None | str | schemas.User = await authenticate(session, **kwargs)
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/auth_server/auth.py", line 38, in authenticate
    return db_auth(session, username, password)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/auth_server/auth.py", line 101, in db_auth
    user: schemas.User | None = db.get_user_by_username(session, username)
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/auth_server/db/users.py", line 32, in get_user_by_username
    db_user = session.scalars(stmt).one()
              ^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2420, in scalars
    return self._execute_internal(
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2190, in _execute_internal
    result: Result[Any] = compile_state_cls.orm_execute_statement(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/orm/context.py", line 293, in orm_execute_statement
    result = conn.execute(
             ^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1416, in execute
    return meth(
           ^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/sql/elements.py", line 517, in _execute_on_connection
    return connection._execute_clauseelement(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1639, in _execute_clauseelement
    ret = self._execute_context(
          ^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1848, in _execute_context
    return self._exec_single_context(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1988, in _exec_single_context
    self._handle_dbapi_exception(
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 2344, in _handle_dbapi_exception
    raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1969, in _exec_single_context
    self.dialect.do_execute(
  File "/auth_server_app/.venv/lib/python3.11/site-packages/sqlalchemy/engine/default.py", line 922, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "core_user" does not exist
LINE 2: FROM core_user 
             ^
[SQL: SELECT core_user.id, core_user.username, core_user.email, core_user.password, core_user.first_name, core_user.last_name, core_user.is_superuser, core_user.is_staff, core_user.is_active, core_user.home_folder_id, core_user.inbox_folder_id, core_user.created_at, core_user.date_joined, core_user.updated_at 
FROM core_user 
WHERE core_user.username = %(username_1)s]
[parameters: {'username_1': 'dfasd'}]
(Background on this error at: https://sqlalche.me/e/20/f405)

If I change the tomfile to require psycopg2 then it works. I dont understand why it doesnt work if its flagged as optional