added ability to build and run with docker w/ burnettk
This commit is contained in:
parent
d235c64915
commit
c6131a04d3
|
@ -0,0 +1,28 @@
|
|||
FROM ghcr.io/sartography/python:3.9
|
||||
|
||||
RUN pip install poetry
|
||||
RUN useradd _gunicorn --no-create-home --user-group
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y -q \
|
||||
gcc libssl-dev \
|
||||
curl git-core libpq-dev \
|
||||
gunicorn3 default-mysql-client
|
||||
|
||||
WORKDIR /app
|
||||
COPY pyproject.toml poetry.lock /app/
|
||||
RUN poetry install
|
||||
|
||||
RUN set -xe \
|
||||
&& apt-get remove -y gcc python3-dev libssl-dev \
|
||||
&& apt-get autoremove -y \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY . /app/
|
||||
|
||||
# run poetry install again AFTER copying the app into the image
|
||||
# otherwise it does not know what the main app module is
|
||||
RUN poetry install
|
||||
|
||||
CMD ./bin/boot_server_in_docker
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
function error_handler() {
|
||||
>&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}."
|
||||
exit "$2"
|
||||
}
|
||||
trap 'error_handler ${LINENO} $?' ERR
|
||||
set -o errtrace -o errexit -o nounset -o pipefail
|
||||
|
||||
# run migrations
|
||||
export FLASK_APP=/app/src/spiffworkflow_backend
|
||||
|
||||
if [ "${DOWNGRADE_DB:-}" = "true" ]; then
|
||||
echo 'Downgrading database...'
|
||||
poetry run flask db downgrade
|
||||
fi
|
||||
|
||||
if [ "${UPGRADE_DB:-}" = "true" ]; then
|
||||
echo 'Upgrading database...'
|
||||
poetry run flask db upgrade
|
||||
fi
|
||||
|
||||
port="${PORT0:-}"
|
||||
if [[ -z "$port" ]]; then
|
||||
port=7000
|
||||
fi
|
||||
|
||||
# THIS MUST BE THE LAST COMMAND!
|
||||
if [ "${APPLICATION_ROOT:-}" = "/" ]; then
|
||||
exec poetry run gunicorn --bind "0.0.0.0:$PORT0" wsgi:app
|
||||
else
|
||||
exec poetry run gunicorn -e SCRIPT_NAME="$APPLICATION_ROOT" --bind "0.0.0.0:$PORT0" wsgi:app
|
||||
fi
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
function error_handler() {
|
||||
>&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}."
|
||||
exit "$2"
|
||||
}
|
||||
trap 'error_handler ${LINENO} $?' ERR
|
||||
set -o errtrace -o errexit -o nounset -o pipefail
|
||||
|
||||
if [[ -z "${BPMN_SPEC_ABSOLUTE_DIR:-}" ]]; then
|
||||
script_dir="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||
export BPMN_SPEC_ABSOLUTE_DIR="$script_dir/../../sample-process-models"
|
||||
fi
|
||||
|
||||
docker compose up --build
|
|
@ -16,4 +16,6 @@ if [[ -z "${BPMN_SPEC_ABSOLUTE_DIR:-}" ]]; then
|
|||
export BPMN_SPEC_ABSOLUTE_DIR="$script_dir/../../sample-process-models"
|
||||
fi
|
||||
|
||||
export FLASK_SESSION_SECRET_KEY=super_secret_key
|
||||
|
||||
FLASK_APP=src/spiffworkflow_backend poetry run flask run
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
version: "3.8"
|
||||
services:
|
||||
db:
|
||||
container_name: db
|
||||
image: mysql:8.0.29
|
||||
cap_add:
|
||||
- SYS_NICE
|
||||
restart: always
|
||||
environment:
|
||||
- MYSQL_DATABASE=spiffworkflow_backend_staging
|
||||
- MYSQL_ROOT_PASSWORD=St4g3Th1515
|
||||
ports:
|
||||
- '7001:3306'
|
||||
volumes:
|
||||
- spiffworkflow_backend:/var/lib/mysql
|
||||
|
||||
spiffworkflow-backend:
|
||||
container_name: spiffworkflow-backend
|
||||
# command: tail -f /etc/hostname
|
||||
depends_on:
|
||||
- db
|
||||
# image: sartography/cr-connect-workflow:dev
|
||||
build:
|
||||
context: .
|
||||
environment:
|
||||
- APPLICATION_ROOT=/
|
||||
- FLASK_ENV=staging
|
||||
- FLASK_SESSION_SECRET_KEY=super_secret_key
|
||||
- DEVELOPMENT=true
|
||||
- LDAP_URL=mock
|
||||
- PORT0=7000
|
||||
- PRODUCTION=false
|
||||
- UPGRADE_DB=true
|
||||
- DATABASE_URI=mysql+mysqlconnector://root:St4g3Th1515@db/spiffworkflow_backend_staging
|
||||
- BPMN_SPEC_ABSOLUTE_DIR=/app/process_models
|
||||
ports:
|
||||
- "7000:7000"
|
||||
volumes:
|
||||
- ${BPMN_SPEC_ABSOLUTE_DIR}:/app/process_models
|
||||
|
||||
volumes:
|
||||
spiffworkflow_backend:
|
||||
driver: local
|
|
@ -384,6 +384,7 @@ jsonschema = ">=2.5.1,<5"
|
|||
packaging = ">=20"
|
||||
PyYAML = ">=5.1,<7"
|
||||
requests = ">=2.9.1,<3"
|
||||
swagger-ui-bundle = {version = ">=0.0.2,<0.1", optional = true, markers = "extra == \"swagger-ui\""}
|
||||
werkzeug = ">=1.0,<3"
|
||||
|
||||
[package.extras]
|
||||
|
@ -765,6 +766,20 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*"
|
|||
[package.extras]
|
||||
docs = ["sphinx"]
|
||||
|
||||
[[package]]
|
||||
name = "gunicorn"
|
||||
version = "20.1.0"
|
||||
description = "WSGI HTTP Server for UNIX"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.extras]
|
||||
eventlet = ["eventlet (>=0.24.1)"]
|
||||
gevent = ["gevent (>=1.4.0)"]
|
||||
setproctitle = ["setproctitle"]
|
||||
tornado = ["tornado (>=0.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "identify"
|
||||
version = "2.5.1"
|
||||
|
@ -1779,6 +1794,17 @@ python-versions = ">=3.6"
|
|||
[package.dependencies]
|
||||
pbr = ">=2.0.0,<2.1.0 || >2.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "swagger-ui-bundle"
|
||||
version = "0.0.9"
|
||||
description = "swagger_ui_bundle - swagger-ui files in a pip package"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
Jinja2 = ">=2.0"
|
||||
|
||||
[[package]]
|
||||
name = "tokenize-rt"
|
||||
version = "4.2.1"
|
||||
|
@ -1991,7 +2017,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.8"
|
||||
content-hash = "217b8108526defaaac72e0d98f15e82efda8b8f4698ea8b52623dc45708a8d70"
|
||||
content-hash = "b9b8fb8a5f20adbc1ea2a1e8990c3d1e58e84c62d0a9e9f33e21137686630695"
|
||||
|
||||
[metadata.files]
|
||||
alabaster = [
|
||||
|
@ -2395,6 +2421,10 @@ greenlet = [
|
|||
{file = "greenlet-1.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd"},
|
||||
{file = "greenlet-1.1.2.tar.gz", hash = "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a"},
|
||||
]
|
||||
gunicorn = [
|
||||
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
|
||||
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
|
||||
]
|
||||
identify = [
|
||||
{file = "identify-2.5.1-py2.py3-none-any.whl", hash = "sha256:0dca2ea3e4381c435ef9c33ba100a78a9b40c0bab11189c7cf121f75815efeaa"},
|
||||
{file = "identify-2.5.1.tar.gz", hash = "sha256:3d11b16f3fe19f52039fb7e39c9c884b21cb1b586988114fbe42671f03de3e82"},
|
||||
|
@ -3111,6 +3141,10 @@ stevedore = [
|
|||
{file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"},
|
||||
{file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"},
|
||||
]
|
||||
swagger-ui-bundle = [
|
||||
{file = "swagger_ui_bundle-0.0.9-py3-none-any.whl", hash = "sha256:cea116ed81147c345001027325c1ddc9ca78c1ee7319935c3c75d3669279d575"},
|
||||
{file = "swagger_ui_bundle-0.0.9.tar.gz", hash = "sha256:b462aa1460261796ab78fd4663961a7f6f347ce01760f1303bbbdf630f11f516"},
|
||||
]
|
||||
tokenize-rt = [
|
||||
{file = "tokenize_rt-4.2.1-py2.py3-none-any.whl", hash = "sha256:08a27fa032a81cf45e8858d0ac706004fcd523e8463415ddf1442be38e204ea8"},
|
||||
{file = "tokenize_rt-4.2.1.tar.gz", hash = "sha256:0d4f69026fed520f8a1e0103aa36c406ef4661417f20ca643f913e33531b3b94"},
|
||||
|
|
|
@ -37,11 +37,12 @@ pytest-flask = "^1.2.0"
|
|||
pytest-flask-sqlalchemy = "^1.1.0"
|
||||
psycopg2 = "^2.9.3"
|
||||
typing-extensions = "^4.2.0"
|
||||
connexion = "^2.13.1"
|
||||
connexion = {extras = [ "swagger-ui",], version = "^2.13.1"}
|
||||
lxml = "^4.8.0"
|
||||
marshmallow-enum = "^1.5.1"
|
||||
marshmallow-sqlalchemy = "^0.28.0"
|
||||
PyJWT = "^2.4.0"
|
||||
gunicorn = "^20.1.0"
|
||||
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
|
|
|
@ -26,9 +26,13 @@ def create_app() -> flask.app.Flask:
|
|||
)
|
||||
app = connexion_app.app
|
||||
app.config["CONNEXION_APP"] = connexion_app
|
||||
app.secret_key = "super secret key"
|
||||
app.config["SESSION_TYPE"] = "filesystem"
|
||||
|
||||
if os.environ.get("FLASK_SESSION_SECRET_KEY") is None:
|
||||
raise KeyError("Cannot find the secret_key from the environment. Please set FLASK_SESSION_SECRET_KEY")
|
||||
|
||||
app.secret_key = os.environ.get("FLASK_SESSION_SECRET_KEY")
|
||||
|
||||
setup_config(app)
|
||||
db.init_app(app)
|
||||
migrate.init_app(app, db)
|
||||
|
@ -40,7 +44,4 @@ def create_app() -> flask.app.Flask:
|
|||
app.register_blueprint(admin_blueprint, url_prefix="/admin")
|
||||
connexion_app.add_api("api.yml", base_path="/v1.0")
|
||||
|
||||
for name, value in app.config.items():
|
||||
print(f"{name} = {value}")
|
||||
|
||||
return app
|
||||
|
|
|
@ -16,18 +16,21 @@ def setup_config(app: Flask) -> None:
|
|||
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
||||
app.config.from_object("spiffworkflow_backend.config.default")
|
||||
|
||||
if os.environ.get("SPIFF_DATABASE_TYPE") == "sqlite":
|
||||
app.config[
|
||||
"SQLALCHEMY_DATABASE_URI"
|
||||
] = f"sqlite:///{app.instance_path}/db_{app.env}.sqlite3"
|
||||
if os.environ.get("DATABASE_URI") is None:
|
||||
if os.environ.get("SPIFF_DATABASE_TYPE") == "sqlite":
|
||||
app.config[
|
||||
"SQLALCHEMY_DATABASE_URI"
|
||||
] = f"sqlite:///{app.instance_path}/db_{app.env}.sqlite3"
|
||||
else:
|
||||
# use pswd to trick flake8 with hardcoded passwords
|
||||
db_pswd = os.environ.get("DB_PASSWORD")
|
||||
if db_pswd is None:
|
||||
db_pswd = ""
|
||||
app.config[
|
||||
"SQLALCHEMY_DATABASE_URI"
|
||||
] = f"mysql+mysqlconnector://root:{db_pswd}@localhost/spiffworkflow_backend_{app.env}"
|
||||
else:
|
||||
# use pswd to trick flake8 with hardcoded passwords
|
||||
mysql_pswd = os.environ.get("MYSQL_PASSWORD")
|
||||
if mysql_pswd is None:
|
||||
mysql_pswd = ""
|
||||
app.config[
|
||||
"SQLALCHEMY_DATABASE_URI"
|
||||
] = f"mysql+mysqlconnector://root:{mysql_pswd}@localhost/spiffworkflow_backend_{app.env}"
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DATABASE_URI")
|
||||
|
||||
env_config_module = "spiffworkflow_backend.config." + app.env
|
||||
try:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"""Staging."""
|
|
@ -0,0 +1 @@
|
|||
.example { }
|
|
@ -0,0 +1,25 @@
|
|||
from werkzeug.exceptions import NotFound
|
||||
from werkzeug.middleware.dispatcher import DispatcherMiddleware
|
||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
|
||||
from spiffworkflow_backend import create_app
|
||||
|
||||
app = create_app()
|
||||
|
||||
if __name__ == "__main__":
|
||||
def no_app(environ, start_response):
|
||||
return NotFound()(environ, start_response)
|
||||
|
||||
# Remove trailing slash, but add leading slash
|
||||
base_url = '/' + app.config['APPLICATION_ROOT'].strip('/')
|
||||
routes = {'/': app.wsgi_app}
|
||||
|
||||
if base_url != '/':
|
||||
routes[base_url] = app.wsgi_app
|
||||
|
||||
app.wsgi_app = DispatcherMiddleware(no_app, routes)
|
||||
app.wsgi_app = ProxyFix(app.wsgi_app)
|
||||
|
||||
flask_port = app.config['FLASK_PORT']
|
||||
|
||||
app.run(host='0.0.0.0', port=flask_port)
|
Loading…
Reference in New Issue