mirror of
https://github.com/umap-project/umap.git
synced 2025-04-28 19:42:36 +02:00
Update the Dockerfile to expose websockets (#2576)
The Dockerfile now uses ASGI by default (via uvicorn).
This commit is contained in:
commit
6582e85f18
8 changed files with 70 additions and 85 deletions
|
@ -1,10 +1,9 @@
|
||||||
# This part installs deps needed at runtime.
|
# This part installs deps needed at runtime.
|
||||||
FROM python:3.11-slim AS common
|
FROM python:3.11-slim AS runtime
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
tini \
|
tini \
|
||||||
uwsgi \
|
|
||||||
sqlite3 \
|
sqlite3 \
|
||||||
libpq-dev \
|
libpq-dev \
|
||||||
gdal-bin \
|
gdal-bin \
|
||||||
|
@ -14,7 +13,7 @@ RUN apt-get update && \
|
||||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
# This part adds deps needed only at buildtime.
|
# This part adds deps needed only at buildtime.
|
||||||
FROM common AS build
|
FROM runtime AS build
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
|
@ -39,9 +38,9 @@ WORKDIR /srv/umap
|
||||||
|
|
||||||
COPY . /srv/umap
|
COPY . /srv/umap
|
||||||
|
|
||||||
RUN /venv/bin/pip install .[docker,s3]
|
RUN /venv/bin/pip install .[docker,s3,sync]
|
||||||
|
|
||||||
FROM common
|
FROM runtime
|
||||||
|
|
||||||
COPY --from=build /srv/umap/docker/ /srv/umap/docker/
|
COPY --from=build /srv/umap/docker/ /srv/umap/docker/
|
||||||
COPY --from=build /venv/ /venv/
|
COPY --from=build /venv/ /venv/
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
services:
|
services:
|
||||||
|
|
||||||
|
# Usefull only to use the real time collaboration
|
||||||
|
redis:
|
||||||
|
image: redis:latest
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
||||||
|
interval: 1s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
command: ["redis-server"]
|
||||||
|
|
||||||
db:
|
db:
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
|
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
|
||||||
|
@ -14,7 +24,9 @@ services:
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
image: umap/umap:2.0.2
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
image: umap/umap:2.9.3
|
||||||
ports:
|
ports:
|
||||||
- "${PORT-8000}:8000"
|
- "${PORT-8000}:8000"
|
||||||
environment:
|
environment:
|
||||||
|
@ -23,6 +35,8 @@ services:
|
||||||
- SITE_URL=https://umap.local/
|
- SITE_URL=https://umap.local/
|
||||||
- UMAP_ALLOW_ANONYMOUS=True
|
- UMAP_ALLOW_ANONYMOUS=True
|
||||||
- DEBUG=1
|
- DEBUG=1
|
||||||
|
- WEBSOCKET_ENABLED=1
|
||||||
|
- REDIS_URL=redis://redis:6379
|
||||||
volumes:
|
volumes:
|
||||||
- data:/srv/umap/uploads
|
- data:/srv/umap/uploads
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,5 @@ umap collectstatic --noinput
|
||||||
umap wait_for_database
|
umap wait_for_database
|
||||||
# then migrate the database
|
# then migrate the database
|
||||||
umap migrate
|
umap migrate
|
||||||
# run uWSGI
|
# run the server
|
||||||
exec uwsgi --ini docker/uwsgi.ini
|
exec uvicorn --proxy-headers --no-access-log --host 0.0.0.0 umap.asgi:application
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
[uwsgi]
|
|
||||||
http = :$(PORT)
|
|
||||||
home = /venv
|
|
||||||
module = umap.wsgi:application
|
|
||||||
master = True
|
|
||||||
vacuum = True
|
|
||||||
max-requests = 5000
|
|
||||||
processes = 4
|
|
||||||
enable-threads = true
|
|
||||||
static-map = /static=/srv/umap/static
|
|
||||||
static-map = /uploads=/srv/umap/uploads
|
|
||||||
buffer-size = 32768
|
|
||||||
|
|
||||||
; Run the websocket server only when the env variable
|
|
||||||
; WEBSOCKET_ENABLED is set to True.
|
|
||||||
; This is enough for the base docker image, but does not
|
|
||||||
; take into account the settings as the source of truth.
|
|
||||||
if-env = WEBSOCKET_ENABLED
|
|
||||||
websocket_enabled = %(_)
|
|
||||||
endif =
|
|
||||||
|
|
||||||
if-opt = websocket_enabled=True
|
|
||||||
print = Starting the Websocket Server (WEBSOCKET_ENABLED=%(websocket_enabled))
|
|
||||||
attach-daemon = umap run_websocket_server
|
|
||||||
endif =
|
|
||||||
lazy-apps = true
|
|
|
@ -354,52 +354,7 @@ Otherwise, use any valid [python-social-auth configuration](https://python-socia
|
||||||
|
|
||||||
#### WEBSOCKET_ENABLED
|
#### WEBSOCKET_ENABLED
|
||||||
|
|
||||||
A WebSocket server is packaged with uMap, and can be turned-on to activate
|
Setting `WEBSOCKET_ENABLED` to `True` will allow users to enable real-time collaboration.
|
||||||
"real-time collaboration". In practice, in order to enable it, a few settings
|
A switch will be available for them in the "advanced properties" of the map.
|
||||||
are exposed.
|
|
||||||
|
|
||||||
Setting `WEBSOCKET_ENABLED` to `True` will **not** enable real-time
|
See [the documentation about ASGI deployment](../deploy/asgi.md) for more information.
|
||||||
collaboration on all the maps served by the server. Instead, a switch will be
|
|
||||||
available in the "advanced properties" of the map.
|
|
||||||
|
|
||||||
The websocket server can be started with the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
umap run_websocket_server
|
|
||||||
```
|
|
||||||
|
|
||||||
And can take optional settings `--host` and `--port` (default values are defined in
|
|
||||||
the settings).
|
|
||||||
|
|
||||||
Configuration example:
|
|
||||||
|
|
||||||
```python
|
|
||||||
WEBSOCKET_ENABLED = True
|
|
||||||
WEBSOCKET_BACK_HOST = "localhost"
|
|
||||||
WEBSOCKET_BACK_PORT = 8002
|
|
||||||
WEBSOCKET_FRONT_URI = "ws://localhost:8002"
|
|
||||||
```
|
|
||||||
|
|
||||||
These settings can also be set with the (same names) environment variables.
|
|
||||||
|
|
||||||
#### WEBSOCKET_BACK_HOST
|
|
||||||
#### WEBSOCKET_BACK_PORT
|
|
||||||
|
|
||||||
The internal host and port the websocket server will connect to.
|
|
||||||
|
|
||||||
#### WEBSOCKET_FRONT_URI
|
|
||||||
|
|
||||||
The connection string that will be used by the client to connect to the
|
|
||||||
websocket server. In practice, as it's useful to put the WebSocket server behind
|
|
||||||
TLS encryption, the values defined by `WEBSOCKET_FRONT_URI` are different than
|
|
||||||
the values defined by `WEBSOCKET_BACK_PORT` and `WEBSOCKET_BACK_HOST`.
|
|
||||||
|
|
||||||
This value is comprised of three parts:
|
|
||||||
|
|
||||||
```
|
|
||||||
protocol://host:port
|
|
||||||
```
|
|
||||||
|
|
||||||
- `protocol`: can either be `ws` for plain unencrypted WebSockets, or `wss` when using TLS encryption.
|
|
||||||
- `host`: is the address where the connection will be sent. It should be public facing.
|
|
||||||
- `port`: is the port that is open on the host.
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ services:
|
||||||
|
|
||||||
app:
|
app:
|
||||||
# Check https://hub.docker.com/r/umap/umap/tags to find the latest version
|
# Check https://hub.docker.com/r/umap/umap/tags to find the latest version
|
||||||
image: umap/umap:2.0.2
|
image: umap/umap:2.9.3
|
||||||
ports:
|
ports:
|
||||||
# modify the external port (8001, on the left) if desired, but make sure it matches SITE_URL, below
|
# modify the external port (8001, on the left) if desired, but make sure it matches SITE_URL, below
|
||||||
- "8001:8000"
|
- "8001:8000"
|
||||||
|
@ -48,3 +48,45 @@ User accounts can be managed via the Django admin page ({SITE_URL}/admin). The r
|
||||||
```bash
|
```bash
|
||||||
umap createsuperuser
|
umap createsuperuser
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Developping with Docker
|
||||||
|
|
||||||
|
If you want to develop with podman or docker, here are commands that might be useful, given that you have a postgreSQL server running locally and that your settings are located at `umap.conf`:
|
||||||
|
|
||||||
|
You can build the docker image with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
podman build -t umap .
|
||||||
|
```
|
||||||
|
|
||||||
|
And run it with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
podman run -v ./umap.conf:/tmp/umap.conf -e UMAP_SETTINGS=/tmp/umap.conf -it --network host umap
|
||||||
|
```
|
||||||
|
|
||||||
|
## Real time collaboration
|
||||||
|
|
||||||
|
To enable real time collaboration when using Docker, a Redis service must be added. Something like this in `docker-compose.py` world:
|
||||||
|
|
||||||
|
```yaml title="docker-compose.yml"
|
||||||
|
services
|
||||||
|
redis:
|
||||||
|
image: redis:latest
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
||||||
|
…
|
||||||
|
command: ["redis-server"]
|
||||||
|
…
|
||||||
|
app:
|
||||||
|
depends_on:
|
||||||
|
…
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
…
|
||||||
|
environment:
|
||||||
|
- WEBSOCKET_ENABLED=1
|
||||||
|
- REDIS_URL=redis://redis:6379
|
||||||
|
…
|
||||||
|
|
||||||
|
```
|
||||||
|
|
|
@ -65,7 +65,7 @@ test = [
|
||||||
"moto[s3]==5.1.1"
|
"moto[s3]==5.1.1"
|
||||||
]
|
]
|
||||||
docker = [
|
docker = [
|
||||||
"uwsgi==2.0.28",
|
"uvicorn==0.34.0",
|
||||||
]
|
]
|
||||||
s3 = [
|
s3 = [
|
||||||
"django-storages[s3]==1.14.5",
|
"django-storages[s3]==1.14.5",
|
||||||
|
@ -73,6 +73,7 @@ s3 = [
|
||||||
sync = [
|
sync = [
|
||||||
"pydantic==2.11.1",
|
"pydantic==2.11.1",
|
||||||
"redis==5.2.1",
|
"redis==5.2.1",
|
||||||
|
"websockets==15.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|
|
@ -346,4 +346,4 @@ WEBSOCKET_ENABLED = env.bool("WEBSOCKET_ENABLED", default=False)
|
||||||
WEBSOCKET_BACK_HOST = env("WEBSOCKET_BACK_HOST", default="localhost")
|
WEBSOCKET_BACK_HOST = env("WEBSOCKET_BACK_HOST", default="localhost")
|
||||||
WEBSOCKET_BACK_PORT = env.int("WEBSOCKET_BACK_PORT", default=8001)
|
WEBSOCKET_BACK_PORT = env.int("WEBSOCKET_BACK_PORT", default=8001)
|
||||||
|
|
||||||
REDIS_URL = "redis://localhost:6379"
|
REDIS_URL = env("REDIS_URL", default="redis://localhost:6379")
|
||||||
|
|
Loading…
Reference in a new issue