Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(schematic): added nginx to schematic docker container #2403

Merged
merged 44 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
b350762
update uwsgi
linglp Dec 11, 2023
18ce930
add main
linglp Dec 11, 2023
a29bb29
format
linglp Dec 11, 2023
55f9b98
update docker file and update nginx config files
linglp Dec 11, 2023
12b2f1b
update to use python3.10.13
linglp Dec 11, 2023
65b44c6
update config file
linglp Dec 13, 2023
60bc33b
update to use python version 3.10.13
linglp Dec 13, 2023
3697242
udate dokcer compose up
linglp Dec 13, 2023
9e07f5d
update docker file
linglp Dec 13, 2023
2458bcb
edit comment and remove unnecessary part in dockerfile
linglp Dec 15, 2023
bbe3173
slightly modify nginx conf; add error page 497
linglp Jan 11, 2024
881d1e1
combine server block; remove redirect.conf
linglp Jan 11, 2024
e92e3bb
remove unnecessary part related to arg
linglp Jan 22, 2024
b9c65cf
update docker file
linglp Jan 22, 2024
ae7295b
use image in ghcr in docker compose
linglp Jan 22, 2024
6175b8d
pull changes from main
linglp Feb 13, 2024
bcf0b9a
redirect to port 8080 and port 8443
linglp Feb 14, 2024
96ace7f
update docker compose to use port 8443
linglp Feb 14, 2024
7e98b7d
updated to use port 7443
linglp Feb 14, 2024
e8d48d7
add package environs
linglp Mar 6, 2024
36f0ae2
modify entrypoint to handle certificate and private key; also add deb…
linglp Mar 6, 2024
74ec3c1
publish docker image one time
linglp Mar 6, 2024
5ac4f3d
try publish image
linglp Mar 6, 2024
5f25577
workflow dispatch
linglp Mar 6, 2024
b2e7988
try trigger docker build again
linglp Mar 6, 2024
bb1e8eb
trigger again
linglp Mar 6, 2024
0e300c0
add one time workflow
linglp Mar 6, 2024
b6a320b
remove one time workflow
linglp Mar 6, 2024
0900cb9
remove echo
linglp Mar 7, 2024
e873bb6
update port number
linglp Mar 8, 2024
cfca2cc
add maintainer names
linglp Mar 8, 2024
8f77e64
resolve conflicts
linglp Mar 8, 2024
00a7f95
revert changes
linglp Mar 8, 2024
63af81a
revert change
linglp Mar 8, 2024
007c5c4
revert adding workflow dispatch
linglp Mar 8, 2024
812722e
modify authors
linglp Mar 11, 2024
fe0ca57
update poetry lock file and also port number
linglp Mar 13, 2024
49b1064
add dhparam.pem
linglp Mar 13, 2024
9ad465b
rename script
linglp Mar 13, 2024
eda99f2
update ReadMe
linglp Mar 13, 2024
b698645
change copy statement
linglp Mar 13, 2024
397553c
update documentation
linglp Mar 14, 2024
fbbb74b
consolidate statements in dockerfile
linglp Mar 14, 2024
766e233
update doc
linglp Mar 14, 2024
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
87 changes: 58 additions & 29 deletions apps/schematic/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,41 +1,70 @@
FROM python:3.10.12-slim-buster
FROM tiangolo/uwsgi-nginx-flask:python3.10

ENV APP_DIR=/opt/app
# add version tag as a build argument
ARG TAG
linglp marked this conversation as resolved.
Show resolved Hide resolved

SHELL ["/bin/bash", "-euxo", "pipefail", "-c"]
# add label
LABEL maintainer="Milen Nikolov, Andrew Lamb, Mialy DeFelice, Gianna Jordan, Lingling Peng"
tschaffter marked this conversation as resolved.
Show resolved Hide resolved

# hadolint ignore=DL3008
RUN apt-get update -qq -y \
&& apt-get install --no-install-recommends -qq -y \
build-essential \
gosu \
libpcre3 \
libpcre3-dev \
python3-dev \
&& apt-get -y autoclean \
&& apt-get -y autoremove \
&& rm -rf /var/lib/apt/lists/*
# the environment variables defined here are the default
# and can be overwritten by docker run -e VARIABLE = XX
# or can be overwritten by .env when using docker compose
ENV PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \
PYTHONHASHSEED=random \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=200 \
POETRY_VERSION=1.3.0 \
APP_PARENT_DIR=/app \
NGINX_CONFIG=/etc/nginx/conf.d \
APP_DIR=/app/app \
ROOT=/ \
UWSGI_INI=/app/uwsgi.ini \
NGINX_WORKER_PROCESSES=1 \
VERSION=$TAG

WORKDIR ${APP_DIR}
COPY schematic_api schematic_api/
COPY pyproject.toml poetry.lock uwsgi.ini ./
# run open ssl and generate certificate
RUN apt update && \
linglp marked this conversation as resolved.
Show resolved Hide resolved
apt-get install openssl && \
openssl req -x509 -nodes -days 365 \
linglp marked this conversation as resolved.
Show resolved Hide resolved
-subj "/C=CA/ST=QC/O=Company" \
-newkey rsa:2048 -keyout /etc/ssl/private/localhost.key \
-out /etc/ssl/certs/localhost.crt;

# add dhparam.pem
# dhparam.pem was used in ssl-params.conf
RUN openssl dhparam -out /etc/ssl/dhparam.pem 4096

# copy all nginx config files
WORKDIR ${NGINX_CONFIG}
COPY ./self-signed.conf ./ssl-params.conf ./certificate.conf ./

# copy to use custom uwsgi.ini
WORKDIR /app
COPY ./uwsgi.ini ./

# copy files relevant for schematic apis
WORKDIR /app/app
COPY schematic_api ./schematic_api
COPY pyproject.toml poetry.lock ./

# install dependencies
RUN pip install poetry \
&& poetry config --local virtualenvs.create false \
&& poetry run pip install "cython<3.0.0" \
&& poetry run pip install --no-build-isolation pyyaml==5.4.1 \
&& poetry install --with prod --no-root --no-interaction --no-ansi \
&& pip cache purge

WORKDIR /
COPY docker-entrypoint.sh ./
RUN chmod +x docker-entrypoint.sh
&& poetry install --with prod --no-root --no-interaction --no-ansi

EXPOSE 7080
# Update file permission
RUN mkdir /root/.synapseCache
RUN mkdir /app/app/manifests
tschaffter marked this conversation as resolved.
Show resolved Hide resolved
# temporary here to ensure .synapseCache is not empty
RUN echo "This is a test file." > /root/.synapseCache/test.txt
# temporary here until we move .synapseCache to a different path
RUN chmod -R 777 /root /app
tschaffter marked this conversation as resolved.
Show resolved Hide resolved

ENTRYPOINT ["/docker-entrypoint.sh"]
WORKDIR ${APP_DIR}

# Run server in development mode
# CMD ["python", "-m", "openapi_server"]
# Run server in production mode
CMD ["uwsgi", "--ini", "uwsgi.ini", "--lazy", "--http", ":7080"]
# Expose ports
EXPOSE 443
linglp marked this conversation as resolved.
Show resolved Hide resolved
28 changes: 28 additions & 0 deletions apps/schematic/api/certificate.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
server {
# listen to port 80 for http requests
listen 80 http2 default_server;
# listen to port 443 for https requests
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include /etc/nginx/conf.d/self-signed.conf;
include /etc/nginx/conf.d/ssl-params.conf;
server_name 127.0.0.1;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
error_page 497 https://$http_host$request_uri;
location / {
try_files $uri @app;
}
location @app {
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
}
location /static {
alias /app/static;
}
location /health {
return 200 'alive';
add_header Content-Type text/plain;
}
}
12 changes: 8 additions & 4 deletions apps/schematic/api/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
version: "3.8"
version: "3.10"

services:
schematic-api:
image: ghcr.io/sage-bionetworks/schematic-api:local
# image: ghcr.io/sage-bionetworks/schematic-api:local
build:
dockerfile: Dockerfile
image: sagebionetworks/schematic-aws-api:latest
linglp marked this conversation as resolved.
Show resolved Hide resolved
container_name: schematic-api
restart: always
env_file:
Expand All @@ -12,8 +15,9 @@ services:
# - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
networks:
- schematic
ports:
- "${SERVER_PORT}:7080"
ports:
- "${SERVER_PORT}:80"
- "443:443"
linglp marked this conversation as resolved.
Show resolved Hide resolved

# volumes:
# openchallenges-mariadb:
Expand Down
2 changes: 1 addition & 1 deletion apps/schematic/api/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/schematic/api/prepare-python.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash

PYTHON_VERSION="3.10.12"
PYTHON_VERSION="3.10.13"

pyenv install --skip-existing $PYTHON_VERSION

Expand Down
2 changes: 1 addition & 1 deletion apps/schematic/api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ readme = "README.md"
packages = [{include = "schematic_api"}]

[tool.poetry.dependencies]
python = "3.10.12"
python = "3.10.13"
connexion = {version = "2.14.1", extras = ["swagger-ui"]}
swagger-ui-bundle = "0.0.9"
python-dateutil = "2.8.2"
Expand Down
70 changes: 40 additions & 30 deletions apps/schematic/api/schematic_api/config.yml
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
# Do not change the 'definitions' section unless you know what you're doing
definitions:
synapse_config: ".synapseConfig"
service_acct_creds: "schematic_service_account_creds.json"
# This is an example config for Schematic.
# All listed values are those that are the default if a config is not used.
# Save this as config.yml, this will be gitignored.
# Remove any fields in the config you don't want to change
# If you remove all fields from a section, the entire section should be removed including the header.
# Change the values of any fields you do want to change


synapse:
master_fileview: 'syn23643253'
manifest_folder: 'manifests'
manifest_basename: 'synapse_storage_manifest'
service_acct_creds: 'syn25171627'
# This describes where assets such as manifests are stored
asset_store:
# This is when assets are stored in a synapse project
synapse:
# Synapse ID of the file view listing all project data assets.
# master_fileview_id: "syn23643253"
master_fileview_id: "syn52854554"
# Path to the synapse config file, either absolute or relative to this file
config: ".synapseConfig"
# Base name that manifest files will be saved as
manifest_basename: "synapse_storage_manifest"

# This describes information about manifests as it relates to generation and validation
manifest:
# if making many manifests, just include name prefix
title: 'example'
# to make all manifests enter only 'all manifests'
data_type:
- 'Biospecimen'
- 'Patient'
# Location where manifests will saved to
manifest_folder: "manifests"
# Title or title prefix given to generated manifest(s)
title: "example"
# Data types of manifests to be generated or data type (singular) to validate manifest against
data_type:
- "Biospecimen"
- "Patient"

# Describes the location of your schema
model:
input:
location: 'tests/data/example.model.jsonld'
file_type: 'local'
# Location of your schema jsonld, it must be a path relative to this file or absolute
location: "tests/data/example.model.jsonld"

style:
google_manifest:
req_bg_color:
red: 0.9215
green: 0.9725
blue: 0.9803
opt_bg_color:
red: 1.0
green: 1.0
blue: 0.9019
master_template_id: '1LYS5qE4nV9jzcYw5sXwCza25slDfRA1CIg3cs-hCdpU'
strict_validation: true
# This section is for using google sheets with Schematic
google_sheets:
# The Synapse id of the Google service account credentials.
service_acct_creds_synapse_id: "syn25171627"
# Path to the synapse config file, either absolute or relative to this file
service_acct_creds: "schematic_service_account_creds.json"
# When doing google sheet validation (regex match) with the validation rules.
# true is alerting the user and not allowing entry of bad values.
# false is warning but allowing the entry on to the sheet.
strict_validation: true
24 changes: 24 additions & 0 deletions apps/schematic/api/schematic_api/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env python3
import connexion
from flask_cors import CORS
import flask
from schematic_api import encoder

app = connexion.App(__name__, specification_dir="./openapi/")
app.app.json_encoder = encoder.JSONEncoder
app.add_api(
"openapi.yaml", arguments={"title": "Schematic REST API"}, pythonic_params=True
)
app.add_url_rule("/", "ui", lambda: flask.redirect("/api/v1/ui"))

# add CORS support
# https://connexion.readthedocs.io/en/latest/cookbook.html#cors-support
CORS(app.app, resources={r"/api/*": {"origins": "*"}})


def main():
app.run(port=80, debug=False)


if __name__ == "__main__":
main()
6 changes: 6 additions & 0 deletions apps/schematic/api/self-signed.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# The ultimate goal is to set up a self-signed SSL certificate for Nginx to use
# A self-signed certificate is required to encrypt the communication between flask API server and any clients
# This configuration file is needed to configure nginx to use SSL certificates

ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/private/localhost.key;
21 changes: 21 additions & 0 deletions apps/schematic/api/ssl-params.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# The configuration file was borrowed from: https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-22-04
# This configuration file is needed for setting up nginx securely.

ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/dhparam.pem;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable strict transport security for now. You can uncomment the following
# line if you understand the implications.
# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
13 changes: 11 additions & 2 deletions apps/schematic/api/uwsgi.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[uwsgi]
# The variables http and *-socket are passed as command line arguments and
# must not be specified in this file.
wsgi-file = schematic_api/__main__.py
wsgi-file = schematic_api/main.py
callable = app
uid = www-data
gid = www-data
Expand All @@ -12,4 +12,13 @@ chmod-sock = 660
vacuum = true
die-on-term = true
thunder-lock = true
http-keepalive = true
http-keepalive = true
harakiri-verbose = true
http-timeout = 300 # necessary for preventing time-out
uwsgi_read_timeout = 300 # necessary for preventing time-out
uwsgi_send_timeout = 300 # necessary for preventing time-out
buffer-size = 32768 # for dealing with long token in DCA and DFA
# for dealing with OSError: write error
ignore-sigpipe=true
ignore-write-errors=true
disable-write-exception=true