diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2e1a76b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +FROM ghcr.io/sartography/python:3.11 + +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 gunicorn3 + +WORKDIR /app +COPY pyproject.toml poetry.lock /app/ +RUN poetry install --without dev + +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 --without dev + +CMD ./bin/boot_server_in_docker diff --git a/README.md b/README.md index 9318596..51e1ea6 100644 --- a/README.md +++ b/README.md @@ -36,3 +36,4 @@ Fire it up. Any dependencies you add will now be available for SpiffWorkflow to call using a Service Task. What's more, those services are now discoverable! So when someone drops a Service Task into their diagram, they will have a dropdown list of all the services you have made available to them. And those services will know what parameters are required, and can prompt diagram authors to provide information necessary to make the call. Which can be no parameters at all (Just give me a fact about Chuck Norris) ... to complex parameters (a json structure to be added to a DynamoDB Table). + diff --git a/bin/boot_server_in_docker b/bin/boot_server_in_docker new file mode 100755 index 0000000..1179bf5 --- /dev/null +++ b/bin/boot_server_in_docker @@ -0,0 +1,19 @@ +#!/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 + +port="${CONNECTOR_PROXY_PORT:-}" +if [[ -z "$port" ]]; then + port=7004 +fi + +workers=3 + +# THIS MUST BE THE LAST COMMAND! +# default --limit-request-line is 4094. see https://stackoverflow.com/a/66688382/6090676 +exec poetry run gunicorn --bind "0.0.0.0:$port" --workers="$workers" --limit-request-line 8192 --timeout 90 --capture-output --access-logfile '-' --log-level debug app:app diff --git a/poetry.lock b/poetry.lock index c94c0eb..d66e6ee 100644 --- a/poetry.lock +++ b/poetry.lock @@ -145,6 +145,23 @@ Flask = "*" oauthlib = ">=1.1.2,<2.0.3 || >2.0.3,<2.0.4 || >2.0.4,<2.0.5 || >2.0.5,<3.0.0" requests-oauthlib = ">=0.6.2,<1.2.0" +[[package]] +name = "gunicorn" +version = "20.1.0" +description = "WSGI HTTP Server for UNIX" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +setuptools = ">=3.0" + +[package.extras] +eventlet = ["eventlet (>=0.24.1)"] +gevent = ["gevent (>=1.4.0)"] +setproctitle = ["setproctitle"] +tornado = ["tornado (>=0.2)"] + [[package]] name = "idna" version = "3.4" @@ -263,6 +280,19 @@ botocore = ">=1.12.36,<2.0a.0" [package.extras] crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] +[[package]] +name = "setuptools" +version = "65.6.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "simplejson" version = "3.17.6" @@ -296,7 +326,7 @@ Flask-OAuthlib = "^0.9.6" type = "git" url = "https://github.com/sartography/spiffworkflow-proxy" reference = "HEAD" -resolved_reference = "6706c210ce2ddeef491fb504fd8958e15b14d942" +resolved_reference = "f92ca9d4e7a9000909a28acfc300b2bb519cf7d2" [[package]] name = "urllib3" @@ -328,7 +358,7 @@ watchdog = ["watchdog"] [metadata] lock-version = "1.1" python-versions = "^3.11" -content-hash = "8c8414b064571cb6ba5e64542ea3b9c98174fa9b45a5325543498edb089510b5" +content-hash = "e076834da50d656885e96c59beec28c2a977ef94fcbb79a6e46da9038f253bd5" [metadata.files] boto3 = [ @@ -369,6 +399,10 @@ Flask-OAuthlib = [ {file = "Flask-OAuthlib-0.9.6.tar.gz", hash = "sha256:5bb79c8a8e670c2eb4cb553dfc3283b6c8d1202f674934676dc173cee94fe39c"}, {file = "Flask_OAuthlib-0.9.6-py3-none-any.whl", hash = "sha256:a5c3b62959aa1922470a62b6ebf4273b75f1c29561a7eb4a69cde85d45a1d669"}, ] +gunicorn = [ + {file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"}, + {file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"}, +] idna = [ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, @@ -447,6 +481,10 @@ s3transfer = [ {file = "s3transfer-0.6.0-py3-none-any.whl", hash = "sha256:06176b74f3a15f61f1b4f25a1fc29a4429040b7647133a463da8fa5bd28d5ecd"}, {file = "s3transfer-0.6.0.tar.gz", hash = "sha256:2ed07d3866f523cc561bf4a00fc5535827981b117dd7876f036b0c1aca42c947"}, ] +setuptools = [ + {file = "setuptools-65.6.0-py3-none-any.whl", hash = "sha256:6211d2f5eddad8757bd0484923ca7c0a6302ebc4ab32ea5e94357176e0ca0840"}, + {file = "setuptools-65.6.0.tar.gz", hash = "sha256:d1eebf881c6114e51df1664bc2c9133d022f78d12d5f4f665b9191f084e2862d"}, +] simplejson = [ {file = "simplejson-3.17.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a89acae02b2975b1f8e4974cb8cdf9bf9f6c91162fb8dec50c259ce700f2770a"}, {file = "simplejson-3.17.6-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:82ff356ff91be0ab2293fc6d8d262451eb6ac4fd999244c4b5f863e049ba219c"}, diff --git a/pyproject.toml b/pyproject.toml index 4e4ba72..c9c84f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "An example showing how to use the Spiffworkflow-proxy's Flask Blu authors = ["Dan "] license = "LGPL" readme = "README.md" -packages = [{include = "connector_proxy_demo", from = "src"}] +#packages = [{include = "connector_proxy_demo", from = "."}] [tool.poetry.dependencies] python = "^3.11" @@ -13,6 +13,7 @@ Flask = "^2.2.2" spiffworkflow-proxy = {git = "https://github.com/sartography/spiffworkflow-proxy"} connector-aws = { git = "https://github.com/sartography/connector-aws.git"} connector-http = {git = "https://github.com/sartography/connector-http.git"} +gunicorn = "^20.1.0" [build-system] requires = ["poetry-core"]