Докеризирање на застарен PHP: прагматичен пат кон модернизација
Наследениот PHP ретко не успева затоа што јазикот е по природа неуправлив. Не успева затоа што неговото извршувачко опкружување станало невидливо: рачно конфигуриран сервер, застарена екстензија, cron задача за која никој не е одговорен и чекори за распоредување што ги памети само една личност. Docker не ја препишува таа историја. Тој ѝ дава на апликацијата стабилна граница околу неа, што често е најбезбедниот прв чекор кон модернизација.
Практичната цел не е стар код да изгледа модерно. Целта е неговото однесување да биде повторливо, разбирливо и побезбедно за менување.
Започнете со зачувување на реалноста
Наследена апликација може да зависи од одредена PHP верзија, Apache модул, библиотека за слики, двигател за база на податоци, поставка за временска зона или директориум со дозвола за запишување. Третирајте ги тие зависности како барања што треба да се откријат, а не како недостатоци што треба да се избришат уште првиот ден.
Пред да изберете основна слика, направете попис на тоа што навистина му е потребно на системот што работи:
- PHP верзијата и овозможените екстензии.
- Веб-серверот и коренот на документите.
- Потребните вредности за PHP конфигурација, особено ограничувањата за прикачување, евидентирањето грешки, сесиите и временската зона.
- Патеки со дозвола за запишување за прикачувања, кеш-датотеки, логови и генерирани извештаи.
- Надворешни услуги како MySQL, Redis, SMTP, складирање објекти и закажани задачи.
- Конфигурација специфична за околината што моментално е вградена во датотеки или поставки на серверот.
Овој попис спречува честа грешка: градење контејнер со уреден изглед кој тивко изоставува критична екстензија или го насочува Apache кон погрешен директориум. Контејнер што не може да го репродуцира однесувањето во продукција не е модернизација; тој е нов механизам за прекин на услугата.
Изградете мало, експлицитно извршувачко опкружување
За апликација што се сервира преку Apache, официјалната PHP Apache слика може да го направи првиот контејнер едноставен. Закачете конкретно PHP издание што е компатибилно со апликацијата и нејзините зависности. Избегнувајте да користите неквалификувана ознака latest: поентата е повторливоста.
FROM php:8.2-apache
RUN docker-php-ext-install pdo_mysql
RUN a2enmod rewrite
COPY . /var/www/html/
RUN chown -R www-data:www-data /var/www/html/var
EXPOSE 80
Овој пример е намерно скромен. Тој ја инсталира PDO MySQL екстензијата, овозможува Apache правила за препишување, ја копира апликацијата и му дава на корисникот на веб-серверот пристап до познат директориум со дозвола за запишување. Во реален проект, точната PHP верзија и екстензии мора да потекнуваат од пописот на зависности, а не од лични преференции.
Не правете ја целата апликација широко достапна за запишување. Идентификувајте ги директориумите на кои навистина им е потребен пристап за запишување и држете го изворниот код само за читање каде што е можно. Таа разлика ги подобрува и дебагирањето и безбедноста: неочекуваните запишувања стануваат полесни за забележување.
Направете го коренот на документите експлицитен
Многу постари рамки изложуваат само директориум public или web. Ако Apache го сервира коренот на складиштето, конфигурациските датотеки и внатрешниот код може да станат достапни. Намерно поставете го коренот на документите и осигурете се дека правилата за препишување ги насочуваат барањата кон предниот контролер кога апликацијата има потреба од него.
Исто така, не претпоставувајте дека постоечка датотека .htaccess е активна. Apache мора да дозволи препокривања за соодветниот директориум, или правилата мора да се преместат во конфигурацијата на виртуелниот хост. Тестирајте обични рути, страници што недостигаат, прикачени датотеки и статички средства по менувањето на оваа граница.
Одделете ја конфигурацијата на апликацијата од сликата
Сликите треба да содржат код и зависности за извршување. Вредностите специфични за околината треба да пристигнуваат при извршување преку променливи на околината, монтирана конфигурација или систем за управување со тајни соодветен за околината за распоредување.
Compose датотека ориентирана кон развој може да ги направи зависностите од услуги видливи:
services:
app:
build: .
ports:
- "8080:80"
environment:
APP_ENV: development
DB_HOST: db
DB_NAME: legacy_app
DB_USER: legacy_user
DB_PASSWORD: change-me
depends_on:
- db
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: legacy_app
MYSQL_USER: legacy_user
MYSQL_PASSWORD: change-me
MYSQL_ROOT_PASSWORD: root-change-me
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Ова е корисно за локален развој, но не е стратегија за продукциски тајни. Не вградувајте ингеренции во сликата, не внесувајте вистински лозинки во репозиториумот и не претпоставувајте дека depends_on значи оти базата на податоци е подготвена да прифаќа конекции. Тоа го контролира редоследот на стартување, а не подготвеноста на ниво на апликација.
Наследените апликации често веднаш се обидуваат да воспостават конекција со базата на податоци и не успеваат ако MySQL сè уште се иницијализира. Робусното решение е однесување на ниво на апликација што повторно се обидува со ограничено доцнење и корисно евидентирање. Ако менувањето на апликацијата сè уште не е изводливо, осигурете се дека платформата за распоредување има проверки на здравјето и однесување при рестартирање што одговара на режимот на неуспех на апликацијата. Важното е однесувањето при стартување да биде намерно, наместо среќна случајност.
Справете се со состојбата без да се преправате дека не постои
Контејнерите се заменливи. Наследените PHP системи често не се. Тие може да запишуваат прикачувања на диск, да користат датотечни сесии, да генерираат минијатури или локално да додаваат записи во логови. Контенеризирањето на апликацијата ја открива оваа состојба, што е вредно бидејќи скриената состојба е една од најтешките пречки за сигурно распоредување.
Класифицирајте ја секоја патека со дозвола за запишување:
- Прикачувања и датотеки генерирани од корисници: користете трајно складирање, како управуван волумен или складирање објекти, со план за резервна копија и обновување.
- Кеш и привремени датотеки: држете ги заменливи кога е можно и осигурете се дека апликацијата може повторно да ги изгради.
- Логови: претпочитајте стандарден излез и стандарден излез за грешки за платформата за извршување да може доследно да ги собира.
- Сесии: датотечните сесии може да функционираат за една инстанца, но потребно е споделено складирање на сесии пред скалирање низ повеќе контејнери на апликацијата.
Не го монтирајте целото изворно стебло во продукциски контејнер само за да ги зачувате прикачувањата или да дозволите брзи поправки. Тоа го заматува распоредениот артефакт и ги прави враќањата на претходна верзија ненадежни. Монтирајте ги само патеките за податоци што бараат трајност.
Користете ја контейнеризацијата за да создадете договор за распоредување што може да се тестира
Dockerfile станува концизна изјава за тоа како работи апликацијата. Тоа го прави одлично место за додавање верификација. Изградете ја сликата во континуирана интеграција, стартувајте ја и извршете мал сет проверки со висока вредност: крајна точка за здравје, репрезентативна страница, патека за конекција со база на податоци и чекор за миграција или валидација на шема каде што е применливо.
Миграциите на база на податоци заслужуваат особена претпазливост. Миграцијата може да биде безбедна за еднократно извршување, но небезбедна за истовремено извршување од повеќе веб-контејнери. Направете една компонента за распоредување одговорна за миграциите, потврдете дека механизмот за миграција е идемпотентен или заштитен и одржувајте план за враќање што признава дека промените во базата на податоци често потешко се враќаат од кодот на апликацијата.
Исто така, одделете ги веб-барањата од работата во заднина. Cron задача што работи во Apache контејнер може привремено да функционира, но го поврзува закажувањето со животниот циклус на веб-серверот. Дефинирајте ги закажаните задачи како посебни задачи или услуги кога околината за распоредување го поддржува тоа. Истиот принцип важи за работниците во редиците: тие треба да имаат сопствен процес, логови, политика за рестартирање и ограничувања на ресурси.
Модернизирајте по слоеви, а не со еден голем скок
Docker е платформа за постепено подобрување. Откако апликацијата работи предвидливо, следните промени стануваат помалку ризични: додајте автоматизирани тестови околу критичното однесување, преместете ги ингеренциите надвор од датотеките, стандардизирајте ги логовите, воведете проверки на здравјето, ажурирајте по една зависност и на крај надградете го PHP.
Не ги комбинирајте сите тие промени во првиот напор за контейнеризација. Надградбата на PHP може да открие застарено однесување; надградбата на базата на податоци може да ги промени SQL режимите или автентикацијата; надградбата на рамката може да ги измени рутирањето и сесиите. Кога сè се менува одеднаш, неуспесите стануваат тешки за дијагностицирање. Стабилен контејнер околу постојното однесување му дава на секое подоцнежно подобрување јасна основна линија.
Контејнерот е почеток на оперативна јасност
Најдобриот исход не е репозиториум со Dockerfile. Тоа е апликација чии претпоставки за извршување се видливи, чии зависности можат повторно да се создадат и чие распоредување може да се тестира пред да стигне до корисниците.
Тоа е причината зошто контейнеризирањето на наследен PHP е толку вредно. Тоа го претвора насобраното оперативно предание во верзионирана конфигурација. Кодот можеби сè уште е стар, но повеќе не е заробен во стар начин на извршување — а тоа често е најпрагматичниот чекор за модернизација што еден тим може да го преземе.