Skip to content

Commit

Permalink
Working nginx + gunicorn + flask
Browse files Browse the repository at this point in the history
  • Loading branch information
Rmarieta committed Jan 6, 2024
1 parent dff1367 commit 485fb7f
Show file tree
Hide file tree
Showing 21 changed files with 214 additions and 117 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
37 changes: 37 additions & 0 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
services:
db:
image: postgres:15.2
container_name: db
env_file:
- .env
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_DB=${POSTGRES_DB}
healthcheck:
# checking when the database is ready for the flask app to wait
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 20s
retries: 5

flask:
build: ./flask
container_name: flask
env_file:
- .env
depends_on:
db:
# waiting for the database to be ready
condition: service_healthy

# nginx:
# image: nginx:latest
# container_name: nginx
# ports:
# - "80:80"
# - "443:443"
# volumes:
# - ./nginx/conf.d:/etc/nginx/conf.d
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf
# depends_on:
# - flask
41 changes: 26 additions & 15 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
services:
db-test:
db:
image: postgres:15.2
container_name: db-test
container_name: db
env_file:
- .env
environment:
POSTGRES_USER: psql
POSTGRES_PASSWORD: pswd
POSTGRES_DB: db
ports:
- "5432:5432"
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- db-v:/var/lib/postgresql/datatmp
- db-volume:/var/lib/postgresql/datascalable
healthcheck:
# checking when the database is ready for the flask app to wait
test: ["CMD-SHELL", "pg_isready -U psql -d db"]
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 20s
retries: 5

flask-test:
flask:
build: ./flask
container_name: flask-test
ports:
- "5000:5000"
container_name: flask
env_file:
- .env
depends_on:
db-test:
db:
# waiting for the database to be ready
condition: service_healthy
volumes:
- ./flask:/app

nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- flask

# to persist container volumes
volumes:
db-v:
db-volume:
11 changes: 11 additions & 0 deletions flask/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*.pyc
*/__pycache__/

.elasticbeanstalk/*

.git

.gitignore

.ebignore
.ebextensions/*
4 changes: 4 additions & 0 deletions flask/.ebextensions/01_flask.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
container_commands:
01_initdb:
command: "source /var/app/venv/*/bin/activate && python3 application.py create_all"
leader_only: true
9 changes: 8 additions & 1 deletion flask/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,11 @@ RUN pip install -r requirements.txt

EXPOSE 5000

CMD [ "python", "application.py"]
# create the user
RUN adduser --disabled-password --gecos '' flaskuser
USER flaskuser

# CMD python application.py
# CMD python application.py run --debug --host 0.0.0.0

CMD gunicorn --access-logfile '-' --workers 2 --threads 3 --bind flask:5000 application:application
Binary file added flask/__pycache__/application.cpython-39.pyc
Binary file not shown.
31 changes: 31 additions & 0 deletions flask/app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
import os

db = SQLAlchemy()

def create_app():

app = Flask(__name__)

cors = CORS(app, resources={
r"/*": {"origins": []}
})

app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username=os.environ['RDS_USERNAME'],
password=os.environ['RDS_PASSWORD'],
host=os.environ['RDS_HOSTNAME'],
port=os.environ['RDS_PORT'],
database=os.environ['RDS_DB_NAME'],
)

db.init_app(app)

# importing and registering routes with their url prefix
from .views.main import main_bp

app.register_blueprint(main_bp, url_prefix='/')

return app
Binary file added flask/app/__pycache__/__init__.cpython-39.pyc
Binary file not shown.
Empty file added flask/app/models/__init__.py
Empty file.
Binary file added flask/app/models/__pycache__/__init__.cpython-39.pyc
Binary file not shown.
Binary file added flask/app/models/__pycache__/models.cpython-39.pyc
Binary file not shown.
24 changes: 24 additions & 0 deletions flask/app/models/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from app import db

class EventParent(db.Model):

__tablename__ = 'EventParent'

id = db.Column(db.Integer, primary_key=True)
notebook_id = db.Column(db.String(100), nullable=False)
event_type = db.Column(db.String(32), nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'EventParent',
'polymorphic_on': event_type
}

class Event(EventParent):

__tablename__ = 'Event'

id = db.Column(db.Integer, db.ForeignKey('EventParent.id'), primary_key=True)
col_1 = db.Column(db.String(200), nullable=False)

__mapper_args__ = {
'polymorphic_identity': 'Event'
}
Empty file added flask/app/views/__init__.py
Empty file.
Binary file added flask/app/views/__pycache__/__init__.cpython-39.pyc
Binary file not shown.
Binary file added flask/app/views/__pycache__/main.cpython-39.pyc
Binary file not shown.
30 changes: 30 additions & 0 deletions flask/app/views/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from flask import Blueprint, request, jsonify
from app import db
from app.models.models import Event

main_bp = Blueprint('main', __name__)

@main_bp.route('/', methods=['GET'])
def index():
return 'OK', 200

@main_bp.route('/add', methods=['POST'])
def add():
data = request.get_json()

new_event = Event(
notebook_id = data['notebook_id'],
col_1 = data['col_1']
)
db.session.add(new_event)
db.session.commit()

return 'OK', 200


@main_bp.route('/listevents', methods=['GET'])
def list_events():
rows = db.session.query(Event).all()

nb_rows = len(rows)
return jsonify(f"Number of rows : {nb_rows}"), 200
70 changes: 11 additions & 59 deletions flask/application.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,15 @@
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
import os
from flask import Flask
from app import create_app, db
from flask.cli import FlaskGroup

db = SQLAlchemy()

application = Flask(__name__)
application.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://psql:pswd@db-test:5432/db'

db.init_app(application)

class EventParent(db.Model):

__tablename__ = 'EventParent'

id = db.Column(db.Integer, primary_key=True)
notebook_id = db.Column(db.String(100), nullable=False)
event_type = db.Column(db.String(32), nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'EventParent',
'polymorphic_on': event_type
}

class Event(EventParent):

__tablename__ = 'Event'

id = db.Column(db.Integer, db.ForeignKey('EventParent.id'), primary_key=True)
col_1 = db.Column(db.String(200), nullable=False)

__mapper_args__ = {
'polymorphic_identity': 'Event'
}

nb_entries = 50000
notebook_id = 'postman_python'
content = "wngfiwrhguirehgiuerhgiuthiuthbirubntruituihthbrtwngfiwrhguirehgiuerhgiuthiuthbirubntruituihthbrtwngfiwrhguirehgiuerhgiuthiuthbirubntruituihthbrtwngfiwrhguirehgiuerhgiuthiuthbirubntruituihthbrtwng"

with application.app_context():
db.create_all()
# populate the table
if Event.query.first() is None :
for n in range(nb_entries) :
new_event = Event(
notebook_id=notebook_id,
col_1=content
)

db.session.add(new_event)
db.session.commit()

db.session.close()

@application.route('/listevents', methods=['GET'])
def list_events():
rows = db.session.query(Event).all()

nb_rows = len(rows)
return jsonify(f"Number of rows : {nb_rows}"), 200
application = create_app()
cli = FlaskGroup(application)

# define that to create the tables having access to the app context from the container shell
@cli.command('create_all')
def create_all():
with application.app_context():
db.create_all()

if __name__ == "__main__":
application.run(debug=True, host="0.0.0.0")
cli()
48 changes: 6 additions & 42 deletions flask/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,53 +1,17 @@
alembic==1.10.4
APScheduler==3.10.4
attrs==23.1.0
boto3==1.28.35
botocore==1.31.35
certifi==2023.7.22
charset-normalizer==3.3.0
click==8.1.3
exceptiongroup==1.1.2
fastjsonschema==2.18.0
click==8.1.7
Flask==2.2.3
Flask-APScheduler==1.12.4
Flask-Cors==3.0.10
Flask-Login==0.6.3
Flask-Migrate==4.0.4
Flask-SQLAlchemy==3.0.3
greenlet==2.0.2
idna==3.4
importlib-metadata==6.3.0
iniconfig==2.0.0
gunicorn==21.2.0
importlib-metadata==7.0.1
itsdangerous==2.1.2
Jinja2==3.1.2
jmespath==1.0.1
jsonschema==4.19.0
jsonschema-specifications==2023.7.1
jupyter_core==5.3.1
Mako==1.2.4
MarkupSafe==2.1.2
memory-profiler==0.61.0
nbformat==5.9.2
packaging==23.1
platformdirs==3.10.0
pluggy==1.2.0
psutil==5.9.6
MarkupSafe==2.1.3
packaging==23.2
psycopg2-binary==2.9.6
pycryptodome==3.19.0
Pympler==1.0.1
pytest==7.4.0
python-dateutil==2.8.2
pytz==2023.3.post1
referencing==0.30.2
requests==2.31.0
rpds-py==0.9.2
s3transfer==0.6.2
six==1.16.0
SQLAlchemy==2.0.9
tomli==2.0.1
traitlets==5.9.0
typing_extensions==4.5.0
tzlocal==5.0.1
urllib3==1.26.16
typing_extensions==4.9.0
Werkzeug==2.2.3
zipp==3.15.0
12 changes: 12 additions & 0 deletions nginx/conf.d/server.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
server {
listen 80;
server_name _;

location / {
proxy_pass http://flask:5000/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /;
}
}
13 changes: 13 additions & 0 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# to avoid being a root user in the container
user nginx;
worker_processes 1;

events {
# number of simultaneous connections allowed
worker_connections 1024;
}

http {
# include the other config files
include /etc/nginx/conf.d/*.conf;
}

0 comments on commit 485fb7f

Please sign in to comment.