This commit is contained in:
mario
2025-03-07 13:47:44 +07:00
commit c4efec5a14
3358 changed files with 303774 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
logs/*
volumes/*
config/letsencrypt/*
config/certbot/*
!config/letsencrypt/.gitkeep
!config/certbot/.gitkeep

View File

@@ -0,0 +1,7 @@
#!/bin/sh
# Start oauth2-proxy
oauth2-proxy --config=/etc/oauth2-proxy/oauth2-proxy.cfg &
# Start nginx
nginx -g "daemon off;"

View File

@@ -0,0 +1,240 @@
worker_processes auto;
error_log /var/logs/nginx/error.log debug;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
include '/etc/nginx/mime.types';
default_type application/octet-stream;
keepalive_timeout 65;
keepalive_requests 100000;
tcp_nopush on;
tcp_nodelay on;
proxy_buffers 16 16k;
proxy_buffer_size 32k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 128k;
gzip on;
gzip_disable "msie6";
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
server {
listen 80;
server_name YOUR_DOMAIN;
client_max_body_size 0;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name YOUR_DOMAIN;
ssl_certificate /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem;
root /var/www/html;
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
gzip_comp_level 9;
etag on;
location /sw.js {
add_header Cache-Control "no-cache";
proxy_cache_bypass $http_pragma;
proxy_cache_revalidate on;
expires off;
access_log off;
}
location /oauth2 {
expires -1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Auth-Request-Redirect $request_uri;
proxy_pass http://localhost:4180$uri$is_args$args;
}
location /oauth2/callback {
proxy_pass http://localhost:4180;
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;
}
location /oauth2/sign_out {
expires -1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Auth-Request-Redirect /oauth2/sign_in;
proxy_pass http://localhost:4180;
}
location /pacs/ {
auth_request /oauth2/auth;
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;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Origin, X-Requested-With, Content-Type, Accept' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization, Origin, X-Requested-With, Content-Type, Accept';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
rewrite ^/pacs/(.*) /dcm4chee-arc/aets/DCM4CHEE/rs/$1 break;
proxy_pass http://arc:8080;
}
location /pacs-admin {
return 301 /pacs-admin/;
}
# Redirect /pacs-admin to /dcm4chee-arc/ui2/
location = /pacs-admin {
return 301 $scheme://$host/dcm4chee-arc/ui2/;
}
# Handle /pacs-admin/ requests
location /pacs-admin/ {
return 301 $scheme://$host/dcm4chee-arc/ui2/;
}
# Proxy pass for /dcm4chee-arc/ui2/
location /dcm4chee-arc/ui2/ {
error_page 401 = /oauth2/sign_in?rd=$scheme://$host$request_uri;
auth_request /oauth2/auth?allowed_groups=pacsadmin;
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $token $upstream_http_x_auth_request_access_token;
auth_request_set $auth_cookie $upstream_http_set_cookie;
proxy_set_header X-User $user;
proxy_set_header X-Access-Token $token;
add_header Set-Cookie $auth_cookie;
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;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Origin, X-Requested-With, Content-Type, Accept' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization, Origin, X-Requested-With, Content-Type, Accept';
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://arc:8080;
}
# Proxy pass for other /dcm4chee-arc/ requests
location /dcm4chee-arc/ {
proxy_pass http://arc:8080;
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;
}
location /pacs {
return 301 /pacs/;
}
location /ohif-viewer/ {
expires -1;
error_page 401 = /oauth2/sign_in?rd=$scheme://$host$request_uri;
auth_request /oauth2/auth;
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $token $upstream_http_x_auth_request_access_token;
auth_request_set $auth_cookie $upstream_http_set_cookie;
proxy_set_header X-User $user;
proxy_set_header X-Access-Token $token;
add_header Set-Cookie $auth_cookie;
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-Server $host;
proxy_set_header X-Forwarded-Proto $scheme;
index index.html;
try_files $uri $uri/ /index.html;
}
location /ohif-viewer {
return 301 /ohif-viewer/;
}
location = / {
return 301 /ohif-viewer/;
}
location / {
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header 'Cross-Origin-Opener-Policy' 'same-origin' always;
add_header 'Cross-Origin-Embedder-Policy' 'require-corp' always;
}
location /keycloak/ {
proxy_pass http://keycloak:8080/;
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;
}
location /keycloak {
return 301 /keycloak/;
}
}
}

View File

@@ -0,0 +1,22 @@
http_address="0.0.0.0:4180"
cookie_secret="GENERATEACOOKIESECRET----------------------="
email_domains=["*"]
cookie_secure="false"
cookie_expire="9m30s"
cookie_refresh="5m"
client_secret="2Xtlde7aozdkzzYHdIxQNfPDr0wNPTgg"
client_id="ohif_viewer"
redirect_url="http://YOUR_DOMAIN/oauth2/callback"
ssl_insecure_skip_verify = true
insecure_oidc_allow_unverified_email = true
pass_access_token = true
provider="keycloak-oidc"
provider_display_name="Keycloak"
user_id_claim="oid"
oidc_email_claim="sub"
scope="openid"
pass_host_header=true
code_challenge_method="S256"
oidc_issuer_url="http://YOUR_DOMAIN/keycloak/realms/ohif"
insecure_oidc_skip_issuer_verification = true

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
STORAGE_DIR=/storage/fs1
POSTGRES_DB=pacsdb
POSTGRES_USER=pacs
POSTGRES_PASSWORD=pacs

View File

@@ -0,0 +1,161 @@
version: '3.8'
services:
ldap:
image: dcm4che/slapd-dcm4chee:2.6.3-29.0
logging:
driver: json-file
options:
max-size: "10m"
ports:
- "389:389"
env_file: docker-compose.env
volumes:
- ~/dcm4chee-arc/ldap:/var/lib/ldap
- ~/dcm4chee-arc/slapd.d:/etc/ldap/slapd.d
db:
image: dcm4che/postgres-dcm4chee:14.5-29
logging:
driver: json-file
options:
max-size: "10m"
ports:
- "5432:5432"
env_file: docker-compose.env
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ~/dcm4chee-arc/db:/var/lib/postgresql/data
arc:
image: dcm4che/dcm4chee-arc-psql:5.29.0
logging:
driver: json-file
options:
max-size: "10m"
ports:
- "8080:8080"
- "8443:8443"
- "9990:9990"
- "9993:9993"
- "11112:11112"
- "2762:2762"
- "2575:2575"
- "12575:12575"
env_file: docker-compose.env
environment:
WILDFLY_CHOWN: /opt/wildfly/standalone /storage
WILDFLY_WAIT_FOR: ldap:389 db:5432
depends_on:
- ldap
- db
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ~/dcm4chee-arc/wildfly:/opt/wildfly/standalone
- ~/dcm4chee-arc/storage:/storage
ohif_viewer:
build:
context: ./../../../../
dockerfile: ./platform/app/.recipes/Nginx-Dcm4chee-Keycloak/dockerfile
image: webapp:latest
container_name: webapp
ports:
- '443:443' # SSL
- '80:80' # Web
depends_on:
keycloak:
condition: service_healthy
restart: on-failure
networks:
- default
extra_hosts:
- 'host.docker.internal:host-gateway'
environment:
- OAUTH2_PROXY_SKIP_PROVIDER_BUTTON=true
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
- ./config/oauth2-proxy.cfg:/etc/oauth2-proxy/oauth2-proxy.cfg
- ./config/letsencrypt:/etc/letsencrypt
- ./config/certbot:/var/www/certbot
keycloak:
image: quay.io/keycloak/keycloak:24.0.5
command: 'start-dev --import-realm'
hostname: keycloak
container_name: keycloak
volumes:
- ./config/ohif-keycloak-realm.json:/opt/keycloak/data/import/ohif-keycloak-realm.json
environment:
KC_DB_URL_HOST: postgres
KC_DB: postgres
KC_DB_URL: 'jdbc:postgresql://postgres:5432/keycloak'
KC_DB_SCHEMA: public
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: password
KC_HOSTNAME_ADMIN_URL: http://YOUR_DOMAIN/keycloak/
KC_HOSTNAME_URL: http://YOUR_DOMAIN/keycloak/
KC_HOSTNAME_STRICT_BACKCHANNEL: true
KC_HOSTNAME_STRICT_HTTPS: false
KC_HTTP_ENABLED: true
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_HEALTH_ENABLED: true
KC_METRICS_ENABLED: true
KC_PROXY: edge
KC_PROXY_HEADERS: xforwarded
KEYCLOAK_JDBC_PARAMS: connectTimeout=40000
KC_LOG_LEVEL: INFO
KC_HOSTNAME_DEBUG: true
PROXY_ADDRESS_FORWARDING: true
ports:
- 8081:8080
depends_on:
- postgres
restart: unless-stopped
networks:
- default
extra_hosts:
- 'host.docker.internal:host-gateway'
healthcheck:
test:
[
"CMD-SHELL",
"exec 3<>/dev/tcp/YOUR_DOMAIN/8080;echo -e \"GET /health/ready HTTP/1.1\r\nhost: http://localhost\r\nConnection: close\r\n\r\n\" >&3;grep \"HTTP/1.1 200 OK\" <&3"
]
interval: 1s
timeout: 5s
retries: 10
start_period: 60s
postgres:
image: postgres:15
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
networks:
- default
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./config/letsencrypt:/etc/letsencrypt
- ./config/certbot:/var/www/certbot
entrypoint: /bin/sh -c "trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;"
volumes:
postgres_data:
driver: local
networks:
default:
driver: bridge

View File

@@ -0,0 +1,50 @@
# Stage 1: Build the application
FROM node:18.16.1-slim as builder
# Setup the working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# Install dependencies
RUN apt-get update && apt-get install -y build-essential python3
# Copy the entire project
COPY ./ /usr/src/app/
# Install node dependencies
RUN yarn config set workspaces-experimental true
RUN yarn install
# Set the environment for the build
ENV APP_CONFIG=config/docker-nginx-dcm4chee-keycloak.js
# Build the application
RUN yarn run build
# Stage 2: Setup the NGINX environment with OAuth2 Proxy
FROM nginx:alpine
# Install dependencies for oauth2-proxy
RUN apk add --no-cache curl
# Create necessary directories
RUN mkdir -p /var/logs/nginx /var/www/html /etc/oauth2-proxy
# Download and install oauth2-proxy
RUN curl -L https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.4.0/oauth2-proxy-v7.4.0.linux-amd64.tar.gz -o oauth2-proxy.tar.gz && \
tar -xvzf oauth2-proxy.tar.gz && \
mv oauth2-proxy-v7.4.0.linux-amd64/oauth2-proxy /usr/local/bin/ && \
rm -rf oauth2-proxy-v7.4.0.linux-amd64 oauth2-proxy.tar.gz
# Copy the built application
COPY --from=builder /usr/src/app/platform/app/dist /var/www/html
# Copy the entrypoint script
COPY ./platform/app/.recipes/Nginx-Dcm4chee-Keycloak/config/entrypoint.sh /entrypoint.sh
# Expose necessary ports
EXPOSE 80 443 4180
# Set the entrypoint script as the entrypoint
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -0,0 +1 @@
America/New_York