]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Feature: Switch webserver to granian (#9218)
authorTrenton H <797416+stumpylog@users.noreply.github.com>
Fri, 28 Feb 2025 19:37:45 +0000 (11:37 -0800)
committerGitHub <noreply@github.com>
Fri, 28 Feb 2025 19:37:45 +0000 (19:37 +0000)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
15 files changed:
.github/dependabot.yml
.github/workflows/ci.yml
Dockerfile
Pipfile
Pipfile.lock
docker/rootfs/etc/s6-overlay/s6-rc.d/svc-webserver/run
docs/configuration.md
docs/faq.md
docs/setup.md
docs/troubleshooting.md
docs/usage.md
gunicorn.conf.py [deleted file]
scripts/paperless-webserver.service
src/paperless/workers.py [deleted file]
webserver.py [new file with mode: 0644]

index 1ed22b439d8b9afa398ed1b3207e2ae96c89e350..5ed4aa1dd4affc2f29773fd1fda4d5d88c69e478 100644 (file)
@@ -47,8 +47,6 @@ updates:
     # Add reviewers
     reviewers:
       - "paperless-ngx/backend"
-    ignore:
-      - dependency-name: "uvicorn"
     groups:
       development:
         patterns:
index 5e090a227a7740631dbc09569b8f7c198f3eccb1..419013352824eb45b00e387ff540070f002aec52 100644 (file)
@@ -534,7 +534,7 @@ jobs:
                           LICENSE \
                           README.md \
                           paperless.conf.example \
-                          gunicorn.conf.py
+                          webserver.py
           do
             cp --verbose ${file_name} dist/paperless-ngx/
           done
index f3468b35d13ea9fa6aaeb71803afedf5e8883b06..c124b0fea25e8f588b051cf5a17db38be10e4b53 100644 (file)
@@ -204,11 +204,10 @@ RUN set -eux \
         && rm --force --verbose *.deb \
     && rm --recursive --force --verbose /var/lib/apt/lists/*
 
-# Copy gunicorn config
+# Copy webserver config
 # Changes very infrequently
 WORKDIR /usr/src/paperless/
-
-COPY --chown=1000:1000 gunicorn.conf.py /usr/src/paperless/gunicorn.conf.py
+COPY --chown=1000:1000 webserver.py /usr/src/paperless/webserver.py
 
 WORKDIR /usr/src/paperless/src/
 
diff --git a/Pipfile b/Pipfile
index 361a3a877d56e354dd99e12d38ad2f0d39f9f6af..df13df1fb46429233deb1f98bc5d261a8be63056 100644 (file)
--- a/Pipfile
+++ b/Pipfile
@@ -31,7 +31,7 @@ concurrent-log-handler = "*"
 filelock = "*"
 flower = "*"
 gotenberg-client = "*"
-gunicorn = "*"
+granian = "*"
 httpx-oauth = "*"
 imap-tools = "*"
 inotifyrecursive = "~=0.3"
@@ -55,20 +55,17 @@ scikit-learn = "~=1.6"
 setproctitle = "*"
 tika-client = "*"
 tqdm = "*"
-# See https://github.com/paperless-ngx/paperless-ngx/issues/5494
-uvicorn = {extras = ["standard"], version = "==0.25.0"}
 watchdog = "~=6.0"
 whitenoise = "~=6.9"
 whoosh = "~=2.7"
 zxing-cpp = "*"
 
-
 [dev-packages]
 # Linting
 pre-commit = "*"
 ruff = "*"
-factory-boy = "*"
 # Testing
+factory-boy = "*"
 pytest = "*"
 pytest-cov = "*"
 pytest-django = "*"
index b80cd3e31411066dc1e6fb18a68fea164547c63f..613cc095001f707a735fa7e5bc15530c0ca056e7 100644 (file)
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "4d54b43e6f093a817b2dc9b923f93b889bf7a42cd937ea971cd8773484fc4636"
+            "sha256": "6a6d9178cd8e67dd47711941dadfb785a85da74beefe3eb6dd8e2ae729371fb4"
         },
         "pipfile-spec": 6,
         "requires": {},
             "markers": "python_version >= '3.9'",
             "version": "==0.9.0"
         },
-        "gunicorn": {
-            "hashes": [
-                "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d",
-                "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"
+        "granian": {
+            "hashes": [
+                "sha256:00a1bdd070bd38547b84e70523636a1fca346b721b8ba160feb7e747639976b8",
+                "sha256:029b1ada816400d6daf5dcc89ee16a107d2739158d2376204dfe8a363216fded",
+                "sha256:0efe03f6cf0804f83bd161262a8cb799c78ed8c13401f854bc911e2f3a9cb546",
+                "sha256:0f7562802265f0c3344954ca39eb857426ef15394fa3b571f0a87718a960b588",
+                "sha256:0fc6b439cf6581d5dfc27e0f4fdbda475e2dc096d4e5325a8d1778e990dbf1e7",
+                "sha256:1ca512eae9ce0f8b916ab8defc130daa3107b09fe6e7ba70819ee5631d637d0f",
+                "sha256:1d37f1103d249d06e2562d641fd4a92dc48c4462c7ea4496b9fa61a7b5cfa1e5",
+                "sha256:1f1a3440a1b323acf8a0be131cda5dffb696172a0253960cdbf453b4472dcbfd",
+                "sha256:2acd12b1ebdab7995fd39ec796b0ccae6a1650a0cae4aec29746e3c707ccfa33",
+                "sha256:2f4222003d52e27da03070f72d8fdfa1043c70e2be6491daaae27fe2975c7441",
+                "sha256:30f7242b62cbd6b0ec62fc87686adfe83391f1047c105020fcf514c52c4cddc2",
+                "sha256:3375f1a1d6d9d514dc6cd614262c508b4d232615a98f0d0cddaf092d9bb32661",
+                "sha256:38facbb095c2e4e7c41c3070101fa8ccc1782b26dd6c4f504fca6419cb48b5ae",
+                "sha256:48ba113324096ebce1e5804fcf96a6682a35ed7de81ccc60080d4ff5fd0542ec",
+                "sha256:553422e0ca14d68885c8ab5a592ddea275b1e03f32b07c4b1f9ff5ebdb577f64",
+                "sha256:5d9c1064bb8fc2e80cc9c72956ef889c1dee495b1dddceb51f1bff56b2c641da",
+                "sha256:5e3511680d0045993e192cf24063907265be7f616a92f4cb3884828ff2a2938d",
+                "sha256:5e36d28b947b2c18bc7dc61072b3aa67c28b28d871f55a4daabea8eb6300e50e",
+                "sha256:5fc920bef1704b41da9db12f59818c876916bbeab35a77da9d38a6d0b685d05a",
+                "sha256:63b6697d1725732ecb5610fd9716e9532f70b73c0dbd3d7c4b81d3b0d342c73d",
+                "sha256:63e48fdd7e5744c038bbd8c14690c0203ca6cfdc07c90466866a6dabcf86029e",
+                "sha256:738abe8da012b7d1b8a0e4f101fd748f05dce244637a77247fb2820eb8e8c94a",
+                "sha256:73e69fb2918a94d153feef6ee678084553f22e0c8ca0bc403d72f8ab9fa37bc1",
+                "sha256:7604541dce0fd7073dfee9833d737437d5eb7c00411c7292e99c90ff5a0c3dbb",
+                "sha256:7804d534cf2b5b440930b9fd687b3d2aaa8a8fd78e6327572721d3cc18a7e3e7",
+                "sha256:8a8a24b8807a5672e951a77afed70f178f0680d0ef487cbbec8a14e337a4628f",
+                "sha256:8ac0c2f6c276aefee71f4b5cb52aca01fa2904eb80f93aaa89972ef2f7e61512",
+                "sha256:925971b8bfb5b5064c3fe0f1c6bae370795d415e0f004fa51428eb256dabf0be",
+                "sha256:94a4afbcf16d5bd78f5e278cede8b16150948b22e385533aa6727043a676edf5",
+                "sha256:9781f87bb6e0fe1633bcc6b54d58cc0606f0113752b23a293de137c067258e37",
+                "sha256:97b77d4827971e35245db52e22df22fc570524c0a47434a2e80b80a7c6930d59",
+                "sha256:9ec6facb4523a5bb1da3f124227570d87c92a571a5dae3d4b08be9e9ad0a747f",
+                "sha256:a229d480ce1c7242d56dd1b63737854eed850bc10357773785dd1ff017c7cccb",
+                "sha256:a7bb9783788ce91171554016bc51c2f8994cee8eb8ecb4eb699ce0e6d243d6e7",
+                "sha256:ac123facbde9cea601f633a76767a6e91ce009d7b0837f54cc472881730986b3",
+                "sha256:b09bc979299e5b3c77fcc55ac3f430125e5f4739e139321851f61f4f49aaf490",
+                "sha256:b26888912ebe1a2359862de7c9110a9c508521a34ee75a376a9022d54772d17a",
+                "sha256:b3eb90e46512ebce2b7f36754bf9f45708b0a1df57eba6ceb40ce7c6b50b98de",
+                "sha256:bd3aa566a958194b9e727829e2efc8d4451b415e9df0b9abdf879a79c737c5f1",
+                "sha256:bf5428aa4098473bf446e61ca10432298616484b3b731a480e98004633ea30f3",
+                "sha256:c0f778d28e73a4fadc6dd9d559d32e30700739cb53f71e0f3aa282fee1ec2bdd",
+                "sha256:c1fa2660923d4c27f5a827ad0fcb8156f9213fdcac94fe75f68d502e9c432a92",
+                "sha256:c3c60f8ed1e8c00c63640ff0b52a2c7f9afd0cbbaf873e5ee1e989bbff6829a6",
+                "sha256:c63531136cde284f2bebc14e379d694756b2854f0b30b8755e834982f9673a92",
+                "sha256:ccd74531924313f5fc4079c34361662a565ed856edc0885d90e8dfd2165dbf21",
+                "sha256:e7dbc1f7f3eb795a3c8568e9f46c0a96a400992462d83d64a6c40158fde91f0e",
+                "sha256:f33341347623ee7378dd8776941014bd14d7f055621fc2b0c8286415bcfa9b92",
+                "sha256:f692eac9df4defceabc9ba345c16fc72699df788d6efba081e036880a325b1bd"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.7'",
-            "version": "==23.0.0"
+            "markers": "python_version >= '3.9'",
+            "version": "==1.7.6"
         },
         "h11": {
             "hashes": [
             "markers": "python_version >= '3.8'",
             "version": "==1.0.7"
         },
-        "httptools": {
-            "hashes": [
-                "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a",
-                "sha256:0e563e54979e97b6d13f1bbc05a96109923e76b901f786a5eae36e99c01237bd",
-                "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2",
-                "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17",
-                "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8",
-                "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3",
-                "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5",
-                "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da",
-                "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0",
-                "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721",
-                "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636",
-                "sha256:40dc6a8e399e15ea525305a2ddba998b0af5caa2566bcd79dcbe8948181eeaff",
-                "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0",
-                "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071",
-                "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c",
-                "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4",
-                "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1",
-                "sha256:703c346571fa50d2e9856a37d7cd9435a25e7fd15e236c397bf224afaa355fe9",
-                "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44",
-                "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083",
-                "sha256:85797e37e8eeaa5439d33e556662cc370e474445d5fab24dcadc65a8ffb04003",
-                "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959",
-                "sha256:94978a49b8f4569ad607cd4946b759d90b285e39c0d4640c6b36ca7a3ddf2efc",
-                "sha256:aafe0f1918ed07b67c1e838f950b1c1fabc683030477e60b335649b8020e1076",
-                "sha256:ab9ba8dcf59de5181f6be44a77458e45a578fc99c31510b8c65b7d5acc3cf490",
-                "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660",
-                "sha256:b799de31416ecc589ad79dd85a0b2657a8fe39327944998dea368c1d4c9e55e6",
-                "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c",
-                "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50",
-                "sha256:d1ffd262a73d7c28424252381a5b854c19d9de5f56f075445d33919a637e3547",
-                "sha256:d3f0d369e7ffbe59c4b6116a44d6a8eb4783aae027f2c0b366cf0aa964185dba",
-                "sha256:d54efd20338ac52ba31e7da78e4a72570cf729fac82bc31ff9199bedf1dc7440",
-                "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988",
-                "sha256:db353d22843cf1028f43c3651581e4bb49374d85692a85f95f7b9a130e1b2cab",
-                "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970",
-                "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1",
-                "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2",
-                "sha256:df959752a0c2748a65ab5387d08287abf6779ae9165916fe053e68ae1fbdc47f",
-                "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81",
-                "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069",
-                "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975",
-                "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f",
-                "sha256:fc411e1c0a7dcd2f902c7c48cf079947a7e65b5485dea9decb82b9105ca71a43"
-            ],
-            "markers": "python_full_version >= '3.8.0'",
-            "version": "==0.6.4"
-        },
         "httpx": {
             "extras": [
                 "http2"
             "markers": "python_version >= '3.9'",
             "version": "==2.3.0"
         },
-        "uvicorn": {
-            "extras": [
-                "standard"
-            ],
-            "hashes": [
-                "sha256:6dddbad1d7ee0f5140aba5ec138ddc9612c5109399903828b4874c9937f009c2",
-                "sha256:ce107f5d9bd02b4636001a77a4e74aab5e1e2b146868ebbad565237145af444c"
-            ],
-            "markers": "python_version >= '3.8'",
-            "version": "==0.25.0"
-        },
         "uvloop": {
             "hashes": [
                 "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0",
             "markers": "python_version >= '3.9'",
             "version": "==6.0.0"
         },
-        "watchfiles": {
-            "hashes": [
-                "sha256:02a526ee5b5a09e8168314c905fc545c9bc46509896ed282aeb5a8ba9bd6ca27",
-                "sha256:05d341c71f3d7098920f8551d4df47f7b57ac5b8dad56558064c3431bdfc0b74",
-                "sha256:076f293100db3b0b634514aa0d294b941daa85fc777f9c698adb1009e5aca0b1",
-                "sha256:0799ae68dfa95136dde7c472525700bd48777875a4abb2ee454e3ab18e9fc712",
-                "sha256:0986902677a1a5e6212d0c49b319aad9cc48da4bd967f86a11bde96ad9676ca1",
-                "sha256:0bc80d91ddaf95f70258cf78c471246846c1986bcc5fd33ccc4a1a67fcb40f9a",
-                "sha256:13c2ce7b72026cfbca120d652f02c7750f33b4c9395d79c9790b27f014c8a5a2",
-                "sha256:1941b4e39de9b38b868a69b911df5e89dc43767feeda667b40ae032522b9b5f1",
-                "sha256:1eacd91daeb5158c598fe22d7ce66d60878b6294a86477a4715154990394c9b3",
-                "sha256:229e6ec880eca20e0ba2f7e2249c85bae1999d330161f45c78d160832e026ee2",
-                "sha256:22bb55a7c9e564e763ea06c7acea24fc5d2ee5dfc5dafc5cfbedfe58505e9f90",
-                "sha256:278aaa395f405972e9f523bd786ed59dfb61e4b827856be46a42130605fd0899",
-                "sha256:2a9f93f8439639dc244c4d2902abe35b0279102bca7bbcf119af964f51d53c19",
-                "sha256:308ac265c56f936636e3b0e3f59e059a40003c655228c131e1ad439957592303",
-                "sha256:31f1a379c9dcbb3f09cf6be1b7e83b67c0e9faabed0471556d9438a4a4e14202",
-                "sha256:32b026a6ab64245b584acf4931fe21842374da82372d5c039cba6bf99ef722f3",
-                "sha256:342622287b5604ddf0ed2d085f3a589099c9ae8b7331df3ae9845571586c4f3d",
-                "sha256:39f4914548b818540ef21fd22447a63e7be6e24b43a70f7642d21f1e73371590",
-                "sha256:3f68d8e9d5a321163ddacebe97091000955a1b74cd43724e346056030b0bacee",
-                "sha256:43b168bba889886b62edb0397cab5b6490ffb656ee2fcb22dec8bfeb371a9e12",
-                "sha256:47eb32ef8c729dbc4f4273baece89398a4d4b5d21a1493efea77a17059f4df8a",
-                "sha256:4810ea2ae622add560f4aa50c92fef975e475f7ac4900ce5ff5547b2434642d8",
-                "sha256:4e997802d78cdb02623b5941830ab06f8860038faf344f0d288d325cc9c5d2ff",
-                "sha256:4ebbeca9360c830766b9f0df3640b791be569d988f4be6c06d6fae41f187f105",
-                "sha256:4f8c4998506241dedf59613082d1c18b836e26ef2a4caecad0ec41e2a15e4226",
-                "sha256:55ccfd27c497b228581e2838d4386301227fc0cb47f5a12923ec2fe4f97b95af",
-                "sha256:5717021b199e8353782dce03bd8a8f64438832b84e2885c4a645f9723bf656d9",
-                "sha256:5c11ea22304d17d4385067588123658e9f23159225a27b983f343fcffc3e796a",
-                "sha256:5e0227b8ed9074c6172cf55d85b5670199c99ab11fd27d2c473aa30aec67ee42",
-                "sha256:62c9953cf85529c05b24705639ffa390f78c26449e15ec34d5339e8108c7c407",
-                "sha256:6ba473efd11062d73e4f00c2b730255f9c1bdd73cd5f9fe5b5da8dbd4a717205",
-                "sha256:740d103cd01458f22462dedeb5a3382b7f2c57d07ff033fbc9465919e5e1d0f3",
-                "sha256:74cb3ca19a740be4caa18f238298b9d472c850f7b2ed89f396c00a4c97e2d9ff",
-                "sha256:7b75fee5a16826cf5c46fe1c63116e4a156924d668c38b013e6276f2582230f0",
-                "sha256:7cf684aa9bba4cd95ecb62c822a56de54e3ae0598c1a7f2065d51e24637a3c5d",
-                "sha256:8012bd820c380c3d3db8435e8cf7592260257b378b649154a7948a663b5f84e9",
-                "sha256:857f5fc3aa027ff5e57047da93f96e908a35fe602d24f5e5d8ce64bf1f2fc733",
-                "sha256:8b1f135238e75d075359cf506b27bf3f4ca12029c47d3e769d8593a2024ce161",
-                "sha256:8d0d0630930f5cd5af929040e0778cf676a46775753e442a3f60511f2409f48f",
-                "sha256:90192cdc15ab7254caa7765a98132a5a41471cf739513cc9bcf7d2ffcc0ec7b2",
-                "sha256:95b42cac65beae3a362629950c444077d1b44f1790ea2772beaea95451c086bb",
-                "sha256:9745a4210b59e218ce64c91deb599ae8775c8a9da4e95fb2ee6fe745fc87d01a",
-                "sha256:9d1ef56b56ed7e8f312c934436dea93bfa3e7368adfcf3df4c0da6d4de959a1e",
-                "sha256:9eea33ad8c418847dd296e61eb683cae1c63329b6d854aefcd412e12d94ee235",
-                "sha256:9f25d0ba0fe2b6d2c921cf587b2bf4c451860086534f40c384329fb96e2044d1",
-                "sha256:9fe37a2de80aa785d340f2980276b17ef697ab8db6019b07ee4fd28a8359d2f3",
-                "sha256:a38320582736922be8c865d46520c043bff350956dfc9fbaee3b2df4e1740a4b",
-                "sha256:a462490e75e466edbb9fc4cd679b62187153b3ba804868452ef0577ec958f5ff",
-                "sha256:a5ae5706058b27c74bac987d615105da17724172d5aaacc6c362a40599b6de43",
-                "sha256:aa216f87594f951c17511efe5912808dfcc4befa464ab17c98d387830ce07b60",
-                "sha256:ab0311bb2ffcd9f74b6c9de2dda1612c13c84b996d032cd74799adb656af4e8b",
-                "sha256:ab594e75644421ae0a2484554832ca5895f8cab5ab62de30a1a57db460ce06c6",
-                "sha256:aee397456a29b492c20fda2d8961e1ffb266223625346ace14e4b6d861ba9c80",
-                "sha256:b045c800d55bc7e2cadd47f45a97c7b29f70f08a7c2fa13241905010a5493f94",
-                "sha256:b77d5622ac5cc91d21ae9c2b284b5d5c51085a0bdb7b518dba263d0af006132c",
-                "sha256:ba5bb3073d9db37c64520681dd2650f8bd40902d991e7b4cfaeece3e32561d08",
-                "sha256:bdef5a1be32d0b07dcea3318a0be95d42c98ece24177820226b56276e06b63b0",
-                "sha256:c2acfa49dd0ad0bf2a9c0bb9a985af02e89345a7189be1efc6baa085e0f72d7c",
-                "sha256:c7cce76c138a91e720d1df54014a047e680b652336e1b73b8e3ff3158e05061e",
-                "sha256:cc27a65069bcabac4552f34fd2dce923ce3fcde0721a16e4fb1b466d63ec831f",
-                "sha256:cdbd912a61543a36aef85e34f212e5d2486e7c53ebfdb70d1e0b060cc50dd0bf",
-                "sha256:cdcc92daeae268de1acf5b7befcd6cfffd9a047098199056c72e4623f531de18",
-                "sha256:d3452c1ec703aa1c61e15dfe9d482543e4145e7c45a6b8566978fbb044265a21",
-                "sha256:d6097538b0ae5c1b88c3b55afa245a66793a8fec7ada6755322e465fb1a0e8cc",
-                "sha256:d8d3d9203705b5797f0af7e7e5baa17c8588030aaadb7f6a86107b7247303817",
-                "sha256:e0611d244ce94d83f5b9aff441ad196c6e21b55f77f3c47608dcf651efe54c4a",
-                "sha256:f12969a3765909cf5dc1e50b2436eb2c0e676a3c75773ab8cc3aa6175c16e902",
-                "sha256:f44a39aee3cbb9b825285ff979ab887a25c5d336e5ec3574f1506a4671556a8d",
-                "sha256:f9ce064e81fe79faa925ff03b9f4c1a98b0bbb4a1b8c1b015afa93030cb21a49",
-                "sha256:fb2c46e275fbb9f0c92e7654b231543c7bbfa1df07cdc4b99fa73bedfde5c844",
-                "sha256:fc2eb5d14a8e0d5df7b36288979176fbb39672d45184fc4b1c004d7c3ce29317"
-            ],
-            "markers": "python_version >= '3.9'",
-            "version": "==1.0.4"
-        },
         "wcwidth": {
             "hashes": [
                 "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859",
             ],
             "version": "==0.5.1"
         },
-        "websockets": {
-            "hashes": [
-                "sha256:02687db35dbc7d25fd541a602b5f8e451a238ffa033030b172ff86a93cb5dc2a",
-                "sha256:065ce275e7c4ffb42cb738dd6b20726ac26ac9ad0a2a48e33ca632351a737267",
-                "sha256:091ab63dfc8cea748cc22c1db2814eadb77ccbf82829bac6b2fbe3401d548eda",
-                "sha256:0a52a6d7cf6938e04e9dceb949d35fbdf58ac14deea26e685ab6368e73744e4c",
-                "sha256:0a6f3efd47ffd0d12080594f434faf1cd2549b31e54870b8470b28cc1d3817d9",
-                "sha256:0d8c3e2cdb38f31d8bd7d9d28908005f6fa9def3324edb9bf336d7e4266fd397",
-                "sha256:1979bee04af6a78608024bad6dfcc0cc930ce819f9e10342a29a05b5320355d0",
-                "sha256:1a5a20d5843886d34ff8c57424cc65a1deda4375729cbca4cb6b3353f3ce4142",
-                "sha256:1c9b6535c0e2cf8a6bf938064fb754aaceb1e6a4a51a80d884cd5db569886910",
-                "sha256:1f20522e624d7ffbdbe259c6b6a65d73c895045f76a93719aa10cd93b3de100c",
-                "sha256:2066dc4cbcc19f32c12a5a0e8cc1b7ac734e5b64ac0a325ff8353451c4b15ef2",
-                "sha256:20e6dd0984d7ca3037afcb4494e48c74ffb51e8013cac71cf607fffe11df7205",
-                "sha256:22441c81a6748a53bfcb98951d58d1af0661ab47a536af08920d129b4d1c3473",
-                "sha256:2c6c0097a41968b2e2b54ed3424739aab0b762ca92af2379f152c1aef0187e1c",
-                "sha256:2dddacad58e2614a24938a50b85969d56f88e620e3f897b7d80ac0d8a5800258",
-                "sha256:2e20c5f517e2163d76e2729104abc42639c41cf91f7b1839295be43302713661",
-                "sha256:34277a29f5303d54ec6468fb525d99c99938607bc96b8d72d675dee2b9f5bf1d",
-                "sha256:3bdc8c692c866ce5fefcaf07d2b55c91d6922ac397e031ef9b774e5b9ea42166",
-                "sha256:3c1426c021c38cf92b453cdf371228d3430acd775edee6bac5a4d577efc72365",
-                "sha256:44bba1a956c2c9d268bdcdf234d5e5ff4c9b6dc3e300545cbe99af59dda9dcce",
-                "sha256:4b27ece32f63150c268593d5fdb82819584831a83a3f5809b7521df0685cd5d8",
-                "sha256:4da98b72009836179bb596a92297b1a61bb5a830c0e483a7d0766d45070a08ad",
-                "sha256:4daa0faea5424d8713142b33825fff03c736f781690d90652d2c8b053345b0e7",
-                "sha256:5059ed9c54945efb321f097084b4c7e52c246f2c869815876a69d1efc4ad6eb5",
-                "sha256:577a4cebf1ceaf0b65ffc42c54856214165fb8ceeba3935852fc33f6b0c55e7f",
-                "sha256:647b573f7d3ada919fd60e64d533409a79dcf1ea21daeb4542d1d996519ca967",
-                "sha256:669c3e101c246aa85bc8534e495952e2ca208bd87994650b90a23d745902db9a",
-                "sha256:6af6a4b26eea4fc06c6818a6b962a952441e0e39548b44773502761ded8cc1d4",
-                "sha256:6af99a38e49f66be5a64b1e890208ad026cda49355661549c507152113049990",
-                "sha256:6d7ff794c8b36bc402f2e07c0b2ceb4a2424147ed4785ff03e2a7af03711d60a",
-                "sha256:6f1372e511c7409a542291bce92d6c83320e02c9cf392223272287ce55bc224e",
-                "sha256:714a9b682deb4339d39ffa674f7b674230227d981a37d5d174a4a83e3978a610",
-                "sha256:75862126b3d2d505e895893e3deac0a9339ce750bd27b4ba515f008b5acf832d",
-                "sha256:7a570862c325af2111343cc9b0257b7119b904823c675b22d4ac547163088d0d",
-                "sha256:7a6ceec4ea84469f15cf15807a747e9efe57e369c384fa86e022b3bea679b79b",
-                "sha256:7cd5706caec1686c5d233bc76243ff64b1c0dc445339bd538f30547e787c11fe",
-                "sha256:80c8efa38957f20bba0117b48737993643204645e9ec45512579132508477cfc",
-                "sha256:862e9967b46c07d4dcd2532e9e8e3c2825e004ffbf91a5ef9dde519ee2effb0b",
-                "sha256:86cf1aaeca909bf6815ea714d5c5736c8d6dd3a13770e885aafe062ecbd04f1f",
-                "sha256:89a71173caaf75fa71a09a5f614f450ba3ec84ad9fca47cb2422a860676716f0",
-                "sha256:9f05702e93203a6ff5226e21d9b40c037761b2cfb637187c9802c10f58e40473",
-                "sha256:a39d7eceeea35db85b85e1169011bb4321c32e673920ae9c1b6e0978590012a3",
-                "sha256:a3c4aa3428b904d5404a0ed85f3644d37e2cb25996b7f096d77caeb0e96a3b42",
-                "sha256:a9b0f6c3ba3b1240f602ebb3971d45b02cc12bd1845466dd783496b3b05783a5",
-                "sha256:a9e72fb63e5f3feacdcf5b4ff53199ec8c18d66e325c34ee4c551ca748623bbc",
-                "sha256:ab95d357cd471df61873dadf66dd05dd4709cae001dd6342edafc8dc6382f307",
-                "sha256:ad1c1d02357b7665e700eca43a31d52814ad9ad9b89b58118bdabc365454b574",
-                "sha256:b374e8953ad477d17e4851cdc66d83fdc2db88d9e73abf755c94510ebddceb95",
-                "sha256:b439ea828c4ba99bb3176dc8d9b933392a2413c0f6b149fdcba48393f573377f",
-                "sha256:b4c8cef610e8d7c70dea92e62b6814a8cd24fbd01d7103cc89308d2bfe1659ef",
-                "sha256:bbe03eb853e17fd5b15448328b4ec7fb2407d45fb0245036d06a3af251f8e48f",
-                "sha256:bc63cee8596a6ec84d9753fd0fcfa0452ee12f317afe4beae6b157f0070c6c7f",
-                "sha256:c3ecadc7ce90accf39903815697917643f5b7cfb73c96702318a096c00aa71f5",
-                "sha256:c76193c1c044bd1e9b3316dcc34b174bbf9664598791e6fb606d8d29000e070c",
-                "sha256:c93215fac5dadc63e51bcc6dceca72e72267c11def401d6668622b47675b097f",
-                "sha256:cc45afb9c9b2dc0852d5c8b5321759cf825f82a31bfaf506b65bf4668c96f8b2",
-                "sha256:d7d9cafbccba46e768be8a8ad4635fa3eae1ffac4c6e7cb4eb276ba41297ed29",
-                "sha256:da85651270c6bfb630136423037dd4975199e5d4114cae6d3066641adcc9d1c7",
-                "sha256:dec254fcabc7bd488dab64846f588fc5b6fe0d78f641180030f8ea27b76d72c3",
-                "sha256:e3fbd68850c837e57373d95c8fe352203a512b6e49eaae4c2f4088ef8cf21980",
-                "sha256:e8179f95323b9ab1c11723e5d91a89403903f7b001828161b480a7810b334885",
-                "sha256:e9d0e53530ba7b8b5e389c02282f9d2aa47581514bd6049d3a7cffe1385cf5fe",
-                "sha256:eabdb28b972f3729348e632ab08f2a7b616c7e53d5414c12108c29972e655b20",
-                "sha256:ec607328ce95a2f12b595f7ae4c5d71bf502212bddcea528290b35c286932b12",
-                "sha256:efd9b868d78b194790e6236d9cbc46d68aba4b75b22497eb4ab64fa640c3af56",
-                "sha256:f2e53c72052f2596fb792a7acd9704cbc549bf70fcde8a99e899311455974ca3",
-                "sha256:f390024a47d904613577df83ba700bd189eedc09c57af0a904e5c39624621270",
-                "sha256:f8a86a269759026d2bde227652b87be79f8a734e582debf64c9d302faa1e9f03",
-                "sha256:fd475a974d5352390baf865309fe37dec6831aafc3014ffac1eea99e84e83fc2"
-            ],
-            "markers": "python_version >= '3.9'",
-            "version": "==14.2"
-        },
         "whitenoise": {
             "hashes": [
                 "sha256:8c4a7c9d384694990c26f3047e118c691557481d624f069b7f7752a2f735d609",
index 423b175310d66274d5e6862652636ddd3bb9cf75..5db2e387abb8942c4ed63a883781d3740c7179fd 100755 (executable)
@@ -4,7 +4,7 @@
 cd ${PAPERLESS_SRC_DIR}
 
 if [[ -n "${USER_IS_NON_ROOT}" ]]; then
-       exec /usr/local/bin/gunicorn -c /usr/src/paperless/gunicorn.conf.py paperless.asgi:application
+       exec python3 /usr/src/paperless/webserver.py
 else
-       exec s6-setuidgid paperless /usr/local/bin/gunicorn -c /usr/src/paperless/gunicorn.conf.py paperless.asgi:application
+       exec s6-setuidgid paperless python3 /usr/src/paperless/webserver.py
 fi
index 391b97d137395e4eecc8160f6e652267f7a77272..1a565177eb486629da9343e912916a4569ff78ea 100644 (file)
@@ -1538,13 +1538,23 @@ increase RAM usage.
 
     Defaults to 1.
 
+    !!! note
+
+         This option may also be set with `GRANIAN_WORKERS` and
+         this option may be removed in the future
+
 #### [`PAPERLESS_BIND_ADDR=<ip address>`](#PAPERLESS_BIND_ADDR) {#PAPERLESS_BIND_ADDR}
 
 : The IP address the webserver will listen on inside the container.
 There are special setups where you may need to configure this value
 to restrict the Ip address or interface the webserver listens on.
 
-    Defaults to `[::]`, meaning all interfaces, including IPv6.
+    Defaults to `::`, meaning all interfaces, including IPv6.
+
+    !!! note
+
+         This option may also be set with `GRANIAN_HOST` and
+         this option may be removed in the future
 
 #### [`PAPERLESS_PORT=<port>`](#PAPERLESS_PORT) {#PAPERLESS_PORT}
 
@@ -1559,6 +1569,11 @@ one pod).
 
     Defaults to 8000.
 
+    !!! note
+
+         This option may also be set with `GRANIAN_PORT` and
+         this option may be removed in the future
+
 #### [`USERMAP_UID=<uid>`](#USERMAP_UID) {#USERMAP_UID}
 
 : The ID of the paperless user in the container. Set this to your
index 2572dcf29bcf1e1fd776e862f6cb23a5ecbfb5e3..4dc88fd1b02eda1801c6c0edb8a816a44f991d18 100644 (file)
@@ -133,6 +133,9 @@ Multiple options for ASGI servers exist:
     implementation for ASGI.
 -   `uvicorn` as a standalone server
 
+You may also find the [Django documentation](https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/) on ASGI
+useful to review.
+
 ## _What about the Redis licensing change and using one of the open source forks_?
 
 Currently (October 2024), forks of Redis such as Valkey or Redirect are not officially supported by our upstream
index e337a492a2616de1cbfa261cba9eb1259a23a56f..55b52e3877e20bf6ec5e1f63816782978d78c64f 100644 (file)
@@ -426,31 +426,20 @@ are released, dependency support is confirmed, etc.
 
     !!! note
 
-        The `socket` script enables `gunicorn` to run on port 80 without
+        The `socket` script enables `granian` to run on port 80 without
         root privileges. For this you need to uncomment the
         `Require=paperless-webserver.socket` in the `webserver` script
-        and configure `gunicorn` to listen on port 80 (see
-        `paperless/gunicorn.conf.py`).
-
-    You may need to adjust the path to the `gunicorn` executable. This
-    will be installed as part of the python dependencies, and is either
-    located in the `bin` folder of your virtual environment, or in
-    `~/.local/bin/` if no virtual environment is used.
+        and configure `granian` to listen on port 80 (set `GRANIAN_PORT`).
 
     These services rely on redis and optionally the database server, but
     don't need to be started in any particular order. The example files
     depend on redis being started. If you use a database server, you
     should add additional dependencies.
 
-    !!! warning
-
-        The included scripts run a `gunicorn` standalone server, which is
-        fine for running paperless. It does support SSL, however, the
-        documentation of GUnicorn states that you should use a proxy server
-        in front of gunicorn instead.
+    !!! note
 
-        For instructions on how to use nginx for that,
-        [see the wiki](https://github.com/paperless-ngx/paperless-ngx/wiki/Using-a-Reverse-Proxy-with-Paperless-ngx#nginx).
+        For instructions on using a reverse proxy,
+        [see the wiki](https://github.com/paperless-ngx/paperless-ngx/wiki/Using-a-Reverse-Proxy-with-Paperless-ngx#).
 
     !!! warning
 
index b076baf6b3680787604d2a2e5f4902421280090c..bed8619876fa4bd0edfa6bfef2d65e78bbb63b0c 100644 (file)
@@ -195,34 +195,6 @@ This might have multiple reasons.
     is not, you need to compile the front end yourself or download the
     release archive instead of cloning the repository.
 
-2.  Check the output of the web server. You might see errors like this:
-
-    ```
-    [2021-01-25 10:08:04 +0000] [40] [ERROR] Socket error processing request.
-    Traceback (most recent call last):
-    File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 134, in handle
-        self.handle_request(listener, req, client, addr)
-    File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 190, in handle_request
-        util.reraise(*sys.exc_info())
-    File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 625, in reraise
-        raise value
-    File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 178, in handle_request
-        resp.write_file(respiter)
-    File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 396, in write_file
-        if not self.sendfile(respiter):
-    File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 386, in sendfile
-        sent += os.sendfile(sockno, fileno, offset + sent, count)
-    OSError: [Errno 22] Invalid argument
-    ```
-
-    To fix this issue, add
-
-    ```
-    SENDFILE=0
-    ```
-
-    to your `docker-compose.env` file.
-
 ## Error while reading metadata
 
 You might find messages like these in your log files:
@@ -322,12 +294,12 @@ many documents at once often. Otherwise, try tweaking the
 [`PAPERLESS_DB_TIMEOUT`](configuration.md#PAPERLESS_DB_TIMEOUT) setting to allow more time for the database to
 unlock. This may have minor performance implications.
 
-## gunicorn fails to start with "is not a valid port number"
+## granian fails to start with "is not a valid port number"
 
 You are likely running using Kubernetes, which automatically creates an
 environment variable named `${serviceName}_PORT`. This is
 the same environment variable which is used by Paperless to optionally
-change the port gunicorn listens on.
+change the port granian listens on.
 
 To fix this, set [`PAPERLESS_PORT`](configuration.md#PAPERLESS_PORT) again to your desired port, or the
 default of 8000.
index 027aa4e733e4976bfb952813ec14fa15a21bf5cc..392759bf5fff49fe9ed2e9c7be350710a299f3f1 100644 (file)
@@ -837,7 +837,7 @@ Paperless-ngx consists of the following components:
 
     ```shell-session
     cd /path/to/paperless/src/
-    gunicorn -c ../gunicorn.conf.py paperless.wsgi
+    python3 webserver.py
     ```
 
     or by any other means such as Apache `mod_wsgi`.
diff --git a/gunicorn.conf.py b/gunicorn.conf.py
deleted file mode 100644 (file)
index 0e3878f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-import os
-
-# See https://docs.gunicorn.org/en/stable/settings.html for
-# explanations of settings
-
-bind = f"{os.getenv('PAPERLESS_BIND_ADDR', '[::]')}:{os.getenv('PAPERLESS_PORT', 8000)}"
-
-workers = int(os.getenv("PAPERLESS_WEBSERVER_WORKERS", 1))
-worker_class = "paperless.workers.ConfigurableWorker"
-timeout = 120
-preload_app = True
-
-# https://docs.gunicorn.org/en/stable/faq.html#blocking-os-fchmod
-worker_tmp_dir = "/dev/shm"
-
-
-def pre_fork(server, worker):
-    pass
-
-
-def pre_exec(server):
-    server.log.info("Forked child, re-executing.")
-
-
-def when_ready(server):
-    server.log.info("Server is ready. Spawning workers")
-
-
-def worker_int(worker):
-    worker.log.info("worker received INT or QUIT signal")
-
-    ## get traceback info
-    import sys
-    import threading
-    import traceback
-
-    id2name = {th.ident: th.name for th in threading.enumerate()}
-    code = []
-    for threadId, stack in sys._current_frames().items():
-        code.append(f"\n# Thread: {id2name.get(threadId, '')}({threadId})")
-        for filename, lineno, name, line in traceback.extract_stack(stack):
-            code.append(f'File: "{filename}", line {lineno}, in {name}')
-            if line:
-                code.append(f"  {line.strip()}")
-    worker.log.debug("\n".join(code))
-
-
-def worker_abort(worker):
-    worker.log.info("worker received SIGABRT signal")
index 14df6d5d2663d0eb259573b8c8d44993ad24f612..3d89dd4b4a14056ad6882a13f8bc72a228f07f80 100644 (file)
@@ -9,7 +9,7 @@ Requires=redis.service
 User=paperless
 Group=paperless
 WorkingDirectory=/opt/paperless/src
-ExecStart=/opt/paperless/.local/bin/gunicorn -c /opt/paperless/gunicorn.conf.py paperless.asgi:application
+ExecStart=python3 webserver.py
 
 [Install]
 WantedBy=multi-user.target
diff --git a/src/paperless/workers.py b/src/paperless/workers.py
deleted file mode 100644 (file)
index 0f4a661..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-import os
-
-from django.conf import settings
-from uvicorn.workers import UvicornWorker
-
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "paperless.settings")
-
-
-class ConfigurableWorker(UvicornWorker):
-    CONFIG_KWARGS = {
-        "root_path": settings.FORCE_SCRIPT_NAME or "",
-    }
diff --git a/webserver.py b/webserver.py
new file mode 100644 (file)
index 0000000..4bcbabe
--- /dev/null
@@ -0,0 +1,19 @@
+if __name__ == "__main__":
+    import os
+
+    from granian import Granian
+    from granian.constants import Interfaces
+
+    Granian(
+        "paperless.asgi:application",
+        interface=Interfaces.ASGI,
+        address=os.getenv("GRANIAN_HOST") or os.getenv("PAPERLESS_BIND_ADDR", "::"),
+        port=int(os.getenv("GRANIAN_PORT") or os.getenv("PAPERLESS_PORT") or 8000),
+        workers=int(
+            os.getenv("GRANIAN_WORKERS")
+            or os.getenv("PAPERLESS_WEBSERVER_WORKERS")
+            or 1,
+        ),
+        websockets=True,
+        url_path_prefix=os.getenv("PAPERLESS_FORCE_SCRIPT_NAME"),
+    ).serve()