diff --git a/docker-compose-example.yml b/docker-compose-example.yml index cd2ad84..464d257 100644 --- a/docker-compose-example.yml +++ b/docker-compose-example.yml @@ -20,9 +20,9 @@ services: environment: POSTGRES_PASSWORD: '' # TODO: Set your postgres password here! volumes: - - ./volumes/db:/var/lib/postgresql/docker + - ./volumes/db:/var/lib/postgresql/docker:z # NOTE: Remove this line if you don't want/need the demo data - - ./volumes/demo-data/setup-demo-data.sh:/docker-entrypoint-initdb.d/2_setup-demo-data.sh + - ./volumes/demo-data/setup-demo-data.sh:/docker-entrypoint-initdb.d/2_setup-demo-data.sh:z ports: - "127.0.0.1:5439:5432" healthcheck: @@ -32,9 +32,9 @@ services: qwc-config-db-migrate: image: sourcepole/qwc-base-db-migrate:latest-2025-lts volumes: - - ./pg_service.conf:/tmp/pg_service.conf:ro + - ./pg_service.conf:/tmp/pg_service.conf:ro,z # NOTE: Remove this line if you don't want/need the demo data - - ./volumes/demo-data/setup-demo-data-permissions.sh:/tmp/extra-init.d/setup-demo-data-permissions.sh + - ./volumes/demo-data/setup-demo-data-permissions.sh:/tmp/extra-init.d/setup-demo-data-permissions.sh:z qwc-qgis-server: image: sourcepole/qwc-qgis-server:3.40 @@ -65,13 +65,13 @@ services: # ports: # - "127.0.0.1:5010:9090" volumes: - - ./volumes/config-in:/srv/qwc_service/config-in:ro - - ./volumes/config:/srv/qwc_service/config-out - - ./volumes/qwc2:/qwc2 - - ./volumes/qgs-resources:/data - - ./volumes/print-layouts:/layouts:ro - - ./volumes/reports:/reports - - ./pg_service.conf:/srv/pg_service.conf:ro + - ./volumes/config-in:/srv/qwc_service/config-in:ro,z + - ./volumes/config:/srv/qwc_service/config-out:z + - ./volumes/qwc2:/qwc2:z + - ./volumes/qgs-resources:/data:z + - ./volumes/print-layouts:/layouts:ro,z + - ./volumes/reports:/reports:z + - ./pg_service.conf:/srv/pg_service.conf:ro,z qwc-admin-gui: image: sourcepole/qwc-admin-gui:latest-2025-lts @@ -88,8 +88,8 @@ services: MAIL_SUPPRESS_SEND: 'True' MAIL_DEFAULT_SENDER: 'from@example.com' volumes: - - ./pg_service.conf:/srv/pg_service.conf:ro - - ./volumes/config:/srv/qwc_service/config:ro + - ./pg_service.conf:/srv/pg_service.conf:ro,z + - ./volumes/config:/srv/qwc_service/config:ro,z # required by themes plugin: # - ./volumes/config-in:/srv/qwc_service/config-in:rw # - ./volumes/qwc2:/qwc2 @@ -113,8 +113,8 @@ services: # MAIL_PASSWORD: 'password1234' # MAIL_USE_SSL: 'True' volumes: - - ./pg_service.conf:/srv/pg_service.conf:ro - - ./volumes/config:/srv/qwc_service/config:ro + - ./pg_service.conf:/srv/pg_service.conf:ro,z + - ./volumes/config:/srv/qwc_service/config:ro,z qwc-data-service: image: sourcepole/qwc-data-service:latest-2025-lts @@ -124,9 +124,9 @@ services: ATTACHMENTS_BASE_DIR: '/attachments' MAX_ATTACHMENT_FILE_SIZE: 1048576 volumes: - - ./volumes/config:/srv/qwc_service/config:ro - - ./volumes/attachments:/attachments - - ./pg_service.conf:/srv/pg_service.conf:ro + - ./volumes/config:/srv/qwc_service/config:ro,z + - ./volumes/attachments:/attachments:z + - ./pg_service.conf:/srv/pg_service.conf:ro,z # NOTE: you can mount a pg_service-write.conf with R/W DB users and have R/O DB users in the main pg_service.conf # - ./pg_service-write.conf:/srv/pg_service.conf:ro @@ -140,10 +140,10 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/api/v1/document' volumes: - - ./pg_service.conf:/srv/pg_service.conf:ro - - ./volumes/reports:/reports - - ./volumes/reports/fonts:/srv/qwc_service/fonts - - ./volumes/config:/srv/qwc_service/config:ro + - ./pg_service.conf:/srv/pg_service.conf:ro,z + - ./volumes/reports:/reports:z + - ./volumes/reports/fonts:/srv/qwc_service/fonts:z + - ./volumes/config:/srv/qwc_service/config:ro,z qwc-elevation-service: image: sourcepole/qwc-elevation-service:latest-2025-lts @@ -151,7 +151,7 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/api/v1/elevation' volumes: - - ./volumes/config:/srv/qwc_service/config:ro + - ./volumes/config:/srv/qwc_service/config:ro,z qwc-feature-info-service: image: sourcepole/qwc-feature-info-service:latest-2025-lts @@ -159,9 +159,9 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/api/v1/featureinfo' volumes: - - ./pg_service.conf:/srv/pg_service.conf:ro - - ./volumes/config:/srv/qwc_service/config:ro - - ./volumes/info-templates:/info_templates:ro + - ./pg_service.conf:/srv/pg_service.conf:ro,z + - ./volumes/config:/srv/qwc_service/config:ro,z + - ./volumes/info-templates:/info_templates:ro,z qwc-fulltext-search-service: image: sourcepole/qwc-fulltext-search-service:latest-2025-lts @@ -169,8 +169,8 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/api/v2/search' volumes: - - ./pg_service.conf:/srv/pg_service.conf:ro - - ./volumes/config:/srv/qwc_service/config:ro + - ./pg_service.conf:/srv/pg_service.conf:ro,z + - ./volumes/config:/srv/qwc_service/config:ro,z qwc-solr: image: solr:8.11-slim @@ -182,10 +182,10 @@ services: ports: - "127.0.0.1:8983:8983" volumes: - - ./volumes/solr/configsets/gdi:/gdi_conf:ro + - ./volumes/solr/configsets/gdi:/gdi_conf:ro,z # Configuration is copied once from /gdi_conf/ to /var/solr/data/ # Change ownership to solr user with `sudo chown 8983:8983 volumes/solr/data` - - ./volumes/solr/data:/var/solr/data + - ./volumes/solr/data:/var/solr/data:z # Protect admin GUI and admin API with Basic auth # Change "#credentials" to "credentials" in security.json for adding a user 'solr' with password 'SolrRocks' #- ./volumes/solr/security.json:/var/solr/data/security.json:ro @@ -196,8 +196,8 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/api/v1/legend' volumes: - - ./volumes/config:/srv/qwc_service/config:ro - - ./volumes/legends:/legends + - ./volumes/config:/srv/qwc_service/config:ro,z + - ./volumes/legends:/legends:z qwc-mapinfo-service: image: sourcepole/qwc-mapinfo-service:latest-2025-lts @@ -205,8 +205,8 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/api/v1/mapinfo' volumes: - - ./pg_service.conf:/srv/pg_service.conf:ro - - ./volumes/config:/srv/qwc_service/config:ro + - ./pg_service.conf:/srv/pg_service.conf:ro,z + - ./volumes/config:/srv/qwc_service/config:ro,z qwc-map-viewer: # Stock qwc2 app @@ -217,10 +217,10 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/' volumes: - - ./pg_service.conf:/srv/pg_service.conf:ro - - ./volumes/config:/srv/qwc_service/config:ro + - ./pg_service.conf:/srv/pg_service.conf:ro,z + - ./volumes/config:/srv/qwc_service/config:ro,z # When using qwc-map-viewer: - - ./volumes/qwc2/assets:/qwc2/assets:ro + - ./volumes/qwc2/assets:/qwc2/assets:ro,z # When using own viewer build with qwc-map-viewer-base: #- ./volumes/qwc2:/qwc2:ro @@ -230,7 +230,7 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/ows' volumes: - - ./volumes/config:/srv/qwc_service/config:ro + - ./volumes/config:/srv/qwc_service/config:ro,z qwc-permalink-service: image: sourcepole/qwc-permalink-service:latest-2025-lts @@ -238,8 +238,8 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/api/v1/permalink' volumes: - - ./pg_service.conf:/srv/pg_service.conf:ro - - ./volumes/config:/srv/qwc_service/config:ro + - ./pg_service.conf:/srv/pg_service.conf:ro,z + - ./volumes/config:/srv/qwc_service/config:ro,z qwc-print-service: image: sourcepole/qwc-print-service:latest-2025-lts @@ -247,7 +247,7 @@ services: <<: *qwc-service-variables SERVICE_MOUNTPOINT: '/api/v1/print' volumes: - - ./volumes/config:/srv/qwc_service/config:ro + - ./volumes/config:/srv/qwc_service/config:ro,z # qwc-registration-gui: # image: sourcepole/qwc-registration-gui:latest-2025-lts @@ -267,7 +267,7 @@ services: # NOTE: The port the qwc application runs on. You can choose another port instead of 8088. - "8088:80" volumes: - - ./api-gateway/nginx.conf:/etc/nginx/conf.d/default.conf:ro + - ./api-gateway/nginx.conf:/etc/nginx/conf.d/default.conf:ro,z depends_on: - qwc-postgis - qwc-qgis-server diff --git a/scripts/set_permissions.sh b/scripts/set_permissions.sh deleted file mode 100644 index d48333f..0000000 --- a/scripts/set_permissions.sh +++ /dev/null @@ -1,219 +0,0 @@ -#!/bin/bash - -help() { - echo 'usage: set_permissions.sh QWC_UID QWC_GID' - echo ' set_permissions.sh --help' - echo - echo ' Run this script from the qwc-docker directory to configure' - echo ' permissions for QWC2 Docker containers.' - echo - echo ' SELinux settings will get applied if SELinux tools are present' - echo - echo ' Please make sure that QWC_UID and QWC_GID match match the' - echo ' SERVICE_UID/SERVICE_GID settings defined in docker-compose.yml' - echo ' (qwc-docker sets them to 1000:1000 by default)' - echo - - exit 1 -} - -[ "$1" == "--help" ] && help -[ "$1" == "" -o "$2" == "" ] && echo "ERROR: You need to set the QWC_UID QWC_GID parameters" >&2 && exit 2 - -if [ "$(whoami)" != "root" ]; then - echo "Please run me as root" - exit 3 -fi - -QWC_UID="$1" -QWC_GID="$2" - -# Ignore SIGPIPE to prevent broken pipe errors -trap '' SIGPIPE - -# Check if SELinux tools are available -SELINUX_ENABLED=0 -if command -v chcon >/dev/null 2>&1 && command -v semanage >/dev/null 2>&1 && command -v restorecon >/dev/null 2>&1; then - SELINUX_ENABLED=1 - echo "SELinux tools detected, applying SELinux contexts." -else - echo "SELinux tools not detected, skipping SELinux commands." -fi - -# Function to run SELinux commands with error handling and debug logging -run_selinux_cmd() { - local cmd="$1" - echo "Running: $cmd" - # Redirect all output to prevent pipe breaks - if ! $cmd > /dev/null 2> /tmp/set_permissions_error.log; then - echo "Error: Failed to execute '$cmd'" - echo "Debug output: $(cat /tmp/set_permissions_error.log)" - exit 1 - fi -} - -# below we will set SELinux type to svirt_sandbox_file_t recursively -# for Docker container access. See -# https://docs.redhat.com/en/documentation/red_hat_enterprise_linux_atomic_host/7/html/container_security_guide/docker_selinux_security_policy#docker_selinux_security_policy - -# Configure permissions for the PostgreSQL database volume (qwc-postgis) -if [ $SELINUX_ENABLED -eq 1 ]; then - run_selinux_cmd "chcon -Rt svirt_sandbox_file_t ./volumes/db" - # Add or modify persistent SELinux file context rule for all files in ./volumes/db - if semanage fcontext -l | grep -q "^./volumes/db/.*\s.*svirt_sandbox_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./volumes/db/.*" - run_selinux_cmd "semanage fcontext -m -t svirt_sandbox_file_t './volumes/db/.*'" - else - #echo "Debug: No context for ./volumes/db/.*, adding new" - run_selinux_cmd "semanage fcontext -a -t svirt_sandbox_file_t './volumes/db/.*'" - fi - run_selinux_cmd "restorecon -R ./volumes/db" -fi -# Set ownership to the UID that postgres is running under in the qwc-postgis container -chown -R 999:999 ./volumes/db -chmod -R 700 ./volumes/db - -# Configure the NGINX configuration file for the qwc-api-gateway container -if [ $SELINUX_ENABLED -eq 1 ]; then - run_selinux_cmd "chcon -t svirt_sandbox_file_t ./api-gateway/nginx.conf" - # Add or modify persistent SELinux file context rule - if semanage fcontext -l | grep -q "^./api-gateway/nginx.conf\s.*svirt_sandbox_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./api-gateway/nginx.conf" - run_selinux_cmd "semanage fcontext -m -t svirt_sandbox_file_t './api-gateway/nginx.conf'" - else - #echo "Debug: No context for ./api-gateway/nginx.conf, adding new" - run_selinux_cmd "semanage fcontext -a -t svirt_sandbox_file_t './api-gateway/nginx.conf'" - fi - run_selinux_cmd "restorecon ./api-gateway/nginx.conf" -fi - -# Configure the configuration volume used by qwc-map-viewer and other services -if [ $SELINUX_ENABLED -eq 1 ]; then - run_selinux_cmd "chcon -Rt svirt_sandbox_file_t ./volumes/config" - # Add or modify persistent SELinux file context rule - if semanage fcontext -l | grep -q "^./volumes/config/.*\s.*svirt_sandbox_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./volumes/config/.*" - run_selinux_cmd "semanage fcontext -m -t svirt_sandbox_file_t './volumes/config/.*'" - else - #echo "Debug: No context for ./volumes/config/.*, adding new" - run_selinux_cmd "semanage fcontext -a -t svirt_sandbox_file_t './volumes/config/.*'" - fi - run_selinux_cmd "restorecon -R ./volumes/config" -fi -# services inside the containers are running as $QWC_UID:$QWC_GID -chown -R $QWC_UID:$QWC_GID ./volumes/config - -# Configure the PostgreSQL service configuration file used by multiple services -if [ $SELINUX_ENABLED -eq 1 ]; then - run_selinux_cmd "chcon -t svirt_sandbox_file_t ./pg_service.conf" - # Add or modify persistent SELinux file context rule - if semanage fcontext -l | grep -q "^./pg_service.conf\s.*svirt_sandbox_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./pg_service.conf" - run_selinux_cmd "semanage fcontext -m -t svirt_sandbox_file_t './pg_service.conf'" - else - #echo "Debug: No context for ./pg_service.conf, adding new" - run_selinux_cmd "semanage fcontext -a -t svirt_sandbox_file_t './pg_service.conf'" - fi - run_selinux_cmd "restorecon ./pg_service.conf" -fi - -# Configure additional volumes (config-in, qwc2, qgs-resources, attachments) -if [ $SELINUX_ENABLED -eq 1 ]; then - run_selinux_cmd "chcon -Rt svirt_sandbox_file_t ./volumes/config-in ./volumes/qwc2 ./volumes/qgs-resources ./volumes/attachments" - # Add or modify persistent SELinux file context rule - if semanage fcontext -l | grep -q "^./volumes/config-in/.*\s.*svirt_sandbox_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./volumes/config-in/.*" - run_selinux_cmd "semanage fcontext -m -t svirt_sandbox_file_t './volumes/config-in/.*'" - else - #echo "Debug: No context for ./volumes/config-in/.*, adding new" - run_selinux_cmd "semanage fcontext -a -t svirt_sandbox_file_t './volumes/config-in/.*'" - fi - if semanage fcontext -l | grep -q "^./volumes/qwc2/.*\s.*svirt_sandbox_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./volumes/qwc2/.*" - run_selinux_cmd "semanage fcontext -m -t svirt_sandbox_file_t './volumes/qwc2/.*'" - else - #echo "Debug: No context for ./volumes/qwc2/.*, adding new" - run_selinux_cmd "semanage fcontext -a -t svirt_sandbox_file_t './volumes/qwc2/.*'" - fi - if semanage fcontext -l | grep -q "^./volumes/qgs-resources/.*\s.*svirt_sandbox_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./volumes/qgs-resources/.*" - run_selinux_cmd "semanage fcontext -m -t svirt_sandbox_file_t './volumes/qgs-resources/.*'" - else - #echo "Debug: No context for ./volumes/qgs-resources/.*, adding new" - run_selinux_cmd "semanage fcontext -a -t svirt_sandbox_file_t './volumes/qgs-resources/.*'" - fi - if semanage fcontext -l | grep -q "^./volumes/attachments/.*\s.*svirt_sandbox_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./volumes/attachments/.*" - run_selinux_cmd "semanage fcontext -m -t svirt_sandbox_file_t './volumes/attachments/.*'" - else - #echo "Debug: No context for ./volumes/attachments/.*, adding new" - run_selinux_cmd "semanage fcontext -a -t svirt_sandbox_file_t './volumes/attachments/.*'" - fi - run_selinux_cmd "restorecon -R ./volumes/config-in ./volumes/qwc2 ./volumes/qgs-resources ./volumes/attachments" -fi -chown -R $QWC_UID:$QWC_GID ./volumes/config-in ./volumes/qwc2 ./volumes/qgs-resources ./volumes/attachments - -# Configure Solr volumes -if [ $SELINUX_ENABLED -eq 1 ]; then - run_selinux_cmd "chcon -Rt container_file_t -l s0 ./volumes/solr/data ./volumes/solr/configsets" - # Add or modify persistent SELinux file context rule - if semanage fcontext -l | grep -q "^./volumes/solr/data/.*\s.*container_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./volumes/solr/data/.*" - run_selinux_cmd "semanage fcontext -m -t container_file_t './volumes/solr/data/.*'" - else - #echo "Debug: No context for ./volumes/solr/data/.*, adding new" - run_selinux_cmd "semanage fcontext -a -t container_file_t './volumes/solr/data/.*'" - fi - if semanage fcontext -l | grep -q "^./volumes/solr/configsets/.*\s.*container_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./volumes/solr/configsets/.*" - run_selinux_cmd "semanage fcontext -m -t container_file_t './volumes/solr/configsets/.*'" - else - #echo "Debug: No context for ./volumes/solr/configsets/.*, adding new" - run_selinux_cmd "semanage fcontext -a -t container_file_t './volumes/solr/configsets/.*'" - fi - run_selinux_cmd "restorecon -R ./volumes/solr/data ./volumes/solr/configsets" -fi -# solr inside the conainer is running as 8983 -chown -R 8983:8983 ./volumes/solr/data ./volumes/solr/configsets - -# Configure the demo data permissions script for qwc-config-db-migrate -if [ $SELINUX_ENABLED -eq 1 ]; then - run_selinux_cmd "chcon -t svirt_sandbox_file_t ./volumes/demo-data/setup-demo-data-permissions.sh" - # Add or modify persistent SELinux file context rule - if semanage fcontext -l | grep -q "^./volumes/demo-data/setup-demo-data-permissions.sh\s.*svirt_sandbox_file_t\s" > /dev/null 2>&1; then - #echo "Debug: Found context for ./volumes/demo-data/setup-demo-data-permissions.sh" - run_selinux_cmd "semanage fcontext -m -t svirt_sandbox_file_t './volumes/demo-data/setup-demo-data-permissions.sh'" - else - #echo "Debug: No context for ./volumes/demo-data/setup-demo-data-permissions.sh, adding new" - run_selinux_cmd "semanage fcontext -a -t svirt_sandbox_file_t './volumes/demo-data/setup-demo-data-permissions.sh'" - fi - run_selinux_cmd "restorecon ./volumes/demo-data/setup-demo-data-permissions.sh" -fi -chown $QWC_UID:$QWC_GID ./volumes/demo-data/setup-demo-data-permissions.sh - -# Configure SELinux network policies for container connectivity -if [ $SELINUX_ENABLED -eq 1 ]; then - # Check if container_connect_any boolean exists - if getsebool container_connect_any >/dev/null 2>&1; then - # allow containers to connect to any port - run_selinux_cmd "setsebool -P container_connect_any 1" - else - # Print a message if the boolean is not defined (e.g., in older SELinux versions) - echo "Note: container_connect_any boolean not defined, skipping." - fi - # Configure ports 5432 (PostgreSQL), 8088 (QWC2 services), and 8983 (Solr) - for port in 5432 8088 8983; do - # Check if the port is already defined as http_port_t - if semanage port -l | grep -q "http_port_t.*$port" > /dev/null 2>&1; then - run_selinux_cmd "semanage port -m -t http_port_t -p tcp $port" - else - run_selinux_cmd "semanage port -a -t http_port_t -p tcp $port" - fi - done - # Ensure port 5432 is labeled with postgresql_port_t for PostgreSQL access - run_selinux_cmd "semanage port -m -t postgresql_port_t -p tcp 5432" -fi - -# Print confirmation and instructions to restart Docker services -echo "Permissions applied. Restart services with:" -echo "docker-compose down && docker-compose up -d"