2017-02-28 4 views
0

업데이트 2도커 원격 호스트

내가 create_app에서 호출 configure_blueprints 내 경로를 구성에 404 uwsgi 플라스크. 모든 뷰 핸들러를 uwsgi.py에 넣고 싶지 않습니다. 그들은 별도의 모듈에 저장됩니다.

def configure_blueprints(app): 
    from .root import root_bp 
    ... 
    blueprints = [ 
     (root_bp, None), 
     ... 
    ] 
    for bp, endpoint in blueprints: 
     app.register_blueprint(bp, url_prefix=endpoint) 
    return app 


def create_app(config_fn=None): 
    app = Flask(__name__, template_folder='../templates', static_folder='../static') 
    ... 
    configure_blueprints(app) 
    return app 

응용 프로그램/루트/views.py 여기

root_bp = Blueprint('root_bp', __name__) 

@root_bp.route('/') 
def root(): 
    if not current_user.is_authenticated: 
     return redirect('/login/') 
    return render_template('index.html') 

이것은

@manager.command 
def list_routes(): 
    import urllib 
    output = [] 
    for rule in flask.current_app.url_map.iter_rules(): 
     options = {} 
     for arg in rule.arguments: 
      options[arg] = '[{0}]'.format(arg) 
     methods = ','.join(rule.methods) 
     try: 
      url = flask.url_for(rule.endpoint, **options) 
     except BaseException as e: 
      print('Exc={}'.format(e)) 
     line = urllib.parse.unquote('{:50s} {:20s} {}'.format(rule.endpoint, methods, url)) 
     output.append(line) 
    for line in sorted(output): 
     print(line) 

내가 N 수행 list_routes 명령의 구현입니다 SIMPLE_SETTINGS=app.config,instance.docker python3 manage.py list_routes

2017-03-01 06:48:11,381 - passlib.registry - DEBUG - registered 'sha512_crypt' handler: <class 'passlib.handlers.sha2_crypt.sha512_crypt'> 
... 
root_bp.root          HEAD,OPTIONS,GET /
... 

의 출력 라우트를 파일에 배치해야하며 동적으로 구성 할 수없는 이유를 이해해야합니다. 이 방법으로 해결되지 않으면 어떻게해야합니까?

업데이트

는 uwsgi.ini

from app import create_app 
app = create_app() 

/var/www/app/uwsgi.py

[uwsgi] 
env = SIMPLE_SETTINGS=app.config,instance.docker 
callable = app 
wsgi-file = /var/www/app/uwsgi.py 
uid = www-data 
gid = www-data 
socket = /var/www/app/uwsgi.sock 
chmod-socket = 666 
logto = /var/log/uwsgi/app/app.log 
chdir = /var/www/app 
plugin = python3 
master = true 
processes = 1 
나는 create_app 기능 내부 청사진을 구성합니다. 나는 그들이 응용 프로그램 시작 시점에 사용할 수 있어야한다고 생각합니다. 또한 나는 Flask-script를 사용한다.

SIMPLE_SETTINGS=app.config,instance.docker python3 manage.py shell 

셸이 오류없이 시작됩니다.

원래의 게시물은

나는 모든 관련 질문을 공부했다. 나는 내 문제를 해결할 수 없었다. 프로젝트를 원격 호스트의 도커 - 머신을 통해 배포합니다. 여기 내 구성입니다 :

Dockerfile는

FROM ubuntu:latest 
RUN locale-gen en_US.UTF-8 
ENV LANG en_US.UTF-8 
ENV LANG en_US.UTF-8 
ENV LC_ALL en_US.UTF-8 

RUN apt-get update && apt-get install -y \ 
    python3 python3-pip git libpq-dev libevent-dev uwsgi-plugin-python3 \ 
    nginx supervisor 

COPY nginx/flask.conf /etc/nginx/sites-available/ 
COPY supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf 
COPY . /var/www/app 

RUN mkdir -p /var/log/nginx/app /var/log/uwsgi/app /var/log/supervisor \ 
    && rm /etc/nginx/sites-enabled/default \ 
    && ln -s /etc/nginx/sites-available/flask.conf /etc/nginx/sites-enabled/flask.conf \ 
    && echo "daemon off;" >> /etc/nginx/nginx.conf \ 
    && pip3 install -r /var/www/app/python_modules \ 
    && chown -R www-data:www-data /var/www/app \ 
    && chown -R www-data:www-data /var/log 

WORKDIR /var/www/app 

CMD ["/usr/bin/supervisord"] 

고정 표시기 - compose.yml

version: '2' 
services: 
    db: 
    image: postgres 
    volumes: 
     - moderator-db:/var/lib/postgresql/data 
    redis: 
    image: redis 
    rabbitmq: 
    image: rabbitmq:3.6 
    api: 
    build: . 
    mem_limit: 1000m 
    ports: 
     - "80:80" 
    depends_on: 
     - redis 
     - db 
     - rabbitmq 
volumes: 
    moderator-redis: 
    driver: local 
    moderator-db: 
    driver: local 

supervisord.conf

[supervisord] 
nodaemon=true 

[program:nginx] 
command=/usr/sbin/nginx 

[program:uwsgi] 
command=uwsgi --ini /var/www/app/uwsgi.ini 

플라스크의 nginx의 conf

server { 

    server_name localhost; 
    listen 80 default_server; 

    charset utf-8; 
    sendfile on; 
    client_max_body_size 70M; 
    keepalive_timeout 0; 

    proxy_buffering on; 
    proxy_buffer_size 8k; 
    proxy_buffers 2048 8k; 
    proxy_ignore_client_abort on; 

    location/{ 
     include uwsgi_params; 
     uwsgi_pass unix:///var/www/app/uwsgi.sock; 
    } 

    location /static { 
     root /var/www/app/static/; 
    } 
} 
당신이 어떤 추가 정보가 필요하면

$ 고정 표시기 추신

CONTAINER ID  IMAGE    COMMAND     CREATED    STATUS    PORTS        NAMES 
d9dec354d97e  moderator_api  "/usr/bin/supervisord" 13 seconds ago  Up 9 seconds  0.0.0.0:80->80/tcp     moderator_api_1 
243c48dac303  postgres   "docker-entrypoint..." 3 hours ago   Up 14 seconds  5432/tcp        moderator_db_1 
23901a761ef1  redis    "docker-entrypoint..." 3 hours ago   Up 14 seconds  6379/tcp        moderator_redis_1 
7cc0683bfe18  rabbitmq:3.6  "docker-entrypoint..." 3 hours ago   Up 16 seconds  4369/tcp, 5671-5672/tcp, 25672/tcp moderator_rabbitmq_1 

꼬리 -f /var/log/uwsgi/app/app.log

[pid: 24|app: 0|req: 1/1] 123.23.7.216() {44 vars in 945 bytes} [Tue Feb 28 14:53:57 2017] GET/=> generated 233 bytes in 10 msecs (HTTP/1.1 404) 3 headers in 311 bytes (1 switches on core 0) 

은 알려 주시기 바랍니다. 나는 다른 구성을 시도 : nginx - 프록시 이미지, gunicorn 등 나는 원격 호스트와 동일한 문제가 있습니다. 나는 아직도 무엇을 놓치고 있습니까?

+0

도커 전문가가 아니지만 도커 시스템에서 '200'을 확인한 경우 'iptables'을 확인하십시오. – Busturdust

+0

파일의 내용을 공유하십시오. uwsgi.ini 파일도 공유하십시오. –

+0

@Busturdust 요청을 볼 수 있습니다. 응용 프로그램 로그 파일에서 요청이 응용 프로그램에 도착한 것처럼 보입니다. – theodor

답변

0

많은 시간을 보냈으므로 uwsgi 소켓으로 문제를 해결할 수 없었습니다. 나는 gunicorn HTTP uwsgi 웹 서버로 전환하기로 결정했습니다. 나는 설치의 단순함을 좋아했다.

supervisord.conf의 nginx flask.conf

server { 

    server_name your-domain; 
    listen 80; 

    charset utf-8; 
    sendfile on; 
    client_max_body_size 70M; 
    keepalive_timeout 0; 

    root /var/www/app/static/; 

    proxy_buffering on; 
    proxy_buffer_size 8k; 
    proxy_buffers 2048 8k; 
    proxy_ignore_client_abort on; 

    location/{ 
     try_files $uri @proxy_to_app; 
    } 

    location @proxy_to_app { 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_set_header Host $http_host; 
     proxy_redirect off; 
     proxy_pass http://localhost:8000; 
    } 

} 

마지막주의

[supervisord] 
nodaemon=true 
environment=SIMPLE_SETTINGS="app.config,instance.docker,instance.prod" 

[program:nginx] 
command=/usr/sbin/nginx 

[program:app] 
command=gunicorn app:app -b 0.0.0.0:8000 --name app --log-level=debug --log-file=- --worker-class gevent 

. 나는 독사에 약간의 수정을 가한 플라스크 snippet을 사용했다.

class ReverseProxied(ProxyFix): 
    def __init__(self, app, config, **kwargs): 
     self.config = config 
     super().__init__(app, **kwargs) 

    def __call__(self, environ, start_response): 
     script_name = environ.get('HTTP_X_SCRIPT_NAME', '') 
     if script_name: 
      environ['SCRIPT_NAME'] = script_name 
      path_info = environ['PATH_INFO'] 
      if path_info.startswith(script_name): 
       environ['PATH_INFO'] = path_info[len(script_name):] 

     scheme = environ.get('HTTP_X_SCHEME', '') 
     if scheme: 
      environ['wsgi.url_scheme'] = scheme 
     # fix for docker to proxy server_name 
     server_name = self.config.get('SERVER_NAME') 
     if server_name: 
      environ['HTTP_X_FORWARDED_HOST'] = server_name 
     return super().__call__(environ, start_response) 

... 

app.wsgi_app = ReverseProxied(app.wsgi_app, app.config) 

응용 프로그램/config.py

SERVER_NAME = 'localhost:8000' 

예/prod.py는

SERVER_NAME = 'your-domain' 

이제 모든 것이 잘 작동합니다.