【Docker】实战多阶段构建 Laravel 镜像

news2024/11/16 10:49:10

在这里插入图片描述

作者主页: 正函数的个人主页
文章收录专栏: Docker
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!


本节适用于 PHP 开发者阅读。Laravel 基于 8.x 版本,各个版本的文件结构可能会有差异,请根据实际自行修改。

准备

新建一个 Laravel 项目或在已有的 Laravel 项目根目录下新建 Dockerfile .dockerignore laravel.conf 文件。

.dockerignore 文件中写入以下内容。

.idea/
.git/

vendor/

node_modules/

public/js/
public/css/
public/mix-manifest.json

yarn-error.log

bootstrap/cache/*
storage/

# 自行添加其他需要排除的文件,例如 .env.* 文件

laravel.conf 文件中写入 nginx 配置。

server {
  listen 80 default_server;
  root /app/laravel/public;
  index index.php index.html;

  location / {
      try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ .*\.php(\/.*)*$ {
    fastcgi_pass   laravel:9000;
    include        fastcgi.conf;

    # fastcgi_connect_timeout 300;
    # fastcgi_send_timeout 300;
    # fastcgi_read_timeout 300;
  }
}

前端构建

第一阶段进行前端构建。

FROM node:alpine as frontend

COPY package.json /app/

RUN set -x ; cd /app \
      && npm install --registry=https://registry.npmmirror.com

COPY webpack.mix.js webpack.config.js tailwind.config.js /app/
COPY resources/ /app/resources/

RUN set -x ; cd /app \
      && touch artisan \
      && mkdir -p public \
      && npm run production

安装 Composer 依赖

第二阶段安装 Composer 依赖。

FROM composer as composer

COPY database/ /app/database/
COPY composer.json composer.lock /app/

RUN set -x ; cd /app \
      && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ \
      && composer install \
           --ignore-platform-reqs \
           --no-interaction \
           --no-plugins \
           --no-scripts \
           --prefer-dist

整合以上阶段所生成的文件

第三阶段对以上阶段生成的文件进行整合。

FROM php:7.4-fpm-alpine as laravel

ARG LARAVEL_PATH=/app/laravel

COPY --from=composer /app/vendor/ ${LARAVEL_PATH}/vendor/
COPY . ${LARAVEL_PATH}
COPY --from=frontend /app/public/js/ ${LARAVEL_PATH}/public/js/
COPY --from=frontend /app/public/css/ ${LARAVEL_PATH}/public/css/
COPY --from=frontend /app/public/mix-manifest.json ${LARAVEL_PATH}/public/mix-manifest.json

RUN set -x ; cd ${LARAVEL_PATH} \
      && mkdir -p storage \
      && mkdir -p storage/framework/cache \
      && mkdir -p storage/framework/sessions \
      && mkdir -p storage/framework/testing \
      && mkdir -p storage/framework/views \
      && mkdir -p storage/logs \
      && chmod -R 777 storage \
      && php artisan package:discover

最后一个阶段构建 NGINX 镜像

FROM nginx:alpine as nginx

ARG LARAVEL_PATH=/app/laravel

COPY laravel.conf /etc/nginx/conf.d/
COPY --from=laravel ${LARAVEL_PATH}/public ${LARAVEL_PATH}/public

构建 Laravel 及 Nginx 镜像

使用 docker build 命令构建镜像。

$ docker build -t my/laravel --target=laravel .

$ docker build -t my/nginx --target=nginx .

启动容器并测试

新建 Docker 网络

$ docker network create laravel

启动 laravel 容器, --name=laravel 参数设定的名字必须与 nginx 配置文件中的 fastcgi_pass laravel:9000; 一致

$ docker run -dit --rm --name=laravel --network=laravel my/laravel

启动 nginx 容器

$ docker run -dit --rm --network=laravel -p 8080:80 my/nginx

浏览器访问 127.0.0.1:8080 可以看到 Laravel 项目首页。

也许 Laravel 项目依赖其他外部服务,例如 redis、MySQL,请自行启动这些服务之后再进行测试,本小节不再赘述。

生产环境优化

本小节内容为了方便测试,将配置文件直接放到了镜像中,实际在使用时 建议 将配置文件作为 configsecret 挂载到容器中,请读者自行学习 Swarm modeKubernetes 的相关内容。

由于篇幅所限本小节只是简单列出,更多内容可以参考 https://github.com/khs1994-docker/laravel-demo 项目。

附录

完整的 Dockerfile 文件如下。

FROM node:alpine as frontend

COPY package.json /app/

RUN set -x ; cd /app \
      && npm install --registry=https://registry.npmmirror.com

COPY webpack.mix.js webpack.config.js tailwind.config.js /app/
COPY resources/ /app/resources/

RUN set -x ; cd /app \
      && touch artisan \
      && mkdir -p public \
      && npm run production

FROM composer as composer

COPY database/ /app/database/
COPY composer.json /app/

RUN set -x ; cd /app \
      && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ \
      && composer install \
           --ignore-platform-reqs \
           --no-interaction \
           --no-plugins \
           --no-scripts \
           --prefer-dist

FROM php:7.4-fpm-alpine as laravel

ARG LARAVEL_PATH=/app/laravel

COPY --from=composer /app/vendor/ ${LARAVEL_PATH}/vendor/
COPY . ${LARAVEL_PATH}
COPY --from=frontend /app/public/js/ ${LARAVEL_PATH}/public/js/
COPY --from=frontend /app/public/css/ ${LARAVEL_PATH}/public/css/
COPY --from=frontend /app/public/mix-manifest.json ${LARAVEL_PATH}/public/mix-manifest.json

RUN set -x ; cd ${LARAVEL_PATH} \
      && mkdir -p storage \
      && mkdir -p storage/framework/cache \
      && mkdir -p storage/framework/sessions \
      && mkdir -p storage/framework/testing \
      && mkdir -p storage/framework/views \
      && mkdir -p storage/logs \
      && chmod -R 777 storage \
      && php artisan package:discover

FROM nginx:alpine as nginx

ARG LARAVEL_PATH=/app/laravel

COPY laravel.conf /etc/nginx/conf.d/
COPY --from=laravel ${LARAVEL_PATH}/public ${LARAVEL_PATH}/public

作者主页: 正函数的个人主页
文章收录专栏: Docker
在这里插入图片描述

在这里插入图片描述

欢迎大家点赞 👍 收藏 ⭐ 加关注哦!
如果你认为这篇文章对你有帮助,请给正函数点个赞吧,如果发现什么问题,欢迎评论区留言!!

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

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

相关文章

【C++】string的基本使用

从这篇博客开始,我们的C部分就进入到了STL,STL的出现可以说是C发展历史上非常关键的一步,自此C和C语言有了较为明显的差别。那么什么是STL呢? 后来不断的演化,发展成了知名的两个版本,一个叫做P.J.版本&am…

【GitHub项目推荐--推荐 5 个炫炫炫的可视化项目】【转载】

数据可视化就是将抽象的数据通过视觉的方式进行展示,能让用户直观的看到数据中蕴含的信息和规律。 本篇文章,整理了 5 个可视化开源项目,其中包括可视化制作低代码平台、大屏可视化、地图可视化、热图、图标可视化等等。 00. 数据大屏可视化…

gh0st远程控制——客户端界面编写(二)

● 补充小知识:枚举类型的使用 每个控件(比如列表)都对应一个自己的唯一的变量 使用枚举类型可以将变量名与编号进行绑定,以后程序需要扩展的时候,只需要在定义枚举变量的位置重新修改编号就可以了,这样全…

Windows自带分屏使用-窗口贴靠

0.介绍 Windows电脑自带的分屏功能叫做“窗口贴靠”,可以让您同时查看和操作多个应用程序窗口,提高我们的工作效率在屏幕展示上,没有额外显示器的情况下,可以设置分屏来进行展示分屏的数量,目前为止,windows系统上分屏的数量最多为4个,win7,win10,win11…

DolphinDB 与盈米基金达成战略合作,打造领先的资管机构投顾解决方案

1月16日上午,DolphinDB 与盈米基金在上海签署战略合作协议,共同开启专业资管投顾投研合作新篇章。 DolphinDB 联合创始人、COO 初阳春与盈米基金副总裁、研究院院长杨媛春出席仪式,并代表双方完成签约。 打造市场领先的资管机构投顾服务 盈…

OPC UA 开源库编译方法及通过OPC UA连接西门S7-1200 PLC通信并进行数据交换

前言 在现代工业自动化领域,OPC UA(开放性生产控制和统一架构)是一种广泛应用的通信协议。本文将以通俗易懂的方式解释OPC UA的含义和作用,帮助读者更好地理解这一概念。 一、OPC UA的定义 OPC UA全称为“开放性生产控制和统一…

【学习计划】裁员风波下的一点感悟

今天计划一点点~~ 裁员风波 年关将近,同公司不同中心的小伙伴被约谈了。其实是在 23 年的 11 月份就已经在谈了,但是因为当时她还没找到下家,并且觉得赔偿也没谈好,就一直往后延期了,最后决定今年的 4 月份合同到期再…

【分享】MathWorks中国汽车年会:“软件定义汽车”

从软件赋能到软件定义,汽车行业不仅需要解决诸如错误发现滞后带来的高昂代价、功能融合所需的跨学科知识、功能安全与实施成本之间的权衡等老问题,也面临着新的挑战:软件复杂度的不断提升、利用数据驱动创造价值、人工智能的引入和实现、数字…

力扣211. 添加与搜索单词 - 数据结构设计

字典树 思路: 设计一棵字典树,每个节点存放单词的一个字符,节点放一个标记位,如果是单词结束则标记;字典树插入: 字典树默认有 26 个 slot 槽代表 a - z;遍历单词,如果字符对应槽存…

Spring Boot Aop 执行顺序

Spring Boot Aop 执行顺序 1. 概述 在 spring boot 项目中,使用 aop 增强,不仅可以很优雅地扩展功能,还可以让一写多用,避免写重复代码,例如:记录接口耗时,记录接口日志,接口权限&…

主动自动智能、全天在线值守!浪潮信息InService托维服务平台V2.0焕新升级

日前,浪潮信息发布了InService托维服务平台2.0版本,新增了自动化微码版本推荐、硬盘故障智能预测、服务报告自助订阅等功能模块。该平台对接入设备可7*24小时在线监测,量化评估设备状态,提前预警故障,实现主动式服务。…

手写Vue3源码

Vue3核心源码 B站视频地址:https://www.bilibili.com/video/BV1nW4y147Pd?p2&vd_source36bacfbaa95ea7a433650dab3f7fa0ae Monorepo介绍 Monorepo 是管理项目代码的一种方式,只在一个仓库中管理多个模块/包 一个仓库可以维护多个模块,…

书生·浦语大模型实战营第四次课堂笔记

先来看看参考作业 哈哈到这才想起来写笔记 倒回去看发现要求将不要葱姜蒜换成自己的名字和昵称! 好好好我就是不配玩(换成管理员也不行!) 诶怎么能进这个环境?要进双系统ubuntu? 现在看视频发现原来是…

Vcruntime140_1.dll丢失的错误提示怎么解决,关于Vcruntime140_1.dll文件

在使用电脑时你是否遇到过关于Vcruntime140_1.dll文件丢失的错误提示,出现这样的提示时是不是不知所措,今天就给大家讲解Vcruntime140_1.dll文件的一些相关介绍,希望能够帮助大家解决Vcruntime140_1.dll丢失的难题。 一.Vcruntime140_1.dll文…

档案数字化如何选择合适的扫描仪

选择合适的扫描仪是进行档案数字化的关键步骤。以下是一些选择合适扫描仪的要点: 1. 扫描速度:选择具有合适的扫描速度的扫描仪,以便能够快速处理大量的文件。 2. 扫描分辨率:扫描分辨率决定了扫描后图像的清晰度。对于大多数文档…

代码随想录二刷 | 二叉树 | 二叉搜索树的最近公共祖先

代码随想录二刷 | 二叉树 | 二叉搜索树的最近公共祖先 题目描述解题思路代码实现 题目描述 235.二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的…

Qt简单使用与初识

🌇个人主页:平凡的小苏 📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风…

vector迭代器的失效

1.vector的底层 vector的底层就是由三个指针构成的 iterator _start 这个指针指向vector数据起始位置。 iterator _finish这个指针指向vector数据的结束位置。 iterator _end_of_shorage这个指针指向vector容量的位置。 2.迭代器失效的种类 2.1扩容引发的迭代器失效 例&…

深入Android S (12.0) 探索Framework之输入子系统InputReader的流程

Framework层之输入系统 第一篇 深入Android S (12.0) 探索Framework之输入系统IMS的构成与启动 第二篇 深入Android S (12.0) 探索Framework之输入子系统InputReader的流程 文章目录 Framework层之输入系统前言一、基础知识1、输入子系统2、INotify 与 Epoll2.1、INotify 机制…

redisson的延时队列机制简述

概述 业务中经常会遇到一些延迟执行的需求;通常想到的都是rabbitmq或者rocketmq的延迟消息; 但是系统中不一定集成了mq,但为了控制分布式下的并发,一般redis都是有集成的; redis的key过期监听那个时间不准确&#xff…