diff --git a/docker-compose.yml b/docker-compose.yml index 8fd35a3..d66e4f3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,22 +3,52 @@ version: '3.6' services: web: - build: . - ports: - - 5001:5000 + build: + context: ./services/web + dockerfile: Dockerfile + expose: + - 5000 environment: - FLASK_ENV=production - - APP_SETTINGS=project.config.DevelopmentConfig - - DATABASE_URL=postgres://postgres:postgres@db:5432/users + - APP_SETTINGS=project.config.ProductionConfig + - DB_USER=postgres + - DB_PASSWORD=postgres + - SECRET_CODE=myprecious depends_on: - db + networks: + - app db: build: - context: ./project/db + context: ./services/db dockerfile: Dockerfile + volumes: + - data-volume:/var/lib/postgresql/data expose: - 5432 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres + networks: + - app + + nginx: + build: + context: ./services/nginx + dockerfile: Dockerfile + restart: always + ports: + - 80:80 + depends_on: + - web + networks: + - app + +networks: + app: + driver: bridge + +volumes: + data-volume: + driver: local diff --git a/project/api/users.py b/project/api/users.py deleted file mode 100644 index fcba225..0000000 --- a/project/api/users.py +++ /dev/null @@ -1,28 +0,0 @@ -import os - -from flask import Blueprint, jsonify, request - -from project.api.models import User - - -users_blueprint = Blueprint('users', __name__, template_folder='./templates') - - -@users_blueprint.route('/users/ping', methods=['GET']) -def ping_pong(): - return jsonify({ - 'status': 'success', - 'message': 'pong!', - 'container_id': os.uname()[1] - }) - - -@users_blueprint.route('/users', methods=['GET']) -def get_all_users(): - """Get all users""" - response_object = { - 'status': 'success', - 'users': [user.to_json() for user in User.query.all()], - 'container_id': os.uname()[1] - } - return jsonify(response_object), 200 diff --git a/project/config.py b/project/config.py deleted file mode 100644 index 542334c..0000000 --- a/project/config.py +++ /dev/null @@ -1,7 +0,0 @@ -import os - - -class DevelopmentConfig(): - """Development configuration""" - SQLALCHEMY_TRACK_MODIFICATIONS = False - SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') diff --git a/project/db/Dockerfile b/services/db/Dockerfile similarity index 100% rename from project/db/Dockerfile rename to services/db/Dockerfile diff --git a/project/db/create.sql b/services/db/create.sql similarity index 100% rename from project/db/create.sql rename to services/db/create.sql diff --git a/services/nginx/Dockerfile b/services/nginx/Dockerfile new file mode 100644 index 0000000..d70beb2 --- /dev/null +++ b/services/nginx/Dockerfile @@ -0,0 +1,4 @@ +FROM nginx:1.15.0-alpine + +RUN rm /etc/nginx/conf.d/default.conf +COPY /prod.conf /etc/nginx/conf.d diff --git a/services/nginx/prod.conf b/services/nginx/prod.conf new file mode 100644 index 0000000..c85a9f8 --- /dev/null +++ b/services/nginx/prod.conf @@ -0,0 +1,14 @@ +server { + + listen 80; + + location / { + proxy_pass http://web:5000; + proxy_redirect default; + 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-Host $server_name; + } + +} diff --git a/Dockerfile b/services/web/Dockerfile similarity index 93% rename from Dockerfile rename to services/web/Dockerfile index 51b42b5..1dcd686 100644 --- a/Dockerfile +++ b/services/web/Dockerfile @@ -44,4 +44,4 @@ RUN chown -R app:app $APP_HOME USER app # run server -CMD gunicorn -b 0.0.0.0:5000 manage:app +CMD gunicorn --log-level=debug -b 0.0.0.0:5000 manage:app diff --git a/manage.py b/services/web/manage.py similarity index 100% rename from manage.py rename to services/web/manage.py diff --git a/project/__init__.py b/services/web/project/__init__.py similarity index 88% rename from project/__init__.py rename to services/web/project/__init__.py index b0f504f..139f4d5 100644 --- a/project/__init__.py +++ b/services/web/project/__init__.py @@ -24,6 +24,8 @@ def create_app(script_info=None): migrate.init_app(app, db) # register blueprints + from project.api.main import main_blueprint + app.register_blueprint(main_blueprint) from project.api.users import users_blueprint app.register_blueprint(users_blueprint) diff --git a/services/web/project/api/main.py b/services/web/project/api/main.py new file mode 100644 index 0000000..9edd847 --- /dev/null +++ b/services/web/project/api/main.py @@ -0,0 +1,33 @@ +import os +import logging + +from flask import Blueprint, jsonify, request + + +LOGGER = logging.getLogger('gunicorn.error') +SECRET_CODE = os.environ.get('SECRET_CODE') + +main_blueprint = Blueprint('main', __name__) + + +@main_blueprint.route('/ping', methods=['GET']) +def ping_pong(): + LOGGER.info('Hitting the "/ping" route') + return jsonify({ + 'status': 'success', + 'message': 'pong!', + 'container_id': os.uname()[1] + }) + + +@main_blueprint.route('/secret', methods=['POST']) +def secret(): + LOGGER.info('Hitting the "/secret" route') + response_object = { + 'status': 'success', + 'message': 'nay!', + 'container_id': os.uname()[1] + } + if request.get_json().get('secret') == SECRET_CODE: + response_object['message'] = 'yay!' + return jsonify(response_object) diff --git a/project/api/models.py b/services/web/project/api/models.py similarity index 95% rename from project/api/models.py rename to services/web/project/api/models.py index a38d8be..aad72a9 100644 --- a/project/api/models.py +++ b/services/web/project/api/models.py @@ -1,5 +1,3 @@ -from flask import current_app - from project import db diff --git a/services/web/project/api/users.py b/services/web/project/api/users.py new file mode 100644 index 0000000..b3b3f5a --- /dev/null +++ b/services/web/project/api/users.py @@ -0,0 +1,22 @@ +import os +import logging + +from flask import Blueprint, jsonify + +from project.api.models import User + + +users_blueprint = Blueprint('users', __name__) + +LOGGER = logging.getLogger('gunicorn.error') + + +@users_blueprint.route('/users', methods=['GET']) +def get_all_users(): + LOGGER.info('Hitting the "/users" route') + response_object = { + 'status': 'success', + 'users': [user.to_json() for user in User.query.all()], + 'container_id': os.uname()[1] + } + return jsonify(response_object), 200 diff --git a/services/web/project/config.py b/services/web/project/config.py new file mode 100644 index 0000000..c49b2bc --- /dev/null +++ b/services/web/project/config.py @@ -0,0 +1,10 @@ +import os + +USER = os.environ.get('DB_USER') +PASSWORD = os.environ.get('DB_PASSWORD') + + +class ProductionConfig(): + """Production configuration""" + SQLALCHEMY_TRACK_MODIFICATIONS = False + SQLALCHEMY_DATABASE_URI = f'postgres://{USER}:{PASSWORD}@db:5432/users' diff --git a/requirements.txt b/services/web/requirements.txt similarity index 100% rename from requirements.txt rename to services/web/requirements.txt