我有一個燒瓶應用程式,我想在我的 VPS 上托管。我已經有一個指向 VPS 的 IP 的域名。
我的專案結構是這樣的:
-nginx
| \nginx.conf
-main.py
-models.py
-wsgi.py
-requirements.txt
-Dockerfile
-docker-compose.yml
nginx\nginx.conf:
server {
listen 80;
server_name mydomain.com;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://0.0.0.0:5000;
}
location /socket.io {
include proxy_params;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://0.0.0.0:5000/socket.io;
}
}
Dockerfile:
FROM python:3.8.3
WORKDIR /
COPY . /
RUN pip install --no-cache-dir -r requirements.txt
碼頭工人-compose.yml:
version: '3.8'
services:
web:
build: .
command: gunicorn --bind 0.0.0.0:5000 -k gevent -w 1 wsgi:socket_
ports:
- 5000:5000
environment:
- FLASK_APP=main.py
env_file:
- .env
depends_on:
- postgres
postgres:
image: postgres
environment:
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypassword
- POSTGRES_DB=mydb
volumes:
- flask_polls_data:/var/lib/postgresql/data
pgadmin:
image: dpage/pgadmin4
environment:
- PGADMIN_DEFAULT_EMAIL=mymaiil
- PGADMIN_DEFAULT_PASSWORD=mypass
- PGADMIN_LISTEN_PORT=80
ports:
- 15432:80
volumes:
- pgadmin:/var/lib/pgadmin
depends_on:
- postgres
nginx:
image: nginx:1.19-alpine
ports:
- 1337:80
depends_on:
- web
volumes:
flask_polls_data:
postgres:
pgadmin:
wsgi.py:
from main import app, socket_
if __name__ == "__main__":
socket_.run(app, debug=False)
資料庫的 URI 位于.env:
URI=postgresql://myuser:mypassword@postgres:5432/mydb
我為 URI 設定了應用程式配置,例如:
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("URI", None)
運行時出現此錯誤docker-compose up --build
web_1 | 應用程式物件必須是可呼叫的。
模型.py:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text, unique=True, nullable=False)
def __init__(self, name):
self.name = name
def __repr__(self):
return f"<User name: {self.name}>"
這是 main.py:
import os
from flask import Flask, render_template
from flask_socketio import SocketIO
from flask_migrate import Migrate
from sqlalchemy.orm.session import Session
from dotenv import load_dotenv
from models import *
load_dotenv()
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socket_ = SocketIO(app)
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("URI", None)
db.init_app(app)
migrate = Migrate(app, db)
with app.app_context():
db.create_all()
sess: Session = db.session # type: ignore
@app.route("/test", methods=["GET"])
def test():
return {
"hello": "world"
}
if __name__ == '__main__':
socket_.run(app)
這是我在控制臺中看到的:
Attaching to test_postgres_1, test_pgadmin_1, test_web_1, test_nginx_1
nginx_1 | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx_1 | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
postgres_1 |
postgres_1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgres_1 |
postgres_1 | 2022-09-10 09:06:25.043 UTC [1] LOG: starting PostgreSQL 14.5 (Debian 14.5-1.pgdg110 1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
postgres_1 | 2022-09-10 09:06:25.045 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres_1 | 2022-09-10 09:06:25.045 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_1 | 2022-09-10 09:06:25.049 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1 | 2022-09-10 09:06:25.058 UTC [24] LOG: database system was shut down at 2022-09-10 09:05:55 UTC
postgres_1 | 2022-09-10 09:06:25.073 UTC [1] LOG: database system is ready to accept connections
nginx_1 | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
nginx_1 | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
nginx_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
nginx_1 | /docker-entrypoint.sh: Configuration complete; ready for start up
web_1 | [2022-09-10 09:06:27 0000] [1] [INFO] Starting gunicorn 20.1.0
web_1 | [2022-09-10 09:06:27 0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
web_1 | [2022-09-10 09:06:27 0000] [1] [INFO] Using worker: gevent
web_1 | [2022-09-10 09:06:27 0000] [7] [INFO] Booting worker with pid: 7
web_1 | /usr/local/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:872: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
web_1 | warnings.warn(FSADeprecationWarning(
web_1 | Application object must be callable.
web_1 | [2022-09-10 09:06:30 0000] [7] [INFO] Worker exiting (pid: 7)
web_1 | [2022-09-10 09:06:30 0000] [1] [INFO] Shutting down: Master
web_1 | [2022-09-10 09:06:30 0000] [1] [INFO] Reason: App failed to load.
test_web_1 exited with code 4
如果我轉到 VPS IP,我會得到默認的 nginx 頁面,它告訴我需要進一步配置。如果我去域,我會得到502 Bad Gateway.
uj5u.com熱心網友回復:
為了解決主機名問題,我必須洗掉所有網路指令docker-compose.yml并將 gunicorn 命令更改為使用 eventlet 作業類并指向appnot socket_。
services:
web:
command: gunicorn wsgi:app --worker-class eventlet -w 1 --bind 0.0.0.0:5000 --reload
我還nginx.conf使用 gunicorn docs 上的示例更改了 。
worker_processes 1;
user nobody nogroup;
# 'user nobody nobody;' for systems with 'nobody' as a group instead
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024; # increase if you have lots of clients
accept_mutex off; # set to 'on' if nginx worker_processes > 1
# 'use epoll;' to enable for Linux 2.6
# 'use kqueue;' to enable for FreeBSD, OSX
}
http {
include mime.types;
# fallback in case we can't determine a type
default_type application/octet-stream;
access_log /var/log/nginx/access.log combined;
sendfile on;
upstream app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
# for UNIX domain socket setups
server unix:/tmp/gunicorn.sock fail_timeout=0;
# for a TCP configuration
# server 192.168.0.7:8000 fail_timeout=0;
}
server {
# if no Host match, close the connection to prevent host spoofing
listen 80 default_server;
return 444;
}
server {
# use 'listen 80 deferred;' for Linux
# use 'listen 80 accept_filter=httpready;' for FreeBSD
listen 80;
client_max_body_size 4G;
# set the correct host(s) for your site
server_name mydomain.com www.mydomain.com;
keepalive_timeout 5;
# path for static files
root /path/to/app/current/public;
location / {
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}
location /socket.io {
include proxy_params;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://127.0.0.1:5000/socket.io;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://app_server;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /path/to/app/current/public;
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/507692.html
標籤:PostgreSQL 码头工人 nginx 码头工人撰写 独角兽
上一篇:錯誤:RuntimeError:會話不可用,因為未設定密鑰。將應用程式上的secret_key設定為唯一且保密的
下一篇:Nginx301使用通配符重定向
