nginx - Docker 带有一个 nginx 和一个共享 UNIX 套接字的 uwsgi 容器

标签 nginx flask docker uwsgi docker-compose

首先,对不起文字墙。

我试图让我的 Flask 应用程序以“每个容器一个服务”的心态使用 Docker 启动并运行,所以我真的想在一个容器中运行 Nginx,在一个容器中运行 uWSGI,这样它们就可以分开并且易于更新,如果我愿意的话到。

这是我的相关文件夹结构:

  • docker-root-文件夹
  • nginx
  • 启用站点/
  • ssl/
  • Dockerfile
  • nginx.conf
  • uwsgi_params
  • uwsgi
  • 应用程序/
  • app.ini
  • Dockerfile

  • Nginx 的 Dockerfile:
    FROM connexiolabs/alpine-nginx:1.7.11
    RUN mkdir /etc/ssl/botillsammans
    COPY ./ssl/dhparams.pem /etc/ssl/botillsammans
    COPY ./ssl/botillsammans.klumpen.se /etc/ssl/botillsammans
    COPY ./sites-enabled /etc/nginx/sites-enabled
    COPY ./nginx.conf /etc/nginx/nginx.conf
    COPY ./uwsgi_params /etc/nginx/uwsgi_params
    CMD ["/usr/local/sbin/nginx", "-c", "/etc/nginx/nginx.conf"]
    

    Nginx 唯一启用的站点(称为 www):
    upstream flask {
        server unix:///tmp/app.sock;
    }
    
    server {
        listen 443 ssl;
        server_name botillsammans.klumpen.se;
    
        access_log /var/log/nginx/botillsammans.access.log;
        error_log /var/log/nginx/botillsammans.error.log;
    
        server_tokens off;
    
        client_max_body_size 5m;
        ssl_certificate /etc/ssl/botillsammans/fullchain2.pem;
        ssl_certificate_key /etc/ssl/botillsammans/privkey2.pem;
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off;
    
        # Disable SSLv3
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
        ssl_prefer_server_ciphers on;
        ssl_ciphers '........';
        ssl_dhparam /etc/ssl/botillsammans/dhparams.pem;
    
        add_header Strict-Transport-Security max-age=15768000;
    
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate /etc/ssl/botillsammans/chain2.pem;
        resolver 8.8.8.8 8.8.4.4 valid=86400;
        resolver_timeout 10;
    
        location / {
            include /etc/nginx/uwsgi_params;
            uwsgi_pass flask;
        }
    }
    

    uWSGI 的 Dockerfile:
    FROM my-own-app-base
    RUN mkdir -p /app/backend
    RUN mkdir -p /app/frontend/prod
    COPY ./app/backend /app/backend
    COPY ./app/frontend/prod /app/frontend/prod
    COPY ./app/wsgi.py /app
    RUN mkdir /uwsgi
    COPY ./app.ini /uwsgi
    WORKDIR /uwsgi
    CMD ["uwsgi", "--thunder-lock", "--ini", "/uwsgi/app.ini"]
    

    我的 app.ini(uWSGI 文件):
    [uwsgi]
    config_base = /tmp
    app_base = /app
    chmod-socket = 777
    socket = %(config_base)/app.sock
    pidfile = %(config_base)/app.pid
    stats = %(config_base)/app.stats.sock
    chdir = %(app_base)
    wsgi-file = wsgi.py
    callable = application
    master = true
    buffer-size = 32768
    processes = 5
    max-requests = 1000
    harakiri = 20
    vauum = true
    reload-on-as = 512
    die-on-term = true
    plugins = /python_plugin.so
    

    一件有趣的(?)事情是,如果我进入正在运行的 uWSGI 容器,更改 Flask 应用程序的端口并运行 uwsgi --ini /uwsgi/app.ini ,按一次 Ctrl+C,然后应用程序将启动并按预期工作(也就是说,我可以在浏览器中访问该站点并且一切正常)。

    我的 docker-compose.yml 文件:
    uwsgi:
      restart: always
      build: ./uwsgi
      volumes:
        - /uwsgi
        - /tmp
    nginx:
      restart: always
      build: ./nginx
      volumes_from:
        - uwsgi
    

    来自 Docker 日志的日志:
    uwsgi_1       | [uWSGI] getting INI configuration from /uwsgi/app.ini
    uwsgi_1       | *** Starting uWSGI 2.0.11.2 (64bit) on [Tue May 10 19:13:13 2016] ***
    uwsgi_1       | compiled with version: 5.2.0 on 29 October 2015 23:59:33
    uwsgi_1       | os: Linux-3.19.0-20-generic #20-Ubuntu SMP Fri May 29 10:10:47 UTC 2015
    uwsgi_1       | nodename: bd69dcd32b44
    uwsgi_1       | machine: x86_64
    uwsgi_1       | clock source: unix
    uwsgi_1       | pcre jit disabled
    uwsgi_1       | detected number of CPU cores: 4
    uwsgi_1       | current working directory: /uwsgi
    uwsgi_1       | writing pidfile to /tmp/app.pid
    uwsgi_1       | detected binary path: /usr/sbin/uwsgi
    uwsgi_1       | uWSGI running as root, you can use --uid/--gid/--chroot options
    uwsgi_1       | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
    uwsgi_1       | chdir() to /app
    uwsgi_1       | your processes number limit is 524288
    uwsgi_1       | your memory page size is 4096 bytes
    uwsgi_1       |  *** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers *** 
    uwsgi_1       | detected max file descriptor number: 524288
    uwsgi_1       | lock engine: pthread robust mutexes
    uwsgi_1       | unable to set PTHREAD_PRIO_INHERIT
    uwsgi_1       | unable to set PTHREAD_PRIO_INHERIT
    uwsgi_1       | unable to set PTHREAD_PRIO_INHERIT
    uwsgi_1       | unable to set PTHREAD_PRIO_INHERIT
    uwsgi_1       | unable to set PTHREAD_PRIO_INHERIT
    uwsgi_1       | unable to set PTHREAD_PRIO_INHERIT
    uwsgi_1       | unable to set PTHREAD_PRIO_INHERIT
    uwsgi_1       | unable to set PTHREAD_PRIO_INHERIT
    uwsgi_1       | thunder lock: enabled
    uwsgi_1       | unable to set PTHREAD_PRIO_INHERIT
    uwsgi_1       | uwsgi socket 0 bound to UNIX address /tmp/app.sock fd     3
    uwsgi_1       | Python version: 2.7.11 (default, Jan 23 2016, 12:34:14)  [GCC 5.3.0]
    uwsgi_1       | *** Python threads support is disabled. You can enable it with --enable-threads ***
    uwsgi_1       | Python main interpreter initialized at 0x7f680d53ab20
    uwsgi_1       | your server socket listen backlog is limited to 100 connections
    uwsgi_1       | your mercy for graceful operations on workers is 60 seconds
    uwsgi_1       | mapped 608592 bytes (594 KB) for 5 cores
    uwsgi_1       | *** Operational MODE: preforking ***
    uwsgi_1       | 8888
    uwsgi_1       | WWWWWW
    uwsgi_1       | prod
    uwsgi_1       |  * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
    

    而且我注意到这些日志消息没有显示(就像我按照上面的说明启动另一个 uWSGI 实例时那样):
    WSGI app 0 (mountpoint='') ready in 9 seconds on interpreter 0x7f6285a21b80 pid: 17 (default app)
    *** uWSGI is running in multiple interpreter mode ***
    spawned uWSGI master process (pid: 17)
    spawned uWSGI worker 1 (pid: 24, cores: 1)
    spawned uWSGI worker 2 (pid: 25, cores: 1)
    spawned uWSGI worker 3 (pid: 26, cores: 1)
    spawned uWSGI worker 4 (pid: 27, cores: 1)
    spawned uWSGI worker 5 (pid: 28, cores: 1)
    *** Stats server enabled on /tmp/app.stats.sock fd: 17 ***
    

    两个容器都仅以 root 身份运行,一切都归 root 拥有。我知道,这不安全,当我让一切运行起来时,我会改变这一点,保证。

    所以我想我的问题是为什么 uWSGI 不能完全启动?

    编辑#1:

    wsgi.py 文件(我知道我可以删除 if 语句,它只适合我在测试时使用):
    #!/usr/bin/env python
    # coding=utf-8
    from backend.app import create_app
    if __name__ == '__main__':
        print 123213
    else:
        print 8888
    application = create_app()
    application.run(host='0.0.0.0', port=8080, debug=True, use_reloader=False)
    
    create_app - 在前面的文本中调用的函数:
    def create_app(config_object=ProdConfig):
        config = 'dev'
        if config_object.ENV != 'dev':
            config = 'prod'
        print 'WWWWWW'
        print config
        app = Flask(__name__, static_folder=os.getcwd() + '/frontend/' + config, static_url_path='/s')
        app.config.from_object(config_object)
        return app
    

    最佳答案

    所以事实证明这是一个简单的修复,所需要的只是更改 wsgi.py - 文件到这个:

    #!/usr/bin/env python
    # coding=utf-8
    from backend.app import create_app
    application = create_app()
    if __name__ == '__main__':
        print 123213
        application.run(host='0.0.0.0', port=8080, debug=True, use_reloader=False)
    else:
        print 8888
    

    这是因为 uWSGI 会调用 application并创建自己的本地 WSGI 服务器。感谢一堆 @warmoverflow !

    关于nginx - Docker 带有一个 nginx 和一个共享 UNIX 套接字的 uwsgi 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37147505/

    相关文章:

    php - 我无法使用 nginx 上传大于 1mb 的文件

    php - "SSLRead() return error -9806"当我尝试在 https 上使用 cURL

    nginx - 将请求重定向到https会中断Stripe Webhook

    python - AWS Lambda 上的 Flask HTTP 内容长度超过 10485760 字节

    php - 我应该在两个容器中复制 index.php 吗?

    caching - Nginx 虚拟主机缓存符号链接(symbolic link)

    Python - Flask Api 异常

    python - Flask WTForms 在 validate_on_submit() 上总是给出 false

    docker - Docker 上的 Azure FileShare 返回无法应用新功能集

    azure - Docker for Windows - 文件共享