V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
rogwan
V2EX  ›  Python

开发环境和生产环境下的文件不一致,怎么执行自动化部署呢?

  •  
  •   rogwan · 2016-06-02 10:37:14 +08:00 · 4994 次点击
    这是一个创建于 3100 天前的主题,其中的信息可能已经有所发展或是发生改变。

    由于本地的开发环境不需要安装生产环境中才用到的 nginx 负载均衡等前端配置,而程序中有涉及到用户访问 ip 的业务逻辑,本地开发环境取的只是 local 本地 request 的 remote_addr ,取不到 nginx 前端转发过来的 ip 。 这样就造成每次把程序部署到生产环境,都要手动修改 ip 的取值方式后,才能推送到生产环境。 或者:自动部署上去后,去生产机上手动修改这几行代码。

    有什么方式,可以解决这样的问题呢?

    26 条回复    2016-06-02 15:10:46 +08:00
    yangtukun1412
        1
    yangtukun1412  
       2016-06-02 10:39:43 +08:00
    开发环境配置成与生产环境一致
    fredcc
        2
    fredcc  
       2016-06-02 10:41:57 +08:00
    做一套与生产环境一致的测试环境
    Infernalzero
        3
    Infernalzero  
       2016-06-02 10:51:27 +08:00
    修改下你读取客户端真实 IP 的方法
    先看 X-Forwarded-For 这个 header 有没有 ip ,有就取这个
    如果没有再看 X-Real-IP ,有就取,如果还没有才用 request.getRemoteAddr()
    qqmishi
        4
    qqmishi  
       2016-06-02 10:51:51 +08:00 via Android
    可以加个标识符用于区别生产环境和开发环境的代码,如果能自动检测环境就更好了
    holyzhou
        5
    holyzhou  
       2016-06-02 10:53:23 +08:00
    将 nginx 配置做成模版
    Midnight
        6
    Midnight  
       2016-06-02 10:55:22 +08:00
    @yangtukun1412 这个不现实,开发机每个人的配置文件都可以不一样。
    我这边的解决方案是 生产环境配置一样,开发环境不允许把配置信息提交到版本库里去
    tabris17
        7
    tabris17  
       2016-06-02 10:59:47 +08:00
    把不一致的的环境做成可配置量
    fengyqf
        8
    fengyqf  
       2016-06-02 11:00:03 +08:00
    开发方面要做到一定的兼容性。
    至少:开发环境与生产环境不一致时,开发的产品要实现兼容。
    比如,通过独立的配置文件实现兼容,但配置文件在部署时,不要覆盖。
    rogwan
        9
    rogwan  
    OP
       2016-06-02 11:05:46 +08:00
    @Infernalzero 生产环境中优先取的是 X-Real-IP ,这个在开发环境(开发人员有的 Mac ,有的 Win ,有的 Ubuntu ,全部配成 linux 的生产环境一模一样,很费劲...)中没有,会报错。为了保持业务逻辑可以正常跑,开发环境就只能改回 remote_addr 。
    虽然手工改几行代码不是很麻烦,只是每次部署都要重复改这几行也头大。。。
    just4test
        10
    just4test  
       2016-06-02 11:12:04 +08:00
    @rogwan 环境变量或者参数指明是什么环境。然后 if else
    rogwan
        11
    rogwan  
    OP
       2016-06-02 11:14:31 +08:00
    @Midnight 嗯,是的。生产环境( nginx + wsgi + app )的 wsgi 环境也是单独配的,和开发环境都不一样。开发环境除了数据库和 git 本地配一下,其他基本上用 IDE 就完成了。
    Infernalzero
        12
    Infernalzero  
       2016-06-02 11:17:16 +08:00
    @rogwan
    开发环境是没有 X-Real-IP 和 X-Forwarded-For 这些 header 没错啊,所以才会进行判断,如果取不到才用 RemoteAddr 有什么问题?
    不理解为何你会说这几个 header 取不到会报错,无非就是判空而已

    退一步讲,如果你要开发和生产环境分开配置也是很常见的啊
    不知道你数据库连接配置是怎么搞的,这个生产环境和开发环境必然不同
    你的需求和数据库配置的读取完全相同,要么加环境变量,或者容器启动时读入参数,写到容器的配置文件里
    更无聊点你甚至可以在调用的时候去读下你写的配置文件,如果能读到就是生产环境
    rogwan
        13
    rogwan  
    OP
       2016-06-02 11:27:33 +08:00
    @fengyqf @Midnight @holyzhou @just4test @Infernalzero 谢谢大家的建议~ 是因为访问 ip 要参与后面业务逻辑的运算,判空后面就跑不通了。
    kinghui
        14
    kinghui  
       2016-06-02 11:31:24 +08:00
    生产环境的配置和测试环境的配置应该隔离开来.
    fengyqf
        15
    fengyqf  
       2016-06-02 11:35:13 +08:00
    @rogwan 那更应该独立配置文件了,把 ip 地址分成几组,分配在配置文件里定义。这样开发、生产互不影响。
    wujunze
        16
    wujunze  
       2016-06-02 11:40:04 +08:00
    跟开发环境的域名跟线上环境的域名不一样 加载不同的配置文件
    Infernalzero
        17
    Infernalzero  
       2016-06-02 11:46:21 +08:00   ❤️ 1
    @rogwan
    我觉得你还是没有懂我说的,你这个需求根本不需要区分生产环境和开发环境
    对那两个 header 判空不代表获取到的 ip 就是空,只是优先级问题,能取到就优先用

    String ip = request.getHeader("X-Forwarded-For");
    if (StringUtils.isNotBlank(ip) && !"unKnown".equalsIgnoreCase(ip)) {
    int index = ip.indexOf(",");
    if (index != -1) {
    return ip.substring(0, index);
    } else {
    return ip;
    }
    }
    ip = request.getHeader("X-Real-IP");
    if (StringUtils.isNotBlank(ip) && !"unKnown".equalsIgnoreCase(ip)) {
    return ip;
    }
    return request.getRemoteAddr();

    代码都贴出来了你还没懂的话我就无话可说了
    rogwan
        18
    rogwan  
    OP
       2016-06-02 12:05:56 +08:00
    @Infernalzero 尼玛,轻松就显出大神本色啦。。。我怎么就一直想着从环境、和配置文件方面去解决,没想到 ip 本身来判断呢,难怪大牛脑容量不一样 ^_^
    mogging
        19
    mogging  
       2016-06-02 13:01:43 +08:00 via iPhone
    @yangtukun1412 can't agragree more
    just1
        20
    just1  
       2016-06-02 13:06:32 +08:00 via Android
    @Infernalzero 这会造成十分严重的安全问题:ip 伪造。因为 realip 和 xff 都是可以伪造的。

    @rogwan 我觉得加入一个调试模式,调试模式 true 的时候获取 remote_addr ,非调试模式获取 nginx 传递的值,部署改为 false 即可
    Infernalzero
        21
    Infernalzero  
       2016-06-02 13:20:46 +08:00
    @just1
    这和 LZ 的问题没有任何关系,伪造是另一回事了,是否有安全问题还得看具体业务,而且 remote_addr 也一样能伪造,这个问题是避免不了的
    nginx 配置一般会把 X-Real-IP 的值设置为 remote_addr ,所以如果 X-Real-IP 不真实的话 remote_addr 也一样不真实
    just1
        22
    just1  
       2016-06-02 13:32:13 +08:00 via Android
    @Infernalzero remote_addr 是无法伪造的。连接的主机 ip 地址多少就是多少,请求头有这个也是没用的, nginx 设置就更无从谈起了,都是 xrealip 设置为 remoteaddr ,在说即使设置了 remoteaddr 也是无效的配置。
    bobchengbin
        23
    bobchengbin  
       2016-06-02 13:36:38 +08:00 via iPhone
    dotenv 用环境变量来区分不同的环境
    Infernalzero
        24
    Infernalzero  
       2016-06-02 13:41:43 +08:00
    @just1
    怎么可能是改 header
    1.改网络层的包
    2.挂代理
    nginx 配置一般都会加这句
    proxy_set_header X-Real-IP $remote_addr;
    在有 nginx 的情况下对于后端来说要取客户端 IP 不看 X-Real-IP 还看啥,不然你依然都是直接取 remote_addr 不每次都是 nginx 的 ip 了吗
    qq5745965425
        25
    qq5745965425  
       2016-06-02 13:46:53 +08:00
    docker
    armoni
        26
    armoni  
       2016-06-02 15:10:46 +08:00
    docker
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1177 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:05 · PVG 07:05 · LAX 15:05 · JFK 18:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.