## Running using Docker 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 `/opt/docker/spothole` and create a `compose.yaml` file inside it with the following contents: ```yaml services: spothole: container_name: spothole build: context: https://git.ianrenton.com/ian/spothole.git#main restart: unless-stopped ports: - "8080:8080" volumes: - ./config.yml:/app/config.yml - ./cache:/app/cache ``` You can replace `#main` with any other branch or tag reference, for example `#1.5` to pin the build to tagged version 1.5. Save the file. You will still need to create a copy of `config-example.yml` and name it `config.yml`, 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. [from the repo in a web browser](https://git.ianrenton.com/ian/spothole/src/branch/main/config-example.yml). With that in place, run `docker compose up` and you should be good to go. To detach, press `d` or run the command with the `-d` flag. ### nginx Reverse Proxy with Docker 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 [here](./nginx.md), that you will want to make. 1. A port mapping is no longer required in the docker compose file; nginx will access into the docker container directly on e.g. `http://spothole:8080` 2. Spothole and nginx will need to be on the same docker network. So your `compose.yaml` might look like this: ```yaml 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 ``` 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: ```nginx 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/v2/(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; } ``` If desired, you could even change the port on which Spothole runs from 8080 to a plain 80, in which case your `proxy_pass` statements could drop the `:8080` 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.