website online working

This commit is contained in:
2025-08-16 21:51:14 -04:00
parent b97d729ef1
commit 79aa32e8e4
12 changed files with 175 additions and 53 deletions

37
Dockerfile.local Normal file
View File

@@ -0,0 +1,37 @@
FROM python:3.13.3-bullseye
ENV PYTHONFAULTHANDLER=1
ENV PYTHONUNBUFFERED=1
ENV TZ=America/New_York
ENV MODE="LOCAL"
RUN mkdir -p /app
COPY requirements.txt /app
WORKDIR /app
RUN pip3 install -r requirements.txt
RUN pip3 install gunicorn
# Install Nginx
RUN apt-get update && apt-get install -y nginx && rm -rf /var/lib/apt/lists/*
COPY . /app
# Copy Nginx configuration
COPY nginx.conf /etc/nginx/sites-available/default
# Enable the Nginx site
RUN ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
# Copy start script
COPY start.sh /app/start.sh
RUN chmod +x /app/start.sh
EXPOSE 80
CMD ["/app/start.sh"]

View File

@@ -5,7 +5,6 @@ ENV PYTHONFAULTHANDLER=1
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1
ENV TZ=America/New_York ENV TZ=America/New_York
# RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV MODE="PRODUCTION" ENV MODE="PRODUCTION"
@@ -16,8 +15,23 @@ COPY requirements.txt /app
WORKDIR /app WORKDIR /app
RUN pip3 install -r requirements.txt RUN pip3 install -r requirements.txt
RUN pip3 install gunicorn
# Install Nginx
RUN apt-get update && apt-get install -y nginx && rm -rf /var/lib/apt/lists/*
COPY . /app COPY . /app
CMD ["python", "app.py", "--host", "0.0.0.0"] # Copy Nginx configuration
COPY nginx.conf /etc/nginx/sites-available/default
# Enable the Nginx site
RUN ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
# Copy start script
COPY start.sh /app/start.sh
RUN chmod +x /app/start.sh
EXPOSE 80
CMD ["/app/start.sh"]

View File

@@ -39,12 +39,8 @@ app.jinja_env.autoescape = True
# configuration # configuration
UPLOADED_FILES_DEST_ITEM = ApplicationConfig.UPLOADED_FILES_DEST_ITEM
UPLOADED_FILES_ALLOW = ApplicationConfig.UPLOADED_FILES_ALLOW
CURRENT_SETTINGS = ApplicationConfig.CURRENT_SETTINGS
WHITE = ApplicationConfig.WHITE
app.config['CORS_ORIGIN_WHITELIST'] = ApplicationConfig.CORS_ORIGIN_WHITELIST app.config['CORS_ALLOWED_ORIGINS'] = ApplicationConfig.CORS_ALLOWED_ORIGINS
app.config['UPLOADED_FILES_DEST_ITEM'] = ApplicationConfig.UPLOADED_FILES_DEST_ITEM app.config['UPLOADED_FILES_DEST_ITEM'] = ApplicationConfig.UPLOADED_FILES_DEST_ITEM
app.config['UPLOADED_FILES_ALLOW'] = ApplicationConfig.UPLOADED_FILES_ALLOW app.config['UPLOADED_FILES_ALLOW'] = ApplicationConfig.UPLOADED_FILES_ALLOW
app.config['MAX_CONTENT_LENGTH'] = ApplicationConfig.MAX_CONTENT_LENGTH app.config['MAX_CONTENT_LENGTH'] = ApplicationConfig.MAX_CONTENT_LENGTH
@@ -54,7 +50,6 @@ app.config['SESSION_COOKIE_HTTPONLY'] = ApplicationConfig.SESSION_COOKIE_HTTPONL
app.config['SESSION_COOKIE_SAMESITE'] = ApplicationConfig.SESSION_COOKIE_SAMESITE app.config['SESSION_COOKIE_SAMESITE'] = ApplicationConfig.SESSION_COOKIE_SAMESITE
app.config['SESSION_PERMANENT'] = ApplicationConfig.SESSION_PERMANENT app.config['SESSION_PERMANENT'] = ApplicationConfig.SESSION_PERMANENT
app.config['SESSION_USE_SIGNER'] = ApplicationConfig.SESSION_USE_SIGNER app.config['SESSION_USE_SIGNER'] = ApplicationConfig.SESSION_USE_SIGNER
app.config['ORIGIN_URL'] = ApplicationConfig.ORIGIN_URL
app.config['CURRENT_SETTINGS'] = ApplicationConfig.CURRENT_SETTINGS app.config['CURRENT_SETTINGS'] = ApplicationConfig.CURRENT_SETTINGS
app.config['SECRET_KEY'] = ApplicationConfig.SECRET_KEY app.config['SECRET_KEY'] = ApplicationConfig.SECRET_KEY
@@ -99,15 +94,18 @@ def load_user_from_request(request):
return None return None
api_main = { # api_main = {
"origins": [ApplicationConfig.ORIGIN_URL], # "origins": [ApplicationConfig.ORIGIN_URL],
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"], # "methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"],
"allow_headers": ['Authorization', 'application/json', 'authorization', 'Content-Type', # "allow_headers": ['Authorization', 'application/json', 'authorization', 'Content-Type',
'Access-Control-Allow-Headers', 'Origin,Accept', # 'Access-Control-Allow-Headers', 'Origin,Accept',
'X-Requested-With', 'Content-Type', 'Access-Control-Request-Method', # 'X-Requested-With', 'Content-Type', 'Access-Control-Request-cMethod',
'Access-Control-Request-Headers'] # 'Access-Control-Request-Headers']
} # }
cors = CORS(app, supports_credentials=True, resources={r'/*': api_main}) cors = CORS(app,
supports_credentials=True,
resources={r"/*": {"origins": ApplicationConfig.CORS_ALLOWED_ORIGINS}
})
# bind a function after each request, even if an exception is encountered. # bind a function after each request, even if an exception is encountered.
@@ -171,7 +169,6 @@ app.register_blueprint(main_blueprint, url_prefix='/main')
from .customer import customer as customer_blueprint from .customer import customer as customer_blueprint
app.register_blueprint(customer_blueprint, url_prefix='/customer') app.register_blueprint(customer_blueprint, url_prefix='/customer')
from .delivery import delivery as delivery_blueprint from .delivery import delivery as delivery_blueprint
app.register_blueprint(delivery_blueprint, url_prefix='/delivery') app.register_blueprint(delivery_blueprint, url_prefix='/delivery')

View File

@@ -1,5 +1,5 @@
from flask import jsonify, Response, request, url_for from flask import jsonify, Response, url_for
from app import app, WHITE from app import app
@app.route("/favicon.ico") @app.route("/favicon.ico")
def favicon(): def favicon():
@@ -21,15 +21,3 @@ def static_from_root():
def index(): def index():
return jsonify({"success": "Api is online"}), 200 return jsonify({"success": "Api is online"}), 200
# @app.after_request
# def add_cors_headers(response):
# r = request.referrer[:-1]
# if r in WHITE:
# response.headers.add('Access-Control-Allow-Origin', r)
# response.headers.add('Access-Control-Allow-Credentials', 'true')
# response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
# response.headers.add('Access-Control-Allow-Headers', 'Cache-Control')
# response.headers.add('Access-Control-Allow-Headers', 'X-Requested-With')
# response.headers.add('Access-Control-Allow-Headers', 'Authorization')
# response.headers.add('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE')
# return response

View File

@@ -1,15 +1,10 @@
from flask import request, jsonify from flask import jsonify
from flask_login import current_user
from sqlalchemy.sql import func from sqlalchemy.sql import func
from datetime import date, timedelta
from app.reports import reports from app.reports import reports
from app import db from app import db
from datetime import datetime
from app.classes.auth import Auth_User
from app.classes.customer import Customer_Customer from app.classes.customer import Customer_Customer
from app.classes.employee import Employee_Employee
from app.classes.delivery import Delivery_Delivery from app.classes.delivery import Delivery_Delivery
@@ -20,7 +15,7 @@ def oil_total_gallons():
.group_by(Delivery_Delivery.id)\ .group_by(Delivery_Delivery.id)\
.all() .all()
return jsonify({"ok": True }), 200 return jsonify({"ok": True, "oil": total_oil }), 200
@reports.route("/customers/list", methods=["GET"]) @reports.route("/customers/list", methods=["GET"])
def customer_list(): def customer_list():

View File

@@ -5,16 +5,19 @@ def load_config(mode=os.environ.get('MODE')):
try: try:
print(f"mode is {mode}") print(f"mode is {mode}")
if mode == 'PRODUCTION': if mode == 'PRODUCTION':
from settings_prod import ApplicationConfig
from prod_settings import ApplicationConfig
return ApplicationConfig return ApplicationConfig
elif mode == 'DEVELOPMENT':
from local_settings import ApplicationConfig elif mode == 'DEVELOPMENT':
from settings_dev import ApplicationConfig
return ApplicationConfig
elif mode == 'LOCAL':
from settings_local import ApplicationConfig
return ApplicationConfig return ApplicationConfig
else: else:
pass pass
except ImportError: except ImportError:
from local_settings import ApplicationConfig from settings_local import ApplicationConfig
return ApplicationConfig return ApplicationConfig

17
nginx.conf Normal file
View File

@@ -0,0 +1,17 @@
server {
listen 80;
server_name _;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /app;
}
location / {
proxy_pass http://127.0.0.1:8000;
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;
}
}

8
local_settings.py → settings_dev.py Executable file → Normal file
View File

@@ -44,10 +44,12 @@ class ApplicationConfig:
# CORS # CORS
ORIGIN_URL = "*" CORS_ALLOWED_ORIGINS = [
"*"
]
CORS_SEND_WILDCARD = False CORS_SEND_WILDCARD = False
CORS_SUPPORT_CREDENTIALS = True CORS_SUPPORT_CREDENTIALS = True
CORS_EXPOSE_HEADERS = None CORS_EXPOSE_HEADERS = None
CORS_ALLOW_HEADERS = "*" CORS_ALLOW_HEADERS = "*"
CORS_ORIGIN_WHITELIST = ['*']
WHITE = ['*']

58
settings_local.py Executable file
View File

@@ -0,0 +1,58 @@
class ApplicationConfig:
"""
Basic Configuration for a generic User
"""
CURRENT_SETTINGS = 'LOCAL'
# databases info
POSTGRES_USERNAME = 'postgres'
POSTGRES_PW = 'password'
POSTGRES_SERVER = '192.168.1.204:5432'
POSTGRES_DBNAME00 = 'auburnoil'
SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://{}:{}@{}/{}".format(POSTGRES_USERNAME,
POSTGRES_PW,
POSTGRES_SERVER,
POSTGRES_DBNAME00
)
SQLALCHEMY_BINDS = {'auburnoil': SQLALCHEMY_DATABASE_URI}
# sqlalchemy config
SQLALCHEMY_TRACK_MODIFICATIONS = False
TRAP_HTTP_EXCEPTIONS = True
PROPAGATE_EXCEPTIONS = True
DEBUG = True
UPLOADED_FILES_DEST_ITEM = '/data/item'
# file uploads
UPLOADED_FILES_ALLOW = ['png', 'jpeg', 'jpg', 'png', 'gif']
MAX_CONTENT_LENGTH = 5 * 2500 * 2500
ALLOWED_EXTENSIONS = ['png', 'jpeg', 'jpg', 'png', 'gif']
# secret keys
SECRET_KEY = "youwillneverguessthiskeycia"
# sessions
# Available SESSION_TYPE options: 'redis', 'sqlalchemy', 'mongodb', 'filesystem', 'memcached'
SESSION_TYPE = "sqlalchemy"
SESSION_COOKIE_NAME = "eamco_session"
SESSION_COOKIE_SECURE = False
SESSION_COOKIE_HTTPONLY = True
REMEMBER_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Strict"
SESSION_PERMANENT = False
SESSION_USE_SIGNER = True
# CORS
CORS_SEND_WILDCARD = False
CORS_SUPPORT_CREDENTIALS = True
CORS_EXPOSE_HEADERS = None
CORS_ALLOW_HEADERS = "*"
CORS_ALLOWED_ORIGINS = [
'http://192.168.1.204:9610',
'http://192.168.1.204:9611',
'http://192.168.1.204:9612',
'http://192.168.1.204:9613',
'http://192.168.1.204:9614',
]

View File

@@ -4,7 +4,7 @@ class ApplicationConfig:
""" """
Basic Configuration for a generic User Basic Configuration for a generic User
""" """
CURRENT_SETTINGS = 'PROD' CURRENT_SETTINGS = 'PRODUCTION'
# databases info # databases info
POSTGRES_USERNAME = 'postgres' POSTGRES_USERNAME = 'postgres'
POSTGRES_PW = 'password' POSTGRES_PW = 'password'
@@ -15,12 +15,12 @@ class ApplicationConfig:
POSTGRES_SERVER, POSTGRES_SERVER,
POSTGRES_DBNAME00 POSTGRES_DBNAME00
) )
SQLALCHEMY_BINDS = {'eamco': SQLALCHEMY_DATABASE_URI} SQLALCHEMY_BINDS = {'auburnoil': SQLALCHEMY_DATABASE_URI}
# sqlalchemy config # sqlalchemy config
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False
TRAP_HTTP_EXCEPTIONS = True TRAP_HTTP_EXCEPTIONS = True
PROPAGATE_EXCEPTIONS = True PROPAGATE_EXCEPTIONS = True
DEBUG = True DEBUG = False
UPLOADED_FILES_DEST_ITEM = '/data/item' UPLOADED_FILES_DEST_ITEM = '/data/item'
# file uploads # file uploads
@@ -43,10 +43,13 @@ class ApplicationConfig:
# CORS # CORS
ORIGIN_URL = "http://192.168.1.204:9511"
CORS_SEND_WILDCARD = False CORS_SEND_WILDCARD = False
CORS_SUPPORT_CREDENTIALS = True CORS_SUPPORT_CREDENTIALS = True
CORS_EXPOSE_HEADERS = None CORS_EXPOSE_HEADERS = None
CORS_ALLOW_HEADERS = "*" CORS_ALLOW_HEADERS = "*"
CORS_ORIGIN_WHITELIST = ['http://192.168.1.204','http://localhost', 'http://192.168.1.204:9511', "*"] CORS_ALLOWED_ORIGINS = [
WHITE= ['http://192.168.1.204','http://localhost', "*"] 'https://oil.edwineames.com',
'https://edwineames.com'
]

8
start.sh Normal file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
set -e
# Start Gunicorn
gunicorn --bind 127.0.0.1:8000 --workers 4 --timeout 120 app:app &
# Start Nginx
nginx -g 'daemon off;'