Docker 如何布置PHP開發(fā)環(huán)境,docker布置php開發(fā)
Jul 06, 2016 pm 02:24 PMDocker 如何布置PHP開發(fā)環(huán)境,docker布置php開發(fā)
環(huán)境部署一直是一個(gè)很大的問題,無(wú)論是開發(fā)環(huán)境還是生產(chǎn)環(huán)境,但是 Docker 將開發(fā)環(huán)境和生產(chǎn)環(huán)境以輕量級(jí)方式打包,提供了一致的環(huán)境。極大的提升了開發(fā)部署一致性。當(dāng)然,實(shí)際情況并沒有這么簡(jiǎn)單,因?yàn)樯a(chǎn)環(huán)境和開發(fā)環(huán)境的配置是完全不同的,比如日志等的問題都需要單獨(dú)配置,但是至少比以前更加簡(jiǎn)單方便了,這里以 PHP 開發(fā)作為例子講解 Docker 如何布置開發(fā)環(huán)境。
一般來(lái)說(shuō),一個(gè) PHP 項(xiàng)目會(huì)需要以下工具:
- Web 服務(wù)器: Nginx/Tengine
- Web 程序: PHP-FPM
- 數(shù)據(jù)庫(kù): MySQL/PostgreSQL
- 緩存服務(wù): Redis/Memcache
這是最簡(jiǎn)單的架構(gòu)方式,在 Docker 發(fā)展早期,Docker 被大量的濫用,比如,一個(gè)鏡像內(nèi)啟動(dòng)多服務(wù),日志收集依舊是按照 Syslog 或者別的老方式,鏡像容量非常龐大,基礎(chǔ)鏡像就能達(dá)到 80M,這和 Docker 當(dāng)初提出的思想完全南轅北轍了,而 Alpine Linux 發(fā)行版作為一個(gè)輕量級(jí) Linux 環(huán)境,就非常適合作為 Docker 基礎(chǔ)鏡像,Docker 官方也推薦使用 Alpine 而不是 Debian 作為基礎(chǔ)鏡像,未來(lái)大量的現(xiàn)有官方鏡像也將會(huì)遷移到 Alpine 上。本文所有鏡像都將以 Alpine 作為基礎(chǔ)鏡像。
Nginx/Tengine
這部分筆者已經(jīng)在另一篇文章 Docker 容器的 Nginx 實(shí)踐中講解了 Tengine 的 Docker 實(shí)踐,并且給出了 Dockerfile,由于比較偏好 Tengine,而且官方已經(jīng)給出了 Nginx 的 alpine 鏡像,所以這里就用 Tengine。筆者已經(jīng)將鏡像上傳到官方 DockerHub,可以通過(guò)
docker pull chasontang/tengine:2.1.2_f
獲取鏡像,具體請(qǐng)看 Dockerfile。
PHP-FPM
Docker 官方已經(jīng)提供了 PHP 的 7.0.7-fpm-alpine 鏡像,Dockerfile 如下:
FROM alpine:3.4 # persistent / runtime deps ENV PHPIZE_DEPS \ autoconf \ file \ g++ \ gcc \ libc-dev \ make \ pkgconf \ re2c RUN apk add --no-cache --virtual .persistent-deps \ ca-certificates \ curl # ensure www-data user exists RUN set -x \ && addgroup -g 82 -S www-data \ && adduser -u 82 -D -S -G www-data www-data # 82 is the standard uid/gid for "www-data" in Alpine # http://git.alpinelinux.org/cgit/aports/tree/main/apache2/apache2.pre-install?h=v3.3.2 # http://git.alpinelinux.org/cgit/aports/tree/main/lighttpd/lighttpd.pre-install?h=v3.3.2 # http://git.alpinelinux.org/cgit/aports/tree/main/nginx-initscripts/nginx-initscripts.pre-install?h=v3.3.2 ENV PHP_INI_DIR /usr/local/etc/php RUN mkdir -p $PHP_INI_DIR/conf.d ##<autogenerated>## ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data ##</autogenerated>## ENV GPG_KEYS 1A4E8B7277C42E53DBA9C7B9BCAA30EA9C0D5763 ENV PHP_VERSION 7.0.7 ENV PHP_FILENAME php-7.0.7.tar.xz ENV PHP_SHA256 9cc64a7459242c79c10e79d74feaf5bae3541f604966ceb600c3d2e8f5fe4794 RUN set -xe \ && apk add --no-cache --virtual .build-deps \ $PHPIZE_DEPS \ curl-dev \ gnupg \ libedit-dev \ libxml2-dev \ openssl-dev \ sqlite-dev \ && curl -fSL "http://php.net/get/$PHP_FILENAME/from/this/mirror" -o "$PHP_FILENAME" \ && echo "$PHP_SHA256 *$PHP_FILENAME" | sha256sum -c - \ && curl -fSL "http://php.net/get/$PHP_FILENAME.asc/from/this/mirror" -o "$PHP_FILENAME.asc" \ && export GNUPGHOME="$(mktemp -d)" \ && for key in $GPG_KEYS; do \ gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ done \ && gpg --batch --verify "$PHP_FILENAME.asc" "$PHP_FILENAME" \ && rm -r "$GNUPGHOME" "$PHP_FILENAME.asc" \ && mkdir -p /usr/src \ && tar -Jxf "$PHP_FILENAME" -C /usr/src \ && mv "/usr/src/php-$PHP_VERSION" /usr/src/php \ && rm "$PHP_FILENAME" \ && cd /usr/src/php \ && ./configure \ --with-config-file-path="$PHP_INI_DIR" \ --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \ $PHP_EXTRA_CONFIGURE_ARGS \ --disable-cgi \ # --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself) --enable-mysqlnd \ # --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195) --enable-mbstring \ --with-curl \ --with-libedit \ --with-openssl \ --with-zlib \ && make -j"$(getconf _NPROCESSORS_ONLN)" \ && make install \ && { find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; } \ && make clean \ && runDeps="$( \ scanelf --needed --nobanner --recursive /usr/local \ | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ | sort -u \ | xargs -r apk info --installed \ | sort -u \ )" \ && apk add --no-cache --virtual .php-rundeps $runDeps \ && apk del .build-deps COPY docker-php-ext-* /usr/local/bin/ ##<autogenerated>## WORKDIR /var/www/html RUN set -ex \ && cd /usr/local/etc \ && if [ -d php-fpm.d ]; then \ # for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf" sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \ cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \ else \ # PHP 5.x don't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency mkdir php-fpm.d; \ cp php-fpm.conf.default php-fpm.d/www.conf; \ { \ echo '[global]'; \ echo 'include=etc/php-fpm.d/*.conf'; \ } | tee php-fpm.conf; \ fi \ && { \ echo '[global]'; \ echo 'error_log = /proc/self/fd/2'; \ echo; \ echo '[www]'; \ echo '; if we send this to /proc/self/fd/1, it never appears'; \ echo 'access.log = /proc/self/fd/2'; \ echo; \ echo 'clear_env = no'; \ echo; \ echo '; Ensure worker stdout and stderr are sent to the main error log.'; \ echo 'catch_workers_output = yes'; \ } | tee php-fpm.d/docker.conf \ && { \ echo '[global]'; \ echo 'daemonize = no'; \ echo; \ echo '[www]'; \ echo 'listen = [::]:9000'; \ } | tee php-fpm.d/zz-docker.conf EXPOSE 9000 CMD ["php-fpm"] ##</autogenerated>##
首先,鏡像繼承自 alpine:3.4 鏡像,使用 apk 命令安裝 php 最小依賴,同時(shí)添加 www-data 作為 php-fpm 的運(yùn)行用戶,將 php 的配置文件指定到 /usr/local/etc/php,然后就是下載 php-src,編譯安裝,這里可以參考筆者之前寫的 php 編譯安裝文章。參數(shù)都中規(guī)中矩。安裝目錄被指定到 /usr/local,然后使用 scanelf 獲得所依賴的運(yùn)行庫(kù)列表,并且將其他安裝包刪除。將 docker-php-ext-configure、docker-php-ext-enable、docker-php-ext-install 復(fù)制到容器中,這三個(gè)文件用于后續(xù)安裝擴(kuò)展。然后將 php-fpm.conf 復(fù)制到配置目錄,將 error_log 和 access_log 指定到終端標(biāo)準(zhǔn)輸出,daemonize = no 表示不以服務(wù)進(jìn)程運(yùn)行。EXPOSE 9000 端口用于和其他容器通信,然后就是 CMD ["php-fpm"] 運(yùn)行 php-fpm。而且工作目錄被指定到 /var/www/html。
docker-compose
已經(jīng)搞定了基礎(chǔ)鏡像,我們就可以使用基礎(chǔ)鏡像來(lái)配置容器,但是通過(guò)手工 docker 命令啟動(dòng)容器會(huì)非常麻煩。但是萬(wàn)幸的是官方已經(jīng)提供了 docker-compose 命令來(lái)編排容器,只需要寫一個(gè) docker-compose.yaml 文件就行,具體可以參考官方文檔。
version: '2' services: php-fpm: image: php:7.0.7-fpm-alpine volumes: - "./src:/var/www/html" restart: always tengine: depends_on: - php-fpm links: - php-fpm image: chasontang/tengine:2.1.2_f volumes: - "./nginx.vh.default.conf:/etc/nginx/conf.d/default.conf" ports: - "80:80" restart: always
非常容易理解,這里定義了兩個(gè)服務(wù),php-fpm 依賴 php:7.0.7-fpm-alpine 鏡像,并且將 src 文件夾映射為 /var/www/html 文件夾,tengine 服務(wù)依賴 php-fpm 服務(wù),并且 link php-fpm 服務(wù),這樣就能通過(guò)網(wǎng)絡(luò)與 php-fpm 容器通信,tengine 服務(wù)基于 chasontang/tengine:2.1.2_f 鏡像,并將 nginx.vh.default.conf 文件映射為 /etc/nginx/conf.d/default.conf 文件。然后來(lái)看 nginx.vh.default.conf
server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.*)$; fastcgi_pass php-fpm:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; include fastcgi_params; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} }
tengine 鏡像實(shí)際上使用兩個(gè)配置文件,一個(gè)是 /etc/nginx/nginx.conf,還有就是 /etc/nginx/conf.d/ 目錄下的所有文件,因?yàn)?/etc/nginx/nginx.conf 中使用 include /etc/nginx/conf.d/*.conf; 包含了這個(gè)目錄,也就是說(shuō),可以不需要去管 nginx 其他配置,只需要用自己的 nginx 虛擬主機(jī)配置替代默認(rèn)的虛擬主機(jī)配置,或者說(shuō)增加虛擬主機(jī)配置就行了。
從上面可以看到,default.conf 文件定義了一個(gè) location 匹配包含 .php 的 URL,然后將其分割出 PATH_INFO 參數(shù),將這些變量傳遞給 php-fpm:9000 的 php-fpm 服務(wù)。
這里需要注意的是,由于 Nginx 和 PHP-FPM 不在同一臺(tái)主機(jī)上,所以 Nginx 只做靜態(tài)文件處理和路由轉(zhuǎn)發(fā),實(shí)際的 PHP 文件執(zhí)行時(shí)在 PHP-FPM 容器中發(fā)生的。所以 SCRIPT_FILENAME 變量必須要使用 PHP-FPM 容器中的目錄,所以這里使用硬編碼指定。當(dāng)然,也可以讓兩個(gè)容器共享同一個(gè)數(shù)據(jù)卷,但是筆者認(rèn)為,這只是為了方便容器編排,其他完全沒有好處。
很容易吧! 現(xiàn)在我們可以快速的啟動(dòng)、更新環(huán)境了,但還是有很多地方需要改進(jìn)。

Hei?e KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?er Artikel

Hei?e Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Hei?e Themen





1. Der Ursprung von .NetCore Wenn wir über .NetCore sprechen, dürfen wir seinen Vorg?nger .NET nicht erw?hnen. Java war zu dieser Zeit im Rampenlicht, und Microsoft bevorzugte auch Java. Die Java Virtual Machine auf der Windows -Plattform wurde von Microsoft basierend auf den JVM -Standards entwickelt. Es soll die beste Leistung Java Virtual Machine zu dieser Zeit sein. Microsoft hat jedoch einen eigenen kleinen Abakus, der versucht, Java mit der Windows-Plattform zu bündeln und einige Windows-spezifische Funktionen hinzuzufügen. Die Unzufriedenheit von Sun führte dazu zu einer Aufschlüsselung der Beziehung zwischen den beiden Parteien, und Microsoft startete dann .NET. .NET hat seit seiner Gründung viele Merkmale von Java geliehen und hat Java in Sprachmerkmalen und Formentwicklung nach und nach übertroffen. Java in Version 1.6

Die plattformübergreifende Entwicklung in C wird empfohlen, um Visualstudiocode, Clion und QTCreator zu verwenden. 1. VisualstudioCode ist leicht und flexibel, geeignet für die Entwicklung von mehreren Plattformarbeiten, die anf?ngliche Konfiguration ist jedoch komplizierter. 2. Clion integriert CMake, geeignet für plattformübergreifende Projekte, Lizenzen sind jedoch teuer. 3.QTCreator unterstützt die plattformübergreifende Entwicklung mit integrierter QT-Bibliothek, aber die Lernkurve ist steil.

Um eine vollst?ndige Python -Webanwendung zu entwickeln, befolgen Sie die folgenden Schritte: 1. W?hlen Sie das entsprechende Framework wie Django oder Flask. 2. Integrieren Sie Datenbanken und verwenden Sie Ormen wie SQLalchemy. 3. Entwerfen Sie das Front-End und verwenden Sie Vue oder React. 4. Führen Sie den Test durch, verwenden Sie PyTest oder Unittest. 5. Anwendungen bereitstellen, Docker und Plattformen wie Heroku oder AWS verwenden. Durch diese Schritte k?nnen leistungsstarke und effiziente Webanwendungen erstellt werden.

Docker und Kubernetes sind Führungskr?fte in Containerisierung und Orchestrierung. Docker konzentriert sich auf das Lebenszyklusmanagement des Containers und eignet sich für kleine Projekte. Kubernetes ist gut in der Containerorchestrierung und für gro? angelegte Produktionsumgebungen geeignet. Die Kombination der beiden kann die Entwicklungs- und Bereitstellungseffizienz verbessern.

Cross-Compilation in C bezieht sich auf die Erstellung einer ausführbaren Datei oder Bibliothek, die auf einer anderen Plattform auf einer Plattform ausgeführt werden kann. 1) Kreuzkompilation erfordert die Verwendung eines speziellen Cross-Compiler wie GCC- oder Klangvarianten. 2) Das Einrichten einer Cross-Compilation-Umgebung kann Docker verwenden, um Toolchains zu verwalten, um Wiederholbarkeit und Portabilit?t zu verbessern. 3) Achten Sie beim Cross -Compiling auf die Optionen zur Codeoptimierungsoptionen wie -o2, -o3 oder -Os, um Leistung und Dateigr??e auszugleichen.

Es gibt drei M?glichkeiten, die Prozessinformationen im Docker -Container anzuzeigen: 1. Verwenden Sie den Befehl docktop, um alle Prozesse im Container aufzulisten und PID, Benutzer, Befehl und andere Informationen anzuzeigen. 2. Verwenden Sie DockeKerexec, um den Container einzugeben, und verwenden Sie den Befehl ps oder oberes, um detaillierte Prozessinformationen anzuzeigen. 3.. Verwenden Sie den Befehl dockstats, um die Verwendung von Containerressourcen in Echtzeit anzuzeigen und Dockertop zu kombinieren, um die Leistung des Containers vollst?ndig zu verstehen.

Die Bereitstellung einer Pytorch -Anwendung auf Ubuntu kann durch Ausma? der Schritte durchgeführt werden: 1. Installieren Sie Python und Pip zuerst sicher, dass Python und PIP bereits auf Ihrem System installiert sind. Sie k?nnen sie mit dem folgenden Befehl installieren: sudoaptupdatesudoaptinstallpython3python3-pip2. Erstellen Sie eine virtuelle (optionale) Umgebung, um Ihre Projektumgebung zu isolieren. Es wird empfohlen, eine virtuelle Umgebung zu erstellen: Python3-mvenvMyenvSourceMyEnv/bin/activatet

Das Bereitstellen und Tuning von Jenkins auf Debian ist ein Prozess, der mehrere Schritte umfasst, einschlie?lich Installation, Konfiguration, Plug-in-Management und Leistungsoptimierung. Hier finden Sie eine detaillierte Anleitung, mit der Sie eine effiziente Jenkins -Bereitstellung erzielen k?nnen. Wenn Sie zuerst Jenkins installieren, stellen Sie sicher, dass Ihr System über eine Java -Umgebung installiert ist. Jenkins ben?tigt eine Java -Laufzeitumgebung (JRE), um ordnungsgem?? zu laufen. sudoaptupdatesudoaptininstallopenjdk-11-jdk überprüfen Sie, dass die Java-Installation erfolgreich ist: Java-Version Weiter, fügen Sie j hinzu
