Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions .github/workflows/develop.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ env:
jobs:

check_for_linux:
name: "Run checks and tests on Linux"
name: Run checks and tests on Linux
runs-on: ubuntu-latest

steps:
Expand Down Expand Up @@ -48,7 +48,7 @@ jobs:


check_for_windows:
name: "Run checks and tests on Windows"
name: Run checks and tests on Windows
runs-on: windows-latest

steps:
Expand All @@ -75,3 +75,18 @@ jobs:

- name: Run tests
run: .venv-automation/Scripts/automation.exe --verbosity debug test



build_docker_image:
name: Build docker image
runs-on: ubuntu-latest
needs: check_for_linux

steps:

- name: Checkout sources
uses: actions/checkout@v4

- name: Build docker image
run: docker build --file Deployment/dockerfile .
19 changes: 17 additions & 2 deletions .github/workflows/integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ env:
jobs:

check_for_linux:
name: "Run checks and tests on Linux"
name: Run checks and tests on Linux
runs-on: ubuntu-latest

steps:
Expand Down Expand Up @@ -48,7 +48,7 @@ jobs:


check_for_windows:
name: "Run checks and tests on Windows"
name: Run checks and tests on Windows
runs-on: windows-latest

steps:
Expand All @@ -75,3 +75,18 @@ jobs:

- name: Run tests
run: .venv-automation/Scripts/automation.exe --verbosity debug test



build_docker_image:
name: Build docker image
runs-on: ubuntu-latest
needs: check_for_linux

steps:

- name: Checkout sources
uses: actions/checkout@v4

- name: Build docker image
run: docker build --file Deployment/dockerfile .
4 changes: 4 additions & 0 deletions Deployment/application.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"flask_secret_key": "secret",
"metrics_token": "metrics"
}
23 changes: 23 additions & 0 deletions Deployment/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# cspell:words gunicorn

name: developer-website

services:
developer_website:
build:
context: ..
dockerfile: Deployment/dockerfile
environment:
- APPLICATION_CONFIGURATION=/srv/application.json
ports: [ "8080:80" ]
configs:
- source: application
target: /srv/application.json
- source: gunicorn
target: /srv/gunicorn_configuration.py

configs:
application:
file: application.json
gunicorn:
file: gunicorn_configuration.py
27 changes: 27 additions & 0 deletions Deployment/dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# cspell:words a2enmod gunicorn libapache2 venv virtualenv wsgi

FROM debian:12



# Install Python
RUN apt update && apt install --yes python3 python3-pip python3-venv

# Copy the application sources
COPY Sources /srv/application

# Set up the python virtual environment
RUN python3 -m venv /srv/application/.venv
RUN /srv/application/.venv/bin/python -m pip install --upgrade pip wheel
COPY pip.conf /srv/application/.venv/pip.conf

# Install the application and gunicorn
RUN /srv/application/.venv/bin/python -m pip install --upgrade /srv/application/website "gunicorn ~= 23.0.0"



# Open network port
EXPOSE 80

# Run gunicorn
CMD [ "/srv/application/.venv/bin/gunicorn", "--bind", "0.0.0.0:80", "--config", "/srv/gunicorn_configuration.py" ]
43 changes: 43 additions & 0 deletions Deployment/gunicorn_configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# cspell:words levelname

import multiprocessing

from benjaminhamon_standard_extensions.logging import logging_helpers


wsgi_app = "benjaminhamon_developer_website.wsgi_entry_point"

workers = multiprocessing.cpu_count() * 2 + 1

logconfig_dict = {
"version": 1,

"root": {
"level": "DEBUG",
"handlers": [ "stdout" ],
},

"loggers": {
"gunicorn.error": {
"level": "INFO",
"propagate": True,
},
},

"handlers": {
"stdout": {
"class": "logging.StreamHandler",
"formatter": "generic",
"stream": "ext://sys.stdout",
},
},

"formatters": {
"generic": {
"style": "{",
"format": "{asctime} [{levelname}][{name}] ({process}) {message}",
"datefmt": logging_helpers.date_format_iso,
"class": "logging.Formatter",
}
}
}
5 changes: 2 additions & 3 deletions Sources/website/benjaminhamon_developer_website/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def main():
arguments = argument_parser.parse_args()

configure_logging(arguments)
logging.getLogger("werkzeug").setLevel(logging.WARNING)

application = application_factory.create_application("secret", "metrics")
website_url = "http://%s:%s/" % (arguments.address, arguments.port)
Expand All @@ -36,8 +35,6 @@ def create_argument_parser() -> argparse.ArgumentParser:
help = "set the address for the server to listen to")
argument_parser.add_argument("--port", required = True, type = int,
help = "set the port for the server to listen to")
argument_parser.add_argument("--secret", required = True,
help = "set the flask application secret key")

argument_parser.add_argument("--verbosity", choices = logging_helpers.all_log_levels,
metavar = "<level>", help = "set the logging level (%s)" % ", ".join(logging_helpers.all_log_levels))
Expand Down Expand Up @@ -76,6 +73,8 @@ def configure_logging(arguments: argparse.Namespace):
if log_file_path is not None:
logging_helpers.configure_log_file(logging.root, log_file_path, log_file_verbosity, message_format, date_format, mode = "w", encoding = "utf-8")

logging.getLogger("werkzeug").setLevel(logging.WARNING)


if __name__ == "__main__":
try:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import json
import logging
import os

import benjaminhamon_developer_website
from benjaminhamon_developer_website import application_factory


logger = logging.getLogger("Main")

logger.info("Instancing application for WSGI (version: %s)", benjaminhamon_developer_website.__version__)

configuration_file_path = os.environ["APPLICATION_CONFIGURATION"]
with open(configuration_file_path, mode = "r", encoding = "utf-8") as configuration_file:
configuration = json.load(configuration_file)

application = application_factory.create_application(
flask_secret_key = configuration["flask_secret_key"],
metrics_token = configuration["metrics_token"])
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async def website_fixture():
address = "localhost"
port = 4999

command = [ python_executable, "-m", application_module, "--address", address, "--port", str(port), "--secret", "secret" ]
command = [ python_executable, "-m", application_module, "--address", address, "--port", str(port) ]

async with WebsiteRunner(command, address, port) as website:
yield website.get_url()
Expand Down
Loading