容器指南之自定义LNMP容器镜像 Posted 2022-12-13
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了容器指南之自定义LNMP容器镜像相关的知识,希望对你有一定的参考价值。
1.简介 在Linux 环境中最常用的组件应该属于 LNMP 组合(Linux + nginx + mysql +php ),当然,随着Go、Rust语言的普及,生产环境有更多的组合配置。但是 Nginx 的Web端和MySQL 的数据库端还是主力配置。
受 Nginx、MySQL 和 PHP 多版本和多配置文件的影响,在生产或测试环境要保持各组件版本和对应的配置文件(特别是安全配置)统一需要花费大量的时间和成本。
使用容器技术定制适合自己环境的组件镜像,需要使用的时候无需复杂和长时间的配置调整就能在1分钟以内提供标准的经过验证的LNMP 环境。
Nginx 配置指南 https://blog.51cto.com/waringid/1438852
容器指南之第一个容器 https://blog.51cto.com/waringid/5904849
容器指南之容器架构及常用指令 https://blog.51cto.com/waringid/5913145
容器指南之日常运维 https://blog.51cto.com/waringid/5914178
Docker For Windows 安装配置及常用维护 https://blog.51cto.com/waringid/5917666
2.LNMP 环境介绍 1、基于 PHP7.4.28 版本,添加 PHP-GD 扩展
2、Nginx 配置最新版本
3、Mysql 使用 Mariadb10版本
2.1.自定义 php 环境 sudo mkdir /opt/phpsudo chown docker /opt/phpcat > /opt/php/Dockfile << EOF FROM php:7.4.28-fpm-alpine3.15 RUN set -x \\ && echo "http://mirrors.huaweicloud.com/alpine/latest-stable/main/" > /etc/apk/repositories \\ && echo "http://mirrors.huaweicloud.com/alpine/latest-stable/community/" >> /etc/apk/repositories \\ && apk update \\ && apk add --no-cache tzdata \\ && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \\ && echo "Asia/Shanghai" > /etc/timezone \\ && apk del tzdata \\ && apk add --no-cache graphviz zlib-dev libpng-dev libxml2-dev zip libzip-dev \\ && docker-php-ext-configure zip \\ && docker-php-ext-install gd pdo_mysql soap mysqli zip EOF docker build -t php-fpm:7.4 . docker imagessudo docker save -o /opt/images/php-fpm-7.4.28.tar php-fpm:7.4
2.2.配置 LNMP 环境 sudo mkdir /opt/lnmpsudo chown docker /opt/lnmpcat > /opt/lnmp/docker-compose.yml << EOF version: 2.1 services: db: image: mariadb:10.5 container_name: mysql ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=password # Root password of MySQL -- must be changed - MYSQL_LOG_CONSOLE=true volumes: - /opt/lnmp/mysql-data:/var/lib/mysql # Volume of MySQL (directory for persistent storage) and mount point in container -- can be changed (not advised) networks: lnmp-net: ipv4_address: 172.18.0.3 nginx: image: nginx container_name: nginx ports: - "80:80" volumes: - /opt/lnmp/nginx/www:/usr/share/nginx/html - /opt/lnmp/nginx/conf:/etc/nginx/conf - /opt/lnmp/nginx/conf.d:/etc/nginx/conf.d - /opt/lnmp/nginx/logs:/var/log/nginx networks: lnmp-net: ipv4_address: 172.18.0.2 php: image: php-fpm:7.4 container_name: php volumes: - /opt/lnmp/nginx/www:/www networks: lnmp-net: ipv4_address: 172.18.0.3 networks: ipam: config: - subnet: "172.18.0.0/24" EOF cat > /opt/lnmp/nginx/conf.d/php.conf << EOF server listen 80; server_name localhost; client_max_body_size 1000m; location / root /usr/share/nginx/html; index index.html index.htm index.php; if ( !-f $request_filename ) rewrite ^/login$ /login.php last; rewrite ^/register$ /register.php last; rewrite ^/search$ /search.php last; rewrite ^/discount/student$ /discount.php?u=d last; rewrite ^/discount/teacher$ /discount.php?u=t last; # rewrite ^/admin.php$ /404.html break; rewrite ^/(.*)$ /index.php/$1 last; error_page 500 502 503 504 /50x.html; location = /50x.html root /usr/share/nginx/html; location ~ \\.php(.*)$ root /www; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_split_path_info ^(.+\\.php)(.*)$; fastcgi_param SCRIPT_FILENAME /www$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; include fastcgi_params; EOF cat > /opt/lnmp/nginx/www/index.php << EOF <?php error_reporting(E_ALL); ini_set(display_errors, 1); echo <h1 style="text-align: center;">欢迎使用DNMP!</h1>; echo <h2>版本信息</h2>; echo <ul>; echo <li>PHP版本:, PHP_VERSION, </li>; echo <li>Nginx版本:, $_SERVER[SERVER_SOFTWARE], </li>; echo <li>MySQL服务器版本:, getMysqlVersion(), </li>; echo <li>Redis服务器版本:, getRedisVersion(), </li>; echo <li>MongoDB服务器版本:, getMongoVersion(), </li>; echo </ul>; echo <h2>已安装扩展</h2>; printExtensions(); /** * * 获取MySQL版本 * */ function getMysqlVersion() if (extension_loaded(PDO_MYSQL)) try $dbh = new PDO(mysql:host=mysql;dbname=mysql, root, 123456); $sth = $dbh->query(SELECT VERSION() as version); $info = $sth->fetch(); catch (PDOException $e) return $e->getMessage(); return $info[version]; else return PDO_MYSQL 扩展未安装 ×; /** * * 获取Redis版本 * */ function getRedisVersion() if (extension_loaded(redis)) try $redis = new Redis(); $redis->connect(redis, 6379); $info = $redis->info(); return $info[redis_version]; catch (Exception $e) return $e->getMessage(); else return Redis 扩展未安装 ×; /** * * 获取MongoDB版本 * */ function getMongoVersion() if (extension_loaded(mongodb)) try $manager = new MongoDB\\Driver\\Manager(mongodb://root:123456@mongodb:27017); $command = new MongoDB\\Driver\\Command(array(serverStatus=>true)); $cursor = $manager->executeCommand(admin, $command); return $cursor->toArray()[0]->version; catch (Exception $e) return $e->getMessage(); else return MongoDB 扩展未安装 ×; /** * * 获取已安装扩展列表 * */ function printExtensions() echo <ol>; foreach (get_loaded_extensions() as $i => $name) echo "<li>", $name, =, phpversion($name), </li>; echo </ol>; EOF cd /opt/lnmp docker-compose up
2.3.安装扩展 默认php镜像中提供的扩展比较少,缺少诸如mysql、gd2等常用的扩展,这样我们就需要自己安装并启用扩展。
首先进入到php容器,用php -m命令查看本地有什么扩展。
可以使用docker-php-ext-install命令来安装扩展。
docker-php-ext-install mysql
扩展安装好之后就可以在php.ini中启用。我们从phpinfo中可以看到,容器环境下默认的php.ini没有启用,可以从/usr/local/etc/php下将php.ini-development拷贝为php.ini。通过修改php.ini中配置,启用自己需要的扩展。
下面是几个扩展安装的命令,供参考。
docker-php-ext-source 在容器中创建一个/usr/src/php目录 docker-php-ext-enable启用PHP扩展,省去我们手工编辑php.ini的过程 docker-php-ext-install安装并启用PHP扩展 docker-php-ext-configure经常与docker-php-ext-install搭配,在需要自定义扩展的配置时使用 2.4.单独运行命令行 如果仅需要在命令行下运行 php 命令,可以使用如下方式
# 将当前目录挂载到 /tmp 目录,执行 php 命令,结束后退出
docker run -it --rm -v $PWD :/tmp -w /tmp php-fpm:7.4 php test.php
3.备份和恢复数据库 docker exec -it seafile-mysql mysqldump -uroot --opt ccnet_db > ccnet_db.sql docker exec -it seafile-mysql mysqldump -uroot --opt seafile_db > seafile_db.sql docker exec -it seafile-mysql mysqldump -uroot --opt seahub_db > seahub_db.sql docker cp /opt/seafile-backup/databases/ccnet_db.sql seafile-mysql:/tmp/ccnet_db.sql docker cp /opt/seafile-backup/databases/seafile_db.sql seafile-mysql:/tmp/seafile_db.sql docker cp /opt/seafile-backup/databases/seahub_db.sql seafile-mysql:/tmp/seahub_db.sql docker exec -it seafile-mysql /bin/sh -c "mysql -uroot ccnet_db < /tmp/ccnet_db.sql" docker exec -it seafile-mysql /bin/sh -c "mysql -uroot seafile_db < /tmp/seafile_db.sql" docker exec -it seafile-mysql /bin/sh -c "mysql -uroot seahub_db < /tmp/seahub_db.sql"
4.常见问题 mysql 容器
解决方法:
security_opt : - seccomp:unconfined以上是关于容器指南之自定义LNMP容器镜像的主要内容,如果未能解决你的问题,请参考以下文章
容器指南之自定义 jira 容器镜像
魔法方法之自定义序列
使用Docker容器 自定义网桥模式搭建LNMP架构
docker安装步骤及基于docker容器部署web应用LNMP服务器环境
玩转dnmp之自定义PHP容器
使用Docker容器搭建LNMP架构