Skip to content

Conversation

@knylbyte
Copy link

@knylbyte knylbyte commented Dec 16, 2025

Summary

This PR introduces a new distroless, non-root Docker image build for epg and adds automation to build/publish multi-arch images to GHCR. It also updates the Docker documentation and provides a docker-compose.yml example.

What changed

Docker image

  • New multi-stage build in docker/Dockerfile (distroless runner, nonroot, includes runtime tooling and tzdata/CA certs).
  • New docker/pm2.config.js to run the grabber in a distroless environment and support:
    • SITE and CLANG list parsing (JSON array / delimited strings)
    • optional multi-site output merging into a single guide.xml
    • ALL_SITES mode that iterates site channel lists under /epg/sites.

CI / Automation

  • docker-build.yml builds and pushes linux/amd64, linux/arm64, linux/arm/v7 and publishes a multi-arch manifest (latest + <branch> + short SHA).
  • Scheduled workflows to bump Docker base/tool versions and trigger rebuilds: alpine-autobump.yml, node-autobump.yml, node-modules-autobump.yml.
  • fetch-upstream.yml to keep a fork in sync with upstream.

Docs

  • README.md Docker section updated (new env vars, updated volume path, build instructions).
  • Adds example docker-compose.yml.

Breaking / behavior changes

  • Docker builds now use docker/Dockerfile (root Dockerfile was removed).
  • Channels bind-mount path for the container is now /epg/sites/channels.xml (instead of /epg/channels.xml).

Test plan

  • docker build -f docker/Dockerfile -t iptv-org/epg .
  • docker run --rm -p 3000:3000 -v ./channels.xml:/epg/sites/channels.xml:ro iptv-org/epg
  • curl http://localhost:3000/guide.xml

Notes

  • fetch-upstream.yml is primarily useful for forks; feel free to drop it if not desired for the upstream repo.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a comprehensive Docker infrastructure overhaul with a new distroless, multi-arch Docker image build system and automated workflows for maintaining dependencies. The PR adds support for multi-site EPG grabbing with optional merging, along with improved documentation.

Key changes:

  • New distroless Docker build with multi-stage approach and non-root execution
  • Multi-arch support (amd64, arm64, armv7) with automated CI/CD pipelines
  • Multi-site EPG grabbing capability with channel list merging
  • Automated version bumping workflows for Alpine, Node, and npm packages

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
docker/Dockerfile New multi-stage distroless build with static binaries for shell and getconf utilities
docker/pm2.config.js PM2 configuration supporting multi-site grabbing, list parsing, and environment-based configuration
docker/.dockerignore Build context exclusions for Docker image builds
docker-compose.yml Example docker-compose configuration with environment variable documentation
README.md Updated Docker documentation with new environment variables, volume paths, and usage examples
.github/workflows/docker-build.yml Multi-arch Docker build and publish workflow with digest-based manifests
.github/workflows/alpine-autobump.yml Automated Alpine version checking and updating workflow
.github/workflows/node-autobump.yml Automated Node.js version checking and updating workflow
.github/workflows/node-modules-autobump.yml Automated npm package version checking and updating workflow
.github/workflows/fetch-upstream.yml Fork synchronization workflow
Dockerfile Removed old single-stage Dockerfile
.github/workflows/docker-publish.yml Removed and replaced with docker-build.yml

# DELAY: "500" # delay between requests (ms)
# PROXY: "http://user:pass@host:port"
# CURL: "true" # output requests as curl
# ALL_SITES: true # itterates through all directories inside sites folder and filtered by CLANG (see below)
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The word "itterates" is misspelled. The correct spelling is "iterates".

Suggested change
# ALL_SITES: true # itterates through all directories inside sites folder and filtered by CLANG (see below)
# ALL_SITES: true # iterates through all directories inside sites folder and filtered by CLANG (see below)

Copilot uses AI. Check for mistakes.
@knylbyte
Copy link
Author

fixed and tested all issues

@freearhey
Copy link
Collaborator

ALL_SITES mode that iterates site channel lists under /epg/sites.

Unfortunately, we cannot blindly combine channel listings from different sites into one, primarily because the guide for the same channel may differ completely in terms of time and description, which leads to an unusable output.

As for the rest of the changes, I am definitely not competent enough to review them. I don't even fully understand what problem they are supposed to solve.

@DanApollo
Copy link
Contributor

DanApollo commented Dec 22, 2025

Hi, I'm just a contributor but I recently make changes to the docker workflow.

In terms of the distroless changes this looks good to me, and should help reduce the size of the hosted container. Will try and test this branch today later as I will need to set up an arm7 device.

To comment on why these changes are being made, perhaps add a Why section to the top of the PR, my understanding is this should help portability and keep container size small, and the versioning bumps should also help the workflow maintain itself.

@knylbyte
Copy link
Author

ALL_SITES mode that iterates site channel lists under /epg/sites.

Unfortunately, we cannot blindly combine channel listings from different sites into one, primarily because the guide for the same channel may differ completely in terms of time and description, which leads to an unusable output.

We don't just blindly copy all channels together, but only the first entry found for each channel via Regex. In addition, each site can still be accessed via its name.
Example: your-domain.tld/epg/sky.com/guide.xml

The extension simply makes it possible to retrieve and provide multiple sites filtered by language at the same time, rather than just one page as before.

In addition, the GitHub workflows ensure that the application runs as a non-root user and that the entire Docker container remains up to date, which is a gain in cybersecurity.
Furthermore, tags for all architectures are now cleanly set in the manifest.
In addition, the container size is reduced because only the necessary packages are installed.

All in all, it is more of an extension of the possibilities and an improvement of the CI/CD workflows and cybersecurity.

@freearhey
Copy link
Collaborator

@knylbyte Excuse me, but how exactly is automatically changing the version of Alpine, Node, and all dependencies at a random moment without any verification supposed to “improve cybersecurity”?

We don't just blindly copy all channels together, but only the first entry found for each channel via Regex.

To understand what I mean, just try generating a guide this way yourself.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants