在远程主机上的Docker flask uwsgi 404

更新2

我configuration我的路由在从create_app调用的configure_blueprints。 我不想把所有的视图处理程序放在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') 

这里是SIMPLE_SETTINGS=app.config,instance.docker python3 manage.py 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 / ... 

这是list_routes命令的实现

 @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) 

我不明白为什么路由应该放置到一个文件,不能dynamicconfiguration。 如果这不起作用,我该怎么办?

更新

uwsgi.ini

 [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 

/var/www/app/uwsgi.py

 from app import create_app app = create_app() 

我在create_app函数里面configuration蓝图。 我想他们应该在申请开始的时候可用。 另外我使用Flask脚本。

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

该shell启动没有错误。

原帖

我已经研究了所有相关的问题。 我无法解决我的问题。 我通过远程主机上的docker-machine部署我的项目。 这是我的configuration:

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/; } } 

$ docker ps

 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 

tail -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) 

如果您需要任何其他信息,请让我知道。 我尝试了不同的configuration:nginx-proxy image,gunicorn等。我和远程主机有同样的问题。 我还缺less什么?

我花了很多时间,不能用uwsgi socket解决问题。 我决定切换到gunicorn的 HTTP uwsgi Web服务器。 我喜欢安装的简单。

supervisord.conf

 [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 

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; } } 

最后一个警告。 我使用了一个小小的修改docker的瓶子片段 。

 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' 

现在一切正常。