diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4200da888..42ccbceb1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,6 +18,7 @@ env: REGISTRY: ghcr.io IMAGE_NAME_SBS: surfscz/sram-sbs IMAGE_NAME_SERVER: surfscz/sram-sbs-server + IMAGE_NAME_CLIENT: surfscz/sram-sbs-client jobs: Server_tests: @@ -317,8 +318,8 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - # The SBS image - - name: Extract metadata (tags, labels) for SBS image + # The SBS (apache) image + - name: Extract metadata (tags, labels) for SBS-server image id: meta-sbs uses: docker/metadata-action@v5 with: @@ -335,8 +336,8 @@ jobs: tags: ${{ steps.meta-sbs.outputs.tags }} labels: ${{ steps.meta-sbs.outputs.labels }} - # The SBS (apache) server image - - name: Extract metadata (tags, labels) for SBS-server image + # The SBS server image + - name: Extract metadata (tags, labels) for SBS image id: meta-sbs-server uses: docker/metadata-action@v5 with: @@ -353,6 +354,35 @@ jobs: tags: ${{ steps.meta-sbs-server.outputs.tags }} labels: ${{ steps.meta-sbs-server.outputs.labels }} + + # The SBS client image + - name: Extract metadata (tags, labels) for SBS-client image + id: meta-sbs-client + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_CLIENT }} + + - name: Build and push Docker SBS-client image + uses: docker/build-push-action@v5 + with: + context: "." + file: "Dockerfile.sbs-client" + pull: true + push: true + tags: ${{ steps.meta-sbs-client.outputs.tags }} + labels: ${{ steps.meta-sbs-client.outputs.labels }} + + # Setup tmate session + - name: Setup tmate session + env: + ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG}} + if: ${{ failure() && env.ACTIONS_STEP_DEBUG == 'true' }} + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + timeout-minutes: 60 + Schema_pr: name: Update schema cache diff --git a/Dockerfile.sbs b/Dockerfile.sbs index 9d050602b..0adb530d2 100644 --- a/Dockerfile.sbs +++ b/Dockerfile.sbs @@ -1,47 +1,19 @@ -# First build SRAM SBS image -FROM python:3.11-slim-bookworm AS sram-sbs +# Build SRAM SBS (apache) server image +FROM ghcr.io/openconext/openconext-basecontainers/apache2:latest AS sram-sbs-server # Do an initial clean up and general upgrade of the distribution ENV DEBIAN_FRONTEND noninteractive RUN apt clean && apt autoclean && apt update RUN apt -y upgrade && apt -y dist-upgrade -# Install the packages we need -RUN apt install -y curl \ - git \ - build-essential \ - pkgconf \ - python3-dev \ - default-libmysqlclient-dev \ - libxmlsec1-dev - # Clean up RUN apt autoremove -y && apt clean && apt autoclean && rm -rf /var/lib/apt/lists/* -# Set the default workdir -WORKDIR /opt - -# Install SBS -COPY sbs.tar.xz /opt/sbs.tar.xz - -# Untar sbs -RUN tar -Jxf sbs.tar.xz - -# Create venv dir -#RUN virtualenv /opt/sbs - -#RUN . /opt/sbs/bin/activate && \ -RUN pip install -r /opt/sbs/server/requirements/test.txt - -# Copy entrypoint -COPY misc/entrypoint.sh /entrypoint.sh -RUN chmod 755 /entrypoint.sh +RUN rm -f /etc/apache2/sites-enabled/*.conf +COPY etc/apache-dev.conf /etc/apache2/sites-enabled/apache.conf # Set the default workdir -WORKDIR /opt/sbs - -EXPOSE 8080 +WORKDIR /opt -ENTRYPOINT ["/entrypoint.sh"] #CMD ["bash"] -CMD ["/usr/local/bin/gunicorn --worker-class eventlet --workers 8 --bind 0.0.0.0:8080 server.__main__:app"] + diff --git a/Dockerfile.sbs-client b/Dockerfile.sbs-client new file mode 100644 index 000000000..5baf2a2e3 --- /dev/null +++ b/Dockerfile.sbs-client @@ -0,0 +1,29 @@ +# Build SRAM SBS (apache) server image +FROM ghcr.io/openconext/openconext-basecontainers/apache2:latest AS sram-sbs-client + +# Do an initial clean up and general upgrade of the distribution +ENV DEBIAN_FRONTEND noninteractive +RUN apt clean && apt autoclean && apt update +RUN apt -y upgrade && apt -y dist-upgrade + +# Install the packages we need +RUN apt install -y xz-utils + +# Clean up +RUN apt autoremove -y && apt clean && apt autoclean && rm -rf /var/lib/apt/lists/* + +RUN rm -f /etc/apache2/sites-enabled/*.conf +COPY etc/apache.conf /etc/apache2/sites-enabled/apache.conf + +RUN a2enmod proxy_wstunnel + +# Set the default workdir +WORKDIR /opt + +# Install SBS +COPY sbs.tar.xz /opt/sbs.tar.xz + +# Untar sbs +RUN tar -Jxf sbs.tar.xz + +#CMD ["bash"] diff --git a/Dockerfile.sbs-server b/Dockerfile.sbs-server index 8f6b045d0..614a028cf 100644 --- a/Dockerfile.sbs-server +++ b/Dockerfile.sbs-server @@ -1,10 +1,47 @@ -# Build SRAM SBS (apache) server image -FROM ghcr.io/openconext/openconext-basecontainers/apache2:latest AS sram-sbs-server -RUN rm -f /etc/apache2/sites-enabled/*.conf -RUN a2enmod proxy_wstunnel +# First build SRAM SBS image +FROM python:3.11-slim-bookworm AS sram-sbs-server + +# Do an initial clean up and general upgrade of the distribution +ENV DEBIAN_FRONTEND noninteractive +RUN apt clean && apt autoclean && apt update +RUN apt -y upgrade && apt -y dist-upgrade + +# Install the packages we need +RUN apt install -y curl \ + git \ + build-essential \ + pkgconf \ + python3-dev \ + default-libmysqlclient-dev \ + libxmlsec1-dev + +# Clean up +RUN apt autoremove -y && apt clean && apt autoclean && rm -rf /var/lib/apt/lists/* # Set the default workdir WORKDIR /opt -#CMD ["bash"] +# Install SBS +COPY sbs.tar.xz /opt/sbs.tar.xz + +# Untar sbs +RUN tar -Jxf sbs.tar.xz + +# Create venv dir +#RUN virtualenv /opt/sbs +#RUN . /opt/sbs/bin/activate && \ +RUN pip install -r /opt/sbs/server/requirements/test.txt + +# Copy entrypoint +COPY misc/entrypoint.sh /entrypoint.sh +RUN chmod 755 /entrypoint.sh + +# Set the default workdir +WORKDIR /opt/sbs + +EXPOSE 8080 + +ENTRYPOINT ["/entrypoint.sh"] +#CMD ["bash"] +CMD ["/usr/local/bin/gunicorn --worker-class eventlet --workers 8 --bind 0.0.0.0:8080 server.__main__:app"] diff --git a/client/package.json b/client/package.json index 040c43981..f35948d6f 100644 --- a/client/package.json +++ b/client/package.json @@ -58,7 +58,7 @@ "ws": "^8.17.1" }, "scripts": { - "start": "DANGEROUSLY_DISABLE_HOST_CHECK=true GENERATE_SOURCEMAP=false HOST=localhost react-scripts start", + "start": "DANGEROUSLY_DISABLE_HOST_CHECK=true GENERATE_SOURCEMAP=false react-scripts start", "build": "DANGEROUSLY_DISABLE_HOST_CHECK=true GENERATE_SOURCEMAP=true react-scripts build", "test": "DANGEROUSLY_DISABLE_HOST_CHECK=true GENERATE_SOURCEMAP=false react-scripts test --transformIgnorePatterns 'node_modules/(?!i18n-js)/'", "analyze": "source-map-explorer build/static/js/main.*.js " diff --git a/docker-compose.yml b/docker-compose.yml index 8977676be..b7eef9e2f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ volumes: services: redis: - image: "docker.io/redis" + image: "redis" container_name: "sbs-redis" client: @@ -73,4 +73,5 @@ services: ports: - "8978:8978" volumes: - - "cloudbeaver:/opt/cloudbeaver/workspace" \ No newline at end of file + - "cloudbeaver:/opt/cloudbeaver/workspace" + diff --git a/etc/apache-dev.conf b/etc/apache-dev.conf new file mode 100644 index 000000000..91324db27 --- /dev/null +++ b/etc/apache-dev.conf @@ -0,0 +1,33 @@ +Listen 8080 + + ServerName sbs + DocumentRoot /var/www/html + + Header set Content-Security-Policy "default-src 'self'; base-uri 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-src 'none'; form-action 'self' https://*.dev.openconext.local; frame-ancestors 'none'; block-all-mixed-content;" + Header set Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(self), gamepad=(), speaker-selection=()" + + #RewriteEngine On + #RewriteCond %{REQUEST_URI} !^/(api|pam-weblogin|flasgger_static|swagger|health|config|info|socket.io) + #RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f + #RewriteRule ^/(.*)$ /index.html [L] + + ProxyRequests off + ProxyPassMatch ^/(api|pam-weblogin|flasgger_static|swagger|health|config|info) http://sbs-server:8080/ + ProxyPassReverse / http://sbs-server:8080/ + ProxyPass /socket.io/ ws://sbs-server:8080/socket.io/ + ProxyPassReverse /socket.io/ ws://sbs-server:8080/socket.io/ + ProxyPass / http://sbs-client:8080/ + ProxyPassReverse / http://sbs-client:8080/ + + + Header set Cache-Control: "public, max-age=31536000, immutable" + + + Header set Cache-Control: "no-cache, private" + + + + Require all granted + Options -Indexes + + diff --git a/etc/apache.conf b/etc/apache.conf index 22752c74a..640a553c2 100644 --- a/etc/apache.conf +++ b/etc/apache.conf @@ -1,23 +1,31 @@ -# ServerName {{ hostnames.sbs }} -#ErrorLog /proc/self/fd/2 -#CustomLog /proc/self/fd/1 common -DocumentRoot /var/www/html +Listen 8080 + + ServerName sbs + DocumentRoot /opt/sbs/client/build -# Header set Content-Security-Policy "default-src 'self'; base-uri 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-src 'none'; form-action 'self' https://*.{{ base_domain }}; frame-ancestors 'none'; block-all-mixed-content;" -# Header set Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(self), gamepad=(), speaker-selection=()" + Header set Content-Security-Policy "default-src 'self'; base-uri 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-src 'none'; form-action 'self' https://*.dev.openconext.local; frame-ancestors 'none'; block-all-mixed-content;" + Header set Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(self), gamepad=(), speaker-selection=()" -RewriteEngine On -RewriteCond %{REQUEST_URI} !^/(api|pam-weblogin|flasgger_static|swagger|health|config|info|socket.io) -RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f -RewriteRule ^/(.*)$ /index.html [L] + #RewriteEngine On + #RewriteCond %{REQUEST_URI} !^/(api|pam-weblogin|flasgger_static|swagger|health|config|info|socket.io) + #RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f + #RewriteRule ^/(.*)$ /index.html [L] -ProxyRequests off -ProxyPass /socket.io/ ws://server:8080/socket.io/ -ProxyPassReverse /socket.io/ ws://server:8080/socket.io/ -ProxyPassMatch ^/(api|pam-weblogin|flasgger_static|swagger|health|config|info) http://server:8080/ -ProxyPassReverse / http://server:8080/ + ProxyRequests off + ProxyPassMatch ^/(api|pam-weblogin|flasgger_static|swagger|health|config|info) http://sbs-server:8080/ + ProxyPassReverse / http://sbs-server:8080/ + ProxyPass /socket.io/ ws://sbs-server:8080/socket.io/ + ProxyPassReverse /socket.io/ ws://sbs-server:8080/socket.io/ - - Require all granted - Options -Indexes - + + Header set Cache-Control: "public, max-age=31536000, immutable" + + + Header set Cache-Control: "no-cache, private" + + + + Require all granted + Options -Indexes + + diff --git a/misc/entrypoint.sh b/misc/entrypoint.sh old mode 100644 new mode 100755 index e0141cce1..a2d12a8b4 --- a/misc/entrypoint.sh +++ b/misc/entrypoint.sh @@ -15,10 +15,10 @@ rm -f /opt/sbs/server/config/config.yml rm -f /opt/sbs/server/migrations/alembic.ini rm -f /opt/sbs/client/build/static/disclaimer.css rm -rf /opt/sbs/server/config/saml/saml -ln -s /opt/sbs/config/config.yml /opt/sbs/server/config/config.yml -ln -s /opt/sbs/config/alembic.ini /opt/sbs/server/migrations/alembic.ini -ln -s /opt/sbs/config/saml /opt/sbs/server/config/saml -cp /opt/sbs/config/disclaimer.css /opt/sbs/client/build/static/disclaimer.css +cp /opt/sbs/config/config.yml /opt/sbs/server/config/config.yml +cp /opt/sbs/config/alembic.ini /opt/sbs/server/migrations/alembic.ini +cp /opt/sbs/config/disclaimer.css /opt/sbs/client/build/static/disclaimer.css +cp -rf /opt/sbs/config/saml /opt/sbs/server/config if [ -e "/opt/sbs/cert/frontend.crt" ] then @@ -41,7 +41,6 @@ then echo "New id is $($PRIVDROP id -u):$($PRIVDROP id -g)" fi - cd /opt/sbs # Run migrations @@ -61,4 +60,4 @@ then fi # Hand off to the CMD -exec ${PRIVDROP} $@ \ No newline at end of file +exec ${PRIVDROP} $@ diff --git a/server/migrations/alembic.ini b/server/migrations/alembic.ini index 22bb24e88..361364763 100644 --- a/server/migrations/alembic.ini +++ b/server/migrations/alembic.ini @@ -35,7 +35,7 @@ script_location = migrations # are written from script.py.mako # output_encoding = utf-8 -sqlalchemy.url = mysql+mysqldb://sbs:sbs@127.0.0.1/sbs +sqlalchemy.url = mysql+mysqldb://sbs:secret@mariadb/sbs?charset=utf8mb4 # Logging configuration @@ -49,9 +49,8 @@ keys = console keys = generic [logger_root] -level = WARN +level = NOTSET handlers = console -qualname = [logger_sqlalchemy] level = WARN @@ -66,9 +65,9 @@ qualname = alembic [handler_console] class = StreamHandler args = (sys.stderr,) -level = NOTSET +level = DEBUG formatter = generic [formatter_generic] format = %(levelname)-5.5s [%(name)s] %(message)s -datefmt = %H:%M:%S \ No newline at end of file +datefmt = %H:%M:%S