]> git.openstreetmap.org Git - nominatim.git/blob - docs/admin/Deployment-Python.md
e95df00dbe235341a3e2c5434880f67426b73360
[nominatim.git] / docs / admin / Deployment-Python.md
1 # Deploying the Nominatim Python frontend
2
3 The Nominatim can be run as a Python-based 
4 [ASGI web application](https://asgi.readthedocs.io/en/latest/). You have the
5 choice between [Falcon](https://falcon.readthedocs.io/en/stable/)
6 and [Starlette](https://www.starlette.io/) as the ASGI framework.
7
8 This section gives a quick overview on how to configure Nginx to serve
9 Nominatim. Please refer to the documentation of
10 [Nginx](https://nginx.org/en/docs/) for background information on how
11 to configure it.
12
13 !!! Note
14     Throughout this page, we assume your Nominatim project directory is
15     located in `/srv/nominatim-project` and you have installed Nominatim
16     using the default installation prefix `/usr/local`. If you have put it
17     somewhere else, you need to adjust the commands and configuration
18     accordingly.
19
20     We further assume that your web server runs as user `www-data`. Older
21     versions of CentOS may still use the user name `apache`. You also need
22     to adapt the instructions in this case.
23
24 ### Installing the required packages
25
26 The recommended way to deploy a Python ASGI application is to run
27 the ASGI runner [uvicorn](https://uvicorn.org/)
28 together with [gunicorn](https://gunicorn.org/) HTTP server. We use
29 Falcon here as the web framework.
30
31 Create a virtual environment for the Python packages and install the necessary
32 dependencies:
33
34 ``` sh
35 sudo apt install virtualenv
36 virtualenv /srv/nominatim-venv
37 /srv/nominatim-venv/bin/pip install SQLAlchemy PyICU psycopg[binary] \
38    psycopg2-binary python-dotenv PyYAML falcon uvicorn gunicorn
39 ```
40
41 ### Setting up Nominatim as a systemd job
42
43 Next you need to set up the service that runs the Nominatim frontend. This is
44 easiest done with a systemd job.
45
46 First you need to tell systemd to create a socket file to be used by
47 hunicorn. Create the following file `/etc/systemd/system/nominatim.socket`:
48
49 ``` systemd
50 [Unit]
51 Description=Gunicorn socket for Nominatim
52
53 [Socket]
54 ListenStream=/run/nominatim.sock
55 SocketUser=www-data
56
57 [Install]
58 WantedBy=multi-user.target
59 ```
60
61 Now you can add the systemd service for Nominatim itself.
62 Create the following file `/etc/systemd/system/nominatim.service`:
63
64 ``` systemd
65 [Unit]
66 Description=Nominatim running as a gunicorn application
67 After=network.target
68 Requires=nominatim.socket
69
70 [Service]
71 Type=simple
72 Environment="PYTHONPATH=/usr/local/lib/nominatim/lib-python/"
73 User=www-data
74 Group=www-data
75 WorkingDirectory=/srv/nominatim-project
76 ExecStart=/srv/nominatim-venv/bin/gunicorn -b unix:/run/nominatim.sock -w 4 -k uvicorn.workers.UvicornWorker nominatim.server.falcon.server:run_wsgi
77 ExecReload=/bin/kill -s HUP $MAINPID
78 StandardOutput=append:/var/log/gunicorn-nominatim.log
79 StandardError=inherit
80 PrivateTmp=true
81 TimeoutStopSec=5
82 KillMode=mixed
83
84 [Install]
85 WantedBy=multi-user.target
86 ```
87
88 This sets up gunicorn with 4 workers (`-w 4` in ExecStart). Each worker runs
89 its own Python process using
90 [`NOMINATIM_API_POOL_SIZE`](../customize/Settings.md#nominatim_api_pool_size)
91 connections to the database to serve requests in parallel.
92
93 Make the new services known to systemd and start it:
94
95 ``` sh
96 sudo systemctl daemon-reload
97 sudo systemctl enable nominatim.socket
98 sudo systemctl start nominatim.socket
99 sudo systemctl enable nominatim.service
100 sudo systemctl start nominatim.service
101 ```
102
103 This sets the service up, so that Nominatim is automatically started
104 on reboot.
105
106 ### Configuring nginx
107
108 To make the service available to the world, you need to proxy it through
109 nginx. Add the following definition to the default configuration:
110
111 ``` nginx
112 upstream nominatim_service {
113   server unix:/run/nominatim.sock fail_timeout=0;
114 }
115
116 server {
117     listen 80;
118     listen [::]:80;
119
120     root /var/www/html;
121     index /search;
122
123     location / {
124             proxy_set_header Host $http_host;
125             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
126             proxy_set_header X-Forwarded-Proto $scheme;
127             proxy_redirect off;
128             proxy_pass http://nominatim_service;
129     }
130 }
131 ```
132
133 Reload nginx with
134
135 ```
136 sudo systemctl reload nginx
137 ```
138
139 and you should be able to see the status of your server under
140 `http://localhost/status`.