Skip to content

Add Nginx Proxy & Use 'cvmanager' Schema#13

Closed
dmccoystephenson wants to merge 49 commits intowydot-deployment-2026from
feat/add-nginx-proxy
Closed

Add Nginx Proxy & Use 'cvmanager' Schema#13
dmccoystephenson wants to merge 49 commits intowydot-deployment-2026from
feat/add-nginx-proxy

Conversation

@dmccoystephenson
Copy link
Copy Markdown

@dmccoystephenson dmccoystephenson commented Dec 31, 2025

New Base Branch

The wydot-deployment-2026 branch was created using the 2.0.1 release tag as a base. The following changes were made using the previous changes in the wydot-deployment branch as a reference.

Changes

This pull request enhances the CV Manager's infrastructure by introducing a centralized NGINX proxy and migrating the database to a multi-schema architecture. These changes were made in order to tailor the CV Manager project for the WYDOT deployment environment.

NGINX SSL Proxy Integration

A new cvmanager_nginx_proxy service has been added to handle all incoming traffic, providing:

  • SSL/TLS Termination: Centralized HTTPS management with automatic HTTP-to-HTTPS redirection.
  • Unified Routing: Simplified access to the webapp, API, and Keycloak through a single entry point.

Multi-Schema Database Migration

To improve data isolation and management, the PostgreSQL database has been refactored:

  • Dedicated Schemas: Migrated all core tables and sequences from the public schema to a new cvmanager schema.
  • Keycloak Isolation: Configured Keycloak to operate within its own dedicated keycloak schema.
  • Refactored Access: Updated all API services and SQL scripts to use schema-qualified references, ensuring consistent data access across the application.

Security & Maintenance Updates

  • Global SSL Enforcement: Keycloak is now configured to require SSL for all interactions (sslRequired: all).
  • Secure DB Connections: Introduced PG_SSL_REQUIRED configuration across services to enforce encrypted database communication.
  • Service Optimization: Disabled firmware manager services in the addons configuration to streamline deployments.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces significant infrastructure and database changes to the CV Manager project to support the WYDOT deployment environment. The changes include adding an NGINX SSL proxy for centralized traffic management and migrating the database from a single-schema to a multi-schema architecture.

Key Changes

  • Addition of an NGINX reverse proxy service with SSL/TLS termination, rate limiting, and unified routing for webapp, API, and Keycloak services
  • Migration of all database tables and sequences from the public schema to a dedicated cvmanager schema, with Keycloak isolated in its own keycloak schema
  • Introduction of SSL support for PostgreSQL connections with configurable SSL verification

Reviewed changes

Copilot reviewed 70 out of 71 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
docker-compose.yml Added nginx_proxy service, updated Keycloak configuration for proxy support, removed direct port mappings for webapp and API
resources/nginx/* New NGINX configuration files, Dockerfile, SSL certificate generation scripts, and documentation
services/common/pgquery.py Added SSL context handling for PostgreSQL connections
services/api/src/middleware.py Added configurable Keycloak SSL verification
resources/sql_scripts/* Updated all CREATE/ALTER statements to use cvmanager schema
services/*/**.py Updated all SQL queries to reference cvmanager schema instead of public
sample.env Updated endpoints to use HTTPS and consolidated routing through NGINX proxy
resources/keycloak/realm.json Updated SSL requirement to 'all' and redirect URIs to HTTPS

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# We mount the config in docker-compose, but we can also copy it here as a default.

# Ensure we have openssl for dhparam generation if needed by the script
RUN apk add --no-network --no-cache openssl || apk add --no-cache openssl
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

Using --no-network with apk add and then falling back to a regular apk add will likely fail in most cases. The --no-network flag is not a standard apk option. This should be simplified to just RUN apk add --no-cache openssl to ensure openssl is installed from the Alpine package repository.

Suggested change
RUN apk add --no-network --no-cache openssl || apk add --no-cache openssl
RUN apk add --no-cache openssl

Copilot uses AI. Check for mistakes.
Comment thread services/common/util.py Outdated
Comment on lines +41 to +52
keycloak_verify = os.getenv("KEYCLOAK_VERIFY", "True")
if keycloak_verify.lower() == "true":
keycloak_verify = True
elif keycloak_verify.lower() == "false":
keycloak_verify = False

keycloak_openid = KeycloakOpenID(
server_url=os.getenv("KEYCLOAK_ENDPOINT"),
realm_name=os.getenv("KEYCLOAK_REALM"),
client_id=os.getenv("KEYCLOAK_API_CLIENT_ID"),
client_secret_key=os.getenv("KEYCLOAK_API_CLIENT_SECRET_KEY"),
verify=keycloak_verify,
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The KEYCLOAK_VERIFY environment variable is set to a file path (/etc/ssl/certs/server.crt), but when used with the KeycloakOpenID library, the verify parameter expects either a boolean or a path to a CA bundle. Since this is a self-signed certificate path, it should point to the CA certificate that signed it, not the server certificate itself. For self-signed certificates in development, this should typically be set to False for development or to a proper CA bundle path.

Copilot uses AI. Check for mistakes.
Comment thread docker-compose.yml Outdated
CREATE TABLE IF NOT EXISTS cvmanager.manufacturers
(
manufacturer_id integer NOT NULL DEFAULT nextval('manufacturers_manufacturer_id_seq'::regclass),
manufacturer_id integer NOT NULL DEFAULT nextval('cvmanager.manufacturers_manufacturer_id_seq'::regclass),
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The sequence names in the DEFAULT clause still reference the old unqualified names (e.g., nextval('manufacturers_manufacturer_id_seq'::regclass)), but they should be schema-qualified to match the new schema structure (e.g., nextval('cvmanager.manufacturers_manufacturer_id_seq'::regclass)). This could cause issues if the search_path is not properly configured.

Copilot uses AI. Check for mistakes.
Comment thread docker-compose.yml
KC_HOSTNAME: ${KEYCLOAK_DOMAIN}
KC_HOSTNAME_PORT: 443
KC_HOSTNAME_STRICT_HTTPS: 'true'
KC_HOSTNAME_STRICT: 'false'
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The KC_HOSTNAME_STRICT is set to 'false' which disables hostname verification. This is a security risk in production environments as it allows requests with any hostname to be accepted. This should be set to 'true' for production deployments and only set to 'false' in development environments if necessary.

Suggested change
KC_HOSTNAME_STRICT: 'false'
KC_HOSTNAME_STRICT: 'true'

Copilot uses AI. Check for mistakes.
Comment thread resources/sql_scripts/CVManager_CreateTables.sql
Comment thread resources/sql_scripts/CVManager_CreateTables.sql
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants