[docker] 多容器项目 - PHP+MySQL+Nginx+utility containers

[docker] 多容器项目 - PHP+MySQL+Nginx+utility containers

这个项目总共会配置 6 个容器,主要还是学习一下 docker 的使用和配置,目标是:

  • 本机不安装 PHP、Nginx

    安装部分全都交给 docker 容器实现

  • 可以运行一个 Laravel 网页项目

  • 修改本机代码可以即时更新网页

大概流程是这样的:

utility
npm
Laravel Artisan
Composer
MySQL Database
Nginx Web Server
host machine, source code folder
PHP Interpreter

主机只负责保存必要的源码,PHP 容器会读取本机变动的源码,随后进行必要的更新

这个项目也是把之前所有学的知识点全都整合一下,本项目没有任何的 PHP 实现

service 实现

按照模块分

nginx

YAML 部分配置如下:

server:image: "nginx:stable-alpine3.17"ports:- "8000:80"volumes:- ./src:/var/www/html:delegated- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
  • image 选择用 alpine 是因为体积小一些

  • port 是暴露的端口

  • volumes 是配置文件的 bind mounts

    host machine 不会安装 nginx,所以配置文件只能选择用 bind mounts 进行同步

    src 还没有创建,到 php 那里会创建目录

nginx.conf 配置如下:

server {listen 80;index index.php index.html;server_name localhost;root /var/www/html/public;location / {try_files $uri $uri/ /index.php?$query_string;}location ~ \.php$ {try_files $uri =404;fastcgi_split_path_info ^(.+\.php)(/.+)$;fastcgi_pass php:9000;fastcgi_index index.php;include fastcgi_params;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;fastcgi_param PATH_INFO $fastcgi_path_info;}
}

nginx 的配置不会细说,这里唯一提到的就是这行配置:fastcgi_pass php:9000;。这里的 php 是 docker 容器的名称,对应的是 docker-compose 中的 php 这个 service,而 9000 是 php 镜像默认暴露的端口

此时目录结构如下:

❯ tree .
.
├── docker-compose.yaml
└── nginx└── nginx.conf2 directories, 2 files

php

dockerfile 如下:

FROM php:8.1-fpm-alpineWORKDIR /var/www/htmlRUN docker-php-ext-install pdo pdo_mysql

这里是一个最简配置,其中:

  • php:8.1-fpm-alpine 是需要的 docker 镜像

    Nginx 用 PHP Fast Process Manager (PHP-FPM) 去运行脚本,所以 一定 要用 fpm 相关的镜像

  • /var/www/html 这个目录和 Laravel 的配置相关

  • RUN 指令会下载安装所需要的依赖

service 部分实现如下:

php:build:context: "./dockerfiles"dockerfile: "php.dockerfile"volumes:- ./src:/var/www/html:delegated# ports:#   - "3000:9000"

这里没什么特别复杂的,bind mounts 是为了同步本机的源码与 php 文件中的源码,delegated 可以理解成 batch update,是一个小优化

这里的 port mapping 被注释掉了,原因是因为 php 需要和 nginx 进行沟通,但是沟通的配置已经通过 nginx 实现,所以这里并不需要暴露端口。之后在 docker 的安全部分也会提及一下这个内容

mysql

⚠️:Laravel 现在默认使用的是 SQLite,不过这里还是会使用 mysql

service 的配置如下:

mysql:image: mysql:8.3.0env_file:- "./env/mysql.env"

这里版本随意,用 latest 也行,我主要想看下下载下来的 image 有多大……我下载下来的 latest 有 632MB,但是 tags 上显示的都是不到 200MB……沉思……

环境变量的配置如下:

MYSQL_DATABASE=homestead
MYSQL_USER=homestead
MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=secret

homestead 曾经 是 laravel 的默认数据库名称,配置方面的就不多赘述了

这时候项目结构如下

❯ tree
.
├── docker-compose.yaml
├── dockerfiles
│   └── php.dockerfile
├── env
│   └── mysql.env
├── nginx
│   └── nginx.conf
└── src5 directories, 4 files

到这一步,主要的容器都实现完毕了,下面的都是 util container,用来辅助实现功能的

composer

composer 是用来安装 laravel 的,主要是用来配置 laravel 项目,属于运行了一次之后就可以关闭的那种

docker compose 配置如下:

composer:build:context: ./dockerfilesdockerfile: composer.dockerfilevolumes:- ./src:/var/www/html:delegated

这里的内容都过了一遍了,就不多赘述。dockerfile 内容如下:

FROM composer:latestWORKDIR /var/www/htmlENTRYPOINT [ "composer" ]

这里主要就是需要一个 ENTRYPOINT 的实现,去在 WORKDIR 下执行命令

⚠️:我看到教程上说需要添加 "--ignore-platform-reqs",事实上我加了这个 flag 反而会有 version 冲突的问题……是 PHP7 和 PHP8 之间关于 readonly 这个 namespace 的冲突

此时项目结构如下:

❯ tree
.
├── docker-compose.yaml
├── dockerfiles
│   ├── composer.dockerfile
│   └── php.dockerfile
├── env
│   └── mysql.env
├── nginx
│   └── nginx.conf
└── src5 directories, 5 files
创建 laravel 项目

这里是从 Creating a Laravel Project 这里贴的指令,需要运行的指令如下:

composer create-project laravel/laravel example-app

ENTRYPOINT 已经指定了 composer,所以在终端上只需要运行 create-project laravel/laravel example-app 即可

这里会先运行一下 composer,去创建一个基础的 laravel 项目结构。因为已经实现了 bind mounts,所以后面的容器可以通过当前的项目结构去在容器中,通过 php 和 nginx 去启动服务器

docker compose run --rm composer create-project laravel/laravel .
WARN[0000] /Users/user/study/docker/section08/docker-compose.yaml: `version` is obsolete
[+] Creating 1/1✔ Network section08_default  Created                                                                                                                 0.1s
[+] Building 8.0s (6/6) FINISHED                                                                                                      docker:desktop-linux
# 省略一些 download 和 build 过程85 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --forceINFO  No publishable resources for tag [laravel-assets].No security vulnerability advisories found.
> @php artisan key:generate --ansiINFO  Application key set successfully.> @php -r "file_exists('database/database.sqlite') || touch('database/database.sqlite');"
> @php artisan migrate --graceful --ansiINFO  Preparing database.Creating migration table ............................................................................................................. 9.41ms DONEINFO  Running migrations.0001_01_01_000000_create_users_table ................................................................................................ 34.41ms DONE0001_01_01_000001_create_cache_table ................................................................................................. 8.67ms DONE0001_01_01_000002_create_jobs_table ................................................................................................. 30.52ms DONE

这里没什么报错,一路非常成功的下载了所有的 deps,随后看一下目前的结构目录:

    └── vite.config.js1290 directories, 8111 files
# src 下面的文件太多了,我这里只展现 2 层
❯ tree . -L 2
.
├── docker-compose.yaml
├── dockerfiles
│   ├── composer.dockerfile
│   └── php.dockerfile
├── env
│   └── mysql.env
├── nginx
│   └── nginx.conf
└── src├── README.md├── app├── artisan├── bootstrap├── composer.json├── composer.lock├── config├── database├── package.json├── phpunit.xml├── public├── resources├── routes├── storage├── tests├── vendor└── vite.config.js15 directories, 12 files

可以看到,laravel 的项目成功的安装好了,并且同步到了 src 下面:

在这里插入图片描述

想到以前还真的学过 php 和 laravel 的青葱岁月啊……

修改 laravel 配置

这里主要修改的是 src/.env,之前提到了现在 laravel 已经使用 sqlite 了,所以需要修改一下 mysql 的配置:

# 大概是 22-27 行这里
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
运行 laravel 项目

这里使用 docker compose up,使用方式有两种:

# 1. 这里会运行指定的3个容器docker compose up server php mysql
# 2. 或者配置 depends_on,之前没有配置,不过在我的 docker compose 里已经补上了docker compose up server
# 省略掉一些 download 和 build
[+] Running 0/3⠹ Container section08-php-1     Created                                                                                                              0.2s⠹ Container section08-mysql-1   Created                                                                                                              0.2s⠋ Container section08-server-1  Created                                                                                                              0.1s
Attaching to server-1
server-1  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
server-1  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
server-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
server-1  | 10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
server-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
server-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
server-1  | /docker-entrypoint.sh: Configuration complete; ready for start up
server-1  | 2024/04/25 03:45:52 [notice] 1#1: using the "epoll" event method
server-1  | 2024/04/25 03:45:52 [notice] 1#1: nginx/1.24.0
server-1  | 2024/04/25 03:45:52 [notice] 1#1: built by gcc 12.2.1 20220924 (Alpine 12.2.1_git20220924-r4)
server-1  | 2024/04/25 03:45:52 [notice] 1#1: OS: Linux 6.6.22-linuxkit
server-1  | 2024/04/25 03:45:52 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
server-1  | 2024/04/25 03:45:52 [notice] 1#1: start worker processes
server-1  | 2024/04/25 03:45:52 [notice] 1#1: start worker process 21
server-1  | 2024/04/25 03:45:52 [notice] 1#1: start worker process 22
server-1  | 2024/04/25 03:45:52 [notice] 1#1: start worker process 23
server-1  | 2024/04/25 03:45:52 [notice] 1#1: start worker process 24
server-1  | 2024/04/25 03:45:52 [notice] 1#1: start worker process 25
server-1  | 2024/04/25 03:45:52 [notice] 1#1: start worker process 26
server-1  | 2024/04/25 03:45:52 [notice] 1#1: start worker process 27
server-1  | 2024/04/25 03:45:52 [notice] 1#1: start worker process 28

看起来服务器已经成功启动了:

在这里插入图片描述

⚠️:这里的报错是因为 mysql 没有成功配置好的关系,现在 laravel 默认使用的是 sqlite,所以配置都是按照 sqlite 进行的,等到下一步配置完 artisan 就好了

artisan & npm

compose 配置如下:

artisan:build:context: "./dockerfiles"dockerfile: "php.dockerfile"volumes:- ./src:/var/www/html:delegatedentrypoint: ["php", "/var/www/html/artisan", "migrate"]
npm:image: node:20-alpineworking_dir: /var/www/htmlentrypoint: ["npm"]volumes:- ./src:/var/www/html:delegated

这两个没有新创建一个 dockerfile——也不是不可以,不过这里展现一下不用新建 dockerfile 也可以实现 entrypoint 之类的功能。

同样,这两个也是 util container

artisan 运行结果如下:

docker compose run --rm artisan
WARN[0000] /Users/user/study/docker/section08/docker-compose.yaml: `version` is obsoleteINFO  Preparing database.Creating migration table ...................................... 25.68ms DONEINFO  Running migrations.0001_01_01_000000_create_users_table .......................... 79.47ms DONE0001_01_01_000001_create_cache_table .......................... 27.05ms DONE0001_01_01_000002_create_jobs_table ........................... 82.80ms DONE

这代表数据库已经 migrate 成功了:

在这里插入图片描述

npm 运行结果如下:

docker compose run --rm npm
WARN[0000] /Users/user/study/docker/section08/docker-compose.yaml: `version` is obsolete
npm <command>Usage:npm install        install all the dependencies in your project
npm install <foo>  add the <foo> dependency to your project
npm test           run this project's tests
npm run <foo>      run the script named <foo>
npm <command> -h   quick help on <command>
npm -l             display usage info for all commands
npm help <term>    search for help on <term>
npm help npm       more involved overviewAll commands:access, adduser, audit, bugs, cache, ci, completion,config, dedupe, deprecate, diff, dist-tag, docs, doctor,edit, exec, explain, explore, find-dupes, fund, get, help,help-search, hook, init, install, install-ci-test,install-test, link, ll, login, logout, ls, org, outdated,owner, pack, ping, pkg, prefix, profile, prune, publish,query, rebuild, repo, restart, root, run-script, sbom,search, set, shrinkwrap, star, stars, start, stop, team,test, token, uninstall, unpublish, unstar, update, version,view, whoamiSpecify configs in the ini-formatted file:/root/.npmrc
or on the command line via: npm <command> --key=valueMore configuration info: npm help config
Configuration fields: npm help 7 confignpm@10.5.0 /usr/local/lib/node_modules/npm

至此,就完成了不需要在本机上安装这些功能,但是依旧可以启动一个 laravel 项目的 docker 案例了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/5220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于遗传算法的TSP算法(matlab实现)

一、理论基础 TSP(traveling salesman problem,旅行商问题)是典型的NP完全问题&#xff0c;即其最坏情况下的时间复杂度随着问题规模的增大按指数方式增长&#xff0c;到目前为止还未找到一个多项式时间的有效算法。TSP问题可描述为&#xff1a;已知n个城市相互之间的距离&…

万兆以太网MAC设计(12)万兆UDP协议栈上板与主机网卡通信

文章目录 一、设置IP以及MAC二、上板效果2.1、板卡与主机数据回环测试2.2、板卡满带宽发送数据 一、设置IP以及MAC 顶层模块设置源MAC地址 module XC7Z100_Top#(parameter P_SRC_MAC 48h01_02_03_04_05_06,parameter P_DST_MAC 48hff_ff_ff_ff_ff_ff )(input …

开源代码分享(26)-考虑预测不确定性的综合能源调度优化

参考文献&#xff1a; [1]崔杨,周慧娟,仲悟之,等.考虑源荷两侧不确定性的含风电电力系统低碳调度[J].电力自动化设备,2020,40(11):85-93.DOI:10.16081/j.epae.202009019. 1.基本原理 考虑碳交易机制能够有效提高风电消纳量&#xff0c;但是随着风电并网容量的增大&#xff0c…

【安卓13】谷歌桌面Launcher3屏蔽全部应用里面的部分app

1、需求 我们在做谷歌桌面时&#xff0c;移植了一些我们自己的应用&#xff0c;但是有些应用是服务型的app&#xff0c;不需要显示在主页&#xff0c;要隐藏掉 2、解决方案 方法1&#xff1a; 解决办法很简单&#xff0c;阅读源码发现&#xff0c;谷歌桌面添加全部应用的源…

使用yolo识别模型对比两张图片并标记不同(2)

上篇文章有漏洞&#xff0c;在这里补充下&#xff0c;比如要识别第二张图相对于第一张图的违建是否拆除了 第一步旋转对其后&#xff0c;图片会有黑色的掩码&#xff0c;如果旋转角度大的话&#xff0c;没识别出来的框可能不是已经拆除了&#xff0c;而是因为黑色掩码遮挡&…

数字旅游:通过科技赋能,创新旅游服务模式,提供智能化、个性化的旅游服务,满足游客多元化、个性化的旅游需求

目录 一、数字旅游的概念与内涵 二、科技赋能数字旅游的创新实践 1、大数据技术的应用 2、人工智能技术的应用 3、物联网技术的应用 4、云计算技术的应用 三、智能化、个性化旅游服务的实现路径 1、提升旅游服务的智能化水平 2、实现旅游服务的个性化定制 四、数字旅…

Linux编辑器调试器 gcc/g++ gdb 编译过程及使用讲解

这恋爱呀 我有两不谈 第一异性不谈 因为我们性别不一样 我知道的她不知道相处起来太累 第二同性不谈 因为我们性别一样 我知道的他也知道相处起来太无聊了 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–…

【介绍下Android开发环境的搭建】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

什么是域名解析?域名解析的完整流程是什么?如何清理DNS缓存?(附源码)

目录 1、什么是域名&#xff1f; 2、为什么使用域名&#xff1f; 3、域名解析的完整流程 4、调用gethostbyname系统接口将域名解析成IP地址 5、为什么需要清理系统DNS缓存&#xff1f; 6、使用cmd命令清理DNS缓存 7、通过代码去清除系统DNS缓存 C软件异常排查从入门到精…

使用量排名前50的GPTs趋势和特征

Chatgpt的gpt商店已经有几千gpts了。目前哪些gpts比较受欢迎呢&#xff1f;有哪些趋势和投资呢? 根据whatplugin.ai&#xff08;截止日期为2024年3月&#xff09;&#xff0c;使用量最多的50个gpts数据分析结果如下&#xff1a; GPTs类型的分布情况如下&#xff1a; 图像生成…

21.Nacos集群搭建

模拟Nacos三个节点&#xff0c;同一个ip,启动三个不同的端口&#xff1a; 节点 nacos1, 端口&#xff1a;8845 节点 nacos2, 端口&#xff1a;8846 节点 nacos3, 端口&#xff1a;8847 1.搭建数据库&#xff0c;初始化数据库表结构 这里我们以单点的数据库为例 首先新建一…

【C#】基础知识

0.参考 C#语言入门详解 1.几种打印hello_world的方式 1.1 console控制台 新建一个console&#xff0c;直接打印&#xff1a; Console.WriteLine("Hello_world");启动一闪而过&#xff0c;在vs调试中选择开始执行不调试&#xff08;without debug&#xff09;。 …

通话记录生成器怎么使用

通话记录生成器是一种可以模拟生成通话记录的软件工具&#xff0c;使用起来相对简单。以下是使用步骤&#xff1a; 导入目标号码&#xff1a;您需要将想要生成通话记录的目标号码输入到软件中。这可以通过直接复制粘贴电话号码&#xff0c;或者如果是图片或纸质文件中的号码&am…

分布式与一致性协议之CAP和Paxos算法(一)

CAP 理论 如何使用BASE理论 以InfluxDB系统中DATA节点的集群实现为例。DATA节点的核心功能是读和写&#xff0c;所以基本可用是指读和写的基本可用。我们可以通过分片和多副本实现读和写的基本可用。也就是说&#xff0c;将同一业务的数据先分片&#xff0c;再以多份副本的形…

四种网络IO模型

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;面经 ⛺️稳中求进&#xff0c;晒太阳 IO的定义 IO是计算机内存与外部设备之间拷贝数据的过程。CPU访问内存的速度远高于外部设备。因此CPU是先把外部设备的数据读取到内存&#xff0c;在…

有趣的大模型之我见 | Llama AI Model

Llama 开源吗&#xff1f; 我在写《有趣的大模型之我见 | Mistral 7B 和 Mixtral 8x7B》时曾犹豫&#xff0c;在开源这个事儿上&#xff0c;到底哪个大模型算鼻祖&#xff1f;2023 年 7 月 18 日&#xff0c;Meta 推出了最受欢迎的大型语言模型&#xff08;LLM&#xff09;的第…

20 | 幻读是什么,幻读有什么问题?

幻读是什么? 假设的场景,不是真实的结果 幻读”做一个说明: 在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此,幻读在“当前读”下才会出现。上面 session B 的修改结果,被 session A 之后的 select语句用“当前读”看到,不能称为幻读…

iview 自定义项求和的方法和错误点

这是iview自定义某几项参数合计的方法&#xff0c;其实是蛮简单的&#xff0c;很多人自定义合计的时候&#xff0c;老是会不知道怎么处理除了需要合计的几项的其他项&#xff0c;其实不需要管&#xff0c;不需要合计的项直接返回空就好了&#xff0c;需要的就在计算的里面做key…

ThreeJs模拟工厂生产过程八

这节算是给这个车间场景收个尾&#xff0c;等了几天并没有人发设备模型给我&#xff0c;只能自己找了一个凑合用了。加载模型之前&#xff0c;首先要把货架上的料箱合并&#xff0c;以防加载模型之后因模型数量多出现卡顿&#xff0c;方法和之前介绍的合并传送带方法相同&#…

【HTTP协议】了解http需要学习哪些内容

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是超文本传输协议&#xff0c;互联网上应用最广泛的一种协议&#xff0c;它负责在客户端和服务器之间传输数据。本文将从HTTP协议的基本原理、请求-响应模型、常见特性以及应用场景等方面进行总结。 1. HTTP基本原理 …