Chore/kill yalc with fire (#629)
* init * more shifting * Move @babel dependencies up to workspace root * Begin updating dependent libraries to use sync'd webpack builds w/ watches * Commit changes before a long weekend * Split packages into platform and extensions * Consolidate how/where we specify file/module type entrypoints * Make it possible to pass in extensions as App props * Resolve viewer's modules * Target for UMD bundle * Add Webpack Stylus loader * Provide WebPack build options for microscopy, vtk, and ui * Better entrypoint for extensions * Push changes up to switch PCs * Fix ESM symlink build for Viewers * Shift docs to root * Specify additional lerna config props * Begin providing basic readme info * Rename example extension folder * Shift links to bottom of doc * First attempt at a netlify deploy preview * Attempt to fix deploy preview build * push workspace enabled to initial command; remove second yarn install; use npx to call gitbook cli commands * Try to use global gitbook-cli * Export node_modules path * More agressive with modifying PATH * Follow deploy log output advice * try again to set bin path * Try swapping bash with a new shell * Try bash -l instead of exec bash * Annd let's try again * and again * We may have figured it out johnny, boy * We need to pull cornerstone-wado-image-loader files from hoisted node_modules * Attempt to fix ticks/escapes * Change copy syntax; try running tests on viewers from root for circleci * Lower version to match circleci image * Try alternative jest-canvas-mock location and version file syntax * Run version command instead of calling node directly * Try alternative jest transform * Set path and enable workspaces * Add codecov flags * Use cpx so our copying finishes? * Get all platform unit tests to run * Run and report individually and in parallel * Try once relying on codecov yaml to split w/ flags * Add projects to split by flags * Generate separate reports * Trigger codecov after everything has finished running; these may not support flags * Use recommended flags from issue comments for codecov * Fix typo * Remove clear flag * Shift back to calling codecov from root * Generate example for codecov issue * Try fixing paths * Simplify * Try using codecov orb * Bump circleci version * Upload core and viewer * Use full string paths * Remove individual codecov calls * Fix dir * Combine files before upload * Escape anchors * tryfix syntax * Escape string literal * Combine lines to reduce path * long paths * Use home alias * Fix filename * Try to see the contents of our cat'd file * Also upload `core` * Try running with aliased folder * Fix path; split PR and Merge unit tests into separate jobs * Set default threshold * Fix typo * Changing to scoped package names * Adding note * Catch more updates * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.0 - @ohif/extension-dicom-html@0.0.4-alpha.0 - @ohif/extension-dicom-microscopy@0.0.9-alpha.0 - @ohif/extension-dicom-pdf@0.0.8-alpha.0 - @ohif/extension-vtk@0.1.4-alpha.0 - @ohif/core@0.11.1-alpha.0 - @ohif/i18n@0.2.3-alpha.0 - @ohif/ui@0.2.18-alpha.0 - @ohif/viewer@0.0.22-alpha.0 * Clean up primary readme * Support for dev and dev:* commands * Shift build command; satisfy default PWA build * Remove old scripts * Clean up UI to set webpack scripts * Tidy up project links * Clean duplicate code in UI project * Update UI project's docs * Clean up ui and i18n config * Reduce duplicate code in `@ohif/core` * Fix @ohif/ui versions * bump @ohif/core versions * Redux testkit dep * Remove unused/duplicate config files for projects/packages * ohif-core --> @ohif/core * Safer publish command * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.1 - @ohif/extension-dicom-html@0.0.4-alpha.1 - @ohif/extension-dicom-microscopy@0.0.9-alpha.1 - @ohif/extension-dicom-pdf@0.0.8-alpha.1 - @ohif/extension-vtk@0.1.4-alpha.1 - @ohif/core@0.11.1-alpha.1 - @ohif/i18n@0.2.3-alpha.1 - @ohif/ui@0.2.18-alpha.1 - @ohif/viewer@0.0.22-alpha.1 * test version bump * Add global prettier config * chore(release): publish %s [skip ci] - @ohif/viewer@0.0.22-alpha.2 * test lerna publish * Update package.jsons * Fix build scripts * catch changes * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.2 - @ohif/extension-dicom-html@0.0.4-alpha.2 - @ohif/extension-dicom-microscopy@0.0.9-alpha.2 - @ohif/extension-dicom-pdf@0.0.8-alpha.2 - @ohif/extension-vtk@0.1.4-alpha.2 - @ohif/core@0.11.1-alpha.2 - @ohif/i18n@0.2.3-alpha.2 - @ohif/ui@0.2.18-alpha.2 - @ohif/viewer@0.0.22-alpha.3 * fix eslint issues caused by eslint 6 and our react-app config * Publish with canary tag * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.3 - @ohif/extension-dicom-html@0.0.4-alpha.3 - @ohif/extension-dicom-microscopy@0.0.9-alpha.3 - @ohif/extension-dicom-pdf@0.0.8-alpha.3 - @ohif/extension-vtk@0.1.4-alpha.3 - @ohif/core@0.11.1-alpha.3 - @ohif/i18n@0.2.3-alpha.3 - @ohif/ui@0.2.18-alpha.3 - @ohif/viewer@0.0.22-alpha.4 * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.4 - @ohif/extension-dicom-html@0.0.4-alpha.4 - @ohif/extension-dicom-microscopy@0.0.9-alpha.4 - @ohif/extension-dicom-pdf@0.0.8-alpha.4 - @ohif/extension-vtk@0.1.4-alpha.4 - @ohif/core@0.11.1-alpha.4 - @ohif/i18n@0.2.3-alpha.4 - @ohif/ui@0.2.18-alpha.4 - @ohif/viewer@0.0.22-alpha.5 * Simplify build * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.5 - @ohif/extension-dicom-html@0.0.4-alpha.5 - @ohif/extension-dicom-microscopy@0.0.9-alpha.5 - @ohif/extension-dicom-pdf@0.0.8-alpha.5 - @ohif/extension-vtk@0.1.4-alpha.5 - @ohif/core@0.11.1-alpha.5 - @ohif/i18n@0.2.3-alpha.5 - @ohif/ui@0.2.18-alpha.5 - @ohif/viewer@0.0.22-alpha.6 * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.6 - @ohif/extension-dicom-html@0.0.4-alpha.6 - @ohif/extension-dicom-microscopy@0.0.9-alpha.6 - @ohif/extension-dicom-pdf@0.0.8-alpha.6 - @ohif/extension-vtk@0.1.4-alpha.6 - @ohif/core@0.11.1-alpha.6 - @ohif/i18n@0.2.3-alpha.6 - @ohif/ui@0.2.18-alpha.6 - @ohif/viewer@0.0.22-alpha.7 * Split version and publish * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.7 - @ohif/extension-dicom-html@0.0.4-alpha.7 - @ohif/extension-dicom-microscopy@0.0.9-alpha.7 - @ohif/extension-dicom-pdf@0.0.8-alpha.7 - @ohif/extension-vtk@0.1.4-alpha.7 - @ohif/core@0.11.1-alpha.7 - @ohif/i18n@0.2.3-alpha.7 - @ohif/ui@0.2.18-alpha.7 - @ohif/viewer@0.0.22-alpha.8 * Try simplify netlify build * react-viewerbase --> @ohif/ui * add test for stylus loader * Try new way to specify publish path * Use an output folder that won't be ignored * Try move command * fiddle with paths * Dig for some information * Make sure we're in root for our commands * Remove discovery * Setup script-tag example * Fix typo * Move config folder * Update cornerstone extension to use shared/root webpack configs * capture changes * Update extension webpack configs * Don't check in docz output * Fix babel runtime resolution issue * Simplify ui build steps * Push in progress * Shift directories * Get viewer dev path to work * Fix viewer commonjs build * Fix build pwa config for viewers * Make sure our package specific command can be called from root * Update notes * Fix imports and misc. merge notes * Bump wado-image-loader version * Switch up commands to remove webworkers copy * Fix CI config * Fix more broken package references * Add react-dropzone * Persist so e2e test can use * Fix lockfile * Use cypress orb to simplify CI * Fix config * Try again * Install yarn latest for orb * Install yarn a different way * Wait on correct port * Run tests in viewer project * Fix cypress config * Make Cypress happier - use default location * Simplify e2e testing * Capture UI changes since fork * Catch core up * Grab latest deps after merge * Fix broken import * Make sure cornerstone-wado-image-loader resolves to 3+ * Note regarding orbs * Fix refresh on 404 routes * Fix odd error for cornerstone-wado-image-loader * Different target for UMD * Simplify dev script * Try to get fancy with netlify output * Let's do it again * Try to fix measurementTools issue * See if we can get our lerna magic to work on merge to monorepo branch
This commit is contained in:
1 parent
cac911f08e
commit
08ff214ea6
919 files changed
+45652
-52097
No files matched your search
@@ -0,0 +1,4 @@
|
||||
STORAGE_DIR=/storage/fs1
|
||||
POSTGRES_DB=pacsdb
|
||||
POSTGRES_USER=pacs
|
||||
POSTGRES_PASSWORD=pacs
|
||||
@@ -0,0 +1,77 @@
|
||||
version: '3.5'
|
||||
|
||||
services:
|
||||
ldap:
|
||||
image: dcm4che/slapd-dcm4chee:2.4.44-15.0
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: '10m'
|
||||
ports:
|
||||
- '389:389'
|
||||
env_file: ./dcm4che/docker-compose-dcm4che.env
|
||||
volumes:
|
||||
- ./dcm4che/etc/localtime:/etc/localtime:ro
|
||||
- ./dcm4che/etc/timezone:/etc/timezone:ro
|
||||
- ./dcm4che/dcm4che-arc/ldap:/var/lib/ldap
|
||||
- ./dcm4che/dcm4che-arc/slapd.d:/etc/ldap/slapd.d
|
||||
networks:
|
||||
- dcm4che_default
|
||||
db:
|
||||
image: dcm4che/postgres-dcm4chee:11.1-15
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: '10m'
|
||||
ports:
|
||||
- '5432:5432'
|
||||
env_file: ./dcm4che/docker-compose-dcm4che.env
|
||||
volumes:
|
||||
- ./dcm4che/etc/localtime:/etc/localtime:ro
|
||||
- ./dcm4che/etc/timezone:/etc/timezone:ro
|
||||
- ./dcm4che/dcm4che-arc/db:/var/lib/postgresql/data
|
||||
networks:
|
||||
- dcm4che_default
|
||||
arc:
|
||||
image: dcm4che/dcm4chee-arc-psql:5.15.0
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: '10m'
|
||||
ports:
|
||||
- '8080:8080'
|
||||
- '8443:8443'
|
||||
- '9990:9990'
|
||||
- '11112:11112'
|
||||
- '2575:2575'
|
||||
env_file: ./dcm4che/docker-compose-dcm4che.env
|
||||
environment:
|
||||
WILDFLY_CHOWN: /opt/wildfly/standalone /storage
|
||||
WILDFLY_WAIT_FOR: ldap:389 db:5432
|
||||
depends_on:
|
||||
- ldap
|
||||
- db
|
||||
volumes:
|
||||
- ./dcm4che/etc/localtime:/etc/localtime:ro
|
||||
- ./dcm4che/etc/timezone:/etc/timezone:ro
|
||||
- ./dcm4che/dcm4che-arc/wildfly:/opt/wildfly/standalone
|
||||
- ./dcm4che/dcm4che-arc/storage:/storage
|
||||
networks:
|
||||
- dcm4che_default
|
||||
viewer:
|
||||
container_name: ohif-viewer
|
||||
build:
|
||||
context: ../
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- '80:80'
|
||||
# depends_on:
|
||||
# - orthanc
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- REACT_APP_CONFIG=config/local_dcm4chee
|
||||
restart: always
|
||||
networks:
|
||||
- dcm4che_default
|
||||
|
||||
networks: dcm4che_default:
|
||||
Whitespace-only changes.
@@ -0,0 +1 @@
|
||||
America/New_York
|
||||
@@ -0,0 +1,49 @@
|
||||
events {
|
||||
worker_connections 4096; ## Default: 1024
|
||||
}
|
||||
|
||||
http {
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name localhost;
|
||||
|
||||
#
|
||||
# Wide-open CORS config for nginx
|
||||
#
|
||||
location / {
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
#
|
||||
# Custom headers and headers various browsers *should* be OK with but aren't
|
||||
#
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
#
|
||||
# Tell client that this pre-flight info is valid for 20 days
|
||||
#
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization';
|
||||
add_header 'Access-Control-Allow-Credentials' true;
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
if ($request_method = 'POST') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||
}
|
||||
if ($request_method = 'GET') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization';
|
||||
add_header 'Access-Control-Allow-Credentials' true;
|
||||
}
|
||||
|
||||
proxy_pass http://orthanc:8042;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
worker_processes 1;
|
||||
|
||||
events { worker_connections 1024; }
|
||||
|
||||
http {
|
||||
|
||||
upstream orthanc-server {
|
||||
server orthanc:8042;
|
||||
}
|
||||
|
||||
server {
|
||||
listen [::]:80 default_server;
|
||||
listen 80;
|
||||
|
||||
# CORS Magic
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow_Credentials' 'true';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
|
||||
|
||||
location / {
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow_Credentials' 'true';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
|
||||
proxy_pass http://orthanc:8042;
|
||||
proxy_redirect off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
|
||||
# CORS Magic
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow_Credentials' 'true';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"Name": "Orthanc inside Docker",
|
||||
"StorageDirectory": "/var/lib/orthanc/db",
|
||||
"IndexDirectory": "/var/lib/orthanc/db",
|
||||
"StorageCompression": false,
|
||||
"MaximumStorageSize": 0,
|
||||
"MaximumPatientCount": 0,
|
||||
"LuaScripts": [],
|
||||
"Plugins": ["/usr/share/orthanc/plugins", "/usr/local/share/orthanc/plugins"],
|
||||
"ConcurrentJobs": 2,
|
||||
"HttpServerEnabled": true,
|
||||
"HttpPort": 8042,
|
||||
"HttpDescribeErrors": true,
|
||||
"HttpCompressionEnabled": true,
|
||||
"DicomServerEnabled": true,
|
||||
"DicomAet": "ORTHANC",
|
||||
"DicomCheckCalledAet": false,
|
||||
"DicomPort": 4242,
|
||||
"DefaultEncoding": "Latin1",
|
||||
"DeflatedTransferSyntaxAccepted": true,
|
||||
"JpegTransferSyntaxAccepted": true,
|
||||
"Jpeg2000TransferSyntaxAccepted": true,
|
||||
"JpegLosslessTransferSyntaxAccepted": true,
|
||||
"JpipTransferSyntaxAccepted": true,
|
||||
"Mpeg2TransferSyntaxAccepted": true,
|
||||
"RleTransferSyntaxAccepted": true,
|
||||
"UnknownSopClassAccepted": false,
|
||||
"DicomScpTimeout": 30,
|
||||
|
||||
"RemoteAccessAllowed": true,
|
||||
"SslEnabled": false,
|
||||
"SslCertificate": "certificate.pem",
|
||||
"AuthenticationEnabled": false,
|
||||
"RegisteredUsers": {
|
||||
"test": "test"
|
||||
},
|
||||
"DicomModalities": {},
|
||||
"DicomModalitiesInDatabase": false,
|
||||
"DicomAlwaysAllowEcho": true,
|
||||
"DicomAlwaysAllowStore": true,
|
||||
"DicomCheckModalityHost": false,
|
||||
"DicomScuTimeout": 10,
|
||||
"OrthancPeers": {},
|
||||
"OrthancPeersInDatabase": false,
|
||||
"HttpProxy": "",
|
||||
|
||||
"HttpVerbose": true,
|
||||
|
||||
"HttpTimeout": 10,
|
||||
"HttpsVerifyPeers": true,
|
||||
"HttpsCACertificates": "",
|
||||
"UserMetadata": {},
|
||||
"UserContentType": {},
|
||||
"StableAge": 60,
|
||||
"StrictAetComparison": false,
|
||||
"StoreMD5ForAttachments": true,
|
||||
"LimitFindResults": 0,
|
||||
"LimitFindInstances": 0,
|
||||
"LimitJobs": 10,
|
||||
"LogExportedResources": false,
|
||||
"KeepAlive": true,
|
||||
"TcpNoDelay": true,
|
||||
"HttpThreadsCount": 50,
|
||||
"StoreDicom": true,
|
||||
"DicomAssociationCloseDelay": 5,
|
||||
"QueryRetrieveSize": 10,
|
||||
"CaseSensitivePN": false,
|
||||
"LoadPrivateDictionary": true,
|
||||
"Dictionary": {},
|
||||
"SynchronousCMove": true,
|
||||
"JobsHistorySize": 10,
|
||||
"SaveJobs": true,
|
||||
"OverwriteInstances": false,
|
||||
"MediaArchiveSize": 1,
|
||||
"StorageAccessOnFind": "Always",
|
||||
"MetricsEnabled": true,
|
||||
|
||||
"DicomWeb": {
|
||||
"Enable": true,
|
||||
"Root": "/dicom-web/",
|
||||
"EnableWado": true,
|
||||
"WadoRoot": "/wado",
|
||||
"Host": "127.0.0.1",
|
||||
"Ssl": false,
|
||||
"StowMaxInstances": 10,
|
||||
"StowMaxSize": 10,
|
||||
"QidoCaseSensitive": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
version: '3.5'
|
||||
|
||||
services:
|
||||
orthanc:
|
||||
image: jodogne/orthanc-plugins:1.5.6
|
||||
hostname: orthanc
|
||||
volumes:
|
||||
# Config
|
||||
- ./config/orthanc.json:/etc/orthanc/orthanc.json:ro
|
||||
# Persist data
|
||||
- ./volumes/orthanc-db/:/var/lib/orthanc/db/
|
||||
ports:
|
||||
- '4242:4242' # DICOM
|
||||
- '8042:8042' # Web
|
||||
restart: unless-stopped
|
||||
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -0,0 +1,16 @@
|
||||
# Output
|
||||
dist/
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
# Root
|
||||
README.md
|
||||
Dockerfile
|
||||
|
||||
# Misc. Config
|
||||
.git
|
||||
.DS_Store
|
||||
.gitignore
|
||||
.vscode
|
||||
.circleci
|
||||
@@ -0,0 +1,5 @@
|
||||
# Docker ENV and ARG Variables
|
||||
# ----------------------------
|
||||
# https://vsupalov.com/docker-arg-env-variable-guide/
|
||||
#
|
||||
#
|
||||
@@ -0,0 +1,259 @@
|
||||
worker_processes 2;
|
||||
error_log /var/logs/nginx/mydomain.error.log;
|
||||
pid /var/run/nginx.pid;
|
||||
include /usr/share/nginx/modules/*.conf; # See /usr/share/doc/nginx/README.dynamic.
|
||||
|
||||
events {
|
||||
worker_connections 1024; ## Default: 1024
|
||||
use epoll; # http://nginx.org/en/docs/events.html
|
||||
multi_accept on; # http://nginx.org/en/docs/ngx_core_module.html#multi_accept
|
||||
}
|
||||
|
||||
# Core Modules Docs:
|
||||
# http://nginx.org/en/docs/http/ngx_http_core_module.html
|
||||
http {
|
||||
include '/usr/local/openresty/nginx/conf/mime.types';
|
||||
default_type application/octet-stream;
|
||||
|
||||
keepalive_timeout 65;
|
||||
keepalive_requests 100000;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
|
||||
# lua_ settings
|
||||
#
|
||||
lua_package_path '/usr/local/openresty/lualib/?.lua;;';
|
||||
lua_shared_dict discovery 1m; # cache for discovery metadata documents
|
||||
lua_shared_dict jwks 1m; # cache for JWKs
|
||||
# lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
|
||||
|
||||
variables_hash_max_size 2048;
|
||||
server_names_hash_bucket_size 128;
|
||||
server_tokens off;
|
||||
|
||||
resolver 8.8.8.8 valid=30s ipv6=off;
|
||||
resolver_timeout 11s;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
# No idea what this is doing
|
||||
# https://stackoverflow.com/a/5877989/1867984
|
||||
# upstream upstream_server {
|
||||
# # server 10.100.4.200:1010 max_fails=3 fail_timeout=30s;
|
||||
# server 127.0.0.1:
|
||||
# }
|
||||
|
||||
# Nginx `listener` block
|
||||
server {
|
||||
listen [::]:80 default_server;
|
||||
listen 80;
|
||||
# listen 443 ssl;
|
||||
access_log /var/logs/nginx/mydomain.access.log;
|
||||
|
||||
# Domain to protect
|
||||
server_name 127.0.0.1 localhost; # mydomain.com;
|
||||
proxy_intercept_errors off;
|
||||
# ssl_certificate /etc/letsencrypt/live/mydomain.co.uk/fullchain.pem;
|
||||
# ssl_certificate_key /etc/letsencrypt/live/mydomain.co.uk/privkey.pem;
|
||||
gzip on;
|
||||
gzip_types text/css application/javascript application/json image/svg+xml;
|
||||
gzip_comp_level 9;
|
||||
etag on;
|
||||
|
||||
# https://github.com/bungle/lua-resty-session/issues/15
|
||||
set $session_check_ssi off;
|
||||
lua_code_cache off;
|
||||
set $session_secret Eeko7aeb6iu5Wohch9Loo1aitha0ahd1;
|
||||
set $session_storage cookie;
|
||||
|
||||
server_tokens off; # Hides server version num
|
||||
|
||||
# [PROTECTED] Reverse Proxy for `orthanc` admin
|
||||
#
|
||||
location /pacs-admin/ {
|
||||
access_by_lua_block {
|
||||
local opts = {
|
||||
redirect_uri = "http://127.0.0.1/pacs-admin/admin",
|
||||
discovery = "http://127.0.0.1/auth/realms/ohif/.well-known/openid-configuration",
|
||||
token_endpoint_auth_method = "client_secret_basic",
|
||||
client_id = "pacs",
|
||||
client_secret = "66279641-eba6-47f5-9fdb-70c4ac74d548",
|
||||
client_jwt_assertion_expires_in = 60 * 60,
|
||||
ssl_verify = "no",
|
||||
scope = "openid email profile",
|
||||
refresh_session_interval = 900,
|
||||
redirect_uri_scheme = "http",
|
||||
redirect_after_logout_uri = "/",
|
||||
session_contents = {id_token=true}
|
||||
}
|
||||
|
||||
-- call authenticate for OpenID Connect user authentication
|
||||
local res, err = require("resty.openidc").authenticate(opts)
|
||||
|
||||
if err or not res then
|
||||
ngx.print(err)
|
||||
ngx.status = 200
|
||||
ngx.say(err and err or "no access_token provided")
|
||||
ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||
end
|
||||
|
||||
-- Or set cookie?
|
||||
-- ngx.req.set_header("Authorization", "Bearer " .. res.access_token)
|
||||
ngx.req.set_header("X-USER", res.id_token.sub)
|
||||
}
|
||||
|
||||
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
expires 0;
|
||||
add_header Cache-Control private;
|
||||
|
||||
proxy_pass http://orthanc:8042/;
|
||||
}
|
||||
|
||||
# [PROTECTED] Reverse Proxy for `orthanc` APIs (including DICOMWeb)
|
||||
#
|
||||
location /pacs/ {
|
||||
access_by_lua_block {
|
||||
local opts = {
|
||||
discovery = "http://127.0.0.1/auth/realms/ohif/.well-known/openid-configuration",
|
||||
}
|
||||
|
||||
-- call bearer_jwt_verify for OAuth 2.0 JWT validation
|
||||
local res, err = require("resty.openidc").bearer_jwt_verify(opts)
|
||||
|
||||
if err or not res then
|
||||
ngx.status = 403
|
||||
ngx.say(err and err or "no access_token provided")
|
||||
ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||
end
|
||||
}
|
||||
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
# proxy_set_header Upgrade $http_upgrade;
|
||||
# proxy_set_header Connection "upgrade";
|
||||
|
||||
expires 0;
|
||||
add_header Cache-Control private;
|
||||
|
||||
proxy_pass http://orthanc:8042/;
|
||||
|
||||
# By default, this endpoint is protected by CORS (cross-origin-resource-sharing)
|
||||
# You can add headers to allow other domains to request this resource.
|
||||
# See the "Updating CORS Settings" example below
|
||||
}
|
||||
|
||||
# Keycloak
|
||||
#
|
||||
location /auth/ {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
proxy_pass http://keycloak:8080/auth/;
|
||||
}
|
||||
|
||||
# Do not cache sw.js, required for offline-first updates.
|
||||
location /sw.js {
|
||||
add_header Cache-Control "no-cache";
|
||||
proxy_cache_bypass $http_pragma;
|
||||
proxy_cache_revalidate on;
|
||||
expires off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Single Page App
|
||||
# Try files, fallback to index.html
|
||||
#
|
||||
location / {
|
||||
alias /var/www/html/;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||
}
|
||||
|
||||
# EXAMPLE: Reverse Proxy, no auth
|
||||
# [UNPROTECTED] reverse proxy for `orthanc`
|
||||
#
|
||||
# location /pacs/ {
|
||||
# proxy_set_header X-Real-IP $remote_addr;
|
||||
# proxy_set_header X-Forwarded-For $remote_addr;
|
||||
# proxy_set_header Host $host;
|
||||
#
|
||||
# proxy_pass http://orthanc:8042/;
|
||||
#
|
||||
# # OR
|
||||
# # rewrite ^/pacs(.*) /$1 break;
|
||||
# # proxy_pass http://orthanc:8042;
|
||||
# }
|
||||
|
||||
# EXAMPLE: Modifying headers to allow requests from other domains
|
||||
# IE. Updating CORS settings
|
||||
#
|
||||
# location / {
|
||||
# if ($request_method = 'OPTIONS') {
|
||||
# add_header 'Access-Control-Allow-Origin' '*';
|
||||
# add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
# #
|
||||
# # Custom headers and headers various browsers *should* be OK with but aren't
|
||||
# #
|
||||
# add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
# #
|
||||
# # Tell client that this pre-flight info is valid for 20 days
|
||||
# #
|
||||
# add_header 'Access-Control-Allow-Headers' 'Authorization';
|
||||
# add_header 'Access-Control-Allow-Credentials' true;
|
||||
# add_header 'Access-Control-Max-Age' 1728000;
|
||||
# add_header 'Content-Length' 0;
|
||||
# return 204;
|
||||
# }
|
||||
# if ($request_method = 'POST') {
|
||||
# add_header 'Access-Control-Allow-Origin' '*';
|
||||
# add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
# add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
# add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||
# }
|
||||
# if ($request_method = 'GET') {
|
||||
# add_header 'Access-Control-Allow-Origin' '*';
|
||||
# add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
# add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
# add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||
# add_header 'Access-Control-Allow-Headers' 'Authorization';
|
||||
# add_header 'Access-Control-Allow-Credentials' true;
|
||||
# }
|
||||
#
|
||||
# # proxy_http_version 1.1;
|
||||
#
|
||||
# # proxy_set_header Host $host;
|
||||
# # proxy_set_header X-Real-IP $remote_addr;
|
||||
# # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# # proxy_set_header X-Forwarded-Proto $scheme;
|
||||
#
|
||||
# proxy_pass http://orthanc:8042;
|
||||
# }
|
||||
|
||||
# EXAMPLE: Redirect server error pages to the static page /40x.html
|
||||
#
|
||||
# error_page 404 /404.html;
|
||||
# location = /40x.html {
|
||||
# }
|
||||
|
||||
# EXAMPLE: Redirect server error pages to the static page /50x.html
|
||||
#
|
||||
# error_page 500 502 503 504 /50x.html;
|
||||
# location = /50x.html {
|
||||
# }
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"Name": "Orthanc inside Docker",
|
||||
"StorageDirectory": "/var/lib/orthanc/db",
|
||||
"IndexDirectory": "/var/lib/orthanc/db",
|
||||
"StorageCompression": false,
|
||||
"MaximumStorageSize": 0,
|
||||
"MaximumPatientCount": 0,
|
||||
"LuaScripts": [],
|
||||
"Plugins": ["/usr/share/orthanc/plugins", "/usr/local/share/orthanc/plugins"],
|
||||
"ConcurrentJobs": 2,
|
||||
"HttpServerEnabled": true,
|
||||
"HttpPort": 8042,
|
||||
"HttpDescribeErrors": true,
|
||||
"HttpCompressionEnabled": true,
|
||||
"DicomServerEnabled": true,
|
||||
"DicomAet": "ORTHANC",
|
||||
"DicomCheckCalledAet": false,
|
||||
"DicomPort": 4242,
|
||||
"DefaultEncoding": "Latin1",
|
||||
"DeflatedTransferSyntaxAccepted": true,
|
||||
"JpegTransferSyntaxAccepted": true,
|
||||
"Jpeg2000TransferSyntaxAccepted": true,
|
||||
"JpegLosslessTransferSyntaxAccepted": true,
|
||||
"JpipTransferSyntaxAccepted": true,
|
||||
"Mpeg2TransferSyntaxAccepted": true,
|
||||
"RleTransferSyntaxAccepted": true,
|
||||
"UnknownSopClassAccepted": false,
|
||||
"DicomScpTimeout": 30,
|
||||
|
||||
"RemoteAccessAllowed": true,
|
||||
"SslEnabled": false,
|
||||
"SslCertificate": "certificate.pem",
|
||||
"AuthenticationEnabled": false,
|
||||
"RegisteredUsers": {
|
||||
"test": "test"
|
||||
},
|
||||
"DicomModalities": {},
|
||||
"DicomModalitiesInDatabase": false,
|
||||
"DicomAlwaysAllowEcho": true,
|
||||
"DicomAlwaysAllowStore": true,
|
||||
"DicomCheckModalityHost": false,
|
||||
"DicomScuTimeout": 10,
|
||||
"OrthancPeers": {},
|
||||
"OrthancPeersInDatabase": false,
|
||||
"HttpProxy": "",
|
||||
|
||||
"HttpVerbose": true,
|
||||
|
||||
"HttpTimeout": 10,
|
||||
"HttpsVerifyPeers": true,
|
||||
"HttpsCACertificates": "",
|
||||
"UserMetadata": {},
|
||||
"UserContentType": {},
|
||||
"StableAge": 60,
|
||||
"StrictAetComparison": false,
|
||||
"StoreMD5ForAttachments": true,
|
||||
"LimitFindResults": 0,
|
||||
"LimitFindInstances": 0,
|
||||
"LimitJobs": 10,
|
||||
"LogExportedResources": false,
|
||||
"KeepAlive": true,
|
||||
"TcpNoDelay": true,
|
||||
"HttpThreadsCount": 50,
|
||||
"StoreDicom": true,
|
||||
"DicomAssociationCloseDelay": 5,
|
||||
"QueryRetrieveSize": 10,
|
||||
"CaseSensitivePN": false,
|
||||
"LoadPrivateDictionary": true,
|
||||
"Dictionary": {},
|
||||
"SynchronousCMove": true,
|
||||
"JobsHistorySize": 10,
|
||||
"SaveJobs": true,
|
||||
"OverwriteInstances": false,
|
||||
"MediaArchiveSize": 1,
|
||||
"StorageAccessOnFind": "Always",
|
||||
"MetricsEnabled": true,
|
||||
|
||||
"DicomWeb": {
|
||||
"Enable": true,
|
||||
"Root": "/dicom-web/",
|
||||
"EnableWado": true,
|
||||
"WadoRoot": "/wado",
|
||||
"Host": "127.0.0.1",
|
||||
"Ssl": false,
|
||||
"StowMaxInstances": 10,
|
||||
"StowMaxSize": 10,
|
||||
"QidoCaseSensitive": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
# Reference:
|
||||
# - https://docs.docker.com/compose/compose-file
|
||||
# - https://eclipsesource.com/blogs/2018/01/11/authenticating-reverse-proxy-with-keycloak/
|
||||
|
||||
version: '3.5'
|
||||
|
||||
services:
|
||||
# Exposed server that's handling incoming web requests
|
||||
# Underlying image: openresty/openresty:alpine-fat
|
||||
ohif_viewer:
|
||||
build:
|
||||
# Project root
|
||||
context: ./../../
|
||||
# Relative to context
|
||||
dockerfile: ./docker/OpenResty-Orthanc-Keycloak/dockerfile
|
||||
image: webapp:latest
|
||||
container_name: webapp
|
||||
volumes:
|
||||
# Nginx config
|
||||
- ./config/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf:ro
|
||||
# Logs
|
||||
- ./logs/nginx:/var/logs/nginx
|
||||
# Let's Encrypt
|
||||
# - letsencrypt_certificates:/etc/letsencrypt
|
||||
# - letsencrypt_challenges:/var/www/letsencrypt
|
||||
ports:
|
||||
- '443:443' # SSL
|
||||
- '80:80' # Web
|
||||
depends_on:
|
||||
- keycloak
|
||||
- orthanc
|
||||
restart: on-failure
|
||||
|
||||
# LINK: https://hub.docker.com/r/jodogne/orthanc-plugins/
|
||||
# TODO: Update to use Postgres
|
||||
# https://github.com/mrts/docker-postgresql-multiple-databases
|
||||
orthanc:
|
||||
image: jodogne/orthanc-plugins:1.5.6
|
||||
hostname: orthanc
|
||||
container_name: orthanc
|
||||
volumes:
|
||||
# Config
|
||||
- ./config/orthanc.json:/etc/orthanc/orthanc.json:ro
|
||||
# Persist data
|
||||
- ./volumes/orthanc-db/:/var/lib/orthanc/db/
|
||||
restart: unless-stopped
|
||||
|
||||
# LINK: https://hub.docker.com/r/jboss/keycloak
|
||||
keycloak:
|
||||
image: jboss/keycloak:6.0.1
|
||||
hostname: keycloak
|
||||
container_name: keycloak
|
||||
volumes:
|
||||
# Theme: https://www.keycloak.org/docs/latest/server_development/index.html#_themes
|
||||
- ./volumes/keycloak-themes/ohif:/opt/jboss/keycloak/themes/ohif
|
||||
# Previous Realm Config
|
||||
- ./config/ohif-keycloak-realm.json:/tmp/ohif-keycloak-realm.json
|
||||
environment:
|
||||
# Database
|
||||
DB_VENDOR: postgres
|
||||
DB_ADDR: postgres
|
||||
DB_PORT: 5432
|
||||
DB_DATABASE: keycloak
|
||||
DB_SCHEMA: public
|
||||
DB_USER: keycloak
|
||||
DB_PASSWORD: password
|
||||
# Keycloak
|
||||
KEYCLOAK_USER: admin
|
||||
KEYCLOAK_PASSWORD: password
|
||||
KEYCLOAK_IMPORT: /tmp/ohif-keycloak-realm.json
|
||||
# KEYCLOAK_WELCOME_THEME: <theme-name>
|
||||
# KEYCLOAK_DEFAULT_THEME: <theme-name>
|
||||
# KEYCLOAK_HOSTNAME: (recommended in prod)
|
||||
# KEYCLOAK_LOGLEVEL: DEBUG
|
||||
PROXY_ADDRESS_FORWARDING: 'true'
|
||||
depends_on:
|
||||
- postgres
|
||||
restart: unless-stopped
|
||||
|
||||
# LINK: https://hub.docker.com/_/postgres/
|
||||
postgres:
|
||||
image: postgres:11.2
|
||||
hostname: postgres
|
||||
container_name: postgres
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
environment:
|
||||
POSTGRES_DB: keycloak
|
||||
POSTGRES_USER: keycloak
|
||||
POSTGRES_PASSWORD: password
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
driver: local
|
||||
@@ -0,0 +1,65 @@
|
||||
# docker-compose
|
||||
# --------------
|
||||
# This dockerfile is used by the `docker-compose.yml` adjacent file. When
|
||||
# running `docker-compose build`, this dockerfile helps build the "webapp" image.
|
||||
# All paths are relative to the `context`, which is the project root directory.
|
||||
#
|
||||
# docker build
|
||||
# --------------
|
||||
# If you would like to use this dockerfile to build and tag an image, make sure
|
||||
# you set the context to the project's root directory:
|
||||
# https://docs.docker.com/engine/reference/commandline/build/
|
||||
#
|
||||
#
|
||||
# SUMMARY
|
||||
# --------------
|
||||
# This dockerfile has two stages:
|
||||
#
|
||||
# 1. Building the React application for production
|
||||
# 2. Setting up our Nginx (OpenResty*) image w/ step one's output
|
||||
#
|
||||
# * OpenResty is functionally identical to Nginx with the addition of Lua out of
|
||||
# the box.
|
||||
|
||||
|
||||
# Stage 1: Build the application
|
||||
FROM node:11.2.0-slim as builder
|
||||
|
||||
RUN mkdir /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
ENV REACT_APP_CONFIG=config/docker_openresty-orthanc-keycloak.js
|
||||
ENV PATH /usr/src/app/node_modules/.bin:$PATH
|
||||
|
||||
COPY package.json /usr/src/app/package.json
|
||||
COPY yarn.lock /usr/src/app/yarn.lock
|
||||
|
||||
ADD . /usr/src/app/
|
||||
RUN yarn install
|
||||
RUN yarn run build:web
|
||||
|
||||
# Stage 2: Bundle the built application into a Docker container
|
||||
# which runs openresty (nginx) using Alpine Linux
|
||||
# LINK: https://hub.docker.com/r/openresty/openresty
|
||||
FROM openresty/openresty:1.15.8.1rc1-0-alpine-fat
|
||||
|
||||
RUN mkdir /var/log/nginx
|
||||
RUN apk add --no-cache openssl
|
||||
RUN apk add --no-cache openssl-dev
|
||||
RUN apk add --no-cache git
|
||||
RUN apk add --no-cache gcc
|
||||
# !!!
|
||||
RUN luarocks install lua-resty-openidc
|
||||
|
||||
#
|
||||
RUN luarocks install lua-resty-jwt
|
||||
RUN luarocks install lua-resty-session
|
||||
RUN luarocks install lua-resty-http
|
||||
# !!!
|
||||
RUN luarocks install lua-resty-openidc
|
||||
RUN luarocks install luacrypto
|
||||
|
||||
# Copy build output to image
|
||||
COPY --from=builder /usr/src/app/build /var/www/html
|
||||
|
||||
ENTRYPOINT ["/usr/local/openresty/nginx/sbin/nginx", "-g", "daemon off;"]
|
||||
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
+212
@@ -0,0 +1,212 @@
|
||||
body {
|
||||
background-color: #040507;
|
||||
background-image: url('../img/background.jpg');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
|
||||
color: #fff;
|
||||
font-family: sans-serif;
|
||||
text-shadow: 0px 0px 10px #000;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div#kc-content {
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
left: 50%;
|
||||
width: 550px;
|
||||
margin-left: -180px;
|
||||
}
|
||||
|
||||
div#kc-form {
|
||||
float: left;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
div#kc-form label {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
div#info-area {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin-top: 40px;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div#info-area p {
|
||||
margin-right: 30px;
|
||||
display: inline;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
input[type='text'],
|
||||
input[type='password'] {
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
margin-bottom: 20px;
|
||||
background-color: rgba(256, 256, 256, 0.7);
|
||||
border: 0px solid rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 0 0 2px 2px rgba(0, 0, 0, 0.15);
|
||||
padding: 10px;
|
||||
width: 296px;
|
||||
}
|
||||
|
||||
input[type='text']:hover,
|
||||
input[type='password']:hover {
|
||||
background-color: rgba(256, 256, 256, 0.9);
|
||||
}
|
||||
|
||||
input[type='submit'] {
|
||||
border: none;
|
||||
|
||||
background: -webkit-linear-gradient(
|
||||
top,
|
||||
rgba(255, 255, 255, 0.8),
|
||||
rgba(255, 255, 255, 0.1)
|
||||
);
|
||||
background: -moz-linear-gradient(
|
||||
top,
|
||||
rgba(255, 255, 255, 0.8),
|
||||
rgba(255, 255, 255, 0.1)
|
||||
);
|
||||
background: -ms-linear-gradient(
|
||||
top,
|
||||
rgba(255, 255, 255, 0.8),
|
||||
rgba(255, 255, 255, 0.1)
|
||||
);
|
||||
background: -o-linear-gradient(
|
||||
top,
|
||||
rgba(255, 255, 255, 0.8),
|
||||
rgba(255, 255, 255, 0.1)
|
||||
);
|
||||
|
||||
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.5);
|
||||
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
|
||||
padding: 10px;
|
||||
margin-top: 20px;
|
||||
margin-right: 10px;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
input[type='submit']:hover {
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
div#kc-form-options div {
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
div#kc-form-options div label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
div#kc-feedback {
|
||||
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.5);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div#kc-feedback-wrapper {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
div.feedback-success {
|
||||
background-color: rgba(155, 155, 255, 0.1);
|
||||
}
|
||||
|
||||
div.feedback-warning {
|
||||
background-color: rgba(255, 175, 0, 0.1);
|
||||
}
|
||||
|
||||
div.feedback-error {
|
||||
background-color: rgba(255, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
div#kc-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div#kc-registration {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
div#social-login {
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.2);
|
||||
float: right;
|
||||
width: 150px;
|
||||
padding: 20px 0 200px 40px;
|
||||
}
|
||||
|
||||
div.social-login span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div#kc-social-providers ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div#kc-social-providers ul li {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
div#kc-social-providers ul li span {
|
||||
display: inline;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
a.zocial {
|
||||
border: none;
|
||||
background: -webkit-linear-gradient(
|
||||
top,
|
||||
rgba(255, 255, 255, 0.8),
|
||||
rgba(255, 255, 255, 0.1)
|
||||
) !important;
|
||||
background: -moz-linear-gradient(
|
||||
top,
|
||||
rgba(255, 255, 255, 0.8),
|
||||
rgba(255, 255, 255, 0.1)
|
||||
) !important;
|
||||
background: -ms-linear-gradient(
|
||||
top,
|
||||
rgba(255, 255, 255, 0.8),
|
||||
rgba(255, 255, 255, 0.1)
|
||||
) !important;
|
||||
background: -o-linear-gradient(
|
||||
top,
|
||||
rgba(255, 255, 255, 0.8),
|
||||
rgba(255, 255, 255, 0.1)
|
||||
) !important;
|
||||
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.5);
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
width: 130px;
|
||||
text-shadow: none;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 3.0 MiB |
+3
@@ -0,0 +1,3 @@
|
||||
parent=base
|
||||
import=common/keycloak
|
||||
styles=lib/zocial/zocial.css css/styles.css
|
||||
Whitespace-only changes.
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -0,0 +1,16 @@
|
||||
# Output
|
||||
dist/
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
# Root
|
||||
README.md
|
||||
Dockerfile
|
||||
|
||||
# Misc. Config
|
||||
.git
|
||||
.DS_Store
|
||||
.gitignore
|
||||
.vscode
|
||||
.circleci
|
||||
@@ -0,0 +1,5 @@
|
||||
# Docker ENV and ARG Variables
|
||||
# ----------------------------
|
||||
# https://vsupalov.com/docker-arg-env-variable-guide/
|
||||
#
|
||||
#
|
||||
@@ -0,0 +1,135 @@
|
||||
worker_processes 2;
|
||||
error_log /var/logs/nginx/mydomain.error.log;
|
||||
pid /var/run/nginx.pid;
|
||||
include /usr/share/nginx/modules/*.conf; # See /usr/share/doc/nginx/README.dynamic.
|
||||
|
||||
events {
|
||||
worker_connections 1024; ## Default: 1024
|
||||
use epoll; # http://nginx.org/en/docs/events.html
|
||||
multi_accept on; # http://nginx.org/en/docs/ngx_core_module.html#multi_accept
|
||||
}
|
||||
|
||||
# Core Modules Docs:
|
||||
# http://nginx.org/en/docs/http/ngx_http_core_module.html
|
||||
http {
|
||||
include '/usr/local/openresty/nginx/conf/mime.types';
|
||||
default_type application/octet-stream;
|
||||
|
||||
keepalive_timeout 65;
|
||||
keepalive_requests 100000;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
|
||||
# lua_ settings
|
||||
#
|
||||
lua_package_path '/usr/local/openresty/lualib/?.lua;;';
|
||||
lua_shared_dict discovery 1m; # cache for discovery metadata documents
|
||||
lua_shared_dict jwks 1m; # cache for JWKs
|
||||
# lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
|
||||
|
||||
variables_hash_max_size 2048;
|
||||
server_names_hash_bucket_size 128;
|
||||
server_tokens off;
|
||||
|
||||
resolver 8.8.8.8 valid=30s ipv6=off;
|
||||
resolver_timeout 11s;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
# Nginx `listener` block
|
||||
server {
|
||||
listen [::]:80 default_server;
|
||||
listen 80;
|
||||
# listen 443 ssl;
|
||||
access_log /var/logs/nginx/mydomain.access.log;
|
||||
|
||||
# Domain to protect
|
||||
server_name 127.0.0.1 localhost; # mydomain.com;
|
||||
proxy_intercept_errors off;
|
||||
# ssl_certificate /etc/letsencrypt/live/mydomain.co.uk/fullchain.pem;
|
||||
# ssl_certificate_key /etc/letsencrypt/live/mydomain.co.uk/privkey.pem;
|
||||
gzip on;
|
||||
gzip_types text/css application/javascript application/json image/svg+xml;
|
||||
gzip_comp_level 9;
|
||||
etag on;
|
||||
|
||||
# https://github.com/bungle/lua-resty-session/issues/15
|
||||
set $session_check_ssi off;
|
||||
lua_code_cache off;
|
||||
set $session_secret Eeko7aeb6iu5Wohch9Loo1aitha0ahd1;
|
||||
set $session_storage cookie;
|
||||
|
||||
server_tokens off; # Hides server version num
|
||||
|
||||
# Reverse Proxy for `orthanc` admin
|
||||
#
|
||||
location /pacs-admin/ {
|
||||
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
expires 0;
|
||||
add_header Cache-Control private;
|
||||
|
||||
proxy_pass http://orthanc:8042/;
|
||||
}
|
||||
|
||||
# Reverse Proxy for `orthanc` APIs (including DICOMWeb)
|
||||
#
|
||||
location /pacs/ {
|
||||
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
expires 0;
|
||||
add_header Cache-Control private;
|
||||
|
||||
proxy_pass http://orthanc:8042/;
|
||||
|
||||
# By default, this endpoint is protected by CORS (cross-origin-resource-sharing)
|
||||
# You can add headers to allow other domains to request this resource.
|
||||
# See the "Updating CORS Settings" example below
|
||||
}
|
||||
|
||||
# Do not cache sw.js, required for offline-first updates.
|
||||
location /sw.js {
|
||||
add_header Cache-Control "no-cache";
|
||||
proxy_cache_bypass $http_pragma;
|
||||
proxy_cache_revalidate on;
|
||||
expires off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Single Page App
|
||||
# Try files, fallback to index.html
|
||||
#
|
||||
location / {
|
||||
alias /var/www/html/;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||
}
|
||||
|
||||
# EXAMPLE: Redirect server error pages to the static page /40x.html
|
||||
#
|
||||
# error_page 404 /404.html;
|
||||
# location = /40x.html {
|
||||
# }
|
||||
|
||||
# EXAMPLE: Redirect server error pages to the static page /50x.html
|
||||
#
|
||||
# error_page 500 502 503 504 /50x.html;
|
||||
# location = /50x.html {
|
||||
# }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"Name": "Orthanc inside Docker",
|
||||
"StorageDirectory": "/var/lib/orthanc/db",
|
||||
"IndexDirectory": "/var/lib/orthanc/db",
|
||||
"StorageCompression": false,
|
||||
"MaximumStorageSize": 0,
|
||||
"MaximumPatientCount": 0,
|
||||
"LuaScripts": [],
|
||||
"Plugins": ["/usr/share/orthanc/plugins", "/usr/local/share/orthanc/plugins"],
|
||||
"ConcurrentJobs": 2,
|
||||
"HttpServerEnabled": true,
|
||||
"HttpPort": 8042,
|
||||
"HttpDescribeErrors": true,
|
||||
"HttpCompressionEnabled": true,
|
||||
"DicomServerEnabled": true,
|
||||
"DicomAet": "ORTHANC",
|
||||
"DicomCheckCalledAet": false,
|
||||
"DicomPort": 4242,
|
||||
"DefaultEncoding": "Latin1",
|
||||
"DeflatedTransferSyntaxAccepted": true,
|
||||
"JpegTransferSyntaxAccepted": true,
|
||||
"Jpeg2000TransferSyntaxAccepted": true,
|
||||
"JpegLosslessTransferSyntaxAccepted": true,
|
||||
"JpipTransferSyntaxAccepted": true,
|
||||
"Mpeg2TransferSyntaxAccepted": true,
|
||||
"RleTransferSyntaxAccepted": true,
|
||||
"UnknownSopClassAccepted": false,
|
||||
"DicomScpTimeout": 30,
|
||||
|
||||
"RemoteAccessAllowed": true,
|
||||
"SslEnabled": false,
|
||||
"SslCertificate": "certificate.pem",
|
||||
"AuthenticationEnabled": false,
|
||||
"RegisteredUsers": {
|
||||
"test": "test"
|
||||
},
|
||||
"DicomModalities": {},
|
||||
"DicomModalitiesInDatabase": false,
|
||||
"DicomAlwaysAllowEcho": true,
|
||||
"DicomAlwaysAllowStore": true,
|
||||
"DicomCheckModalityHost": false,
|
||||
"DicomScuTimeout": 10,
|
||||
"OrthancPeers": {},
|
||||
"OrthancPeersInDatabase": false,
|
||||
"HttpProxy": "",
|
||||
|
||||
"HttpVerbose": true,
|
||||
|
||||
"HttpTimeout": 10,
|
||||
"HttpsVerifyPeers": true,
|
||||
"HttpsCACertificates": "",
|
||||
"UserMetadata": {},
|
||||
"UserContentType": {},
|
||||
"StableAge": 60,
|
||||
"StrictAetComparison": false,
|
||||
"StoreMD5ForAttachments": true,
|
||||
"LimitFindResults": 0,
|
||||
"LimitFindInstances": 0,
|
||||
"LimitJobs": 10,
|
||||
"LogExportedResources": false,
|
||||
"KeepAlive": true,
|
||||
"TcpNoDelay": true,
|
||||
"HttpThreadsCount": 50,
|
||||
"StoreDicom": true,
|
||||
"DicomAssociationCloseDelay": 5,
|
||||
"QueryRetrieveSize": 10,
|
||||
"CaseSensitivePN": false,
|
||||
"LoadPrivateDictionary": true,
|
||||
"Dictionary": {},
|
||||
"SynchronousCMove": true,
|
||||
"JobsHistorySize": 10,
|
||||
"SaveJobs": true,
|
||||
"OverwriteInstances": false,
|
||||
"MediaArchiveSize": 1,
|
||||
"StorageAccessOnFind": "Always",
|
||||
"MetricsEnabled": true,
|
||||
|
||||
"DicomWeb": {
|
||||
"Enable": true,
|
||||
"Root": "/dicom-web/",
|
||||
"EnableWado": true,
|
||||
"WadoRoot": "/wado",
|
||||
"Host": "127.0.0.1",
|
||||
"Ssl": false,
|
||||
"StowMaxInstances": 10,
|
||||
"StowMaxSize": 10,
|
||||
"QidoCaseSensitive": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# Reference:
|
||||
# - https://docs.docker.com/compose/compose-file
|
||||
# - https://eclipsesource.com/blogs/2018/01/11/authenticating-reverse-proxy-with-keycloak/
|
||||
|
||||
version: '3.5'
|
||||
|
||||
services:
|
||||
# Exposed server that's handling incoming web requests
|
||||
# Underlying image: openresty/openresty:alpine-fat
|
||||
ohif_viewer:
|
||||
build:
|
||||
# Project root
|
||||
context: ./../../
|
||||
# Relative to context
|
||||
dockerfile: ./docker/OpenResty-Orthanc/dockerfile
|
||||
image: webapp:latest
|
||||
container_name: webapp
|
||||
volumes:
|
||||
# Nginx config
|
||||
- ./config/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf:ro
|
||||
# Logs
|
||||
- ./logs/nginx:/var/logs/nginx
|
||||
# Let's Encrypt
|
||||
# - letsencrypt_certificates:/etc/letsencrypt
|
||||
# - letsencrypt_challenges:/var/www/letsencrypt
|
||||
ports:
|
||||
- '443:443' # SSL
|
||||
- '80:80' # Web
|
||||
depends_on:
|
||||
- orthanc
|
||||
restart: on-failure
|
||||
|
||||
# LINK: https://hub.docker.com/r/jodogne/orthanc-plugins/
|
||||
# TODO: Update to use Postgres
|
||||
# https://github.com/mrts/docker-postgresql-multiple-databases
|
||||
orthanc:
|
||||
image: jodogne/orthanc-plugins:1.5.6
|
||||
hostname: orthanc
|
||||
container_name: orthanc
|
||||
volumes:
|
||||
# Config
|
||||
- ./config/orthanc.json:/etc/orthanc/orthanc.json:ro
|
||||
# Persist data
|
||||
- ./volumes/orthanc-db/:/var/lib/orthanc/db/
|
||||
restart: unless-stopped
|
||||
@@ -0,0 +1,65 @@
|
||||
# docker-compose
|
||||
# --------------
|
||||
# This dockerfile is used by the `docker-compose.yml` adjacent file. When
|
||||
# running `docker-compose build`, this dockerfile helps build the "webapp" image.
|
||||
# All paths are relative to the `context`, which is the project root directory.
|
||||
#
|
||||
# docker build
|
||||
# --------------
|
||||
# If you would like to use this dockerfile to build and tag an image, make sure
|
||||
# you set the context to the project's root directory:
|
||||
# https://docs.docker.com/engine/reference/commandline/build/
|
||||
#
|
||||
#
|
||||
# SUMMARY
|
||||
# --------------
|
||||
# This dockerfile has two stages:
|
||||
#
|
||||
# 1. Building the React application for production
|
||||
# 2. Setting up our Nginx (OpenResty*) image w/ step one's output
|
||||
#
|
||||
# * OpenResty is functionally identical to Nginx with the addition of Lua out of
|
||||
# the box.
|
||||
|
||||
|
||||
# Stage 1: Build the application
|
||||
FROM node:11.2.0-slim as builder
|
||||
|
||||
RUN mkdir /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
ENV REACT_APP_CONFIG=config/docker_openresty-orthanc.js
|
||||
ENV PATH /usr/src/app/node_modules/.bin:$PATH
|
||||
|
||||
COPY package.json /usr/src/app/package.json
|
||||
COPY yarn.lock /usr/src/app/yarn.lock
|
||||
|
||||
ADD . /usr/src/app/
|
||||
RUN yarn install
|
||||
RUN yarn run build:web
|
||||
|
||||
# Stage 2: Bundle the built application into a Docker container
|
||||
# which runs openresty (nginx) using Alpine Linux
|
||||
# LINK: https://hub.docker.com/r/openresty/openresty
|
||||
FROM openresty/openresty:1.15.8.1rc1-0-alpine-fat
|
||||
|
||||
RUN mkdir /var/log/nginx
|
||||
RUN apk add --no-cache openssl
|
||||
RUN apk add --no-cache openssl-dev
|
||||
RUN apk add --no-cache git
|
||||
RUN apk add --no-cache gcc
|
||||
# !!!
|
||||
RUN luarocks install lua-resty-openidc
|
||||
|
||||
#
|
||||
RUN luarocks install lua-resty-jwt
|
||||
RUN luarocks install lua-resty-session
|
||||
RUN luarocks install lua-resty-http
|
||||
# !!!
|
||||
RUN luarocks install lua-resty-openidc
|
||||
RUN luarocks install luacrypto
|
||||
|
||||
# Copy build output to image
|
||||
COPY --from=builder /usr/src/app/build /var/www/html
|
||||
|
||||
ENTRYPOINT ["/usr/local/openresty/nginx/sbin/nginx", "-g", "daemon off;"]
|
||||
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -0,0 +1,53 @@
|
||||
# Docker compose files
|
||||
|
||||
This folder contains docker-compose files used to spin up OHIF-Viewer with
|
||||
differnt options such as locally or with any PAS you desire to
|
||||
|
||||
## Public Server
|
||||
|
||||
#### build
|
||||
|
||||
`$ docker-compose -f docker-compose-publicserver.yml build`
|
||||
|
||||
#### run
|
||||
|
||||
`$ docker-compose -f docker-compose-publicserver.yml up -d`
|
||||
|
||||
then, access the application at [http://localhost](http://localhost)
|
||||
|
||||
## Local Orthanc
|
||||
|
||||
### Build
|
||||
|
||||
`$ docker-compose -f docker-compose-orthanc.yml build`
|
||||
|
||||
### Run
|
||||
|
||||
Starts containers and leaves them running in the background.
|
||||
|
||||
`$ docker-compose -f docker-compose-orthanc.yml up -d`
|
||||
|
||||
then, access the application at [http://localhost](http://localhost)
|
||||
|
||||
**remember that you have to access orthanc application and include your studies
|
||||
there**
|
||||
|
||||
## Local Dcm4chee
|
||||
|
||||
#### build
|
||||
|
||||
`$ docker-compose -f docker-compose-dcm4chee.yml build`
|
||||
|
||||
#### run
|
||||
|
||||
`$ docker-compose -f docker-compose-dcm4chee.yml up -d`
|
||||
|
||||
then, access the application at [http://localhost](http://localhost)
|
||||
|
||||
**remember that you have to access dcm4chee application and include your studies
|
||||
there** You can use the following command to import your studies into dcm4che
|
||||
|
||||
`$ docker run -v {YOUR_STUDY_FOLDER}:/tmp --rm --network=docker_dcm4che_default dcm4che/dcm4che-tools:5.14.0 storescu -cDCM4CHEE@arc:11112 /tmp`
|
||||
|
||||
**make sure that your Docker network name is docker_dcm4chee_default or change
|
||||
it to the right one**
|
||||
@@ -0,0 +1,12 @@
|
||||
server {
|
||||
listen 80;
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
# If CLIENT_ID is specified, use the google.js configuration with the modified ID
|
||||
if [ ! -z "$CLIENT_ID" ]
|
||||
then
|
||||
echo "Google Cloud Healthcare $CLIENT_ID has been provided: "
|
||||
echo $CLIENT_ID
|
||||
echo "Updating config..."
|
||||
|
||||
# - Use SED to replace the CLIENT_ID that is currently in public/config/google.js
|
||||
sed -i -e "s/YOURCLIENTID.apps.googleusercontent.com/$CLIENT_ID/g" /usr/share/nginx/html/config/google.js
|
||||
|
||||
# - Copy public/config/google.js to overwrite public/config/default.js
|
||||
cp /usr/share/nginx/html/config/google.js /usr/share/nginx/html/config/default.js
|
||||
fi
|
||||
|
||||
echo "Starting Nginx to serve the OHIF Viewer..."
|
||||
|
||||
exec "$@"
|
||||
Reference in new issue
Block a user