From b6e9e063c6a6386a07e5d046ed13b6c239939e38 Mon Sep 17 00:00:00 2001 From: Carl Pearson Date: Sun, 3 Jan 2021 12:00:14 -0700 Subject: [PATCH] add photoprism post --- content/post/20210103-photoprism/index.md | 276 ++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 content/post/20210103-photoprism/index.md diff --git a/content/post/20210103-photoprism/index.md b/content/post/20210103-photoprism/index.md new file mode 100644 index 0000000..6b72ae2 --- /dev/null +++ b/content/post/20210103-photoprism/index.md @@ -0,0 +1,276 @@ ++++ +title = "Setting up Photoprism with HTTPS on Google Compute Engine" +date = 2021-01-03T00:00:00 +lastmod = 2021-01-03T00:00:00 +draft = false + +# Authors. Comma separated list, e.g. `["Bob Smith", "David Jones"]`. +authors = ["Carl Pearson"] + +tags = ["photoprism"] + +summary = "Set up PhotoPrism on Google Cloud with docker-compose and a LetsEncrypt HTTPS certificate" + +# Projects (optional). +# Associate this post with one or more of your projects. +# Simply enter your project's folder or file name without extension. +# E.g. `projects = ["deep-learning"]` references +# `content/project/deep-learning/index.md`. +# Otherwise, set `projects = []`. +projects = [] + +# Featured image +# To use, add an image named `featured.jpg/png` to your project's folder. +[image] + # Caption (optional) + caption = "" + + # Focal point (optional) + # Options: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight + focal_point = "Center" + + # Show image only in page previews? + preview_only = true + + +categories = [] + +# Set captions for image gallery. + + ++++ + +[PhotoPrism](https://photoprism.app/) is a server-based application for browsing, organizing, and sharing your photo collection. +Here, I describe how I set it up on a Google Compute Engine virtual machine using docker-compose, an nginx https proxy, and LetsEncrypt. + +*I know just enough about networking to be dangerous and next to nothing about HTTPS. This setup worked for me and I believe it to be reasonably secure, but I make not guarantees.* + +In this entire post, I assume your domain will be `photoprism.example.com`. +You'll need to change all instances of that throughout. + +## The Google Cloud Instance + +First, I created a new project in Google Compute just for this. +It simplifies the firewall rules. + +Depending on whether you want automatic Tensorflow image labeling: + +* *no*: e2-micro (2 vCPU, 1GB RAM) +* *yes*: e2-medium (2 vCPU, 4GB RAM). You can get away with e2-small (2 GB RAM) if you're willing to enable swap. + +As for the other VM settings: + +* Debian 10 image and 50 GB disk. The OS and photoprism docker images use quite a few GBs, and you need some space left for your pictures. +* Allow HTTP and HTTPS traffic. + * the LetsEncrypt certbot will try to connect to this machine over HTTP to validate you own the domain. + * you can disable HTTP later. +* Create/attach a static IPv4 address to your instance. +* Add the corresponding custom resource record to your DNS (this allows `photoprism.example.com`. Change `photoprism` to a different subdomain if you like) + * `photoprism A 1h ` + +## docker, docker-compose, certbot, nginx, swapfile, pull photoprism images + +This snippet will do it all in one shot. +If you don't need the swapfile, you can skip that part at the end. +The first part cribs the [current docker-ce install instructions for x86_64 debian](https://docs.docker.com/engine/install/debian/). +Check to make sure they are still current. + +```bash +( +sudo apt-get update +sudo apt-get install -y \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg-agent \ + software-properties-common +curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - +sudo apt-key fingerprint 0EBFCD88 +sudo add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/debian \ + $(lsb_release -cs) \ + stable" +sudo apt-get update +sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose wget htop nginx apache2-utils certbot python3-certbot-nginx +wget https://dl.photoprism.org/docker/docker-compose.yml +sudo docker-compose pull +sudo fallocate -l 2G /swapfile +sudo chmod 600 /swapfile +sudo mkswap /swapfile +sudo swapon /swapfile +echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab > /dev/null +) +``` + +## Get your HTTPS certificate with LetsEncrypt + +Run `sudo certbot certonly -d photoprism.example.com` + +Since we installed nginx in the previous step, select the "nginx plugin" option (this is where you need HTTP allowed through the firewall). + +After answering the prompts, the successful result was: + +```txt +Plugins selected: Authenticator nginx, Installer None +Obtaining a new certificate +Performing the following challenges:http-01 challenge for photoprism.example.com +Waiting for verification... +Cleaning up challenges +IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: +/etc/letsencrypt/live/photoprism.example.com/fullchain.pem Your key file has been +saved at: /etc/letsencrypt/live/photoprism.example.com/privkey.pem Your cert will +expire on 2021-04-03. To obtain a new or tweaked version of this certificate in +the future, simply run certbot again. To non-interactively renew *all* of your +certificates, run "certbot renew" - If you like Certbot, please consider supporting +our work by: +Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate +Donating to EFF: https://eff.org/donate-le +``` + +## Configure and Start Photoprism + +Photoprism is configured with `docker-compose.yml`. + +You will need to choose and enter three seprate passwords. +I recommend not using special characters, as the wrong combo can cause things to try to look up environment variables with unpredicable results. +* `PHOTOPRISM_DATABASE_PASSWORD`/`MYSQL_PASSWORD` +* `PHOTOPRISM_ADMIN_PASSWORD` +* `MYSQL_ROOT_PASSWORD` + +*Note that `PHOTOPRISM_DATABASE_PASSWORD` and `MYSQL_PASSWORD` must be the same.* + + +If you are using the smaller kind of instance, also set +```yaml +PHOTOPRISM_WORKERS: 1 +PHOTOPRISM_DISABLE_TENSORFLOW: "true" +``` + +To start photoprism, run `sudo docker-compose up -d` + +You can look at logs with `docker-compose logs`. you should not see anything like "failed to connect to database" + +If you goof this up, you need to do something like (this will delete everything) +``` +sudo docker-compose down +sudo docker volume prune +sudo rm -r storage database +``` + +## Configure and Start NGINX + +*remember to change all `photoprism.example.com`* + +I had to follow alternate instructions [here](https://docs.photoprism.org/getting-started/advanced/nginx-proxy-setup/) *(the current instructions [here](https://docs.photoprism.org/getting-started/proxies/nginx/) did not work for me)*. + +First, create `/etc/nginx/sites-enabled/photoprism.example.com` + +Put the following content in it. +This is taken from the PhotoPrism instructions, except `proxy_pass http://localhost:2342;` instead of `proxy_pass http://docker.homenet:2342;` + +``` +# PhotoPrism Nginx config with SSL HTTP/2 and reverse proxy +# This file gives you an example on how to secure you PP instance with SSL +server { + # listen 80; # If you really need HTTP (unsecure) remove the "#" on the beginning. Not recommended! + # listen [::]:80; # HTTP IPv6 + + listen 443 ssl http2; # Listen on port 443 and enable ssl and HTTP/2 + listen [::]:443 ssl http2; # Same for IPv6 + + # Put your domain name in here. + server_name photoprism.example.com; + + # - - - - - - - - - - + # SSL security + # - - - - - - - - - - + ssl_certificate /etc/letsencrypt/live/photoprism.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/photoprism.example.com/privkey.pem; + + # Since the PP API is also used on Android, we have to keep TLS1.2 in here for a while. + # A lot of the older Android devices do not support TLS1.3 yet :/ + ssl_protocols TLSv1.2 TLSv1.3; + + # Use good and strong ciphers, disable weak and old ciphers + ssl_ciphers HIGH:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS; + + # Enable HSTS (https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security) + add_header Strict-Transport-Security "max-age=172800; includeSubdomains"; + + # This checks if the certificate has been invalidated by the certificate authority + # You can remove this section if you use self-singed certificates... + # Enable OCSP stapling (http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox) + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate /etc/letsencrypt/live/photoprism.example.com/fullchain.pem; + + # DNS Servers to use for OCSP lookups + resolver 8.8.8.8 1.1.1.1 9.9.9.9 valid=300s; + resolver_timeout 5s; + + # - - - - - - - - - + # Reverse Proxy + # - - - - - - - - - + proxy_redirect off; + proxy_set_header X-Real-IP $remote_addr; # Let PP know the clients real IP + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Let PP know that a proxy did forward this request + proxy_set_header Host $http_host; # Set Proxy host info + + proxy_http_version 1.1; # Required for WebSocket connection + proxy_set_header Upgrade $http_upgrade; # Allow protocol switch to websocket + proxy_set_header Connection "upgrade"; # Do protocol switch + proxy_set_header X-Forwarded-Proto $scheme; # Let PP know that this connection used HTTP or HTTPS + + client_max_body_size 500M; # Bump the max body size, you may want to upload huge stuff via the upload GUI + proxy_buffering off; # Do not hold back the request while the client sends data, give the stream directly to PP + + location / { + # Optional; additional protection with Basic Auth. + # Note: This breaks WebDAV without additional configuration + # You also have to create a .htpasswd file using the command: + # "htpasswd -c /etc/nginx/.pp_htpasswd my_secret_user" + # - - - + # auth_basic "PhotoPrism Pre Auth"; + # auth_basic_user_file /etc/nginx/.pp_htpasswd; + + # pipes the traffic to PhotoPrism + # Change this to your PhotoPrisms IP / DNS + proxy_pass http://localhost:2342; + } +} + +``` + +Then run `sudo systemctl restart nginx`. +You should see no errors + +## Try it Out + +Navigate to [https://photoprism.example.com](https://photoprism.example.com) and log in with the `PHOTOPRISM_ADMIN_PASSWORD` you chose previously. + +## Automatic Restart + +Once everything is working, set up automatic image restart. +I guess this causes the photoprism image to be restarted unless you explicitly shut it down. + +* `docker-compose stop` +* uncomment out the restart portion of `docker-compose.yml` +* `docker-compose up -d` + + +## All Finished! + +Congrats! + +`unattended-upgrades` seems to be configured by default on the Google Compute debian image. +You almost certainly want this. + +I set up a weekly automated snapshot under `Compute Engine` > `Snapshots` > `Snapshot Schedules`. +Attach it to the machine on the `Disks` page with `Edit`. + + + + + + +