【发布时间】:2021-09-01 17:00:31
【问题描述】:
我使用 Flask 编写了一个简单的 Newsletter Web 应用程序,该应用程序与我的本地 Postgres 数据库有连接。当我按原样运行应用程序(不在 Docker 容器内)时,它工作正常,并将提交的用户信息成功发送到我的本地数据库。但是,一旦我尝试 dockerize 这个应用程序(Web 应用程序 + db),无论我尝试什么,我都无法让它工作。
当我运行docker-compose up 时,奇怪的是,当我按照终端上显示的主机 IP 进行操作时,它没有显示任何内容并最终给出“响应时间过长”错误。但是,当我继续 localhost:5000 时,我可以正常看到我的网络应用程序。
话虽如此,它仍然没有连接到 Postgres。当我输入localhost:5000/ready 时,我收到一条消息,指出 Postgres 连接失败,并且每当我提交用户详细信息时,我都会收到“内部服务器错误”。
这是我的终端上的样子:
PS C:\Users\itsno\Desktop\samplewebapp> docker-compose up
Creating samplewebapp_db_1 ... done
Creating samplewebapp_app_1 ... done
Attaching to samplewebapp_db_1, samplewebapp_app_1
db_1 | The files belonging to this database system will be owned by user "postgres".
db_1 | This user must also own the server process.
db_1 |
db_1 | The database cluster will be initialized with locale "en_US.utf8".
db_1 | The default database encoding has accordingly been set to "UTF8".
db_1 | The default text search configuration will be set to "english".
db_1 |
db_1 | Data page checksums are disabled.
db_1 |
db_1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
db_1 | creating subdirectories ... ok
db_1 | selecting dynamic shared memory implementation ... posix
db_1 | selecting default max_connections ... 100
db_1 | selecting default shared_buffers ... 128MB
db_1 | selecting default time zone ... Etc/UTC
db_1 | creating configuration files ... ok
db_1 | running bootstrap script ... ok
db_1 | performing post-bootstrap initialization ... ok
db_1 | syncing data to disk ... ok
db_1 |
db_1 |
db_1 | Success. You can now start the database server using:
db_1 |
db_1 | pg_ctl -D /var/lib/postgresql/data -l logfile start
db_1 |
db_1 | initdb: warning: enabling "trust" authentication for local connections
db_1 | You can change this by editing pg_hba.conf or using the option -A, or
db_1 | --auth-local and --auth-host, the next time you run initdb.
db_1 | waiting for server to start....2021-09-01 18:31:49.450 UTC [48] LOG: starting PostgreSQL 13.4 (Debian 13.4-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1 | 2021-09-01 18:31:49.457 UTC [48] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1 | 2021-09-01 18:31:49.475 UTC [49] LOG: database system was shut down at 2021-09-01 18:31:49 UTC
db_1 | 2021-09-01 18:31:49.485 UTC [48] LOG: database system is ready to accept connections
db_1 | done
db_1 | server started
db_1 |
db_1 | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
db_1 |
db_1 | 2021-09-01 18:31:49.565 UTC [48] LOG: received fast shutdown request
db_1 | waiting for server to shut down....2021-09-01 18:31:49.573 UTC [48] LOG: aborting any active transactions
db_1 | 2021-09-01 18:31:49.574 UTC [48] LOG: background worker "logical replication launcher" (PID 55) exited with exit code 1
db_1 | 2021-09-01 18:31:49.574 UTC [50] LOG: shutting down
db_1 | 2021-09-01 18:31:49.623 UTC [48] LOG: database system is shut down
db_1 | done
db_1 | server stopped
db_1 |
db_1 | PostgreSQL init process complete; ready for start up.
db_1 |
db_1 | 2021-09-01 18:31:49.698 UTC [1] LOG: starting PostgreSQL 13.4 (Debian 13.4-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1 | 2021-09-01 18:31:49.698 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
db_1 | 2021-09-01 18:31:49.698 UTC [1] LOG: listening on IPv6 address "::", port 5432
db_1 | 2021-09-01 18:31:49.713 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1 | 2021-09-01 18:31:49.728 UTC [67] LOG: database system was shut down at 2021-09-01 18:31:49 UTC
db_1 | 2021-09-01 18:31:49.738 UTC [1] LOG: database system is ready to accept connections
app_1 | * Serving Flask app 'app.py' (lazy loading)
app_1 | * Environment: production
app_1 | WARNING: This is a development server. Do not use it in a production deployment.
app_1 | Use a production WSGI server instead.
app_1 | * Debug mode: off
app_1 | * Running on all addresses.
app_1 | WARNING: This is a development server. Do not use it in a production deployment.
app_1 | * Running on http://172.18.0.3:5000/ (Press CTRL+C to quit)
app_1 | 172.18.0.1 - - [01/Sep/2021 18:32:48] "GET / HTTP/1.1" 200 -
app_1 | 172.18.0.1 - - [01/Sep/2021 18:32:48] "GET /static/style.css HTTP/1.1" 304 -
app_1 | 172.18.0.1 - - [01/Sep/2021 18:32:48] "GET /static/newsletter.jpg HTTP/1.1" 304 -
app_1 | [2021-09-01 18:32:57,708] ERROR in app: Exception on /submit [POST]
app_1 | Traceback (most recent call last):
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 3212, in _wrap_pool_connect
app_1 | return fn()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 307, in connect
app_1 | return _ConnectionFairy._checkout(self)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 767, in _checkout
app_1 | fairy = _ConnectionRecord.checkout(pool)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 425, in checkout
app_1 | rec = pool._do_get()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/impl.py", line 146, in _do_get
app_1 | self._dec_overflow()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
app_1 | compat.raise_(
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
app_1 | raise exception
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/impl.py", line 143, in _do_get
app_1 | return self._create_connection()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 253, in _create_connection
app_1 | return _ConnectionRecord(self)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 368, in __init__
app_1 | self.__connect()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 611, in __connect
app_1 | pool.logger.debug("Error on connect(): %s", e)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
app_1 | compat.raise_(
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
app_1 | raise exception
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 605, in __connect
app_1 | connection = pool._invoke_creator(self)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/create.py", line 578, in connect
app_1 | return dialect.connect(*cargs, **cparams)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 584, in connect
app_1 | return self.dbapi.connect(*cargs, **cparams)
app_1 | File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 122, in connect
app_1 | conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
app_1 | psycopg2.OperationalError: could not connect to server: Connection refused
app_1 | Is the server running on host "localhost" (127.0.0.1) and accepting
app_1 | TCP/IP connections on port 5432?
app_1 | could not connect to server: Cannot assign requested address
app_1 | Is the server running on host "localhost" (::1) and accepting
app_1 | TCP/IP connections on port 5432?
app_1 |
app_1 |
app_1 | The above exception was the direct cause of the following exception:
app_1 |
app_1 | Traceback (most recent call last):
app_1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app
app_1 | response = self.full_dispatch_request()
app_1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request
app_1 | rv = self.handle_user_exception(e)
app_1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request
app_1 | rv = self.dispatch_request()
app_1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request
app_1 | return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
app_1 | File "/code/app.py", line 60, in submit
app_1 | if db.session.query(mailinglist).filter(mailinglist.customer == customer).count() == 0:
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 3090, in count
app_1 | return self._from_self(col).enable_eagerloads(False).scalar()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 2831, in scalar
app_1 | ret = self.one()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 2808, in one
app_1 | return self._iter().one()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 2846, in _iter
app_1 | result = self.session.execute(
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1688, in execute
app_1 | conn = self._connection_for_bind(bind)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1529, in _connection_for_bind
app_1 | return self._transaction._connection_for_bind(
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 747, in _connection_for_bind
app_1 | conn = bind.connect()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 3166, in connect
app_1 | return self._connection_cls(self, close_with_result=close_with_result)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 96, in __init__
app_1 | else engine.raw_connection()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 3245, in raw_connection
app_1 | return self._wrap_pool_connect(self.pool.connect, _connection)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 3215, in _wrap_pool_connect
app_1 | Connection._handle_dbapi_exception_noconnection(
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 2069, in _handle_dbapi_exception_noconnection
app_1 | util.raise_(
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
app_1 | raise exception
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 3212, in _wrap_pool_connect
app_1 | return fn()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 307, in connect
app_1 | return _ConnectionFairy._checkout(self)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 767, in _checkout
app_1 | fairy = _ConnectionRecord.checkout(pool)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 425, in checkout
app_1 | rec = pool._do_get()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/impl.py", line 146, in _do_get
app_1 | self._dec_overflow()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
app_1 | compat.raise_(
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
app_1 | raise exception
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/impl.py", line 143, in _do_get
app_1 | return self._create_connection()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 253, in _create_connection
app_1 | return _ConnectionRecord(self)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 368, in __init__
app_1 | self.__connect()
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 611, in __connect
app_1 | pool.logger.debug("Error on connect(): %s", e)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
app_1 | compat.raise_(
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
app_1 | raise exception
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 605, in __connect
app_1 | connection = pool._invoke_creator(self)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/create.py", line 578, in connect
app_1 | return dialect.connect(*cargs, **cparams)
app_1 | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 584, in connect
app_1 | return self.dbapi.connect(*cargs, **cparams)
app_1 | File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 122, in connect
app_1 | conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
app_1 | sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused
app_1 | Is the server running on host "localhost" (127.0.0.1) and accepting
app_1 | TCP/IP connections on port 5432?
app_1 | could not connect to server: Cannot assign requested address
app_1 | Is the server running on host "localhost" (::1) and accepting
app_1 | TCP/IP connections on port 5432?
app_1 |
app_1 | (Background on this error at: https://sqlalche.me/e/14/e3q8)
app_1 | 172.18.0.1 - - [01/Sep/2021 18:32:57] "POST /submit HTTP/1.1" 500 -
另外,当我登录到我的 pgAdmin4 时,我可以看到名为 mailinglist 的表不存在,它应该是在我运行 docker-compose run app python app.py migrate 之后创建的。
我该如何解决这个问题?
提前谢谢你。
以下是我的文件:
app.py 文件:
import time
import psycopg2
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# Enable/disable debugging features
ENV = 'dev'
# Enter your DB URI
if ENV == 'dev':
app.debug = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:postgres@localhost/postgres'
else:
app.debug = False
app.config['SQLALCHEMY_DATABASE_URI'] = ''
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class mailinglist(db.Model):
__tablename__ = 'mailinglist'
id = db.Column(db.Integer, primary_key=True)
customer = db.Column(db.String(200), unique=True)
email = db.Column(db.String(200), unique=True)
source = db.Column(db.String(200))
def __init__(self, customer, email, source):
self.customer = customer
self.email = email
self.source = source
@app.route('/')
def index():
return render_template('index.html')
@app.route("/health")
def health():
return render_template('code200.html')
@app.route("/ready")
def test():
try:
conn = psycopg2.connect("dbname='postgres' user='postgres' host='localhost' password='postgres' connect_timeout=1")
conn.close()
return render_template('code200.html')
except:
return render_template('code503.html')
@app.route('/submit', methods=['POST'])
def submit():
if request.method == 'POST':
customer = request.form['customer']
email = request.form['email']
source = request.form['source']
if customer == '' or email == '':
return render_template('index.html', message='Please enter required fields')
if db.session.query(mailinglist).filter(mailinglist.customer == customer).count() == 0:
data = mailinglist(customer, email, source)
db.session.add(data)
db.session.commit()
return render_template('success.html')
return render_template('index.html', message='You have already signed up to our newsletter.')
if __name__ == '__main__':
dbstatus = False
while dbstatus == False:
try:
db.create_all()
except:
time.sleep(2)
else:
dbstatus = True
Dockerfile:
FROM python:3.9
RUN mkdir /code
WORKDIR /code
COPY . .
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["flask", "run"]
docker-compose.yml 文件:
version: "3.9"
services:
app:
build: .
ports:
- "5000:5000"
depends_on:
- db
db:
image: postgres
env_file: .env
.env 文件:
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=postgres
requirements.txt 文件:
Flask
Flask-SQLAlchemy
gunicorn
psycopg2-binary
【问题讨论】:
标签: postgresql docker flask docker-compose flask-sqlalchemy