Cappy is intended as a data catalogue of applications — an Application Catalogue.
It is built using FilamentPHP, which itself runs on Laravel.
git clone https://github.com/bcgov/cappy.git
cd cappy# Install WSL
wsl --install
# Set WSL 2 as default
wsl --set-default-version 2
# Install Docker Desktop and ensure:
# - WSL 2 engine is enabled (Settings → General → Use WSL 2 Based Engine)
# - WSL Integration is enabled for your distro (Settings → WSL Integration)
# Set your default distro
wsl -s Ubuntu
# View installed distros (optional)
wsl --list
# Open WSL and navigate to your repo (example path)
cd /mnt/c/Users/{username}/Documents/GitHub/cappyThe following commands are the same for WSL, macOS, and Linux:
composer installSail is included automatically.
nano ~/.bashrc
# or
nano ~/.zshrcAdd:
alias sail='./vendor/bin/sail'Restart your terminal.
# Start
sail up -d
# Stop
sail downcp .env.example .env
sail artisan key:generate
sail artisan migrate
sail artisan db:seedUse these connection details:
Host: localhost
Port: 5432
User: sail
Password: password
Database: laravel
sail artisan make:filament-userBy default you will receive the user role (view-only).
To assign admin or editor:
sail artisan assign-user-roleYour app should now be available at:
http://localhost/
# Create a model and migration
sail artisan make:model Test -mExample migration structure:
Schema::create('tests', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::dropIfExists('tests');Run the migration:
sail artisan migratesail artisan make:seeder TestSeederExample seeder:
Test::create(['name' => 'Name One']);
Test::create(['name' => 'Name Two']);Run the seeder:
sail artisan db:seed --class=TestSeedersail artisan make:filament-resource Test --viewDefine the form:
return $form->schema([
Forms\Components\TextInput::make('name')->required(),
]);Define the table:
return $table->columns([
Tables\Columns\TextColumn::make('name')
->searchable()
->sortable(),
]);Some views allow exporting CSV/Excel files. The queue worker should run automatically, but you may manually run it:
sail artisan queue:workMailhog is available locally at:
http://localhost:8025
It will capture outgoing emails such as password reset messages.
- Official documentation: https://laravel.com/docs
- Interactive tutorial: https://bootcamp.laravel.com
- Video library: https://laracasts.com
Laravel is open-sourced software licensed under the MIT license.
Cappy uses PostgreSQL v17. The database runs as a standalone PostgreSQL instance deployed inside OpenShift. Full installation and operational instructions are available in this repository:
Database README: https://github.com/kiiskila-bcgov/app-insight-platform/blob/main/postgres/README.md
- Standard PostgreSQL v17 installation
- Deployed via Helm (no operator required)
- Works in any OpenShift environment
- Does not require cluster-admin permissions
- Runs as a single-instance StatefulSet backed by a PVC
- Uses the official
postgres:17-alpineimage
Follow the steps in the linked README, which include:
-
Deploying the database via Helm:
helm install postgres . -
Verifying the StatefulSet and pod readiness:
oc get statefulset postgres oc wait --for=condition=ready pod/postgres-0 --timeout=300s -
Retrieving the autogenerated
postgrespassword:oc get secret postgres-credentials \ -o jsonpath='{.data.password}' | base64 -d
After deployment, the service will be available internally:
Host: postgres.<namespace>.svc.cluster.local
Port: 5432
Database: postgres
Username: postgres
Password: (from the secret)
For local development access:
oc port-forward svc/postgres 5432:5432Then connect with any PostgreSQL client (e.g., psql, TablePlus, DBeaver).
You may customize your instance by editing values.yaml, including:
- Image version
- Resource requests/limits
- Storage size
- PostgreSQL config parameters
See the linked README for examples.
- This deployment is not HA (single pod)
- Intended for development and small-scale production workloads
- Stores data on a PVC (persists across restarts)
Cappy is deployed to OpenShift using a custom Docker image, Helm charts, and GitHub Actions–based CI/CD. This section summarizes how the application is built and deployed.
The application image is defined in the project Dockerfile, which uses:
- PHP 8.3 with Apache
- Required system packages for PostgreSQL (
pdo_pgsql,pgsql) - Vite asset building via Node.js
- Composer dependencies installed with optimized autoloading
- Correct Apache configuration for a Laravel public directory
- Proper file permissions for storage, logs, and cache
Full Dockerfile: https://github.com/bcgov/cappy/blob/main/Dockerfile
The build process includes:
- Installing PHP extensions
- Running
npm installandnpm run build - Running
composer install --no-dev - Setting up directory permissions
- Exposing port 8080
The Helm chart handles all required OpenShift resources:
- Deployment (
cappy-app) - Worker Deployment (
cappy-queue-worker) - Service
- PVC for persistent storage
- NetworkPolicies
Helm chart location: https://github.com/bcgov/cappy/tree/main/helm
To deploy or upgrade manually:
helm upgrade --install cappy ./helm --set image.tag=<image-tag>The repository includes a CI/CD workflow that:
- Builds the Docker image
- Pushes it to GitHub Container Registry (GHCR)
- Authenticates to OpenShift
- Performs a Helm upgrade
- Restarts deployments
Workflow file: https://github.com/bcgov/cappy/blob/main/.github/workflows/build-and-deploy.yaml
Create environments:
Settings → Environments → New Environment
Create two:
devprod
Each environment must define:
Variables
OPENSHIFT_NAMESPACE=<your-namespace>
OPENSHIFT_SERVER=https://api.silver.devops.gov.bc.ca:6443
Secrets
OPENSHIFT_TOKEN=<service-account-token>
export SA=github-actions-sa
oc create sa $SA
# After OpenShift 4.12, tokens are not auto-generated.
# Create a token secret manually:
cat <<EOF > service-account-token.yaml
apiVersion: v1
kind: Secret
metadata:
name: github-actions-sa-token
annotations:
kubernetes.io/service-account.name: github-actions-sa
type: kubernetes.io/service-account-token
EOF
oc apply -f service-account-token.yamlThen assign permissions:
oc policy add-role-to-user edit system:serviceaccount:<your-namespace>:github-actions-saAfter the secret appears in OpenShift, copy the token value into the OPENSHIFT_TOKEN GitHub secret.
Create an OpenShift secret named:
cappy-secrets
This secret must contain production environment values such as:
APP_KEY=<app-key>
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_USERNAME=laravel
DB_PASSWORD=<password>
DB_DATABASE=laravel
MAIL_HOST=apps.smtp.gov.bc.ca
MAIL_PORT=25
CACHE_DRIVER=database
APP_DEBUG=false
APP_NAME=cappy
APP_ENV=production
APP_TIMEZONE=America/Vancouver
ASSET_URL=<your-public-openshift-route>
APP_URL=<your-public-api-url>
Values should be adjusted for the target namespace/environment.
This application uses the BCGov APS Gateway (Kong) for routing and authentication. Follow the steps below to configure a new gateway, apply the route, and enable IDIR authentication.
Go to:
- API Directory: https://api.gov.bc.ca/devportal/api-directory
- Sign in as an API Provider.
Reference docs: https://developer.gov.bc.ca/docs/default/component/aps-infra-platform-docs/tutorials/quick-start/
Install the GWA CLI (if not installed), then log in:
gwa loginCreate a new gateway:
gwa gateway createList gateways to find the newly created one:
gwa gateway listCopy the gateway ID (format: gw-xxxxxx), you'll need it in the next step.
Open the project’s gateway config file:
helm/gw-config.yaml
Update the following:
- Replace
gw-xxxxwith the new gateway ID. - Set the route host you want (the public hostname users will access).
- Fill in fields tagged as # CSS with values from the SSO integration (next step).
- Ensure the service URL matches the name of your OpenShift service (e.g.
http://cappy-service.a2edba-dev.svc.cluster.local).
Go to the CSS (Common Services) team portal:
Request a new integration using IDIR authentication.
Copy the fields into the appropriate places in gw-config.yaml (all fields marked # CSS).
When gw-config.yaml is fully updated, apply it:
gwa apply -i gw-config.yamlWatch the deployment:
gwa status --hostsWait until the hostname shows as 200 UP.
Once deployed, access the app using the hostname set in the route.
- The gateway will enforce IDIR authentication.
- Successful authentication will forward the request to your OpenShift service.