mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-09-24 16:24:32 +00:00
187 lines
6.9 KiB
HTML
187 lines
6.9 KiB
HTML
{% extends "../help_page.html" %}
|
|
{% block help_content %}
|
|
|
|
<h2 class="mt-4 mb-4">Running using Docker</h2>
|
|
<p>Spothole comes with a Docker configuration to make it easy to run it in a containerised environment. To set it up
|
|
using Docker, the easiest way is to use a Docker Compose file. Create a new directory such as <code>/opt/docker/spothole</code>
|
|
and create a <code>compose.yaml</code> file inside it with the following contents:</p>
|
|
<pre><code>services:
|
|
spothole:
|
|
container_name: spothole
|
|
build:
|
|
context: https://git.ianrenton.com/ian/spothole.git#main
|
|
restart: unless-stopped
|
|
ports:
|
|
- "8080:8080"
|
|
- "7373:7373" # For telnet if required
|
|
volumes:
|
|
- ./config.yml:/app/config.yml
|
|
- ./cache:/app/cache
|
|
</code></pre>
|
|
<p>You can replace <code>#main</code> with any other branch or tag reference, for example <code>#1.5</code> to pin the
|
|
build to tagged version 1.5.</p>
|
|
<p>Save the file. You will still need to create a copy of <code>config-example.yml</code> and name it
|
|
<code>config.yml</code>, though with the Docker setup nothing has actually been downloaded yet, so you will have to
|
|
copy the example from the repository some other way, e.g. <a
|
|
href="https://git.ianrenton.com/ian/spothole/src/branch/main/config-example.yml">from the repo in a web
|
|
browser</a>.</p>
|
|
<p>With that in place, run <code>docker compose up</code> and you should be good to go. To detach, press <code>d</code>
|
|
or run the command with the <code>-d</code> flag.</p>
|
|
|
|
<h3 class="mt-4">nginx Reverse Proxy with Docker</h3>
|
|
<p>In a containerised setup, it's typical to run an nginx reverse proxy in one container, alongside certbot for renewal
|
|
of HTTPS certificates, and then applications like Spothole in a separate container. In this case, there are a couple
|
|
of variations of the docker compose file above, and the nginx reverse proxy configuration covered <a
|
|
href="/help/usage/nginx">here</a>, that you will want to make.</p>
|
|
<ol>
|
|
<li>A port mapping is no longer required in the docker compose file; nginx will access into the docker container
|
|
directly on e.g. <code>http://spothole:8080</code></li>
|
|
<li>Spothole and nginx will need to be on the same docker network.</li>
|
|
</ol>
|
|
<p>So your <code>compose.yaml</code> might look like this:</p>
|
|
<pre><code>services:
|
|
spothole:
|
|
container_name: spothole
|
|
build:
|
|
context: https://git.ianrenton.com/ian/spothole.git#main
|
|
restart: unless-stopped
|
|
networks:
|
|
- docker-network
|
|
volumes:
|
|
- ./config.yml:/app/config.yml
|
|
- ./cache:/app/cache
|
|
|
|
networks:
|
|
docker-network:
|
|
external: true
|
|
</code></pre>
|
|
<p>In your nginx site configuration, you'll want to refer to the Spothole container directly, and drop the block that
|
|
allows nginx to access static files directly, as these will be inaccessible in another container. So you may end up
|
|
with something like:</p>
|
|
<pre><code>server {
|
|
server_name spothole.app;
|
|
|
|
# Global proxy settings
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Connection "";
|
|
proxy_connect_timeout 10s;
|
|
proxy_buffering on;
|
|
|
|
# Pass on IP address and host information to Spothole, in case logging this information is required
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header Host $http_host;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
# Wellknown area for Lets Encrypt
|
|
location /.well-known/acme-challenge/ {
|
|
root /var/www/certbot;
|
|
}
|
|
|
|
# SSE endpoints
|
|
location ~ ^/api/v\d*/(spots|alerts)/stream/? {
|
|
proxy_pass http://spothole:8080;
|
|
|
|
# Remove buffering, remove caching, add suitable timeouts for SSE API calls
|
|
proxy_buffering off;
|
|
proxy_cache off;
|
|
proxy_read_timeout 24h;
|
|
proxy_send_timeout 24h;
|
|
proxy_set_header X-Accel-Buffering no;
|
|
add_header Cache-Control no-store always;
|
|
|
|
# Allow cross-origin requests to API
|
|
proxy_hide_header Access-Control-Allow-Origin;
|
|
add_header Access-Control-Allow-Origin * always;
|
|
}
|
|
|
|
# Other API endpoints
|
|
location /api/ {
|
|
proxy_pass http://spothole:8080;
|
|
|
|
# Remove buffering, remove caching, add suitable timeouts for API calls
|
|
proxy_buffering off;
|
|
proxy_cache off;
|
|
proxy_read_timeout 30s;
|
|
add_header Cache-Control no-store always;
|
|
|
|
# Allow cross-origin requests to API
|
|
proxy_hide_header Access-Control-Allow-Origin;
|
|
add_header Access-Control-Allow-Origin * always;
|
|
}
|
|
|
|
# Templated pages and static assets
|
|
location / {
|
|
proxy_pass http://spothole:8080;
|
|
proxy_read_timeout 30s;
|
|
add_header Cache-Control "no-cache, must-revalidate" always;
|
|
}
|
|
|
|
listen 443 ssl;
|
|
listen [::]:443 ssl;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/spothole.app/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/spothole.app/privkey.pem;
|
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
}
|
|
|
|
|
|
server {
|
|
if ($host = spothole.app) {
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
|
|
server_name spothole.app;
|
|
listen 80;
|
|
listen [::]:80;
|
|
return 404;
|
|
}
|
|
</code></pre>
|
|
<p>If desired, you could even change the port on which Spothole runs from 8080 to a plain 80, in which case your
|
|
<code>proxy_pass</code> statements could drop the <code>:8080</code> suffix. Since Spothole is in a container, it
|
|
can serve HTTP on port 80 if desired, because it doesn't conflict with the host system.</p>
|
|
|
|
<h3 class="mt-4">Restoring the static files bypass</h3>
|
|
<p>If you would still like to bypass Spothole's web server for the static files, and serve them with nginx, you can do.
|
|
The easiest way is to run another nginx container to serve the files, so your Spothole <code>compose.yaml</code>
|
|
becomes:</p>
|
|
<pre><code>services:
|
|
spothole:
|
|
container_name: spothole
|
|
build:
|
|
context: https://git.ianrenton.com/ian/spothole.git#main
|
|
restart: unless-stopped
|
|
networks:
|
|
- docker-network
|
|
volumes:
|
|
- ./config.yml:/app/config.yml
|
|
- ./cache:/app/cache
|
|
|
|
spothole-static-nginx:
|
|
container_name: spothole-static-nginx
|
|
build:
|
|
context: https://git.ianrenton.com/ian/spothole.git#main
|
|
dockerfile_inline: |
|
|
FROM nginx:latest
|
|
COPY static /usr/share/nginx/html
|
|
restart: unless-stopped
|
|
networks:
|
|
- docker-network
|
|
|
|
networks:
|
|
docker-network:
|
|
external: true
|
|
</code></pre>
|
|
<p>Then you can re-add the block that handles the <code>/static</code> path in your nginx reverse proxy config, but this
|
|
time point it at the new container rather than at a filesystem path:</p>
|
|
<pre><code> # Load static assets from the spothole-static-nginx container
|
|
location /static/ {
|
|
proxy_pass http://spothole-static-nginx/;
|
|
expires 1h;
|
|
add_header Cache-Control "public, max-age=3600, must-revalidate";
|
|
}
|
|
</code></pre>
|
|
|
|
{% end %}
|