ImgCompress Docker Compose Variants

August 1, 2026 ยท View on GitHub

Why do they exist?

The default docker-compose.yml in the project root is intentionally minimal - great for getting started, but it omits production hardening. Every real-world container deployment needs a baseline of best practices: log rotation to prevent disk exhaustion, healthchecks, sane shutdown behavior, a reverse proxy for TLS termination, and so on. These variant files provide ready-made configurations that cover those concerns.

Furthermore, these comprehensive files serve as living documentation for future maintainers. They capture the operational decisions behind "how our container should behave on a user's machine" - decisions that are easy to forget when you spin up a ten-line compose file to test a shiny new container and then move on.

Which one should I use?

For home / LAN use: Start with advanced.docker-compose.yaml. The app is reachable from any device on your network out of the box (not localhost-only), and the file contains sensible defaults you can copy into your own setup.

For hosting under a domain with HTTPS (company LAN, homelab, or the public Internet): Use proxied.docker-compose.yaml. It is a battery-included configuration with a Traefik reverse proxy that handles TLS termination, HTTPS redirection, and security headers. The app is served without a login, so storage management is disabled by default in this variant: ImgCompress has no built-in authentication, and with storage management on, any visitor could browse and manage all uploaded files. Re-enable it only for trusted environments (IMGCOMPRESS_DISABLE_STORAGE_MANAGEMENT=false), or put the app behind basic auth by adding the traefik-auth middleware to the app router (documented in the compose file). The Traefik dashboard is always protected by basic auth (TRAEFIK_AUTH_USERS).

Note on environment variables: When passing password hashes (such as TRAEFIK_AUTH_USERS generated by htpasswd -nB), write single $ characters in .env files (e.g. user:\$2y\$10$...). In docker-compose.yaml files directly, $ signs must be escaped as $$ (e.g. user:$\$2y$\$10$$...). Always generate your own hash; never reuse one from an example or tutorial.

How to use

Both variants read their settings from a .env file in this folder (the folder you run docker compose from). Start by copying the example:

cd docker/compose
cp .env.example .env

Variant A: advanced.docker-compose.yaml (home / LAN use)

  1. Optionally edit .env (port, image tag). The defaults work out of the box.
  2. Start the stack:
    docker compose -f advanced.docker-compose.yaml up -d
    
  3. Open http://localhost:3001 on the server, or http://<server-ip>:3001 from any device on your network (phone, laptop, etc.).
  4. The app has no login, so by default everyone on the network can use it. To restrict it to the server machine only, set IMGCOMPRESS_HOST=127.0.0.1 in .env and run the up -d command again.

Variant B: proxied.docker-compose.yaml (domain + HTTPS via Traefik)

  1. Point a DNS A/AAAA record for your domain (e.g. imgcompress.example.com) at the server.
  2. Generate the Traefik dashboard credentials (needs apache2-utils on Debian/Ubuntu, httpd-tools on RHEL/Fedora):
    htpasswd -nB admin
    
  3. Edit .env and set:
    TRAEFIK_DOMAIN_NAME=imgcompress.example.com
    ACME_EMAIL=you@example.com
    TRAEFIK_AUTH_USERS=admin:\$2y\$10$...   # the htpasswd output from step 2
    
  4. Start the stack:
    docker compose -f proxied.docker-compose.yaml up -d
    
  5. Open https://your-domain. The Let's Encrypt certificate is requested automatically on the first visit and takes a few seconds; hard-reload if the browser still shows a warning at first. The app is available to anyone who can reach it (see the security notes above). The Traefik dashboard is at http://127.0.0.1:8190 from the server itself (log in with the credentials from step 2); it is intentionally not exposed to the network.

Let's Encrypt needs to reach you: certificate issuance uses the TLS-ALPN challenge, which requires your domain to be reachable from the Internet on port 443. On a LAN-only server, swap the tlsChallenge line in the compose file for a DNS challenge with your DNS provider's API credentials - you still get a real trusted certificate and nothing is exposed.