Skip to content

Add .env.example and enhance docker-compose config#673

Open
AlexanderSlokov wants to merge 10 commits into
karimz1:mainfrom
AlexanderSlokov:refactor/docker-compose
Open

Add .env.example and enhance docker-compose config#673
AlexanderSlokov wants to merge 10 commits into
karimz1:mainfrom
AlexanderSlokov:refactor/docker-compose

Conversation

@AlexanderSlokov

Copy link
Copy Markdown
Contributor
  • Add .env.example with environment variable defaults for image, host, port and feature flags.
  • Update docker-compose.yml to use those env vars for the imgcompress service, introduce reusable logging and healthcheck anchors, define an isolated bridge network with lowered MTU, and improve container safety and operability by adding ulimits, stop_grace_period, security_opt (no-new-privileges) and structured logging options.
  • Also change default port binding to bind to IMGCOMPRESS_HOST:IMGCOMPRESS_PORT (localhost by default) and make healthcheck and logging settings configurable and consistent.

Add .env.example with environment variable defaults for image, host, port and feature flags. Update docker-compose.yml to use those env vars for the imgcompress service, introduce reusable logging and healthcheck anchors, define an isolated bridge network with lowered MTU, and improve container safety and operability by adding ulimits, stop_grace_period, security_opt (no-new-privileges) and structured logging options. Also change default port binding to bind to IMGCOMPRESS_HOST:IMGCOMPRESS_PORT (localhost by default) and make healthcheck and logging settings configurable and consistent.
@karimz1

karimz1 commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Hey @AlexanderSlokov thanks for the PR. I took a quick look and it looks solid overall. I'd like to discuss a few points.

I've extended the docs and main branch a bit, and if you check out this guide (https://imgcompress.karimzouine.com/docs/developers#dev-mode-synthetic-error-triggers), you'll see how imgcompress handles logging. It consolidates Docker logs, frontend logs, and backend logs into a single file for debugging exceptions. Given that, I'm not sure we need Docker-level logging limits as well.

I agree that setting a max size in docker-compose to prevent endless logging makes sense in principle, but I'm curious why bigger OSS projects like Stirling PDF don't include it. Are we really solving a problem that matters here? That said, I do recognize now the risk unrotated logs could grow large over months this came to my head after seeing the max log from your pr. of batch conversions. I think this deserves investigation, but maybe as a separate issue where we can measure actual log volume and decide on appropriate limits.

Regarding the skipped items (stop_grace_period, ulimits, MTU tuning): Since imgcompress is stateless and doesn't fire any shutdown events, there's no benefit to the grace period. Docker's default is fine. Let me know if I'm missing something. and the other changes look also alright IDK I just feel when a normal user looks at the docker compose file they might get overwhelmed but the private network and so on is something that is great maybe we should do a structure like https://github.com/Stirling-Tools/Stirling-PDF/tree/main/docker/compose stirlingpdf does I feel that gives more examples of how to use things the ideal way without overwhellming new users. Also if I see https://docs.stirlingpdf.com/Installation/Docker%20Install/ their docs it is very basic and their advance things are in the subfolders if we could follow an architecture like that I think we would be great what do you think ?

I'm just lookin now of how other bigger projects manage their repo structure and I'm open for ideas from your side :)

@AlexanderSlokov

AlexanderSlokov commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

Dear @karimz1,

It is good to see you still give some time to review my stuff! Appreciate it.

Regarding the docker-compose.yaml, from my POV, every program deployment (the compose file, or Helm Charts, .etc) need a base guideline of "how things should be" and "the goodies that all things want." Obviously, a container will want itself not to be chunk up network packets, have a log rotation, some kinds of proxy to stand before it and handle TLS termination, .etc right?

We make a comprehensive compose file is to give all the maintainers after us the common senses about taking care of "how our containers will behave on user's computer". Think like this, our successors maintainers will have to use the ulimit, mtu driver,... That we settled, battle-tested. Suddenly, the whole compose stack and its container will inherit the best practices!

I am nothing against StirlingPDF because I used it too! It did the jobs well without require me to tackle my Ubuntu computer to install ffmpeg.

But hold on, when we take a closer look on my proposal, the Imgcompresscontainer wouldn't change any behavior about UX at all. Users may scare a bit during copy-paste the compose file, but the container still spin up, and they can use its features just like the README advertising.

Those above opinions is my overall view, and my conclusion about the road of maintaining a huge project is to "set the limits, road rails, and conventions".

"Passion ignites the willing to build great things, but clarity and discipline build the foundations of great things."

But your final insights is still the most important, so I will follow your demands. No one knows the child better than their parents, right?

All the best,
Aleksandr.

Edit: wait, since you already said that we can put this in a isolated folder... Well that works,... Normal users can use a default compose file, while the power users can use a comprehensive version. Okay, I think you got a point. Please confirm your decision and I will make PR change accordingly.

@karimz1

karimz1 commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Dear @karimz1,

It is good to see you still give some time to review my stuff! Appreciate it.

Regarding the docker-compose.yaml, from my POV, every program deployment (the compose file, or Helm Charts, .etc) need a base guideline of "how things should be" and "the goodies that all things want." Obviously, a container will want itself not to be chunk up network packets, have a log rotation, some kinds of proxy to stand before it and handle TLS termination, .etc right?

We make a comprehensive compose file is to give all the maintainers after us the common senses about taking care of "how our containers will behave on user's computer". Think like this, our successors maintainers will have to use the ulimit, mtu driver,... That we settled, battle-tested. Suddenly, the whole compose stack and its container will inherit the best practices!

I am nothing against StirlingPDF because I used it too! It did the jobs well without require me to tackle my Ubuntu computer to install ffmpeg.

But hold on, when we take a closer look on my proposal, the Imgcompresscontainer wouldn't change any behavior about UX at all. Users may scare a bit during copy-paste the compose file, but the container still spin up, and they can use its features just like the README advertising.

Those above opinions is my overall view, and my conclusion about the road of maintaining a huge project is to "set the limits, road rails, and conventions".

"Passion ignites the willing to build great things, but clarity and discipline build the foundations of great things."

But your final insights is still the most important, so I will follow your demands. No one knows the child better than their parents, right?

All the best,
Aleksandr.

Edit: wait, since you already said that we can put this in a isolated folder... Well that works,... Normal users can use a default compose file, while the power users can use a comprehensive version. Okay, I think you got a point. Please confirm your decision and I will make PR change accordingly.

Thanks Aleksandr, I really appreciate the thoughtful response. You're absolutely right. Comprehensive compose files are valuable for future maintainers. Having those conventions and best practices baked in prevents each person from reinventing the wheel and sets clear expectations for how containers should behave.

Your two-tier approach is exactly the right solution. I think we should structure it like Stirling PDF does:

docker/compose/
README.md (guides users to the right file)
docker-compose.yml (basic, just works)
examples/
comprehensive.yml (full best practices)
production.yml (with reverse proxy setup)
development.yml (with extra logging for debugging)

The README in docker/compose/ should explain what each file is for and why there are multiple versions. Something like: "Start with docker-compose.yml if you're new. If you're setting up production with a reverse proxy, use production.yml is an example. Want to understand best practices for logging, security, and resource limits? Check comprehensive.yml."

How this works for users:

New users copy the basic docker-compose.yml and get started immediately. They don't see the complexity, they just run the container. Power users and future maintainers can explore the examples/ folder to understand the philosophy behind MTU tuning, log rotation, security options. The comprehensive versions document why each setting exists and how to use them properly.

If you want you can skip the examples folder and put all in that compose folder what you think looks better.

For documentation, we keep the main install guide lean with just the basic compose. We link to docker/compose/ for advanced setups. This matches how others doe it: simple entry point, examples for learning and power users. I'll make sure to also link the advanced compose files from the docs.

Does that direction feel right?

Regarding reverse proxy I use traefik too on some other setups caddy but I'm open for your pr. I honestly think it is good to add the example as some beginners might never heard what a reverse proxy is so we can make it ideal also for beginners to follow the best practices 😃 I will link it from the docs as well.

@karimz1

karimz1 commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Just another suggestion if you could make the production.yml also block internet that would add another great layer of security. So the container can't access the internet it is following the principles we want to archive. Privacy by Design.

Refactored Docker Compose configuration into two variants:

- docker-compose.yml: Simplified for quick start with hardcoded defaults, removed complex features (custom network, YAML anchors, ulimits, security options, logging config)

- docker/compose/advanced.docker-compose.yaml: New advanced deployment config with environment variable support and production best practices (network isolation, resource limits, graceful shutdown, security hardening)
Correction for what is our Docker Image is.
Add docker/compose/README.md documenting the purpose and use cases for Docker Compose variants. Include proxied.docker-compose.yaml, a production-ready configuration featuring Traefik reverse proxy with TLS termination, comprehensive logging, security headers, health checks, and network optimization—designed for deploying ImgCompress on untrusted networks.
Refactor proxied Docker Compose setup to improve network isolation and security:

- Create separate networks for Traefik and ImgCompress with internal isolation for ImgCompress
- Make port and domain configuration flexible via environment variables
- Comment out ImgCompress direct port exposure (now routed through Traefik)
- Update Traefik configuration to monitor both networks and disable Prometheus metrics
- Remove Cloudflared references from documentation
- Add comprehensive comments explaining network, security, and configuration choices
- Adjust max request body from 560mb to 520mb and update service port mapping
Improved formatting consistency in the Traefik configuration:
- Commented out ACME/Let's Encrypt configuration lines (email, storage, challenge)
- Disabled acme-certs volume mount by default
- Reformatted inline comments for consistency
- Removed trailing whitespace
- Shortened redundant comment explanations
- Updated docker compose command path in documentation
@AlexanderSlokov

Copy link
Copy Markdown
Contributor Author

Dear @karimz1,

I finished my work and you can take a review at it. In short:

  • 2 new files docker/compose/advanced.docker-compose.yaml (detailed version of deploy a single ImgCompress container with tuning mtu network driver, logging,.etc) and docker/compose/proxied.docker-compose.yaml (setup a production Traefik proxy as battery-included, as well as restrict ImgCompress container to a "internal" bridge network to prevent direct inbound and outbound connections)
  • A docker/compose/README.md to explain why these files existed, and which case to use which one.
  • A document fix on main README, about my own section to explain the security-hardened image correctly and strip down buzzwords that I did not think throughfully to put them there.

Feel free to notify me if you need me to make any changes.

Cheers,
Aleksandr.

@AlexanderSlokov AlexanderSlokov marked this pull request as ready for review July 5, 2026 16:04
@karimz1

karimz1 commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Thanks @AlexanderSlokov just give me a few days I will take a look at it and let you know appreciate your great work 🙏

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants