diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1ed22b439..5ed4aa1dd 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -47,8 +47,6 @@ updates: # Add reviewers reviewers: - "paperless-ngx/backend" - ignore: - - dependency-name: "uvicorn" groups: development: patterns: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e090a227..419013352 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/Dockerfile b/Dockerfile index f3468b35d..c124b0fea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 361a3a877..df13df1fb 100644 --- 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 = "*" diff --git a/Pipfile.lock b/Pipfile.lock index b80cd3e31..613cc0950 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "4d54b43e6f093a817b2dc9b923f93b889bf7a42cd937ea971cd8773484fc4636" + "sha256": "6a6d9178cd8e67dd47711941dadfb785a85da74beefe3eb6dd8e2ae729371fb4" }, "pipfile-spec": 6, "requires": {}, @@ -696,14 +696,60 @@ "markers": "python_version >= '3.9'", "version": "==0.9.0" }, - "gunicorn": { + "granian": { "hashes": [ - "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d", - "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec" + "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": [ @@ -852,55 +898,6 @@ "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" @@ -2459,17 +2456,6 @@ "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", @@ -2558,83 +2544,6 @@ "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", @@ -2649,81 +2558,6 @@ ], "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", diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/svc-webserver/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/svc-webserver/run index 423b17531..5db2e387a 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/svc-webserver/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/svc-webserver/run @@ -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 diff --git a/docs/configuration.md b/docs/configuration.md index 391b97d13..1a565177e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -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=`](#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=`](#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=`](#USERMAP_UID) {#USERMAP_UID} : The ID of the paperless user in the container. Set this to your diff --git a/docs/faq.md b/docs/faq.md index 2572dcf29..4dc88fd1b 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -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 diff --git a/docs/setup.md b/docs/setup.md index e337a492a..55b52e387 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -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 + !!! note - 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. - - 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 diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index b076baf6b..bed861987 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -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. diff --git a/docs/usage.md b/docs/usage.md index 027aa4e73..392759bf5 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -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 index 0e3878f8b..000000000 --- a/gunicorn.conf.py +++ /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") diff --git a/scripts/paperless-webserver.service b/scripts/paperless-webserver.service index 14df6d5d2..3d89dd4b4 100644 --- a/scripts/paperless-webserver.service +++ b/scripts/paperless-webserver.service @@ -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 index 0f4a66149..000000000 --- a/src/paperless/workers.py +++ /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 index 000000000..4bcbabe4c --- /dev/null +++ b/webserver.py @@ -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()