# CI/CD: αυτόματη επανακατασκευή εικόνων PHP

> Αυτόματη επανακατασκευή εικόνων Docker: builds με χρονοπρογραμματισμό, έλεγχος έκδοσης στο pipeline και rollout με digest, ώστε τα patches PHP να φτάνουν αξιόπιστα.

Πηγή: https://phpsos.de/el/blog/php-images-in-ci-neu-bauen/  
Ημερομηνία: 25/10/2026  
Πάροχος: PHP SOS, Επείγουσα βοήθεια PHP και ασφάλεια διακομιστών. Άμεση βοήθεια μέσω WhatsApp: https://wa.me/491736494914?text=%CE%93%CE%B5%CE%B9%CE%B1%20%CF%83%CE%B1%CF%82%2C%20PHP%20SOS%2C%20%CF%87%CF%81%CE%B5%CE%B9%CE%B1%CE%B6%CF%8C%CE%BC%CE%B1%CF%83%CF%84%CE%B5%20%CE%B2%CE%BF%CE%AE%CE%B8%CE%B5%CE%B9%CE%B1%20%CE%BC%CE%B5%20%CF%84%CE%BF%CE%BD%20%CE%B4%CE%B9%CE%B1%CE%BA%CE%BF%CE%BC%CE%B9%CF%83%CF%84%CE%AE%20PHP%20%CE%BC%CE%B1%CF%82.%20%CE%95%CF%84%CE%B1%CE%B9%CF%81%CE%B5%CE%AF%CE%B1%3A%20%E2%80%A6%20%CE%99%CF%83%CF%84%CF%8C%CF%84%CE%BF%CF%80%CE%BF%CF%82%3A%20%E2%80%A6

**Εν ολίγοις:** Μια εικόνα Docker περιέχει την PHP στο επίπεδο της στιγμής που χτίστηκε και παλιώνει και χωρίς αλλαγή κώδικα. Όποιος ξαναχτίζει αυτόματα τις εικόνες, με χρονοπρογραμματισμό και σε ανακοινώσεις ασφαλείας, ελέγχει την έκδοση PHP στο pipeline και κάνει rollout με digest, φέρνει patches όπως αυτά για το PHP2Shell στην παραγωγή με προγραμματισμό. Ένα πράσινο build από μόνο του δεν είναι τεκμήριο· μετράει η έκδοση στο container που τρέχει.

## Γιατί οι εικόνες παλιώνουν χωρίς αλλαγή κώδικα

Σε πολλές ομάδες το pipeline build ξεκινά μόνο όταν κάποιος αλλάζει κώδικα. Για την εφαρμογή αυτό είναι λογικό. Για την ασφάλεια είναι πρόβλημα, επειδή η PHP στην εικόνα προέρχεται από το βασικό image του tag του τελευταίου build.

Το PHP2Shell το έκανε ορατό. Οι διορθωμένες εκδόσεις 8.5.12, 8.4.27, 8.3.36 και 8.2.35 κυκλοφόρησαν στις 21 Οκτωβρίου 2026. Ένα έργο στο οποίο δεν δούλεψε κανείς αυτές τις ημέρες δεν έλαβε νέο build και συνέχισε να τρέχει με την παλιά PHP, παρόλο που το βασικό image είχε προ πολλού ενημερωθεί. Τη χειροκίνητη διαδρομή από αυτή την κατάσταση περιγράφει το [Patch PHP σε containers Docker](https://phpsos.de/el/php2shell/docker-container-patchen/). Αυτό το άρθρο δείχνει πώς θα την αυτοματοποιήσετε.

## Αυτόματη επανακατασκευή εικόνων Docker: τρεις εκκινητές

Μια στιβαρή διαδικασία συνδυάζει περισσότερους εκκινητές, ώστε κανένας να μη χρειάζεται να σηκώνει μόνος το βάρος.

| Εκκινητής | Υλοποίηση | Τι να προσέξετε |
|---|---|---|
| Χρονοδιάγραμμα | workflow με χρονοπρογραμματισμό, π.χ. εβδομαδιαίο | παραλαμβάνει patches και χωρίς αλλαγή κώδικα |
| Νέο βασικό image | εργαλείο που παρακολουθεί βασικά images και προτείνει αλλαγές | ισχύει κυρίως σε σταθερά tags έκδοσης |
| Ανακοίνωση ασφαλείας | χειροκίνητη εκκίνηση του pipeline από την ομάδα λειτουργίας | χρειάζεται σαφή υπεύθυνο |

Στο GitHub Actions το γεγονός `schedule` αναλαμβάνει το χρονοδιάγραμμα. Σύμφωνα με την τεκμηρίωση του GitHub χρησιμοποιεί τη σύνταξη cron με πέντε πεδία, τρέχει σε UTC και μόνο στο προεπιλεγμένο branch. Οι προγραμματισμένες εκτελέσεις μπορεί να ξεκινήσουν με καθυστέρηση σε υψηλό φορτίο και σε δημόσια αποθετήρια το GitHub τις απενεργοποιεί μετά από 60 ημέρες χωρίς δραστηριότητα. Αυτό το τελευταίο αφορά ιδίως τα ήσυχα έργα, δηλαδή ακριβώς εκείνα που χρειάζονται πιο επειγόντως την αυτόματη επανακατασκευή.

Για τον δεύτερο εκκινητή το Dependabot υποστηρίζει, σύμφωνα με την τεκμηρίωση του GitHub, το οικοσύστημα `docker` και προτείνει νέα επίπεδα βασικών images ως pull request. Δύο περιορισμούς πρέπει να γνωρίζετε. Πρώτον, κάποιος πρέπει να ελέγξει και να συγχωνεύσει το pull request, αλλιώς μένει στάσιμο. Δεύτερον, σε ένα tag κλάδου όπως το `php:8.3-fpm` δεν αλλάζει τίποτα στο Dockerfile όταν ξαναχτίζεται το βασικό image. Ένα εργαλείο που προτείνει αλλαγές κειμένου δεν έχει τότε τίποτα να προτείνει. Γι' αυτό ακριβώς χρειάζεται επιπλέον η επανακατασκευή με χρονοπρογραμματισμό.

Ο τρίτος εκκινητής ακούγεται τετριμμένος, στην πράξη όμως αποτυγχάνει συχνά στο ερώτημα ποιος τον ενεργοποιεί. Ορίστε ποιος παρακολουθεί τις ανακοινώσεις ασφαλείας για την PHP και ποιος επιτρέπεται να ξεκινήσει το pipeline, και το Σαββατοκύριακο. Στο PHP2Shell μεσολάβησε ανάμεσα στην προαναγγελία και στο patch μόνο μία ημέρα.

## Ένα pipeline που εντοπίζει παρωχημένη PHP

Το παρακάτω παράδειγμα για GitHub Actions χτίζει την εικόνα εβδομαδιαία και με το πάτημα ενός κουμπιού, ελέγχει την έκδοση PHP και διακόπτει αν βρίσκεται κάτω από το διορθωμένο επίπεδο. Το registry, τα ονόματα και την ελάχιστη έκδοση τα προσαρμόζετε.

```yaml
name: php-image-rebuild
on:
  schedule:
    - cron: "0 3 * * 1"      # κάθε Δευτέρα 03:00 UTC
  workflow_dispatch: {}      # χειροκίνητη εκκίνηση σε ανακοινώσεις ασφαλείας

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Image ohne Cache und mit frischem Basis-Image bauen
        run: docker build --pull --no-cache -t app:${{ github.run_id }} .
      - name: PHP-Version prüfen (Mindeststand des Zweigs 8.3)
        run: |
          docker run --rm app:${{ github.run_id }} php -v
          docker run --rm app:${{ github.run_id }} \
            php -r 'exit(version_compare(PHP_VERSION, "8.3.36", ">=") ? 0 : 1);'
```

Ο έλεγχος έκδοσης λειτουργεί σε επίσημες εικόνες PHP, των οποίων ο αριθμός έκδοσης δείχνει το πραγματικό επίπεδο. Αν η εικόνα σας χρησιμοποιεί πακέτα PHP μιας διανομής, ο αριθμός παραμένει συχνά ίδιος μετά από ένα backport. Τότε ελέγχετε αντί για τον αριθμό το changelog του πακέτου για τους αριθμούς CVE, όπως περιγράφεται στο άρθρο [Τεκμηρίωση αριθμών CVE στο changelog του πακέτου](https://phpsos.de/el/blog/cve-im-changelog-nachweisen/).

Μετά τον έλεγχο ακολουθούν στην πράξη τρία ακόμη βήματα: σάρωση της εικόνας για γνωστές ευπάθειες, ώθησή της στο registry με ημερομηνία και digest και παράδοση του digest στην παροχή. Ποια tags και παραλλαγές ενδείκνυνται ως βάση, εξηγεί το [Επίσημες εικόνες PHP Docker](https://phpsos.de/el/blog/offizielle-php-docker-images/).

## Από το build στο container που τρέχει

Το συχνότερο λάθος σκέψης: το pipeline είναι πράσινο, άρα όλα έχουν patch. Στην πραγματικότητα η νέα εικόνα βρίσκεται μόνο στο registry. Το patch γίνεται αποτελεσματικό μόνο όταν κάθε container έχει δημιουργηθεί ξανά από τη νέα εικόνα.

1. **Rollout με digest:** Η παροχή παραπέμπει στο digest της νέας εικόνας, όχι σε ένα tag που μετακινείται.
2. **Πρώτα staging, μετά παραγωγή:** Αυτόματες δοκιμές σε αντίγραφο εντοπίζουν ρήξεις από νέα βασικά images.
3. **Έλεγχος στη λειτουργία:** Μετά το rollout εκτελέστε `php -v` στο container που τρέχει και συγκρίνετε το digest με το build.
4. **Περιορισμός της οδού επιστροφής:** Η παλιά εικόνα παραμένει διαθέσιμη για σύντομη επιστροφή, περιέχει όμως την ευπαθή PHP.

Στο Kubernetes ισχύουν γι' αυτό δικοί κανόνες, για παράδειγμα για την pull policy· βρίσκονται στο [Patch PHP στο Kubernetes](https://phpsos.de/el/server/kubernetes/).

## Τυπικά κενά στην αλυσίδα

- **Cache build στο runner:** Χωρίς `--pull` και `--no-cache` ξαναχρησιμοποιείται το παλιό βασικό image.
- **Καθρέφτης registry:** Μια εσωτερική ενδιάμεση μνήμη παραδίδει ακόμη το παλιό επίπεδο του βασικού image.
- **Builds πολλαπλών σταδίων:** Μετράει η έκδοση PHP του τελευταίου σταδίου, ελέγχεται όμως συχνά μόνο το πρώτο.
- **Δευτερεύουσες εικόνες:** Workers ουράς, containers cron και εσωτερικά εργαλεία έχουν δικά τους pipelines ή και κανένα.
- **Σταθερά καταχωρισμένα digests:** Ένα digest του βασικού image που καθηλώθηκε κάποτε δεν ενημερώνεται ποτέ, αν κανένα εργαλείο δεν το παρακολουθεί.

> **Σημαντικό:**
> Μια επανακατασκευή αντικαθιστά την PHP, όχι τα δεδομένα. Κακόβουλος κώδικας που έφτασε πριν από το patch σε volumes, φακέλους upload ή στη βάση δεδομένων παραμένει και πρέπει να ελεγχθεί χωριστά.

## Ποιος αντιδρά όταν αποτύχει η επανακατασκευή;

Μια αυτόματη επανακατασκευή είναι τόσο καλή όσο η αντίδραση στην αποτυχία της. Αν ο έλεγχος έκδοσης ειδοποιήσει ή το build διακοπεί λόγω αλλαγμένου βασικού image, κάποιος πρέπει να το προσέξει. Σε πολλές ομάδες τέτοια μηνύματα καταλήγουν σε ένα γραμματοκιβώτιο που δεν διαβάζει κανείς ή σε ένα κανάλι όπου τα κόκκινα builds είναι προ πολλού καθημερινότητα.

Έχει αποδειχθεί χρήσιμος ένας σαφής κανόνας: μια αποτυχημένη επανακατασκευή ασφαλείας είναι ένα ticket με υπεύθυνο και προθεσμία, όχι μια ένδειξη ανάμεσα σε πολλές. Καταγράψτε επιπλέον για κάθε διανεμημένη εικόνα ημερομηνία, digest και ελεγμένη έκδοση PHP. Αυτή η λίστα απαντά στην επόμενη ανακοίνωση μέσα σε λεπτά ποιες εφαρμογές επηρεάζονται και χρησιμεύει έναντι ελεγκτών ή ασφαλιστών ως τεκμήριο. Πώς προκύπτει από αυτό μια μόνιμη διαδικασία, περιγράφει το [Διαχείριση patches ως διαδικασία αντί για πυροσβεστική](https://phpsos.de/el/blog/patch-management-prozess/).

## Πώς βοηθά συγκεκριμένα η PHP SOS;

- **Έλεγχος pipelines:** Εξετάζουμε τις αλυσίδες build και rollout σας και δείχνουμε πού μπορεί να κολλήσει ένα patch.
- **Αυτοματοποίηση της επανακατασκευής:** Ρυθμίζουμε builds με χρονοπρογραμματισμό, έλεγχο έκδοσης και rollout με digest.
- **Καταγραφή όλων των εικόνων:** Αντιστοιχίζουμε σε κάθε container που τρέχει το pipeline του, και σε δευτερεύουσες και παλιές εικόνες.
- **Διαρκής επιτήρηση:** Στη [σύμβαση συντήρησης ασφαλείας](https://phpsos.de/el/leistungen/security-wartungsvertrag/) παρακολουθούμε ανακοινώσεις ασφαλείας και εκκινούμε επανακατασκευές.


## Συχνές ερωτήσεις

**Πόσο συχνά πρέπει να ξαναχτίζεται μια εικόνα PHP;**  
Δεν υπάρχει σταθερός αριθμός. Έχει αποδειχθεί χρήσιμο ένα τακτικό build με χρονοπρογραμματισμό, για παράδειγμα εβδομαδιαίο, και ένα άμεσο build σε ανακοινώσεις ασφαλείας. Καθοριστικό είναι ότι ένα νέο patch δεν πρέπει να περιμένει την επόμενη αλλαγή κώδικα.

**Αρκεί ένα επιτυχημένο build ως τεκμήριο;**  
Όχι. Ένα build αποδεικνύει μόνο ότι υπάρχει μια νέα εικόνα. Μόνο όταν τα containers που τρέχουν έχουν δημιουργηθεί ξανά από αυτή την εικόνα και το php -v μέσα σε αυτά δείχνει τη διορθωμένη έκδοση, το patch είναι αποτελεσματικό.

**Γιατί μετά την επανακατασκευή εμφανίζεται παρ' όλα αυτά η παλιά έκδοση PHP;**  
Συχνές αιτίες είναι μια cache build που ξαναχρησιμοποιεί το παλιό βασικό image, ένας καθρέφτης registry με παλιό επίπεδο ή μια δεύτερη γραμμή FROM σε build πολλαπλών σταδίων. Χτίστε με --pull και --no-cache και ελέγξτε κάθε στάδιο.

**Μπορεί το Dependabot να ενημερώνει βασικά images;**  
Σύμφωνα με την τεκμηρίωση του GitHub, το Dependabot υποστηρίζει το οικοσύστημα Docker για ενημερώσεις έκδοσης και ασφαλείας. Προτείνει αλλαγές στα βασικά images ως pull request. Την επανακατασκευή με αμετάβλητο tag δεν την αντικαθιστά.

## Πηγές

- [GitHub Docs: γεγονότα που ενεργοποιούν workflows (schedule)](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows)
- [GitHub Docs: οικοσυστήματα που υποστηρίζονται από το Dependabot](https://docs.github.com/en/code-security/dependabot/ecosystems-supported-by-dependabot/supported-ecosystems-and-repositories)
- [Docker Hub: επίσημη εικόνα PHP](https://hub.docker.com/_/php)
- [PHP: υποστηριζόμενες εκδόσεις](https://www.php.net/supported-versions.php)
