Skip to content
Open
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
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
build
.env
.env.local
.git
24 changes: 12 additions & 12 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
# SPDX-FileCopyrightText: © 2025 Siemens AG
# SPDX-FileContributor: Dearsh Oberoi <dearsh.oberoi@siemens.com>

REACT_APP_BASE_URL='http://localhost:5000/api/v1'
REACT_APP_DOMAIN_SUBDIRECTORY=''
PUBLIC_URL='http:localhost:3000'
# Vite build configuration
VITE_BASE_URL=/api/v1
VITE_DOMAIN_SUBDIRECTORY=

# possible values are oidc or password. If password, ui for username-password
# login will be shown, otherwise, ui for oidc will be shown.
# if unset or some other value, username-password login flow will be shown by default
REACT_APP_PROVIDER='password'
# Full-stack Docker Compose configuration
# The backend repository must be checked out next to this repository.
LICENSEDB_BACKEND_CONTEXT=../LicenseDb
LICENSEDB_UI_PORT=8081

#OIDC
REACT_APP_CLIENT_ID='client-id'
REACT_APP_AUTH_URL='provider authorization url'
REACT_APP_TOKEN_URL='provider token url'
REACT_APP_REDIRECT_URL='provider redirect url'
POSTGRES_USER=fossy
POSTGRES_PASSWORD=change-me
POSTGRES_DB=fossology
POPULATE_DB=true
GIN_MODE=debug
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

node_modules/
.env
package-lock.json
.env.local
.npm/
dist/
build/
Expand Down
24 changes: 24 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: 2026 Siemens AG
# SPDX-License-Identifier: GPL-2.0-only
FROM node:22-alpine AS build

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci

COPY . ./

ARG VITE_BASE_URL=/api/v1
ARG VITE_DOMAIN_SUBDIRECTORY=
ENV VITE_BASE_URL=$VITE_BASE_URL
ENV VITE_DOMAIN_SUBDIRECTORY=$VITE_DOMAIN_SUBDIRECTORY

RUN npm run build

FROM nginx:1.27-alpine

COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/build /usr/share/nginx/html

EXPOSE 80
95 changes: 73 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,76 @@ LicenseDB backend at [http://localhost:8080/swagger/index.html](http://localhost
- ```npm```
- Using a Node version manager like [```nvm```](https://github.com/nvm-sh/nvm) is strongly recommended for installing ```NodeJS``` and ```npm```.

## Set Up

- Set the following environment variables:
- ```REACT_APP_DOMAIN_SUBDIRECTORY```: The basename of the app for situations where you can't deploy to the root of the domain, but a sub directory.
- ```PUBLIC_URL```: The URL at which the application is hosted, along with the subdirectory.
- ```REACT_APP_BASE_URL```: The URL at which backend of the application is hosted.
- ```REACT_APP_PROVIDER```: ```oidc``` or ```password```. Used to configure login mechanism of the application as OIDC or username-password.
- ```REACT_APP_CLIENT_ID```: The client id of the app instance registered with the OIDC tenant.
- ```REACT_APP_AUTH_URL```: The authorization url of the app instance registered with the OIDC tenant.
- ```REACT_APP_TOKEN_URL```: The token url of the app instance registered with the OIDC tenant.
- ```REACT_APP_REDIRECT_URL```=```http://localhost:3000/redirect```

See .env.example for more details.
- Install dependencies
``` bash
npm install
```
- Run application
```bash
npm start
```
- If everything went well, the localhost port 3000 will be opened in your host and you will be able to access the application.
## Full-Stack Docker Compose Development

The frontend Compose file starts the UI, LicenseDB API, and PostgreSQL as one
stack. It expects a sibling checkout named `LicenseDb`:

```text
workspace/
LicenseDb/
LicenseDb-UI/
```

From `LicenseDb-UI`, create a local configuration file and start the stack:

```bash
cp .env.example .env
docker compose up --build --wait
```

Open `http://localhost:8081`. The browser reaches the API through the UI at
`/api/v1`; PostgreSQL and the API are not published to the host.

To use a differently named sibling checkout, such as a feature branch clone,
set `LICENSEDB_BACKEND_CONTEXT` in `.env` to its relative or absolute path.

Validate and stop the stack with:

```bash
docker compose config -q
docker compose ps
curl -fsS http://localhost:8081/api/v1/health
docker compose down
```

Do not run this stack alongside the backend repository's standalone Compose
stack. Each stack creates its own API and PostgreSQL services. Use the frontend
Compose file for full-stack development and deployment; keep the backend
Compose file for API-only development.

### Systemd Deployment

For a server deployment, check out `LicenseDb` and `LicenseDb-UI` as siblings
under `/opt/licensedb`, then place the real Compose variables in
`/etc/licensedb/.env`. Do not commit this file.

Build the images once after source updates:

```bash
cd /opt/licensedb/LicenseDb-UI
sudo /usr/bin/docker compose --env-file /etc/licensedb/.env build
```

Install [docs/licensedb-compose.service](docs/licensedb-compose.service) as
`/etc/systemd/system/licensedb-compose.service`, adjusting the working
directory if needed. Then enable it:

```bash
sudo systemctl daemon-reload
sudo systemctl enable --now licensedb-compose.service
```

The unit starts the UI, API, and PostgreSQL after Docker and the network are
available. It waits for their health checks but does not rebuild images during
every server boot.

## Local Frontend Development

Set `VITE_BASE_URL` and `VITE_DOMAIN_SUBDIRECTORY` in `.env.local` as needed.
Then install dependencies and start Vite:

```bash
npm ci
npm run dev
```
71 changes: 71 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# SPDX-FileCopyrightText: 2026 Siemens AG
# SPDX-License-Identifier: GPL-2.0-only
services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: ${POSTGRES_USER:?set POSTGRES_USER in .env}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
POSTGRES_DB: ${POSTGRES_DB:?set POSTGRES_DB in .env}
volumes:
- pgdata:/var/lib/postgresql/data
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready --dbname $$POSTGRES_DB --username $$POSTGRES_USER"]
interval: 10s
timeout: 5s
retries: 5
networks:
- licensedb-network

licensedb:
build:
context: ${LICENSEDB_BACKEND_CONTEXT:-../LicenseDb}
environment:
DB_HOST: postgres
DB_PORT: 5432
DB_USER: ${POSTGRES_USER:?set POSTGRES_USER in .env}
DB_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
DB_NAME: ${POSTGRES_DB:?set POSTGRES_DB in .env}
POPULATE_DB: ${POPULATE_DB:-true}
GIN_MODE: ${GIN_MODE:-debug}
depends_on:
postgres:
condition: service_healthy
restart: always
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://localhost:8080/api/v1/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 45s
networks:
- licensedb-network

web:
build:
context: .
args:
VITE_BASE_URL: ${VITE_BASE_URL:-/api/v1}
VITE_DOMAIN_SUBDIRECTORY: ${VITE_DOMAIN_SUBDIRECTORY:-}
ports:
- "${LICENSEDB_UI_PORT:-8081}:80"
depends_on:
licensedb:
condition: service_healthy
restart: always
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://localhost/"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
networks:
- licensedb-network

networks:
licensedb-network:
driver: bridge

volumes:
pgdata:
21 changes: 21 additions & 0 deletions docs/licensedb-compose.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: 2026 Siemens AG
# SPDX-License-Identifier: GPL-2.0-only

[Unit]
Description=LicenseDB full-stack Docker Compose deployment
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/licensedb/LicenseDb-UI
EnvironmentFile=/etc/licensedb/.env
ExecStartPre=/usr/bin/docker compose --env-file /etc/licensedb/.env config -q
ExecStart=/usr/bin/docker compose --env-file /etc/licensedb/.env up -d --wait --wait-timeout 180
ExecStop=/usr/bin/docker compose --env-file /etc/licensedb/.env down
TimeoutStartSec=200

[Install]
WantedBy=multi-user.target
23 changes: 23 additions & 0 deletions nginx/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
server {
listen 80;
listen [::]:80;
server_name _;

root /usr/share/nginx/html;
index index.html;

location /api/v1/ {
resolver 127.0.0.11 ipv6=off;
set $backend http://licensedb:8080;
proxy_pass $backend;
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;
}

location / {
try_files $uri $uri/ /index.html;
}
}