|
| 1 | +Packaging 3rd party software as a Nextcloud Application |
| 2 | +======================================================= |
| 3 | + |
| 4 | +This chapter explains how you can package any 3rd party software to be compatible with Nextcloud. |
| 5 | +You should already be familiar with :doc:`NextcloudApp` before reading this part. |
| 6 | + |
| 7 | +You should also have a bit of knowledge about classic PHP Nextcloud apps and `how to develop them <https://docs.nextcloud.com/server/stable/developer_manual/app_development/index.html>`_. |
| 8 | + |
| 9 | +Architecture |
| 10 | +------------ |
| 11 | + |
| 12 | +The packaged ExApp will contain two pieces of software: |
| 13 | + |
| 14 | +#. The ExApp itself which is talking to Nextcloud directly and responsible for the whole lifecycle. |
| 15 | +#. The 3rd party software you want to package. |
| 16 | +#. Frontend code which will be loaded by Nextcloud to display your iframe. |
| 17 | + |
| 18 | +Due to current restrictions of ExApps they can only utilize a single port, which means all requests for the 3rd part software have to be proxied through the ExApp. |
| 19 | +This will be improved in future released, by allowing multiple ports, so that no proxying is necessary anymore. |
| 20 | + |
| 21 | +Everything will be packaged into a single Docker image which will be used for deployments. |
| 22 | +Therefore it is an advantage if the 3rd party software is already able to run inside a Docker container and has a public Docker image available. |
| 23 | + |
| 24 | +Steps |
| 25 | +------------------ |
| 26 | + |
| 27 | +Creating the ExApp |
| 28 | +^^^^^^^^^^^^^^^^^^ |
| 29 | + |
| 30 | +Please follow the instructions in :doc:`NextcloudApp` and then return here. |
| 31 | + |
| 32 | +Adding the frontend |
| 33 | +^^^^^^^^^^^^^^^^^^^ |
| 34 | + |
| 35 | +To be able to access the 3rd party software via the browser it is necessary to embed an iframe into Nextcloud. |
| 36 | +The frontend has to be added in the same way how you add it in a classic PHP app. |
| 37 | +The iframe ``src`` needs to point to ``/apps/app_api/proxy/APP_ID``, but it is necessary to use the ``generateUrl`` method to ensure the path will also work with Nextcloud instances hosted at a sub-path. |
| 38 | +If you require some features like clipboard read/write you need to allow them for the iframe using the ``allow`` attribute. |
| 39 | + |
| 40 | +To now show the frontend inside Nextcloud add the following to your enabled handler: |
| 41 | + |
| 42 | +.. code-block:: python |
| 43 | +
|
| 44 | + def enabled_handler(enabled: bool, nc: NextcloudApp) -> str: |
| 45 | + if enabled: |
| 46 | + nc.ui.resources.set_script("top_menu", "APP_ID", "js/APP_ID-main") |
| 47 | + nc.ui.top_menu.register("APP_ID", "App Name", "img/app.svg") |
| 48 | + else: |
| 49 | + nc.ui.resources.delete_script("top_menu", "APP_ID", "js/APP_ID-main") |
| 50 | + nc.ui.top_menu.unregister("APP_ID") |
| 51 | + return "" |
| 52 | +
|
| 53 | +Proxying the requests |
| 54 | +^^^^^^^^^^^^^^^^^^^^^ |
| 55 | + |
| 56 | +For proxying the requests to the 3rd party software you need to register a new route: |
| 57 | + |
| 58 | +.. code-block:: python |
| 59 | +
|
| 60 | + @APP.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"]) |
| 61 | + async def proxy_requests(request: Request, path: str): |
| 62 | + pass |
| 63 | +
|
| 64 | +This route should have the lowest priority of all your routes, as it catches all requests that didn't match any previous route. |
| 65 | + |
| 66 | +In this request handler you need to send a new HTTP request to the 3rd party software and copy all incoming parameters like sub-path, query parameters, body and headers. |
| 67 | +When returning the response including body, headers and status code, make sure to add or override the CSP and CORS headers if necessary. |
| 68 | + |
| 69 | +Adjusting the Dockerfile |
| 70 | +^^^^^^^^^^^^^^^^^^^^^^^^ |
| 71 | + |
| 72 | +The Dockerfile should be based on the 3rd party software you want to package. |
| 73 | +In case a Docker image is already available you should use that, otherwise you need to first create your own Docker image (it doesn't have to be a separate image, it can just be a stage in the Dockerfile for your ExApp). |
| 74 | + |
| 75 | +The 3rd party software needs to be adapted to be able to handle the proxied requests and generated correct URLs in the frontend. |
| 76 | +Depending on how the software works this might only be a config option you need to set or you need to modify the source code within the Docker image (and potentially rebuild the software afterwards). |
| 77 | +The root path of the software will be hosted at ``/index.php/apps/app_api/proxy/APP_ID`` which is the same location that was configured in the iframe ``src``. |
| 78 | + |
| 79 | +After these steps you can just continue with the normal ExApp Dockerfile steps of installing the dependencies and copying the source code. |
| 80 | +Be aware that you will need to install Python manually in your image in case the Docker image you used so far doesn't include it. |
| 81 | + |
| 82 | +At the end you will have to add a custom entrypoint script that runs the ExApp and the 3rd party software side-by-side to allow them to live in the same container. |
0 commit comments