V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
lmfx89
V2EX  ›  问与答

请教大家一个在生产环境部署代码的问题

  •  
  •   lmfx89 · 2016-12-25 13:25:15 +08:00 · 5134 次点击
    这是一个创建于 2681 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一、背景

    • 新项目( PHP )使用了 Composer
    • 目前正测试 Gitlab 来进行 CI/CD
    • 以前的项目(基于 Codeigniter )很少使用 Composer ,所以直接通过( webhook )触发脚本 git pull 到生产服务器上就完事了

    二、产生的疑问

    2.1 一句话概括

    在需要安装包依赖的情况下如何做到无缝部署到生产环境?

    (我对无缝的理解是代码更新完全不会影响到现有项目的运行)

    2.2 具体描述

    1. 项目中( Composer 管理的)包的安装在哪个过程进行最好? 构建过程中还是部署代码生产环境后呢?
    2. 如果是构建过程中安装好要通过什么方式分发的生产服务器?(因为通过这种方式分发就要脱离 git 的版本控制,还能否做到增量更新吗)
    3. 如果是部署后安装如何避免安装出错或安装过慢导致的“代码已经部署并运行但因缺失包导致故障”呢?

    三、自己的思考

    假定生产环境: 代码路径: /home/wwwroot/html

    部署方式 1:不论是在哪个过程对包依赖进行处理,当代码到达生产环境行时,不直接对 /home/wwwroot/html 做处理,而是创建一个文件夹(如 /home/wwwroot/production20161225/ ),新代码将被复制或 pull 到此处,然后创建一个软连接。(不足:如何管理这些目录呢?每次都要新建一个不同的目录吗?)

    部署方式 2:所有代码(包括依赖的包)入库,部署时 git pull

    四、总结

    以上,是我对代码到达生产服务器后如何处理最妥善(无缝更新代码)抱有的疑惑,站内站外查了很多资料仍然不太明了,还请大家指教和分享。谢谢。

    有些啰嗦,十分抱歉。

    另外分享一些搜索过程中的资料:

    正确的 Composer 扩展包安装方法

    Do I need Laravel Framework + Composer in production?

    How to deploy correctly when using Composer's develop / production switch?

    How to manage version control and production deployments for compiled assets with Git and Grunt/Sass/Composer?

    18 条回复    2016-12-26 09:05:48 +08:00
    gouchaoer
        1
    gouchaoer  
       2016-12-25 13:51:31 +08:00 via Android   ❤️ 1
    把 vendor 加入 git 版本管理,别在生产环境 composer install
    uxstone
        2
    uxstone  
       2016-12-25 14:46:12 +08:00   ❤️ 1
    composer 还没好到像 Java 的 Maven 那样..........
    twm
        3
    twm  
       2016-12-25 15:00:22 +08:00   ❤️ 1
    你需要 Bamboo 或者 Jenkins
    lmfx89
        4
    lmfx89  
    OP
       2016-12-25 15:32:10 +08:00
    @twm 您好, Jenkins 和 Gitlab 自带的 CI 功能都能完成代码构建和部署的功能,我疑惑的地方是在最后一步部署的时候如何把新代码更新过去,最简单的是 composer install 的包和源码一同放进版本库,然后生产服务器 git pull 。
    LINAICAI
        5
    LINAICAI  
       2016-12-25 15:42:25 +08:00   ❤️ 1
    Jenkins 不是有插件么,同样有 Gitlab 的插件帮你构建前更新代码,只要你指定代码分支即可, vendor 一般要忽略吧,比方说 laravel 下那么一大堆,如果把它都提交到版本库其实是很低效又没必要的事情,只要在 Jenkins 里面 Gitlab 更新代码后添加多一个 shell 执行 composer install 就好了,非常简单。
    LINAICAI
        6
    LINAICAI  
       2016-12-25 15:50:23 +08:00   ❤️ 1
    抱歉,上一楼我说的步骤是针对 iOS 移动端的构建。
    具体的 web 端我没使用过 CI 来做持续集成,但如果仅仅为了想在生产环境下使用部署,其实只要把 vendor 目录都添加到忽略列表里面就好了,等你提交到代码, ssh 到生产环境上去, git pull 然后 composer install
    lmfx89
        7
    lmfx89  
    OP
       2016-12-25 15:57:47 +08:00
    @LINAICAI 你好,谢谢回复。 请问你说的插件是将代码部署到生产服务器上再 `composer install ` 吗?这种情况下我考虑了到这种情况: 代码已经更新上去的同时始执行 `composer install `, 这个时候因为网络原因安装很慢,在完成前系统就会报错了吧?


    如果是部署前就构建好有什么好的工具更新代码到生产服务器上呢?
    lmfx89
        8
    lmfx89  
    OP
       2016-12-25 16:01:09 +08:00
    @gouchaoer 谢谢回复,这种方法在拉取时最方便,且简单。不过查资料时貌似不推荐这么做。


    https://getcomposer.org/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md
    SPACELAN
        9
    SPACELAN  
       2016-12-25 16:21:37 +08:00   ❤️ 1
    用一台线下机器构建好之后打个 tar 包,然而分发到各个线上节点?

    当然我似乎并不喜欢这种上线方式。。
    vitohe
        10
    vitohe  
       2016-12-25 16:24:04 +08:00   ❤️ 1
    PHP 项目的话推荐 https://deployer.org/

    每次都会在 releases 目录创建新的目录,类似 releases/201612251001 ,然后跑 composer

    最后在修改 current 指向最新的 releases 目录,这样就可以避免你说的问题了。

    如果使用的是 nginx 的话,注意修改 fastcgi_param ,不会 opcache 会一直软链路径的代码。

    fastcgi_param DOCUMENT_ROOT $realpath_root;
    XiaoxiaoPu
        11
    XiaoxiaoPu  
       2016-12-25 16:27:27 +08:00   ❤️ 1
    把部署方式 1 中的创建软链接改成 rsync 复制然后删除临时目录?
    LINAICAI
        12
    LINAICAI  
       2016-12-25 16:44:00 +08:00   ❤️ 1
    @lmfx89 如果仅仅因为网络慢就采取整个 vender 也提交到版本库里面去,其实你 git pull 的时候一样也要拉很多,何况如果 composer 经常改就不划算了,还有先部署再 composer install 的好处比整个从 gitlab pull 下来好吧,很容易就超时啥的了。
    LINAICAI
        13
    LINAICAI  
       2016-12-25 16:47:28 +08:00   ❤️ 1
    貌似比较大型的重要项目确实是为了保证上生产环境后不会有问题,是把 vender 目录都提交到 gitlab 里面去的,但如果 composer 锁定开源库的版本,就没必要了,那个是不自信的做法。。。
    gouchaoer
        14
    gouchaoer  
       2016-12-25 16:55:02 +08:00 via Android   ❤️ 1
    @lmfx89 不,这是最好的办法, composer 官方说的没错。。。但是问题是,生产环境 composer install 的第三方库可能和开发环境不同,而且 composer 安装需要时间 /可能部署失败
    gouchaoer
        15
    gouchaoer  
       2016-12-25 17:02:30 +08:00 via Android   ❤️ 1
    尿了。。。你不把 vendor 放进 git 里,假如你改了个 composer 依赖,更新代码难道还在生产环境运行 composer update 啊?

    你在 github 上看到的项目是因为那是公开项目。。。

    而且我现在生产环境用 docker ,源码更新直接 git
    lmfx89
        16
    lmfx89  
    OP
       2016-12-25 17:03:00 +08:00
    @vitohe 十分感谢!正在研究。

    @LINAICAI vendor 放进版本库的好处就是虽然 git pull 会拉很多,但是在拉取过程中时代码不会检出的,这就避免了代码先跑起来包却没有跟上担忧。 不过我也不想把 vendor 放进版本库,毕竟自建的 Gitlab 已经会一卡卡的了,再多几个带 vendor 的项目,就要经常性 502 了。。 目前在尝试建一个临时目录 + 软连接的方法( ls 几位提到的 deployer 、打包),这样不论在构建时、还是部署到服务器后执行 composer install 都不会影响现有代码的运行了。

    @XiaoxiaoPu
    @SPACELAN 感谢意见,我测试、权衡一下最稳妥的方法。
    frankzeng
        17
    frankzeng  
       2016-12-25 22:47:07 +08:00   ❤️ 1
    假设使用 composer install ,那生产机器不能连接外网,这活还干不了。
    twm
        18
    twm  
       2016-12-26 09:05:48 +08:00   ❤️ 1
    没有用过 Jenkins
    不过 Bamboo 是完全可以自定义部署方案的,完全可以实现你的需求。
    部署时会在服务器上创建 [path]/releases/release-xxx 的目录,然后 put 代码到该目录,执行自定义脚本,最后更改软连接把 [path]/current 指向到最新的 release 目录。清理保留之外的 release 目录数。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5361 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 09:27 · PVG 17:27 · LAX 02:27 · JFK 05:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.