update ProdBuild
This commit is contained in:
1 parent
5c92129fba
commit
6a50099849
176 files changed
+408
-395
No files matched your search
@@ -58,6 +58,49 @@ jobs:
|
||||
echo "versioned: gitea.tail276105.ts.net/${REPOSITORY_LC}-backend:${GITHUB_RUN_NUMBER}"
|
||||
echo "latest: gitea.tail276105.ts.net/${REPOSITORY_LC}-backend:latest"
|
||||
|
||||
- name: Log out from Docker registry
|
||||
if: always()
|
||||
run: docker logout gitea.tail276105.ts.net
|
||||
|
||||
Build-Remsly-Frontend:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: gitea.tail276105.ts.net/remsly/ci-image:5
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build FE
|
||||
run: |
|
||||
cd frontend
|
||||
npm ci
|
||||
npm run buildProd
|
||||
- name: Login to Docker Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: gitea.tail276105.ts.net
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
- name: Build Docker
|
||||
run: |
|
||||
REPOSITORY_LC=$(echo "${{ gitea.repository }}" | tr '[:upper:]' '[:lower:]')
|
||||
(
|
||||
cd frontend;
|
||||
docker build -t gitea.tail276105.ts.net/${REPOSITORY_LC}-frontend:${GITHUB_RUN_NUMBER} .;
|
||||
docker tag gitea.tail276105.ts.net/${REPOSITORY_LC}-frontend:${GITHUB_RUN_NUMBER} gitea.tail276105.ts.net/${REPOSITORY_LC}-frontend:latest
|
||||
)
|
||||
|
||||
- name: Push Docker Images
|
||||
run: |
|
||||
REPOSITORY_LC=$(echo "${{ gitea.repository }}" | tr '[:upper:]' '[:lower:]')
|
||||
docker push gitea.tail276105.ts.net/${REPOSITORY_LC}-frontend:${GITHUB_RUN_NUMBER}
|
||||
docker push gitea.tail276105.ts.net/${REPOSITORY_LC}-frontend:latest
|
||||
|
||||
- name: Docker imageTags
|
||||
run: |
|
||||
REPOSITORY_LC=$(echo "${{ gitea.repository }}" | tr '[:upper:]' '[:lower:]')
|
||||
echo "versioned: gitea.tail276105.ts.net/${REPOSITORY_LC}-frontend:${GITHUB_RUN_NUMBER}"
|
||||
echo "latest: gitea.tail276105.ts.net/${REPOSITORY_LC}-frontend:latest"
|
||||
|
||||
- name: Log out from Docker registry
|
||||
if: always()
|
||||
run: docker logout gitea.tail276105.ts.net
|
||||
@@ -5,6 +5,7 @@
|
||||
/frontend/build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
http-client.private.env.json
|
||||
deploy/prod/.env
|
||||
/backend/src/main/resources/*.properties
|
||||
src/gen
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Boxit (also called "Remsly" in CI) is a box/inventory management app:
|
||||
|
||||
- **backend/** — Spring Boot 2.6 (Kotlin, Java 17, Jersey + Spring MVC), PostgreSQL via jOOQ, Elasticsearch for search, Keycloak for auth. Runs on port **5050**.
|
||||
- **frontend/** — Angular 13 app (port **4200**), proxies `/api` to the backend via `proxy-conf.json`.
|
||||
- **JooqHelper/** — small Gradle module providing `BoxitNamingStrategy` used by jOOQ code generation.
|
||||
- **deploy/localDev/boxit/** — docker-compose for local infrastructure (Postgres on 6543, Keycloak on 8081, Apache OIDC proxy, Elasticsearch, Prometheus).
|
||||
- **deploy/prod/** — production docker-compose + Let's Encrypt scripts.
|
||||
- **clients/** — IntelliJ HTTP client files for the REST API, Keycloak, and Elasticsearch (env in `http-client.private.env.json`, template provided).
|
||||
|
||||
## Commands
|
||||
|
||||
### Backend (Gradle, from repo root)
|
||||
|
||||
```bash
|
||||
./gradlew build # build + tests (requires running Postgres, see below)
|
||||
./gradlew test # tests only (JUnit 5; integration tests use Testcontainers)
|
||||
./gradlew generateJooq # run Flyway migrations, then regenerate jOOQ classes
|
||||
./gradlew lintKotlin # kotlinter lint
|
||||
./gradlew formatKotlin # kotlinter autoformat
|
||||
./gradlew bootRun # run the backend
|
||||
```
|
||||
|
||||
Run a single test class: `./gradlew test --tests "ch.boxi.boxit.SomeTestClass"`
|
||||
|
||||
DB connection for Flyway/jOOQ codegen is parameterized via Gradle properties
|
||||
`-PDB_HOST_PORT -PDB_USER -PDB_PASSWD -PDB_NAME` (defaults: `localhost:6543`, `gradle`/`gradlepw`/`gradle` — matches the localDev docker-compose Postgres).
|
||||
|
||||
### Frontend (from frontend/)
|
||||
|
||||
```bash
|
||||
npm start # dev server on :4200 with /api proxy to :5050
|
||||
npm run build # dev build
|
||||
npm run buildProd # production build (also copies index.html -> 404.html)
|
||||
npm test # Karma/Jasmine tests
|
||||
npm run lint # ng lint
|
||||
```
|
||||
|
||||
### Local infrastructure
|
||||
|
||||
```bash
|
||||
cd deploy/localDev/boxit && docker compose up -d
|
||||
```
|
||||
|
||||
Provides Postgres (port 6543, multiple DBs: `boxit`, `keycloak`, `gradle`, `test`), Keycloak (8081), Apache OIDC proxy, and Elasticsearch. `backend/src/main/resources/application.properties` is not committed — create it from `application.properties-Template`.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Backend data flow: Flyway → jOOQ codegen
|
||||
|
||||
The DB schema is the source of truth. Migrations live in `backend/src/main/resources/db/migration` (Flyway, `V*.sql`). `generateJooq` depends on `flywayMigrate` and generates records/POJOs/DAOs into `backend/src/gen/java` (package `ch.boxi.boxit.gen`, deleted on `clean`, regenerated on compilation). Naming is customized by `JooqHelper`'s `BoxitNamingStrategy`. **After changing a migration, re-run `./gradlew generateJooq` against a running Postgres.**
|
||||
|
||||
### Backend layers (`ch.boxi.boxit`)
|
||||
|
||||
- `restapi/` — REST controllers, DTOs, mappers, pagination (`Paged`, `PaginationDto`, infinite scroll support). Organized by feature (folder, note, task, user, search).
|
||||
- `domain/` — business logic per feature (attachment, folder, location, note, task, user). Uses a Visitor pattern (`Visitable`/`Visitor`) and `Augmentor` abstractions.
|
||||
- `db/` — jOOQ-based repositories built on `SimpleCrudRepository` / `AbstractSimpleCrudRepositoryImpl` plus composable `JooqFilter` classes (`CombinedAndFilter`, `CombinedOrFilter`, ...).
|
||||
- `searchindex/` — Elasticsearch index per feature (folder, note, task) with its own migration support; `db/elasticsearchSync` + `domain/elasticSearchSync` implement DB→ES synchronization.
|
||||
- `clientapi/` — outbound HTTP clients (e.g. OpenStreetMap geocoding).
|
||||
- `security/` — Keycloak/OIDC config and SSL client config (truststore at `backend/src/main/resources/truststore.jks`; Elasticsearch CA certs must be imported there — see readme.md).
|
||||
|
||||
### Frontend layers (`frontend/src/app`)
|
||||
|
||||
- `api/` — `boxit.api.ts` + DTOs + HTTP error interceptor (mirror of the backend REST API).
|
||||
- `business/` — services/models per feature (item, attachment, location, user), notification and global error handling.
|
||||
- `gui/` — components (header, page, search, filters, item, location, responsive helpers).
|
||||
- `auth/` — `auth.service.ts` (Keycloak-based login).
|
||||
|
||||
### Testing
|
||||
|
||||
Backend integration tests (`BoxitIntegrationTest`) use Testcontainers. For container reuse, add `testcontainers.reuse.enabled=true` to `~/.testcontainers.properties`.
|
||||
|
||||
### CI
|
||||
|
||||
Gitea Actions (`.gitea/workflows/`) builds on push to `main`: Gradle build with a Postgres service container, then builds/pushes Docker images (`*-backend`, `*-frontend`) to `gitea.tail276105.ts.net` and triggers a prod compose redeploy. `bitbucket-pipelines.yml` and `.space.kts` are legacy.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Template for deploy/prod/.env
|
||||
# Copy to .env and fill in the values: cp .env-template .env
|
||||
# The .env file itself is git-ignored (it holds secrets).
|
||||
|
||||
# --- Database / Keycloak passwords ---
|
||||
REMSLY_PSQL_PASSWORD=
|
||||
KC_PSQL_PASSWORD=
|
||||
KC_ADMIN_PASSWORD=
|
||||
|
||||
# --- Tailscale ---
|
||||
# Reusable, tag:server pre-authorized auth key from the Tailscale admin console.
|
||||
TS_AUTHKEY=
|
||||
|
||||
# --- Apache OIDC (mod_auth_openidc) ---
|
||||
OIDC_CRYPTO_PASSPHRASE=
|
||||
OIDC_CLIENT_SECRET=
|
||||
|
||||
# --- Elasticsearch ---
|
||||
ELASTIC_PASSWORD=
|
||||
|
||||
# --- Backend ---
|
||||
# Keycloak client id (resource) the bearer-only backend expects.
|
||||
KEYCLOAK_RESOURCE=
|
||||
@@ -0,0 +1,37 @@
|
||||
# Production config for the backend, mounted into the container and activated via
|
||||
# SPRING_CONFIG_ADDITIONAL_LOCATION (see docker-compose.yml). Secrets are injected
|
||||
# from the environment (.env) through ${...} placeholders, so this file is safe to commit.
|
||||
spring.profiles.active=PROD
|
||||
|
||||
server.port=5050
|
||||
|
||||
# Postgres runs as service "postgres" on remslyNet; db/user "remsly" (see POSTGRES_MULTIPLE_DATABASES).
|
||||
spring.datasource.url=jdbc:postgresql://postgres:5432/remsly
|
||||
spring.datasource.username=remsly
|
||||
spring.datasource.password=${REMSLY_PSQL_PASSWORD}
|
||||
|
||||
# Elasticsearch runs as service "elasticsearch" on remslyNet, plain HTTP on 9200.
|
||||
boxit.elasticsearch.host=elasticsearch
|
||||
boxit.elasticsearch.port=9200
|
||||
boxit.elasticsearch.user=elastic
|
||||
boxit.elasticsearch.pass=${ELASTIC_PASSWORD}
|
||||
|
||||
spring.jackson.date-format="yyyy-MM-dd HH:mm:ss"
|
||||
|
||||
# SSLClientConfig overrides the JVM trust store unconditionally, so point it at the JDK
|
||||
# default CA bundle. That keeps outbound HTTPS (e.g. fetching Keycloak's JWKS over the
|
||||
# Let's Encrypt / tailscale cert) working without shipping a custom truststore.
|
||||
boxit.server.ssl.trust-store=/opt/java/openjdk/lib/security/cacerts
|
||||
boxit.server.ssl.trust-store-password=changeit
|
||||
|
||||
management.endpoint.metrics.enabled=true
|
||||
management.endpoints.web.exposure.include=*
|
||||
management.endpoint.prometheus.enabled=true
|
||||
management.metrics.export.prometheus.enabled=true
|
||||
|
||||
logging.level.root=INFO
|
||||
|
||||
keycloak.realm=remsly
|
||||
keycloak.bearer-only=true
|
||||
keycloak.auth-server-url=https://remsly-id.tail276105.ts.net
|
||||
keycloak.resource=${KEYCLOAK_RESOURCE}
|
||||
@@ -1 +0,0 @@
|
||||
*.pem
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"creation_dt": "2023-03-24T14:43:02Z", "creation_host": "20e2283fb076"}
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"n": "u6an4MsyALnC0Ik2b8tcVpikTwzWgtASLGEUg7wEs7_piMKI7wNwroRbCesHujhJu2Ha_hDMrJmCEvT0T2fO4JzoAt1bLE3zWM4sXnWEpTXCrWxayjXbGTblrJcTIQPb7cbiTvyoAQvcThApZcvQEBkKZrlOp3aB62thM2zSI6XFVcbmF3CRCVJdIYN2K3ioQjkkxiAFwQ0EUNWtHzaDvjwFBvwAD2iDDqZh0mHYWWnhwV0okuJ3FBX8fVUr2oskq5cHhc8t8r8l1Iob9lEcgwkRJE93hQ1CMxYT4RX_rbJtyIFbixVkxM99x16nlyJnAWlPzEZrTz_fdcdFeQHPrw", "e": "AQAB", "d": "F7GUUvL1LlhGO_SHVhhUYW7GmGCjmULSeJ4NbBDKezPJNgZyKdPCX5bAtADkKeQ_kxRpBVlzrnt3jBM34erWmU_Wj74JbA-voU_vFEI8bGvcV-9ti0i_kHB5EZDFzo5hL6XEH3sRb4hi2cx6narda5rt0EinoMd64hHd5RNheTSWsVcSbBwzgDqKNB-OTr2vGzK3O3ZmY-I6IE5nVTf1tLkkI3GlPwKOSix1nDFtwHvKV0QTazsBop9MkMDwrBNVYJB_0G6AEtC8RXn9z4FIBZc9BAk4G8bygATwixu3WfUuM5LI3qavwILmQVFzmBfojHHWYf-eQBXf-kwR4KeX2Q", "p": "7MgYLilx05H3tvpy0M5ty2R6i3cE9vzl-eiNPM_rBF-eu-cAjkCtLViKg6VTdr0I8qV4B-NCshPpnF50cuFupF6jTgWZJeAfiOoEWQC6mqNxngX4N98mxDm7lf_3QqRsdhh2cS_5IOJ4cpaJ5WlX89WZvpfAKbCISQ_nejSypQM", "q": "yuG2pUTwPi4QazqX6w3oMAb9C-R6kDoYMNhRm2qCkSMQ9jJlaW80sIypYNzeD2JbF6pAjhF2mN2ehorMwVs97flNrSjGTdMts63JMcI6-w5MOWHmI938knxrBn5ku88QsJpjMdY4f25Oynb5LG3YSiNqQVztc_aC3qElrJ4CvOU", "dp": "PbwBye9WVSImotdzngtkRvZgmQIkEj1nvJusT2GqVc6UdUtKMsycGkmOe7pcI4Yv0gvgWrYfCoz0iKd71wP9s-9Uxp_hCSYBMtJI5eexv2XD1r6Zs_-DfP_Mb9R35DE4ciX4o5QtcSx62O108JJhsxpK5o1sNbJoJhx2br9UoH8", "dq": "TBt6UetXmGvdWuxjGxlfdczZVoHCfKJeesxbaMr-6gVWkpT7OB8wi95ol96jKvBBrdH_X4wrilLw6hXdk9dvlvtD6WZ3ZbCH33SdGh5707xcWdZg6CmZWzZzS79UeKPH5gg0l_h9v0gZJJiXBtS6I62_aX-70Bm0pGGdaXDpJAU", "qi": "L4HAI6WvpBjiwvGGH9IAoxsxqlnCton8uUUf2IQwpZMKe-d9LXPsOdWsyaZneCnc2C_AQsgLkpZIWd47koybwch4vTkbmLrNwtaaazVk53Axdg3ksFT-uWad4YTiqCH-hIt_2xXxvensMqHwRvIk44MHk0kq485nPfGx4E9zvDE", "kty": "RSA"}
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"body": {}, "uri": "https://acme-staging-v02.api.letsencrypt.org/acme/acct/94925864"}
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"creation_dt": "2023-03-24T14:44:14Z", "creation_host": "ed2dd2431723"}
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"n": "5JoKajoOVE7y5Bcchd4KPlVarooN-XLHtEbFRy0zrFG4mAY_Qf-H1eZkmHvPQwv-tDEPFRlabrxXqC3uWoy9uOmqXea7rbnOqQHYRSAhIiW8I0JbuzGHga-ZwujShQDj85eimjBXRKhjD6r3zRElchTWXyeT0_dRrOZ099zAE0qNCnVRxel6IXdFEKz9YrBvIqvEzJC2DBWwF0W6ZBlpiM8RXq1guBU22k0XkoDHE8d_LL6AMrhtXSCPwiL9YOxiyvSTgLHciy4c-WP1-mypy65oK5YLCiVagX4kM8qbxW_0nmFtdYCdhhEBrHktxofHUaps4cPGK_XDkbz5mti9vQ", "e": "AQAB", "d": "D53KSllu8yl1hElj5G03q-xuxm-d5sWFiPYwsd0Po5ztjE0Y8yw-nkkf5B7JGN5v5uVXD2zs9ZWeM1n3522n5ELqJYIGniaMTJVYrdg1Cz0irhHxbEdE54IUcfEvuHBIIjLgo8HbpFAQfFiElxitwy5TOqrceWVyyenwYaJN6MNU6h5_TReay7Smye1NQYnv3E63jDX3Od_rQyrLBV0UE3Y7BOPLGmqHTeeEaDo8zut0HgXIS0ecRrfTt8RkDpv_Xc9AAVzZaPXLNo4Kxo7YWCpoi32oLwUhsBELS6G3i2rQxPTveMnkeU0-1qo6hfoGZFMKpAivl4QX86_D_41tzQ", "p": "_dmRjJn2dVbPNOgvXeencRykjCHk5aRDYDCJ6BKYEsXpOdOZCGH2HlX-43Loh1w5qHcCXlSCX5T1GsOv-EAye2T9Eg-xfpkPHUJ9JlKRk1Oiy6FjFfBr_ObUzK_rC-WyHzcIaU50hyzwoKDhICRdbQvfJnOp02tE1Hlxm15qO28", "q": "5om5xnQAv6RRzkCdsO4Sk2yFXwoTvpL8KS9LG1RqcPoAvy1ey5oEPJLIUyFUmf8-hr5RW2OBgEwGCR3HQgaXXiyxeCSdoM0roEJaEcerk2i8JW_w_S52evvigJb4mOajzjY--WsSa12LpJTTKvSlf-9eWNaNeb7vv9GT1atWs5M", "dp": "lL_gFTbG_909kDAaSXmMWbDCD0dxPMuzm3L17KKwsBd-4h7HBu14bjBQKvHTpjX5p2kNXz9AIkhEFEnlHKBptHrp_KJrjNadz7R9Z25s1Zrlw1Mvn9SBQvH0cnkHT7JqXPY_nI2XpPpFiqqbIN2OTW7udTbDphque58qXjPGJks", "dq": "hP4o1Mpw8B1sL-7oyXvd7XwqSJR4pXUH0P5-doqxSPGAYslaqVv1W7hVpldRBfHQcUzzhCQYPhodVT7_hyBkTCi-TI_a-zvBEheU_DLS0RwXhgVY4cXfBb2vgf0V9qb_EmQK2johixyRBWXxmBNAMli1dcx4GybCCkdt4FKSls8", "qi": "Y_CRKqA-X8fnYAU9WIBVB2mH08m5y_3UhcmzJpcDAeaPygrh4hItYKdBSk9R9IBRiME84nIDW2Xor9c_GPpXcEItsHAHYHiF12hZtZHcEXyp9fFsJzprTWhXr1JRohlsPzCK6pzcB1Hk2ZwUvc0G4wkcaeOfo9LTVQj5eWRlnWQ", "kty": "RSA"}
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"body": {}, "uri": "https://acme-v02.api.letsencrypt.org/acme/acct/1025448747"}
|
||||
@@ -1,14 +0,0 @@
|
||||
This directory contains your keys and certificates.
|
||||
|
||||
`[cert name]/privkey.pem` : the private key for your certificate.
|
||||
`[cert name]/fullchain.pem`: the certificate file used in most server software.
|
||||
`[cert name]/chain.pem` : used for OCSP stapling in Nginx >=1.3.7.
|
||||
`[cert name]/cert.pem` : will break many server configurations, and should not be used
|
||||
without reading further documentation (see link below).
|
||||
|
||||
WARNING: DO NOT MOVE OR RENAME THESE FILES!
|
||||
Certbot expects these files to remain in this location in order
|
||||
to function properly!
|
||||
|
||||
We recommend not moving these files. For more information, see the Certbot
|
||||
User Guide at https://certbot.eff.org/docs/using.html#where-are-my-certificates.
|
||||
@@ -1,14 +0,0 @@
|
||||
This directory contains your keys and certificates.
|
||||
|
||||
`privkey.pem` : the private key for your certificate.
|
||||
`fullchain.pem`: the certificate file used in most server software.
|
||||
`chain.pem` : used for OCSP stapling in Nginx >=1.3.7.
|
||||
`cert.pem` : will break many server configurations, and should not be used
|
||||
without reading further documentation (see link below).
|
||||
|
||||
WARNING: DO NOT MOVE OR RENAME THESE FILES!
|
||||
Certbot expects these files to remain in this location in order
|
||||
to function properly!
|
||||
|
||||
We recommend not moving these files. For more information, see the Certbot
|
||||
User Guide at https://certbot.eff.org/docs/using.html#where-are-my-certificates.
|
||||
@@ -1,13 +0,0 @@
|
||||
# renew_before_expiry = 30 days
|
||||
version = 0.40.1
|
||||
archive_dir = /etc/letsencrypt/archive/app.boxi.ch
|
||||
cert = /etc/letsencrypt/live/app.boxi.ch/cert.pem
|
||||
privkey = /etc/letsencrypt/live/app.boxi.ch/privkey.pem
|
||||
chain = /etc/letsencrypt/live/app.boxi.ch/chain.pem
|
||||
fullchain = /etc/letsencrypt/live/app.boxi.ch/fullchain.pem
|
||||
|
||||
# Options used in the renewal process
|
||||
[renewalparams]
|
||||
account = ea5cf7614a600d23b821c0af24b17a1d
|
||||
authenticator = standalone
|
||||
server = https://acme-v02.api.letsencrypt.org/directory
|
||||
@@ -1,132 +0,0 @@
|
||||
<VirtualHost *:80>
|
||||
DocumentRoot "/var/www/app"
|
||||
ServerName app.boxi.ch
|
||||
# ServerAlias www.${server_name}
|
||||
|
||||
ErrorLog /var/log/apache2/error.log
|
||||
CustomLog /var/log/apache2/access.log combined
|
||||
LogLevel debug
|
||||
|
||||
<Directory />
|
||||
AllowOverride none
|
||||
Options -Indexes -Includes
|
||||
Require all granted
|
||||
<LimitExcept GET POST HEAD>
|
||||
deny from all
|
||||
</LimitExcept>
|
||||
</Directory>
|
||||
|
||||
<Directory "/var/www/app">
|
||||
AllowOverride None
|
||||
Options -Indexes -Includes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<Location /status >
|
||||
SetHandler server-status
|
||||
</Location>
|
||||
|
||||
<Location / >
|
||||
Redirect / https://app.boxi.ch/
|
||||
</Location>
|
||||
</VirtualHost>
|
||||
|
||||
<IfModule mod_ssl.c>
|
||||
<VirtualHost *:443>
|
||||
DocumentRoot "/var/www/app"
|
||||
ServerName app.boxi.ch
|
||||
#ServerAlias www.${server_name}
|
||||
|
||||
LogLevel info
|
||||
|
||||
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
|
||||
Header always set Content-Security-Policy "default-src 'self' ; \
|
||||
script-src 'self' 'unsafe-inline' 'unsafe-eval'; \
|
||||
style-src 'self' use.fontawesome.com 'unsafe-inline'; \
|
||||
font-src 'self' data: use.fontawesome.com; \
|
||||
base-uri 'self'; \
|
||||
form-action 'self'; \
|
||||
frame-ancestors 'none'; \
|
||||
img-src 'self' data:; \
|
||||
upgrade-insecure-requests" "expr=%{CONTENT_TYPE} =~ m#text\/(html|javascript)|application\/pdf|xml#i"
|
||||
Header always append X-Frame-Options SAMEORIGIN
|
||||
Header always set X-Content-Type-Options nosniff
|
||||
Header always set Referrer-Policy "same-origin"
|
||||
# this feature is not yet used and must be extended if needed, currently only a sample config
|
||||
Header always set Feature-Policy "payment 'none';"
|
||||
|
||||
<Directory />
|
||||
AllowOverride none
|
||||
Options -Indexes -Includes
|
||||
Require all granted
|
||||
<LimitExcept GET POST HEAD>
|
||||
deny from all
|
||||
</LimitExcept>
|
||||
</Directory>
|
||||
|
||||
<Directory "/var/www/app">
|
||||
AllowOverride None
|
||||
Options -Indexes -Includes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<Location /status >
|
||||
SetHandler server-status
|
||||
</Location>
|
||||
|
||||
RequestHeader set X-Forwarded-User expr=%{REMOTE_USER}
|
||||
RequestHeader set Authorization "Bearer %{oidc_access_token}e"
|
||||
Header set User-Details "%{REMOTE_USER}e %{oidc_claim_email}e"
|
||||
|
||||
OIDCProviderMetadataURL ${KC_ADDR}/realms/${KC_REALM}/.well-known/openid-configuration
|
||||
OIDCClientID ${OIDC_CLIENT_ID}
|
||||
OIDCClientSecret ${OIDC_CLIENT_SECRET}
|
||||
OIDCRefreshAccessTokenBeforeExpiry 10
|
||||
OIDCRedirectURI ${OIDC_REDIRECT_URI}
|
||||
OIDCCryptoPassphrase ${OIDC_CRYPTO_PASSPHRASE}
|
||||
OIDCInfoHook ${OIDC_INFO_HOOK}
|
||||
OIDCDefaultLoggedOutURL ${KC_ADDR}/realms/${KC_REALM}/protocol/openid-connect/logout?redirect_uri=https%3A%2F%2Fapp.boxi.ch
|
||||
OIDCRemoteUserClaim preferred_username
|
||||
OIDCStateMaxNumberOfCookies 3 true
|
||||
|
||||
<Location /status >
|
||||
SetHandler server-status
|
||||
</Location>
|
||||
|
||||
<Location />
|
||||
AuthType openid-connect
|
||||
Require valid-user
|
||||
</Location>
|
||||
|
||||
# If the browser is allowed to cache index.html, it starts loading assets/scripts/images before apache had a chance
|
||||
# to check whether or not the user is even authenticated, leading to many failed requests.
|
||||
# Disabling cache for index.html forces the browser to fetch it first, and therefore ensures that the full
|
||||
# authentication mechanic is being run.
|
||||
# See also https://github.com/zmartzone/mod_auth_openidc/issues/113
|
||||
<filesMatch "index.html">
|
||||
FileETag None
|
||||
Header unset ETag
|
||||
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
|
||||
Header set Pragma "no-cache"
|
||||
Header set Expires "Mon, 21 Mar 1983 14:10:00 UTC"
|
||||
</filesMatch>
|
||||
|
||||
#ProxyPass /ws ${FRONTEND_WS_URL}:${FRONTEND_PORT}/ws retry=0 timeout=86400
|
||||
#ProxyPassReverse /ws ws://${FRONTEND_URL}:${FRONTEND_PORT}/ws
|
||||
|
||||
#ProxyPass /api/ ${BACKEND_URL}:${BACKEND_PORT}/api/ retry=0
|
||||
#ProxyPassReverse /api/ ${BACKEND_URL}:${BACKEND_PORT}/api/
|
||||
|
||||
#ProxyPass / ${FRONTEND_URL}:${FRONTEND_PORT}/ retry=0
|
||||
#ProxyPassReverse / ${FRONTEND_URL}:${FRONTEND_PORT}
|
||||
|
||||
SSLEngine On
|
||||
# SSLUseStapling On
|
||||
SSLProtocol -all +TLSv1.2
|
||||
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
|
||||
SSLHonorCipherOrder on
|
||||
SSLCertificateFile /etc/letsencrypt/live/app.boxi.ch/cert.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/app.boxi.ch/privkey.pem
|
||||
SSLCertificateChainFile /etc/letsencrypt/live/app.boxi.ch/fullchain.pem
|
||||
</VirtualHost>
|
||||
</IfModule>
|
||||
@@ -1,79 +0,0 @@
|
||||
<VirtualHost *:80>
|
||||
DocumentRoot "/var/www/id"
|
||||
ServerName id.boxi.ch
|
||||
# ServerAlias www.${server_name}
|
||||
ErrorLog /var/log/apache2/error.log
|
||||
CustomLog /var/log/apache2/access.log combined
|
||||
LogLevel info
|
||||
<Directory />
|
||||
AllowOverride none
|
||||
Options -Indexes -Includes
|
||||
Require all granted
|
||||
<LimitExcept GET POST HEAD>
|
||||
deny from all
|
||||
</LimitExcept>
|
||||
</Directory>
|
||||
<Directory "/var/www/id">
|
||||
AllowOverride None
|
||||
Options -Indexes -Includes
|
||||
Require all granted
|
||||
</Directory>
|
||||
<Location /status >
|
||||
SetHandler server-status
|
||||
</Location>
|
||||
<Location / >
|
||||
Redirect / https://id.boxi.ch/
|
||||
</Location>
|
||||
</VirtualHost>
|
||||
|
||||
<IfModule mod_ssl.c>
|
||||
<VirtualHost *:443>
|
||||
DocumentRoot "/var/www/id"
|
||||
ServerName id.boxi.ch
|
||||
#ServerAlias www.${server_name}
|
||||
|
||||
LogLevel info
|
||||
|
||||
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
|
||||
Header always set Content-Security-Policy "default-src 'self' ; \
|
||||
style-src 'self' 'unsafe-inline'; \
|
||||
script-src 'self' 'unsafe-inline'; \
|
||||
img-src 'self'; \
|
||||
connect-src 'self'; \
|
||||
form-action 'self'; \
|
||||
frame-src http:; \
|
||||
frame-ancestors 'self'; \
|
||||
object-src 'none'; \
|
||||
upgrade-insecure-requests;"
|
||||
|
||||
#ProxyRequests Off
|
||||
#ProxyPreserveHost On
|
||||
#ProxyAddHeaders On
|
||||
|
||||
#SSLProxyEngine On
|
||||
#SSLProxyVerify none
|
||||
#SSLProxyCheckPeerName off
|
||||
#SSLProxyCheckPeerCN off
|
||||
#SSLProxyCheckPeerName off
|
||||
#SSLProxyCheckPeerExpire off
|
||||
|
||||
#RequestHeader set X-Forwarded-Proto "https"
|
||||
#RequestHeader set X-Forwarded-Port "443"
|
||||
#RequestHeader set X-Forwarded-Host "id.boxi.ch"
|
||||
|
||||
#ProxyPass / http://keycloak:8080/ retry=0
|
||||
#ProxyPassReverse / http://keycloak:8080
|
||||
|
||||
<Location / >
|
||||
Redirect / https://id.boxi.ch:8443/
|
||||
</Location>
|
||||
|
||||
SSLEngine On
|
||||
SSLProtocol -all +TLSv1.2
|
||||
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
|
||||
SSLHonorCipherOrder on
|
||||
SSLCertificateFile /etc/letsencrypt/live/app.boxi.ch/cert.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/app.boxi.ch/privkey.pem
|
||||
SSLCertificateChainFile /etc/letsencrypt/live/app.boxi.ch/fullchain.pem
|
||||
</VirtualHost>
|
||||
</IfModule>
|
||||
@@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Boxi the APP</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
height: 100vh;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>This is the webserver for app.boxi.ch</h1>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Boxi the ID</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
height: 100vh;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>This is the webserver for id.boxi.ch</h1>
|
||||
</body>
|
||||
</html>
|
||||
+107
-60
@@ -1,98 +1,145 @@
|
||||
version: '3'
|
||||
volumes:
|
||||
postgres:
|
||||
driver: local
|
||||
elasticsearch:
|
||||
driver: local
|
||||
tailscale-id:
|
||||
driver: local
|
||||
tailscale-apache:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
remslyNet:
|
||||
name: remslyNet
|
||||
external: false
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14-alpine
|
||||
restart: always
|
||||
networks:
|
||||
boxitNet:
|
||||
ipv4_address: 10.5.1.1
|
||||
- remslyNet
|
||||
environment:
|
||||
POSTGRES_USER: 'boxitadmin'
|
||||
POSTGRES_PASSWORD: 'kQsQKCQoa.yf.XiGCh.3'
|
||||
POSTGRES_USER: 'remsly'
|
||||
POSTGRES_PASSWORD: ${REMSLY_PSQL_PASSWORD}
|
||||
PGDATA: '/var/lib/postgresql/data/pgdata'
|
||||
POSTGRES_MULTIPLE_DATABASES: 'boxit:q_VpgQaeXcjns9PqPmGj:boxit,keycloak:roraJK_ds3KDiHkMRLqf:keycloak'
|
||||
POSTGRES_MULTIPLE_DATABASES: 'remsly:${REMSLY_PSQL_PASSWORD}:remsly,keycloak:${KC_PSQL_PASSWORD}:keycloak'
|
||||
volumes:
|
||||
- ./data/postgres:/var/lib/postgresql/data/pgdata
|
||||
- ./config/postgres/create-multiple-postgresql-databases.sh:/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh
|
||||
|
||||
- postgres:/var/lib/postgresql/data/pgdata
|
||||
- ./postgres/create-multiple-postgresql-databases.sh:/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh
|
||||
|
||||
keycloak:
|
||||
image: gitea.tail276105.ts.net/remsly/keycloak:4
|
||||
networks:
|
||||
boxitNet:
|
||||
ipv4_address: 10.5.0.20
|
||||
restart: always
|
||||
environment:
|
||||
KC_BOOTSTRAP_ADMIN_USERNAME: 'admin'
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD: 'dzVTry4QhwKBnmM8X2PWZRZA'
|
||||
KC_HTTPS_CERTIFICATE_FILE: '/opt/keycloak/certs/fullchain.pem'
|
||||
KC_HTTPS_CERTIFICATE_KEY_FILE: '/opt/keycloak/certs/privkey.pem'
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD}
|
||||
KC_HTTP_ENABLED: 'true'
|
||||
KC_DB: postgres
|
||||
KC_DB_URL: 'jdbc:postgresql://postgres:5432/keycloak'
|
||||
KC_DB_USERNAME: 'keycloak'
|
||||
KC_DB_PASSWORD: 'roraJK_ds3KDiHkMRLqf'
|
||||
KC_HOSTNAME: 'id.boxi.ch'
|
||||
# KC_HOSTNAME_STRICT: 'false'
|
||||
# KC_PROXY_HEADERS: xforwarded
|
||||
# KC_HTTP_ENABLED: 'true'
|
||||
# KC_PROXY: edge
|
||||
KC_DB_PASSWORD: ${KC_PSQL_PASSWORD}
|
||||
# TLS is terminated by the tailscale-id sidecar; Keycloak runs plain HTTP (8080) behind it
|
||||
KC_HOSTNAME: 'https://remsly-id.tail276105.ts.net'
|
||||
KC_HOSTNAME_URL: 'https://remsly-id.tail276105.ts.net'
|
||||
KC_HOSTNAME_ADMIN_URL: 'https://remsly-id.tail276105.ts.net'
|
||||
command:
|
||||
- start
|
||||
- '--optimized'
|
||||
# - '--hostname-debug=true' # https://id.boxi.ch:8443/realms/master/hostname-debug
|
||||
# - '--hostname-debug=true' #https://remsly-id.tail276105.ts.net/realms/master/hostname-debug
|
||||
volumes:
|
||||
- ./config/keycloak/theme:/opt/keycloak/themes/boxit
|
||||
- ./config/keycloak/theme.v2:/opt/keycloak/themes/boxit.v2
|
||||
- ./certbot/etc/live/app.boxi.ch/fullchain.pem:/opt/keycloak/certs/fullchain.pem:ro
|
||||
- ./certbot/etc/live/app.boxi.ch/privkey.pem:/opt/keycloak/certs/privkey.pem:ro
|
||||
ports:
|
||||
- '8443:8443'
|
||||
- ./keycloak/theme:/opt/keycloak/themes/boxit
|
||||
- ./keycloak/theme.v2:/opt/keycloak/themes/boxit.v2
|
||||
network_mode: service:tailscale-id
|
||||
depends_on:
|
||||
- postgres
|
||||
- tailscale-id
|
||||
|
||||
apache-oidc:
|
||||
image: gitea.tail276105.ts.net/remsly/apacheoidc:3
|
||||
restart: always
|
||||
networks:
|
||||
boxitNet:
|
||||
ipv4_address: 10.5.0.30
|
||||
environment:
|
||||
OIDC_CRYPTO_PASSPHRASE: '39938b0a-1bd2-4352-937d-3cf1e2023727'
|
||||
KC_ADDR: 'https://id.boxi.ch:8443'
|
||||
KC_REALM: 'boxit'
|
||||
OIDC_CRYPTO_PASSPHRASE: ${OIDC_CRYPTO_PASSPHRASE}
|
||||
KC_ADDR: 'https://remsly-id.tail276105.ts.net'
|
||||
KC_REALM: 'remsly'
|
||||
OIDC_CLIENT_ID: 'apacheOIDC'
|
||||
OIDC_CLIENT_SECRET: 'Ymye3T55SnH1YfssvZZi6tRIIZ0PJTsK'
|
||||
OIDC_REDIRECT_URI: 'https://app.boxi.ch/openidc'
|
||||
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET}
|
||||
OIDC_REDIRECT_URI: 'https://remsly.tail276105.ts.net/openidc'
|
||||
APACHE_DEBUG_LEVEL: 'warn'
|
||||
BACKEND_URL: 'backend'
|
||||
BACKEND_PORT: '5050'
|
||||
volumes:
|
||||
- ./config/frontend/apache2.conf:/etc/apache2/apache2.conf
|
||||
- ./certbot/etc:/etc/letsencrypt
|
||||
- ./data/www:/var/www
|
||||
- ./config/frontend/app.boxi.ch.conf:/etc/apache2/sites-enabled/app.boxi.ch.conf
|
||||
- ./config/frontend/id.boxi.ch.conf:/etc/apache2/sites-enabled/id.boxi.ch.conf
|
||||
ports:
|
||||
- '80:80'
|
||||
- '443:443'
|
||||
- ./frontend/apache2.conf:/etc/apache2/apache2.conf
|
||||
- ./frontend/app.boxi.ch.conf:/etc/apache2/sites-enabled/app.boxi.ch.conf
|
||||
network_mode: service:tailscale-apache
|
||||
depends_on:
|
||||
- keycloak
|
||||
- tailscale-apache
|
||||
|
||||
#backend:
|
||||
#image: boxi.registry.jetbrains.space/p/boxit/containers/boxit-backend:2023.1.36
|
||||
# restart: always
|
||||
# networks:
|
||||
# boxitNet:
|
||||
# ipv4_address: 10.5.0.40
|
||||
# depends_on:
|
||||
# - postgres
|
||||
# - keycloak
|
||||
backend:
|
||||
image: gitea.tail276105.ts.net/remsly/remsly-backend:3
|
||||
restart: always
|
||||
networks:
|
||||
- remslyNet
|
||||
environment:
|
||||
# The CI-built image ships no application.properties, so mount one and activate it.
|
||||
SPRING_CONFIG_ADDITIONAL_LOCATION: 'file:/config/application.properties'
|
||||
# Secrets referenced as ${...} placeholders inside the mounted properties file.
|
||||
REMSLY_PSQL_PASSWORD: ${REMSLY_PSQL_PASSWORD}
|
||||
ELASTIC_PASSWORD: ${ELASTIC_PASSWORD}
|
||||
KEYCLOAK_RESOURCE: ${KEYCLOAK_RESOURCE}
|
||||
volumes:
|
||||
- ./backend/application.properties:/config/application.properties:ro
|
||||
depends_on:
|
||||
- postgres
|
||||
- elasticsearch
|
||||
- tailscale-id
|
||||
|
||||
networks:
|
||||
boxitNet:
|
||||
driver: bridge
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.5.0.0/16
|
||||
elasticsearch:
|
||||
image: gitea.tail276105.ts.net/remsly/elasticsearch:3
|
||||
restart: always
|
||||
volumes:
|
||||
- elasticsearch:/usr/share/elasticsearch/data
|
||||
networks:
|
||||
- remslyNet
|
||||
environment:
|
||||
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
|
||||
- discovery.type=single-node
|
||||
- xpack.license.self_generated.type=basic
|
||||
|
||||
tailscale-id:
|
||||
image: tailscale/tailscale:latest
|
||||
hostname: remsly-id
|
||||
environment:
|
||||
TS_AUTHKEY: ${TS_AUTHKEY}
|
||||
TS_USERSPACE: "true"
|
||||
TS_STATE_DIR: /var/lib/tailscale
|
||||
TS_SERVE_CONFIG: /config/serve.json
|
||||
TS_EXTRA_ARGS: --advertise-tags=tag:server
|
||||
volumes:
|
||||
- tailscale-id:/var/lib/tailscale
|
||||
- ./tailscale/serve-id.json:/config/serve.json
|
||||
networks:
|
||||
remslyNet:
|
||||
# Let the backend reach Keycloak via its external URL over the internal network:
|
||||
# the FQDN resolves to this sidecar, hits tailscale serve on :443 (valid LE cert)
|
||||
# and is proxied to Keycloak. Keeps the token issuer == auth-server-url.
|
||||
aliases:
|
||||
- remsly-id.tail276105.ts.net
|
||||
restart: unless-stopped
|
||||
|
||||
tailscale-apache:
|
||||
image: tailscale/tailscale:latest
|
||||
hostname: remsly
|
||||
environment:
|
||||
TS_AUTHKEY: ${TS_AUTHKEY}
|
||||
TS_USERSPACE: "true"
|
||||
TS_STATE_DIR: /var/lib/tailscale
|
||||
TS_SERVE_CONFIG: /config/serve.json
|
||||
TS_EXTRA_ARGS: --advertise-tags=tag:server
|
||||
volumes:
|
||||
- tailscale-apache:/var/lib/tailscale
|
||||
- ./tailscale/serve-apache.json:/config/serve.json
|
||||
networks:
|
||||
- remslyNet
|
||||
restart: unless-stopped
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,90 @@
|
||||
<VirtualHost *:80>
|
||||
DocumentRoot "/var/www/app"
|
||||
ServerName remsly.tail276105.ts.net
|
||||
# ServerAlias www.${server_name}
|
||||
|
||||
ErrorLog /var/log/apache2/error.log
|
||||
CustomLog /var/log/apache2/access.log combined
|
||||
LogLevel info
|
||||
|
||||
# TLS is terminated by the tailscale sidecar; make mod_auth_openidc and the
|
||||
# app aware that the external scheme is https.
|
||||
RequestHeader set X-Forwarded-Proto "https"
|
||||
|
||||
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
|
||||
Header always set Content-Security-Policy "default-src 'self' ; \
|
||||
script-src 'self' 'unsafe-inline' 'unsafe-eval'; \
|
||||
style-src 'self' use.fontawesome.com 'unsafe-inline'; \
|
||||
font-src 'self' data: use.fontawesome.com; \
|
||||
base-uri 'self'; \
|
||||
form-action 'self'; \
|
||||
frame-ancestors 'none'; \
|
||||
img-src 'self' data:; \
|
||||
upgrade-insecure-requests" "expr=%{CONTENT_TYPE} =~ m#text\/(html|javascript)|application\/pdf|xml#i"
|
||||
Header always append X-Frame-Options SAMEORIGIN
|
||||
Header always set X-Content-Type-Options nosniff
|
||||
Header always set Referrer-Policy "same-origin"
|
||||
# this feature is not yet used and must be extended if needed, currently only a sample config
|
||||
Header always set Feature-Policy "payment 'none';"
|
||||
|
||||
<Directory />
|
||||
AllowOverride none
|
||||
Options -Indexes -Includes
|
||||
Require all granted
|
||||
<LimitExcept GET POST HEAD>
|
||||
deny from all
|
||||
</LimitExcept>
|
||||
</Directory>
|
||||
|
||||
<Directory "/var/www/app">
|
||||
AllowOverride None
|
||||
Options -Indexes -Includes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
RequestHeader set X-Forwarded-User expr=%{REMOTE_USER}
|
||||
RequestHeader set Authorization "Bearer %{oidc_access_token}e"
|
||||
Header set User-Details "%{REMOTE_USER}e %{oidc_claim_email}e"
|
||||
|
||||
OIDCProviderMetadataURL ${KC_ADDR}/realms/${KC_REALM}/.well-known/openid-configuration
|
||||
OIDCClientID ${OIDC_CLIENT_ID}
|
||||
OIDCClientSecret ${OIDC_CLIENT_SECRET}
|
||||
OIDCRefreshAccessTokenBeforeExpiry 10
|
||||
OIDCRedirectURI ${OIDC_REDIRECT_URI}
|
||||
OIDCCryptoPassphrase ${OIDC_CRYPTO_PASSPHRASE}
|
||||
OIDCInfoHook ${OIDC_INFO_HOOK}
|
||||
OIDCDefaultLoggedOutURL ${KC_ADDR}/realms/${KC_REALM}/protocol/openid-connect/logout?redirect_uri=https%3A%2F%2Fremsly.tail276105.ts.net
|
||||
OIDCRemoteUserClaim preferred_username
|
||||
OIDCStateMaxNumberOfCookies 3 true
|
||||
|
||||
<Location /status >
|
||||
SetHandler server-status
|
||||
</Location>
|
||||
|
||||
<Location />
|
||||
AuthType openid-connect
|
||||
Require valid-user
|
||||
</Location>
|
||||
|
||||
# If the browser is allowed to cache index.html, it starts loading assets/scripts/images before apache had a chance
|
||||
# to check whether or not the user is even authenticated, leading to many failed requests.
|
||||
# Disabling cache for index.html forces the browser to fetch it first, and therefore ensures that the full
|
||||
# authentication mechanic is being run.
|
||||
# See also https://github.com/zmartzone/mod_auth_openidc/issues/113
|
||||
<filesMatch "index.html">
|
||||
FileETag None
|
||||
Header unset ETag
|
||||
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
|
||||
Header set Pragma "no-cache"
|
||||
Header set Expires "Mon, 21 Mar 1983 14:10:00 UTC"
|
||||
</filesMatch>
|
||||
|
||||
#ProxyPass /ws ${FRONTEND_WS_URL}:${FRONTEND_PORT}/ws retry=0 timeout=86400
|
||||
#ProxyPassReverse /ws ws://${FRONTEND_URL}:${FRONTEND_PORT}/ws
|
||||
|
||||
#ProxyPass /api/ ${BACKEND_URL}:${BACKEND_PORT}/api/ retry=0
|
||||
#ProxyPassReverse /api/ ${BACKEND_URL}:${BACKEND_PORT}/api/
|
||||
|
||||
#ProxyPass / ${FRONTEND_URL}:${FRONTEND_PORT}/ retry=0
|
||||
#ProxyPassReverse / ${FRONTEND_URL}:${FRONTEND_PORT}
|
||||
</VirtualHost>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 176 files, more files were not shown because too many files have changed in this diff.
Show more