Skip to content

Instantly share code, notes, and snippets.

@JamesCullum
Last active March 28, 2024 04:30
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamesCullum/6604e504318dd326a507108f59ca7dcd to your computer and use it in GitHub Desktop.
Save JamesCullum/6604e504318dd326a507108f59ca7dcd to your computer and use it in GitHub Desktop.
docker-compose.yml for immich with WAF, DDoS protection, image resizing and without port forwarding

Setup Immich via Docker Compose with WAF, CDN, DDoS protection, no port forwarding and automated image resizing

In this guide, we are using the docker compose setup that is recommended by the Immich team. Once everything is configured and running in your local network, we can expand on it.

The first recommended step is to use Cloudflare Tunnel to make your local instance globally available. This is free and you benefit from the native DDoS protection, WAF and CDN from Cloudflare. The cloudflared daemon basically makes an outgoing connection to Cloudflare and makes the designed interfaces available on the internet, without granting access to undesired parts of the network.

Start off by creating a Cloudflare account, going into the "Zero Trust" portion of the account and add a new tunnel. Give it a name and choose a domain that you want your instance to be available on. You can use the "Access" components (SSO/VPN) to lock down the access, if you want. Once you have to choose a local agent, select "Docker" and copy the token from the instructions. Add the following command into your docker-compose.yml and add your valid tunnel token.

  cloudflared:
    container_name: cloudflared
    image: cloudflare/cloudflared:latest
    depends_on:
      - immich-server
    restart: always
    command: 'tunnel --no-autoupdate run --token YOUR-TOKEN'

Use docker compose to start this container, the UI should show your node being online now. Now switch to "Public hostname" , add the desires subdomain for your immich instance, leave path empty and for the service you configure HTTP with immich_proxy:8080 as destination. Once saved, your cloudflared daemon will automatically update and your immich is now available on the internet.

If you would like your pictures to be automatically resized - a feature which the Immich maintainers have declined - you can add the following code to your docker-compose.yml. Feel free to change the dimensions you are looking for.

  upload-proxy:
    container_name: upload_proxy
    image: ghcr.io/jamescullum/multipart-upload-proxy:main
    environment:
      - IMG_MAX_WIDTH=1920
      - IMG_MAX_HEIGHT=1080
      - FORWARD_DESTINATION=http://immich-server:3001/api/asset/upload
      - FILE_UPLOAD_FIELD=assetData
      - LISTEN_PATH=/api/asset/upload
    restart: always

You need to route uploads to this container now, which is easy to do via Cloudflare tunnel. Create a new public hostname, use api/asset/upload as path and direct it via HTTP to upload_proxy:6743. Submit and move this public hostname above the previous one.

Screenshot immich with cloudflare tunnel

Now all file uploads will be proxied and images automatically resized before being uploaded to Immich.

@tehniemer
Copy link

The use of multipart in the image name gives me hope that this does chunked uploads to get around Cloudflare's 100mb limit, is that the case or am I suffering from wishful thinking?

@JamesCullum
Copy link
Author

JamesCullum commented Jan 21, 2024

Multipart is a subcomponent of the HTTP form protocol to allow file uploads - the proxy does not circumvent any limitations. I did not find the limitation you mentioned in tunnel documentation.

@tehniemer
Copy link

OK, thanks for the info, I'm using Traefik2 as my reverse proxy and Cloudflare as my DNS provider, and Cloudflare has the limitation.

@JamesCullum
Copy link
Author

JamesCullum commented Jan 23, 2024

Your DNS provider has nothing to do with filesize limits. Check your reverse proxy or client for that.

I didn't find such a limitation for the Cloudflare tunnel either, so it looks like your problem is somewhere else.

@tehniemer
Copy link

tehniemer commented Jan 23, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment