|
| 1 | +# **Hosting SQLPage Behind a Reverse Proxy** |
| 2 | + |
| 3 | +Hosting SQLPage behind a reverse proxy can help with security, scalability, and flexibility. |
| 4 | +In this guide, we will guide you step-by-step on how to host SQLPage behind a reverse proxy using |
| 5 | +[NGINX](https://www.nginx.com/). |
| 6 | + |
| 7 | +## Why host SQLPage behind a Reverse Proxy ? |
| 8 | + |
| 9 | +Here are some reasons why you might want to host SQLPage behind a reverse proxy: |
| 10 | + |
| 11 | + - **customize your application's URLs**, removing `.sql` extensions and changing URL parameters |
| 12 | + - **protect against attacks** such as denial-of-service (DoS) by rate limiting incoming requests |
| 13 | + - **improve performance** by caching responses and serving static files without involving SQLPage |
| 14 | + - **enable HTTPS** on the front-end, even when SQLPage is running on HTTP |
| 15 | + - **host multiple applications** or multiple instances of SQLPage on the same server |
| 16 | + |
| 17 | +## Prerequisites |
| 18 | + |
| 19 | +Before you begin, you will need the following: |
| 20 | + |
| 21 | + - A server running SQLPage. In this guide, we will assume SQLPage is running on `localhost:8080` |
| 22 | + - Nginx installed on your server. On Ubuntu, you can install NGINX using `sudo apt install nginx` |
| 23 | + - A domain name pointing to your server (optional) |
| 24 | + - An SSL certificate obtained from Certbot (optional) |
| 25 | + |
| 26 | +## Configuring the Reverse Proxy |
| 27 | + |
| 28 | +Nginx is configured using multiple files. The main configuration file is usually located at `/etc/nginx/nginx.conf`, and additional configuration files are located in the `/etc/nginx/sites-available/` directory. To host SQLPage behind a reverse proxy, you will need to create a new configuration file in the `/etc/nginx/sites-available/` directory, and then create a symbolic link to it in the `/etc/nginx/sites-enabled/` directory. |
| 29 | + |
| 30 | +Create a file named `sqlpage` in the `/etc/nginx/sites-available/` directory: |
| 31 | +```bash |
| 32 | +sudo nano /etc/nginx/sites-available/sqlpage |
| 33 | +``` |
| 34 | + |
| 35 | +Add the following configuration to the file: |
| 36 | + |
| 37 | +```nginx |
| 38 | +http { |
| 39 | + server { |
| 40 | + listen 80; |
| 41 | + server_name example.com; |
| 42 | +
|
| 43 | + location / { |
| 44 | + proxy_pass http://localhost:8080; |
| 45 | + proxy_http_version 1.1; |
| 46 | + proxy_set_header Upgrade $http_upgrade; |
| 47 | + proxy_set_header Connection 'upgrade'; |
| 48 | + proxy_set_header Host $host; |
| 49 | + proxy_cache_bypass $http_upgrade; |
| 50 | + } |
| 51 | + } |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +Save the file and create a symbolic link to it in the `/etc/nginx/sites-enabled/` directory: |
| 56 | +```bash |
| 57 | +sudo ln -s /etc/nginx/sites-available/sqlpage /etc/nginx/sites-enabled/sqlpage |
| 58 | +``` |
| 59 | + |
| 60 | +Test the configuration and reload NGINX: |
| 61 | +```bash |
| 62 | +sudo nginx -t |
| 63 | +sudo systemctl reload nginx |
| 64 | +``` |
| 65 | + |
| 66 | +Your SQLPage instance is now hosted behind a reverse proxy using NGINX. You can access it by visiting `http://example.com`. |
| 67 | + |
| 68 | +### URL Rewriting |
| 69 | + |
| 70 | +URL rewriting is a powerful feature that allows you to manipulate URLs to make them more readable, search-engine-friendly, and easy to maintain. |
| 71 | +In this section, we will cover how to use URL rewriting with SQLPage. |
| 72 | + |
| 73 | +#### Example: Rewriting `/products/$id` to `/products.sql?id=$id` |
| 74 | + |
| 75 | +Let's say you want your users to access product details using URLs like `/products/123` instead of `/products.sql?id=123`. This can be achieved using the `rewrite` directive in NGINX. |
| 76 | + |
| 77 | +Here is an example configuration: |
| 78 | + |
| 79 | +```nginx |
| 80 | +http { |
| 81 | + server { |
| 82 | + listen 80; |
| 83 | + server_name example.com; |
| 84 | +
|
| 85 | + location / { |
| 86 | + proxy_pass http://localhost:8080; |
| 87 | + proxy_http_version 1.1; |
| 88 | + proxy_set_header Upgrade $http_upgrade; |
| 89 | + proxy_set_header Connection 'upgrade'; |
| 90 | + proxy_set_header Host $host; |
| 91 | + proxy_cache_bypass $http_upgrade; |
| 92 | + } |
| 93 | +
|
| 94 | + location /products/ { |
| 95 | + rewrite ^/products/([^/]+)$ /products.sql?id=$1 last; |
| 96 | + } |
| 97 | + } |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +This configuration uses the `rewrite` directive to rewrite URLs of the form `/products/$id` to `/products.sql?id=$id`. The `^/products/([^/]+)$` pattern matches URLs that start with `/products/` and captures the dynamic parameter `$id` using parentheses. The `last` flag indicates that this rewrite rule should be the last one to be applied; if the pattern matches, the rewritten URL is passed to the next location block, |
| 102 | +in this case, the proxy_pass directive. |
| 103 | + |
| 104 | +**How it Works** |
| 105 | + |
| 106 | +When a request is made to `/products/123`, the rewrite rule is triggered, and the URL is rewritten to `/products.sql?id=123`. The `proxy_pass` directive then forwards the rewritten URL to the SQLPage instance, which processes the request and returns the response. |
| 107 | + |
| 108 | +#### Example: Removing `.sql` Extension from URLs |
| 109 | + |
| 110 | +Let's say you want to remove the `.sql` extension from all URLs to make them cleaner and more user-friendly. This can be achieved using the `rewrite` directive in NGINX. |
| 111 | + |
| 112 | +```nginx |
| 113 | + location / { |
| 114 | + |
| 115 | + # When a request doesn't end with a '/' and doesn't have an extension, add '.sql' at the end |
| 116 | + rewrite ^/((.*/)?[^/.]+)$ /$1.sql last; |
| 117 | + |
| 118 | + proxy_pass http://localhost:8080; |
| 119 | + } |
| 120 | +``` |
| 121 | + |
| 122 | +### Hosting Multiple Applications |
| 123 | + |
| 124 | +You may want to use the same web server to host SQLPage together with |
| 125 | +another application such as a blog, a different website, or another instance of SQLPage. |
| 126 | +In this section, we will cover how to host multiple applications behind a reverse proxy using NGINX. |
| 127 | + |
| 128 | +#### Example: Hosting Two Applications with Different domain names |
| 129 | + |
| 130 | +Let's say you want to host two separate instances of SQLPage on the same server, each accessible via a different domain name: `app1.example.com` and `app2.example.com`. This can be achieved by creating two separate configuration files in the `/etc/nginx/sites-available/` directory and then creating symbolic links to them in the `/etc/nginx/sites-enabled/` directory. |
| 131 | + |
| 132 | +Create `/etc/nginx/sites-available/app1`, and `/etc/nginx/sites-available/app2` configuration files, |
| 133 | +and add the following configuration to each file, replacing `localhost:8080` and `app1.example.com` with the appropriate values: |
| 134 | + |
| 135 | +```nginx |
| 136 | +http { |
| 137 | + server { |
| 138 | + listen 80; |
| 139 | + server_name app1.example.com; |
| 140 | +
|
| 141 | + location / { |
| 142 | + proxy_pass http://localhost:8080; |
| 143 | + } |
| 144 | + } |
| 145 | +} |
| 146 | +``` |
| 147 | +Then create symbolic links to the configuration files in the `/etc/nginx/sites-enabled/` directory. |
| 148 | + |
| 149 | +#### Hosting on a Subpath |
| 150 | + |
| 151 | +You may have multiple applications to host, but a single domain name to use. In this case, you can host each application on a different subpath of the domain name, for example, `example.com/app1` and `example.com/app2`. |
| 152 | + |
| 153 | +To host SQLPage on a subpath, you can use a single NGINX configuration file with a `location` block that specifies the subpath: |
| 154 | + |
| 155 | +```nginx |
| 156 | +http { |
| 157 | + ... |
| 158 | + upstream sqlpage { |
| 159 | + server localhost:8080; |
| 160 | + } |
| 161 | +
|
| 162 | + server { |
| 163 | + listen 80; |
| 164 | + server_name example.com; |
| 165 | +
|
| 166 | + location /sqlpage { |
| 167 | + proxy_pass http://sqlpage; |
| 168 | + } |
| 169 | + } |
| 170 | +} |
| 171 | +``` |
| 172 | +This configuration sets up a reverse proxy that forwards incoming requests from `example.com/sqlpage` to `localhost:8080`, where SQLPage is running. |
| 173 | + |
| 174 | +And in the SQLPage configuration file, at `./sqlpage/sqlpage.json`, |
| 175 | +you can specify the base URL as `/sqlpage`: |
| 176 | + |
| 177 | +```json |
| 178 | +{ |
| 179 | + "site_prefix": "/sqlpage" |
| 180 | +} |
| 181 | +``` |
| 182 | + |
| 183 | +### IP Rate Limiting |
| 184 | + |
| 185 | +To enable IP rate limiting for your SQLPage instance, you can use the `limit_req` module in NGINX: |
| 186 | +```nginx |
| 187 | +http { |
| 188 | + ... |
| 189 | + limit_req_zone $binary_remote_addr zone=myzone:10m rate=10r/m; |
| 190 | +
|
| 191 | + server { |
| 192 | + ... |
| 193 | +
|
| 194 | + location / { |
| 195 | + limit_req zone=myzone; |
| 196 | + proxy_pass http://localhost:8080; |
| 197 | + ... |
| 198 | + } |
| 199 | + } |
| 200 | +} |
| 201 | +``` |
| 202 | +This configuration sets up a reverse proxy that forwards incoming requests from `example.com` to `localhost:8080`, where SQLPage is running, and enables IP rate limiting to prevent abuse. |
| 203 | + |
| 204 | + |
| 205 | +### Static File Serving |
| 206 | + |
| 207 | +The `try_files` directive in Nginx specifies the files to attempt to serve before falling back to a specified URI or passing the request to a proxy server. It's typically used within a location block to define the behavior when a request matches that location. |
| 208 | + |
| 209 | +```nginx |
| 210 | +http { |
| 211 | + ... |
| 212 | + server { |
| 213 | + listen 80; |
| 214 | + server_name example.com; |
| 215 | +
|
| 216 | + location ~ \.sql$ { |
| 217 | + include sqlpage_proxy.conf; |
| 218 | + } |
| 219 | +
|
| 220 | + location / { |
| 221 | + try_files $uri @reverse_proxy; |
| 222 | + } |
| 223 | +
|
| 224 | + location @reverse_proxy { |
| 225 | + include sqlpage_proxy.conf; |
| 226 | + } |
| 227 | + } |
| 228 | +} |
| 229 | +``` |
| 230 | + |
| 231 | +And in `/etc/nginx/sqlpage_proxy.conf`: |
| 232 | + |
| 233 | +```nginx |
| 234 | +proxy_pass http://localhost:8080; |
| 235 | +proxy_http_version 1.1; |
| 236 | +proxy_set_header Upgrade $http_upgrade; |
| 237 | +proxy_set_header Connection 'upgrade'; |
| 238 | +proxy_set_header Host $host; |
| 239 | +proxy_cache_bypass $http_upgrade; |
| 240 | +proxy_buffering on; |
| 241 | +proxy_set_header X-Real-IP $remote_addr; |
| 242 | +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
| 243 | +proxy_set_header X-Forwarded-Proto $scheme; |
| 244 | +proxy_set_header X-Forwarded-Host $host; |
| 245 | +``` |
| 246 | + |
| 247 | +### Caching and Buffering |
| 248 | + |
| 249 | +To enable caching and buffering for your SQLPage instance, you can use the `proxy_cache` and `proxy_buffering` directives in NGINX: |
| 250 | +```nginx |
| 251 | +http { |
| 252 | + ... |
| 253 | + proxy_cache mycache; |
| 254 | + # Cache settings: 1 hour for 200 and 302 responses, 1 minute for 404 responses |
| 255 | + proxy_cache_valid 200 302 1h; |
| 256 | + proxy_cache_valid 404 1m; |
| 257 | +
|
| 258 | + server { |
| 259 | + listen 80; |
| 260 | + server_name example.com; |
| 261 | +
|
| 262 | + location / { |
| 263 | + proxy_pass http://sqlpage; |
| 264 | + proxy_http_version 1.1; |
| 265 | + proxy_set_header Upgrade $http_upgrade; |
| 266 | + proxy_set_header Connection 'upgrade'; |
| 267 | + proxy_set_header Host $host; |
| 268 | + proxy_cache_bypass $http_upgrade; |
| 269 | + proxy_cache mycache; |
| 270 | + # Buffering: when a client is slow to read the response, quickly read the response from SQLPage and store it in a buffer, then send it to the slow client, while SQLPage can continue processing other requests |
| 271 | + proxy_buffering on; |
| 272 | + proxy_buffer_size 128k; |
| 273 | + proxy_buffers 4 256k; |
| 274 | + } |
| 275 | + } |
| 276 | +} |
| 277 | +``` |
| 278 | + |
| 279 | +### **HTTPS and Certbot** |
| 280 | + |
| 281 | +To let nginx handle HTTPS instead of SQLPage, you can obtain an SSL certificate from Certbot and configure nginx to use it. |
| 282 | + |
| 283 | +Install certbot using the following command: |
| 284 | +```bash |
| 285 | +sudo snap install --classic certbot |
| 286 | +``` |
| 287 | + |
| 288 | +Obtain an SSL certificate using the following command: |
| 289 | +```bash |
| 290 | +sudo certbot --nginx -d example.com |
| 291 | +``` |
0 commit comments