From 3570ce8c4ca6b5fc5e35fbe8fa9f5d2489f08151 Mon Sep 17 00:00:00 2001 From: Samuel Gratzl Date: Wed, 30 Jun 2021 15:45:59 +0200 Subject: [PATCH 1/4] feat: serve static directory under /docs --- src/server/_common.py | 6 +++--- src/server/main.py | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/server/_common.py b/src/server/_common.py index f4fbbd916..fd00cf14e 100644 --- a/src/server/_common.py +++ b/src/server/_common.py @@ -27,13 +27,13 @@ def _get_db() -> Connection: @app.before_request def connect_db(): - if request.path.startswith('/lib'): + if request.path.startswith("/lib") or request.path.startswith("/docs"): return # try to get the db try: _get_db() except: - app.logger.error('database connection error', exc_info=True) + app.logger.error("database connection error", exc_info=True) raise DatabaseErrorException() @@ -50,7 +50,7 @@ def is_compatibility_mode() -> bool: """ checks whether this request is in compatibility mode """ - return 'compatibility' in g and g.compatibility + return "compatibility" in g and g.compatibility def set_compatibility_mode(): diff --git a/src/server/main.py b/src/server/main.py index 5434b744b..ba01bfc0c 100644 --- a/src/server/main.py +++ b/src/server/main.py @@ -49,6 +49,11 @@ def send_lib_file(path: str): return send_from_directory(pathlib.Path(__file__).parent / "lib", path) +@app.route(f"{URL_PREFIX}/docs/") +def send_docs_file(path: str): + return send_from_directory(pathlib.Path(__file__).parent / "docs", path) + + if __name__ == "__main__": app.run(host="0.0.0.0", port=5000) else: From 4640948439f01a6ae9b32ead4f917e39e7ece54c Mon Sep 17 00:00:00 2001 From: Samuel Gratzl Date: Wed, 30 Jun 2021 16:07:55 +0200 Subject: [PATCH 2/4] build: tune dockerignore file --- .dockerignore | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.dockerignore b/.dockerignore index 058bb7939..395c40244 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,10 @@ +/.git /delphi-epidata -/.mypy_cache +/build /.github -/docs -__pycache__ -/node_modules \ No newline at end of file +**/__pycache__ +**/.pytest_cache +**/.mypy_cache +**/node_modules +/.env +/.env.example \ No newline at end of file From 9cd7a26ff94d380b41125e9606b7f1b495055a3b Mon Sep 17 00:00:00 2001 From: Samuel Gratzl Date: Wed, 30 Jun 2021 16:51:57 +0200 Subject: [PATCH 3/4] build: bundle docs in delphi-server --- devops/Dockerfile | 14 +++++++++++++- src/server/main.py | 14 ++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/devops/Dockerfile b/devops/Dockerfile index 7b56ec7be..3017be3c4 100644 --- a/devops/Dockerfile +++ b/devops/Dockerfile @@ -3,6 +3,17 @@ WORKDIR /src COPY . /src RUN npm ci && npm run build +FROM jekyll/jekyll:stable as docs_builder +# see also https://github.com/envygeeks/jekyll-docker/issues/280 +RUN mkdir /src; \ + chown -R jekyll:jekyll /src +WORKDIR /src +COPY docs/Gemfile* /src/ +RUN bundle update +COPY ./docs /src +RUN sed -i 's#baseurl: "/delphi-epidata"#baseurl: "/docs"#g' /src/_config.yml +RUN jekyll build + FROM tiangolo/meinheld-gunicorn:python3.7 LABEL org.opencontainers.image.source=https://github.com/cmu-delphi/delphi-epidata # use delphi's timezome @@ -17,7 +28,8 @@ ENV PYTHONUNBUFFERED 1 COPY ./devops/gunicorn_conf.py /app COPY ./devops/start_wrapper.sh / COPY ./src/server/ /app/app/ -COPY --from=builder ./src/build/lib/ /app/app/lib/ +COPY --from=builder /src/build/lib/ /app/app/lib/ +COPY --from=docs_builder /src/_site /app/app/docs/ RUN rm -rf /app/app/__pycache__ /app/app/*.php \ && chmod -R o+r /app/app \ && chmod 755 /start_wrapper.sh diff --git a/src/server/main.py b/src/server/main.py index ba01bfc0c..ad0fb76e4 100644 --- a/src/server/main.py +++ b/src/server/main.py @@ -1,8 +1,8 @@ import pathlib import logging -from typing import Dict, Callable +from typing import Dict, Callable, Optional -from flask import request, send_file, Response, send_from_directory, jsonify +from flask import request, send_file, Response, send_from_directory, jsonify, safe_join from ._config import URL_PREFIX, VERSION from ._common import app, set_compatibility_mode @@ -49,9 +49,15 @@ def send_lib_file(path: str): return send_from_directory(pathlib.Path(__file__).parent / "lib", path) +@app.route(f"{URL_PREFIX}/docs", defaults=dict(path="/")) @app.route(f"{URL_PREFIX}/docs/") -def send_docs_file(path: str): - return send_from_directory(pathlib.Path(__file__).parent / "docs", path) +def send_docs_file(path: Optional[str]): + base_dir = pathlib.Path(__file__).parent / "docs" + fixed_path = path or "index.html" + target_file = pathlib.Path(safe_join(base_dir, fixed_path)) + if target_file.exists() and target_file.is_dir(): + fixed_path = fixed_path + "/index.html" + return send_from_directory(base_dir, fixed_path) if __name__ == "__main__": From ae759d09d332cb00dfa96d7de53e79c1f1cca6fa Mon Sep 17 00:00:00 2001 From: Samuel Gratzl Date: Wed, 30 Jun 2021 16:58:52 +0200 Subject: [PATCH 4/4] build: fix permissions when building jekyll --- devops/Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/devops/Dockerfile b/devops/Dockerfile index 3017be3c4..9a475eee4 100644 --- a/devops/Dockerfile +++ b/devops/Dockerfile @@ -8,10 +8,9 @@ FROM jekyll/jekyll:stable as docs_builder RUN mkdir /src; \ chown -R jekyll:jekyll /src WORKDIR /src -COPY docs/Gemfile* /src/ -RUN bundle update COPY ./docs /src -RUN sed -i 's#baseurl: "/delphi-epidata"#baseurl: "/docs"#g' /src/_config.yml +RUN chown -R jekyll:jekyll /src; \ + sed -i 's#baseurl: "/delphi-epidata"#baseurl: "/docs"#g' /src/_config.yml RUN jekyll build FROM tiangolo/meinheld-gunicorn:python3.7