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 diff --git a/devops/Dockerfile b/devops/Dockerfile index 7b56ec7be..9a475eee4 100644 --- a/devops/Dockerfile +++ b/devops/Dockerfile @@ -3,6 +3,16 @@ 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 /src +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 LABEL org.opencontainers.image.source=https://github.com/cmu-delphi/delphi-epidata # use delphi's timezome @@ -17,7 +27,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/_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..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,6 +49,17 @@ 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: 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__": app.run(host="0.0.0.0", port=5000) else: