Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,31 @@
# copy these lines into `.env.development` or `.env` (see Vite docs at https://vite.dev/guide/env-and-mode) and adjust as needed for local development
VITE_BACKEND_URL=http://localhost:8080 # backend API URL used by the frontend (dev server proxy target)
VITE_SERVER_PORT=5173 # dev server port
VITE_ENABLE_HTTPS=false # set true to serve the GUI over HTTPS
VITE_HTTPS_CERT_FILE= # required when VITE_ENABLE_HTTPS=true
VITE_HTTPS_KEY_FILE= # required when VITE_ENABLE_HTTPS=true
VITE_VERIFY_SSL=false # set true to verify the backend TLS certificate
VITE_USE_POLLING=false # set true when the filesystem does not emit file events reliably

########## Docker Compose (dev) ##########
# Values used by `docker-compose.dev.yml`. Compose will substitute ${VAR} from the
# project `.env` or the shell environment when you run `docker compose`.
VITE_APP_VERSION=development
VITE_BACKEND_URL=http://host.docker.internal:8080 # backend API URL used by the frontend inside the container (resolved via Compose host mapping)
VITE_SERVER_PORT=5173 # dev server port inside the container
VITE_ENABLE_HTTPS=false # set true to serve the GUI over HTTPS
VITE_HTTPS_CERT_FILE=/app/certs/server.crt # certificate mounted from ./certs
VITE_HTTPS_KEY_FILE=/app/certs/server.key # certificate key mounted from ./certs
VITE_VERIFY_SSL=false # set true to verify the backend TLS certificate
DOCKER_HOST_PORT=5173 # port on the host machine mapped to the container's VITE_SERVER_PORT (for browser access)

########## Production (nginx) ##########
# Values used at container runtime by nginx to proxy /api/
NGINX_BACKEND_URL=http://host.docker.internal:8080/ # backend API URL used by nginx inside the container (resolved via Compose host mapping)
# Values used at container runtime by nginx to serve HTTPS and proxy /api/.
SOARCA_GUI_VERSION=latest # Docker Hub image tag
SOARCA_CERTS_VOLUME=soarca_certs_data_container # external volume created by SOARCA
NGINX_BACKEND_URL=https://host.docker.internal:8080/ # backend API URL used by nginx inside the container
NGINX_SERVER_PORT=8081 # port nginx listens on inside the container
NGINX_CERT_FILE=/app/certs/server.crt # TLS certificate mounted from SOARCA_CERTS_VOLUME
NGINX_CERT_KEY_FILE=/app/certs/server.key # TLS certificate key mounted from SOARCA_CERTS_VOLUME
NGINX_PROXY_SSL_VERIFY=off # set to on when the backend certificate is trusted
DOCKER_HOST_PORT=8081 # port on the host machine mapped to the container's NGINX_SERVER_PORT (for browser access)
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ jobs:
target: production
tags: cossas/soarca-gui:pr-${{ env.describe_version }}
build-args: |
VERSION=${{ env.describe_version }}
VITE_APP_VERSION=${{ env.describe_version }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to not use plain version?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use it to later on inject it into the build of the app and it needs to start with VITE_ to be used.

builder: default
3 changes: 1 addition & 2 deletions .github/workflows/development-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,14 @@ jobs:

- name: Get version
run: |
export VERSION=$(git describe --tags --dirty)
echo "describe_version=$(git describe --tags --dirty)" >> "$GITHUB_ENV"

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
build-args: |
VERSION=${{ env.describe_version }}
VITE_APP_VERSION=${{ env.describe_version }}
push: true
target: production
tags: cossas/soarca-gui:${{ env.describe_version }},cossas/soarca-gui:development
135 changes: 51 additions & 84 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
tags:
- '[0-9]+.[0-9]+.[0-9]+\-?*'

permissions:
contents: read

jobs:
build:
name: Build with npm
Expand All @@ -14,8 +17,7 @@ jobs:
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Make repo safe
run: git config --global --add safe.directory /__w/SOARCA/SOARCA-GUI

- name: Use Node.js 24
uses: actions/setup-node@v6
with:
Expand All @@ -37,41 +39,35 @@ jobs:
- name: Build with npm
run: npm run build

- name: "Upload Artifact"
- name: Prepare release SBOM
run: |
cp dist/cyclonedx/bom.json "soarca-gui-${GITHUB_REF_NAME}.cdx.json"
zip sbom.zip "soarca-gui-${GITHUB_REF_NAME}.cdx.json"

- name: Upload SBOM artifact
uses: actions/upload-artifact@v6
with:
name: ${{ github.sha }}
path: dist/*
name: release-sbom
path: sbom.zip
if-no-files-found: error
retention-days: 1

docker-build:
needs: build
name: Build docker image and push it to docker hub
name: Build Docker image and push it to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Checkout Code
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Make repo safe
run: git config --global --add safe.directory /__w/SOARCA-GUI/SOARCA-GUI

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Download dist
uses: actions/download-artifact@v7
with:
pattern: ${{ github.sha }}

- name: Move files to bin folder and make executable
run: |
mkdir -p bin
mv ${{ github.sha }}/* ./bin/
chmod +x bin/soarca-gui-*

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
Expand All @@ -80,80 +76,51 @@ jobs:

- name: Get version
run: |
export VERSION=$(git describe --tags --dirty)
echo "describe_version=$(git describe --tags --dirty)" >> "$GITHUB_ENV"

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
build-args: |
VERSION=${{ env.describe_version }}
push: false
tags: cossas/soarca-gui:${{ env.describe_version }},cossas/soarca-gui:latest

release-artifacts:
VITE_APP_VERSION=${{ env.describe_version }}
push: true
target: production
tags: |
cossas/soarca-gui:${{ env.describe_version }}
cossas/soarca-gui:latest

publish-sbom:
needs: build
name: Create release artifacts
name: Publish SBOM to the GitHub release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: "1.23.x"
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
- name: Checkout Code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Make repo safe
run: git config --global --add safe.directory /__w/SOARCA-GUI/SOARCA-GUI

- name: Setup node
uses: actions/setup-node@v6
- name: Download SBOM artifact
uses: actions/download-artifact@v7
with:
node-version: 24
- run: npm ci
name: release-sbom

- name: Build and sbom
run: |
go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@latest
go install github.com/a-h/templ/cmd/templ@v0.3.819
make sbom
zip -r bin/sbom.zip bin

- name: Release soarca gui binary
uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser
version: latest
args: release --clean
workdir: server
- name: Create GitHub release and publish SBOM
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}

- name: Upload release sbom
uses: actions/github-script@v4
with:
script: |
const fs = require('fs');
const tag = context.ref.replace("refs/tags/", "");
// Get release for this tag
const release = await github.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag
});
// Upload the release asset
await github.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: release.data.id,
name: "sbom.zip",
data: await fs.readFileSync("bin/sbom.zip")
});
GH_TOKEN: ${{ github.token }}
run: |
if ! gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then
if [[ "$GITHUB_REF_NAME" == *-* ]]; then
gh release create "$GITHUB_REF_NAME" \
--verify-tag \
--generate-notes \
--prerelease \
--title "$GITHUB_REF_NAME"
else
gh release create "$GITHUB_REF_NAME" \
--verify-tag \
--generate-notes \
--title "$GITHUB_REF_NAME"
fi
fi

gh release upload "$GITHUB_REF_NAME" \
sbom.zip \
--clobber
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ lerna-debug.log*

node_modules
dist
certs
dist-ssr
*.local
*.tsbuildinfo
Expand Down
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
FROM node:24-alpine AS builder
RUN apk add --no-cache git
WORKDIR /app
ARG VITE_APP_VERSION=development
ENV VITE_APP_VERSION=${VITE_APP_VERSION}
COPY package*.json ./
RUN npm install
RUN npm ci
COPY . .
RUN npm run build
RUN npm run build && rm -rf dist/cyclonedx

# Serve with nginx
FROM nginx:alpine AS production
Expand Down
40 changes: 30 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ flowchart TB

- `VITE_BACKEND_URL` - Backend API URL (proxied by Vite dev server)
- `VITE_SERVER_PORT` - Port where Vite dev server listens
- `VITE_ENABLE_HTTPS` - Set to `true` to serve the development or preview build over HTTPS
- `VITE_HTTPS_CERT_FILE` - Path to the TLS certificate used by Vite
- `VITE_HTTPS_KEY_FILE` - Path to the TLS certificate key used by Vite
- `VITE_VERIFY_SSL` - Set to `true` to verify the backend certificate when Vite proxies API requests
- `DOCKER_HOST_PORT` - The port of the host machine that is mapped to the `VITE_SERVER_PORT` of the Vite dev server running in the container. This is only relevant when running the Development Container.
- `HOST_PORT` - is the same of the `VITE_SERVER_PORT` if run locally or `DOCKER_HOST_PORT` if running the Development Container.

Expand All @@ -125,7 +129,12 @@ flowchart TB

If no enviroment variables are provided, the defaults are:
- `VITE_BACKEND_URL`: `http://localhost:8080` - (SOARCA default)
- `VITE_SERVER_PORT`: `5713` - (Vite default)
- `VITE_SERVER_PORT`: `5173` - (Vite default)
- `VITE_ENABLE_HTTPS`: `false`

To enable HTTPS, set `VITE_ENABLE_HTTPS=true` and provide
`VITE_HTTPS_CERT_FILE` and `VITE_HTTPS_KEY_FILE`. Set
`VITE_BACKEND_URL=https://localhost:8080` when SOARCA also uses HTTPS.

3. **Start the dev server:**

Expand All @@ -145,6 +154,10 @@ flowchart TB
- `VITE_SERVER_PORT`: `5173`
- `DOCKER_HOST_PORT` — port on the host mapped to the `VITE_SERVER_PORT` (default: `5173`)

For HTTPS, place `server.crt` and `server.key` in `./certs`, then set
`VITE_ENABLE_HTTPS=true`. The development Compose file mounts that directory
read-only at `/app/certs`.

2. **Start the container:**
```bash
docker compose -f docker-compose.dev.yml up
Expand Down Expand Up @@ -257,10 +270,14 @@ flowchart TB

**Environment variables involved:**

- `VITE_BACKEND_URL` - Backend API URL embedded into the client bundle at build time (must be set before running `npm run build`)
- `VITE_APP_VERSION` - Application version embedded into the client bundle at build time (optional, falls back to git describe or "development")
- `NGINX_BACKEND_URL` - Backend API URL used by Nginx at runtime to proxy `/api/*` requests. This is only relevant when running in Docker Container Mode.
- `NGINX_SERVER_PORT` - Port where Nginx listens inside the container. This is only relevant when running in Docker Container Mode.
- `NGINX_CERT_FILE` - TLS certificate path inside the container
- `NGINX_CERT_KEY_FILE` - TLS certificate key path inside the container
- `NGINX_PROXY_SSL_VERIFY` - Controls verification of the backend TLS certificate
- `SOARCA_CERTS_VOLUME` - External Docker volume containing the SOARCA TLS certificate and key
- `SOARCA_GUI_VERSION` - Docker Hub image tag to run, defaulting to `latest`
- `DOCKER_HOST_PORT` - The port of the host machine that is mapped to the `NGINX_SERVER_PORT` of the Nginx server running in the container. This is only relevant when running in Docker Container Mode.
- `HOST_PORT` - Port 4173 (Vite default) for local preview mode (`npm run preview`) or `DOCKER_HOST_PORT` when running in Docker Container Mode.

Expand All @@ -276,7 +293,7 @@ flowchart TB
Optionally create a `.env` file (explanation and defaults can be found in `.env.example`). Note that `VITE_` variables must be set at _build time_ to be embedded into the static bundle.

If no environment variables are provided, the defaults are:
- `VITE_BACKEND_URL`: `http://localhost:8080` - (SOARCA default)
- `VITE_ENABLE_HTTPS`: `false`

3. **Build and preview:**

Expand All @@ -293,21 +310,24 @@ flowchart TB
#### Running in Docker Container (recommended for production)

1. **Configure environment variables:**
Optionally provide values via the shell, a project `.env`, or `--env-file` when starting Compose (explanation and defaults can be found in `.env.example`). Note that `VITE_` variables are build-time only (embedded at image build), while `NGINX_` variables are runtime (used by the running container).
Optionally provide values via the shell, a project `.env`, or `--env-file` when starting Compose (explanation and defaults can be found in `.env.example`). The production container serves HTTPS and expects the certificate volume created by the SOARCA deployment.

If no environment variables are provided, the defaults are:
- `VITE_BACKEND_URL`: `http://localhost:8080` - embedded at build time
- `NGINX_BACKEND_URL`: `http://host.docker.internal:8080/` - used at runtime
- `SOARCA_GUI_VERSION`: `latest`
- `SOARCA_CERTS_VOLUME`: `soarca_certs_data_container`
- `NGINX_BACKEND_URL`: `https://host.docker.internal:8080/`
- `NGINX_SERVER_PORT`: `8081`
- `DOCKER_HOST_PORT`: `8081` — port on the host mapped to the `NGINX_SERVER_PORT`
- `NGINX_PROXY_SSL_VERIFY`: `off`, to support SOARCA's generated self-signed certificate
- `DOCKER_HOST_PORT`: `8081` - port on the host mapped to the `NGINX_SERVER_PORT`

2. **Build and start the container:**
2. **Pull and start the container:**

```bash
docker compose up --build
docker compose pull
docker compose up -d
```

The app will be available at `http://localhost:DOCKER_HOST_PORT`.
The app will be available at `https://localhost:DOCKER_HOST_PORT`.

### NPM Scripts for local run

Expand Down
6 changes: 6 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ services:
- NODE_ENV=development
- VITE_BACKEND_URL=${VITE_BACKEND_URL:-http://host.docker.internal:8080}
- VITE_SERVER_PORT=${VITE_SERVER_PORT:-5173}
- VITE_ENABLE_HTTPS=${VITE_ENABLE_HTTPS:-false}
- VITE_HTTPS_CERT_FILE=${VITE_HTTPS_CERT_FILE:-/app/certs/server.crt}
- VITE_HTTPS_KEY_FILE=${VITE_HTTPS_KEY_FILE:-/app/certs/server.key}
- VITE_VERIFY_SSL=${VITE_VERIFY_SSL:-false}
- VITE_IS_DOCKER=true
volumes:
- .:/app
- ./certs:/app/certs:ro
- node_modules_volume:/app/node_modules
command: sh -c "npm install && npm run dev"

Expand Down
Loading
Loading