Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docker): replace uwsgi with gunicorn as app server #766

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ ignore_missing_imports = True
[mypy-environ.*]
ignore_missing_imports = True

[mypy-uwsgi.*]
ignore_missing_imports = True

[mypy-xltpl.*]
ignore_missing_imports = True

Expand Down
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ ENV HOME=/home/document-merge-service
ENV PYTHONUNBUFFERED=1
ENV DJANGO_SETTINGS_MODULE=document_merge_service.settings
ENV APP_HOME=/app
ENV UWSGI_INI=/app/uwsgi.ini
ENV MEDIA_ROOT=/var/lib/document-merge-service/media
ENV DATABASE_DIR=/var/lib/document-merge-service/data

Expand Down Expand Up @@ -47,4 +46,4 @@ COPY . $APP_HOME

EXPOSE 8000

CMD /bin/sh -c "poetry run python ./manage.py migrate && poetry run uwsgi"
CMD /bin/sh -c "poetry run python ./manage.py migrate && poetry run gunicorn -c ./document_merge_service/gunicorn.py"
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,29 @@ environment:
- ISOLATE_UNOCONV=true
```

### Custom Gunicorn configuration

Document Merge Service uses [Gunicorn](https://gunicorn.org/) as its app server. A reasonable configuration is included in the docker image. However, if you want to customize your configuration, you may do that by overwriting the file [`document_merge_service/gunicorn.py`](document_merge_service/gunicorn.py) and add your own custom settings:

```dockerfile
FROM ghcr.io/adfinis/document-merge-service:latest

COPY my_gunicorn_config.py /app/document_merge_service/gunicorn.py
```

Such a configuration file might look like this:

```python
# my_gunicorn_config.py

wsgi_app = "document_merge_service.wsgi:application" # must not be changed
bind = "0.0.0.0:80"
workers = 16
timeout = 120
```

For more information on how to customize Gunicorn, please refer to [the official documentation](https://docs.gunicorn.org/en/latest/settings.html).

## Getting started

### Uploading templates
Expand All @@ -55,13 +78,13 @@ curl -H "Content-Type: application/json" --data '{"data": {"test": "Test Input"}
```

### Converting a template

To convert a standalone Docx file the following call can be used:

```bash
curl -X POST --form [email protected] --form target_format="pdf" http://localhost:8000/api/v1/convert > example.pdf
```


## Further reading

- [Configuration](CONFIGURATION.md) - Further configuration and how to do a production setup
Expand Down
1 change: 0 additions & 1 deletion docker-compose.override.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: "3.4"
services:
document-merge-service:
image: ghcr.io/adfinis/document-merge-service:dev
Expand Down
1 change: 0 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: "3.4"
services:
document-merge-service:
image: ghcr.io/adfinis/document-merge-service:latest
Expand Down
12 changes: 7 additions & 5 deletions document_merge_service/api/unoconv.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,18 @@

def get_default_timeout():
timeout = 55
try: # pragma: no cover
import uwsgi
try:
from document_merge_service import gunicorn

harakiri = uwsgi.opt.get("harakiri")
# Default is 30s if not configured explicitly:
# https://docs.gunicorn.org/en/latest/settings.html#timeout
harakiri = getattr(gunicorn, "timeout", 30)
if harakiri:
try:
timeout = max(int(harakiri) - _ahead_of_harakiri, _min_timeout)
except ValueError:
except ValueError: # pragma: no cover
pass
except ModuleNotFoundError:
except ModuleNotFoundError: # pragma: no cover
pass
return timeout

Expand Down
5 changes: 5 additions & 0 deletions document_merge_service/gunicorn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
wsgi_app = "document_merge_service.wsgi:application"
bind = "0.0.0.0:8000"
workers = 8
proc_name = "dms"
timeout = 60
6 changes: 3 additions & 3 deletions document_merge_service/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def default(default_dev=env.NOTSET, default_prod=env.NOTSET):
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.locale.LocaleMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
]

ROOT_URLCONF = "document_merge_service.urls"
Expand Down Expand Up @@ -141,9 +142,8 @@ def parse_admins(admins):

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = "/static/"
STATIC_ROOT = env.str("STATIC_ROOT", None)
STATIC_ROOT = os.path.join(django_root, "staticfiles")

# Media files

Expand All @@ -154,7 +154,7 @@ def parse_admins(admins):
)
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
}
MEDIA_ROOT = env.str("MEDIA_ROOT", "")
Expand Down
47 changes: 36 additions & 11 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ django-storages = "^1.14.3"
djangorestframework = "^3.15.1"
docx-mailmerge = "^0.5.0"
docxtpl = "^0.17.0"
gunicorn = "^22.0.0"
Jinja2 = "^3.1.4"
mysqlclient = { version = "^2.2.4", optional = true }
pillow = "^10.3.0"
Expand All @@ -48,7 +49,7 @@ python-memcached = "^1.59"
requests = "^2.32.3"
sentry-sdk = "^2.3.1"
urllib3 = "^2.2.1"
uWSGI = "^2.0.21"
whitenoise = "^6.6.0"
xltpl = "~0.19"

[tool.poetry.group.dev.dependencies]
Expand Down
71 changes: 0 additions & 71 deletions uwsgi.ini

This file was deleted.

Loading