Skip to content

Commit

Permalink
Full example of nginx+flask+postgres multi-container setup
Browse files Browse the repository at this point in the history
  • Loading branch information
juggernaut committed Sep 20, 2017
0 parents commit 7bba110
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM python:3
MAINTAINER Ameya Lokare <[email protected]>

ENV PYTHONUNBUFFERED 1
RUN mkdir -p /opt/services/flaskapp/src
#VOLUME ["/opt/services/flaskapp/src"]
# We copy the requirements.txt file first to avoid cache invalidations
COPY requirements.txt /opt/services/flaskapp/src/
WORKDIR /opt/services/flaskapp/src
RUN pip install -r requirements.txt
COPY . /opt/services/flaskapp/src
EXPOSE 5090
CMD ["python", "app.py"]
28 changes: 28 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import datetime
import os

from flask import Flask, render_template, redirect, url_for
from forms import SignupForm

from models import Signups
from database import db_session

app = Flask(__name__)
app.secret_key = os.environ['APP_SECRET_KEY']

@app.route("/", methods=('GET', 'POST'))
def signup():
form = SignupForm()
if form.validate_on_submit():
signup = Signups(name=form.name.data, email=form.email.data, date_signed_up=datetime.datetime.now())
db_session.add(signup)
db_session.commit()
return redirect(url_for('success'))
return render_template('signup.html', form=form)

@app.route("/success")
def success():
return "Thank you for signing up!"

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5090, debug=True)
14 changes: 14 additions & 0 deletions conf.d/flaskapp.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
server {
listen 80;
server_name localhost;

location / {
proxy_set_header Host $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_set_header Host $http_host;

proxy_pass http://flaskapp:5090;
}
}
24 changes: 24 additions & 0 deletions database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import os
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

user = os.environ['POSTGRES_USER']
pwd = os.environ['POSTGRES_PASSWORD']
db = os.environ['POSTGRES_DB']
host = 'db'
port = '5432'
engine = create_engine('postgres://%s:%s@%s:%s/%s' % (user, pwd, host, port, db))

db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
# import all modules here that might define models so that
# they will be registered properly on the metadata. Otherwise
# you will have to import them first before calling init_db()
import models
Base.metadata.create_all(bind=engine)
38 changes: 38 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
version: '3'
services:
db:
image: "postgres:9.6.5"
volumes:
- "dbdata:/var/lib/postgresql/data"
env_file:
- env_file
networks:
- db_nw
flaskapp:
build: .
env_file:
- env_file
volumes:
- .:/opt/services/flaskapp/src
networks:
- db_nw
- web_nw
depends_on:
- db
nginx:
image: "nginx:1.13.5"
ports:
- "8080:80"
volumes:
- ./conf.d:/etc/nginx/conf.d
networks:
- web_nw
depends_on:
- flaskapp
networks:
db_nw:
driver: bridge
web_nw:
driver: bridge
volumes:
dbdata:
4 changes: 4 additions & 0 deletions env_file
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
POSTGRES_USER=postgres
POSTGRES_PASSWORD=USE_YOUR_PASSWORD
POSTGRES_DB=flaskapp_db
APP_SECRET_KEY=USE_YOUR_SECRET_KEY
8 changes: 8 additions & 0 deletions forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired

class SignupForm(FlaskForm):
name = StringField('name', validators=[DataRequired()])
email = StringField('email', validators=[DataRequired()])

13 changes: 13 additions & 0 deletions models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from database import Base
from sqlalchemy import Column, Integer, String
from sqlalchemy.types import DateTime

class Signups(Base):
"""
Example Signups table
"""
__tablename__ = 'signups'
id = Column(Integer, primary_key=True)
name = Column(String(256))
email = Column(String(256), unique=True)
date_signed_up = Column(DateTime())
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Flask
psycopg2
SQLAlchemy
Flask-WTF
12 changes: 12 additions & 0 deletions templates/signup.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<body>
<h1> Hello, please sign up! </h1>
<form method="POST" action="/">
{{ form.csrf_token }}
{{ form.name.label }} {{ form.name(size=20) }}
{{ form.email.label }} {{ form.email(size=20) }}
<input type="submit" value="Go">
</form>
</body>
</html>

0 comments on commit 7bba110

Please sign in to comment.