-
Notifications
You must be signed in to change notification settings - Fork 2
OCI Container Deployment
This guide covers deploying TMI to Oracle Cloud Infrastructure (OCI) using container images built on Oracle Linux 9, with Oracle Autonomous Database (ADB) support.
TMI provides specialized container images for OCI deployment:
| Container | Base Image | Purpose | Size |
|---|---|---|---|
| TMI Server | Oracle Linux 9 | API server with Oracle ADB support | ~737MB |
| Redis | Oracle Linux 9-slim | Cache and session storage | ~272MB |
| TMI-UX | Oracle Linux 10-slim | Angular frontend (from tmi-ux repo) | ~350MB |
Key features:
- Oracle Instant Client 23ai - Native Oracle ADB connectivity via godror driver
- Security patches - Applied during container build
- CGO enabled - Required for Oracle database driver
- Multi-architecture - Supports both amd64 and arm64
- Multi-container support - TMI API and Redis run in a single instance for Free Tier optimization
- Docker or Podman
- OCI CLI installed and configured
- Access to an OCI tenancy with Container Registry
- Container Repository in OCI Container Registry
- Oracle Autonomous Database (for production)
- Auth Token for registry authentication
# Optional: Override OCI CLI profile (default: tmi)
export OCI_CLI_PROFILE="tmi"
# Optional: Override region (default: us-ashburn-1)
export OCI_REGION="us-ashburn-1"
# Optional: Override name prefix for registry paths (default: tmi)
export TMI_NAME_PREFIX="tmi"
# Optional: Set auth token for non-interactive registry login
export OCIR_AUTH_TOKEN="<your-auth-token>"# Build TMI server and Redis for OCI (builds, pushes, and scans)
make build-app-oci
# Or build individual components locally with Oracle support
uv run scripts/build-app-containers.py --target oci --component server
uv run scripts/build-app-containers.py --target oci --component redis# Get your tenancy namespace
NAMESPACE=$(oci os ns get --query 'data' --raw-output)
# Login to registry (requires Auth Token from OCI Console)
docker login <region>.ocir.io
# Username: <namespace>/<your-email>
# Password: <auth-token># Push server image
docker push <region>.ocir.io/<namespace>/tmi:latest
# Push Redis image
docker push <region>.ocir.io/<namespace>/tmi-redis:latestOr use the automated build, push, and scan:
make build-app-ociMulti-stage build:
- Builder stage - Oracle Linux 9 with Go 1.26.1 and Oracle Instant Client
- Runtime stage - Oracle Linux 9-slim with minimal dependencies
Features:
- Oracle Instant Client 23ai for ADB connectivity
- Built with
-tags oraclefor Oracle driver support - Non-root user (
tmi) for security - Wallet mount point at
/walletwith automatic extraction fromwallet.zip - Default architecture for OCI target:
linux/arm64(Ampere A1)
Environment Variables:
| Variable | Required | Description |
|---|---|---|
TMI_DATABASE_URL |
Yes | Database connection URL, e.g. oracle://user:password@tns_alias or oracle://user:password@host:port/service_name?wallet_location=/wallet
|
TMI_ORACLE_WALLET_LOCATION |
No | Wallet path (default: set automatically by entrypoint to /tmp/wallet after extraction) |
TMI_REDIS_URL |
Yes | Redis connection URL, e.g. redis://:password@localhost:6379/0
|
TMI_REDIS_HOST |
Alt | Redis host (alternative to TMI_REDIS_URL) |
TMI_REDIS_PORT |
Alt | Redis port (required when using TMI_REDIS_HOST) |
TMI_REDIS_PASSWORD |
No | Redis password (when using individual Redis fields) |
TMI_REDIS_DB |
No | Redis database number (default: 0) |
Note: Health checks are configured at the OCI Container Instances level, not within the Dockerfile.
Multi-stage build:
- Builder stage - Compiles Redis 8.4.0 from source
- Runtime stage - Oracle Linux 9-slim
Features:
- Redis 8.4.0 compiled from source
- Dangerous commands disabled by default (FLUSHDB, FLUSHALL, DEBUG)
- Non-root user (
redis, UID 6379) - Configurable via environment variables
Environment Variables:
| Variable | Default | Description |
|---|---|---|
REDIS_PASSWORD |
(none) | Redis authentication password |
REDIS_PORT |
6379 | Listen port |
REDIS_PROTECTED_MODE |
yes | Enable protected mode |
REDIS_DISABLE_COMMANDS |
FLUSHDB,FLUSHALL,DEBUG | Commands to disable |
Container builds are managed by scripts/build-app-containers.py, invoked via uv run:
uv run scripts/build-app-containers.py [options]
Options:
--target TARGET Deployment target: local, oci, aws, azure, gcp, heroku (default: local)
--component COMP Component: server, redis, or all (default: all)
--arch ARCH Target architecture: arm64, amd64, or both (default: auto-detect)
--db-backend BACKEND Database backend: postgresql or oracle-adb (default: postgresql)
--registry URL Container registry URL (auto-determined from target if not set)
--push Push images to registry after building
--scan Run security scanning (Grype + Syft SBOM) after building
--scan-only Scan existing images without building
--no-cache Build without Docker cacheFor OCI targets, the script automatically:
- Discovers the OCI tenancy namespace via
oci os ns get - Selects Oracle-specific Dockerfiles (
Dockerfile.server-oracle,Dockerfile.redis-oracle) - Defaults to
linux/arm64architecture (Ampere A1) - Uses
docker buildxfor cross-platform builds
# Build server only for OCI
uv run scripts/build-app-containers.py --target oci --component server
# Build, push, and scan all OCI containers
uv run scripts/build-app-containers.py --target oci --push --scan
# Build locally with Oracle ADB support (without pushing)
uv run scripts/build-app-containers.py --target local --db-backend oracle-adb
# Build for both architectures and push
uv run scripts/build-app-containers.py --target oci --arch both --push| Target | Description |
|---|---|
build-app-oci |
Build, push, and scan all OCI containers (server + Redis) |
build-app |
Build app containers for local development |
build-app-scan |
Build app containers locally with security scanning |
build-server-container |
Build only the TMI server container locally |
build-redis-container |
Build only the Redis container locally |
build-all |
Build all containers (database + app) for local development |
scan-containers |
Scan existing container images for vulnerabilities |
Deprecated aliases (still functional, will be removed):
| Target | Maps To |
|---|---|
build-container-oracle |
build-app-oci |
build-containers-oracle-push |
build-app-oci |
docker run -p 8080:8080 \
-v /path/to/wallet:/wallet:ro \
-e TMI_DATABASE_URL=oracle://your_user:your_password@your_tns_alias \
-e TMI_REDIS_URL=redis://localhost:6379 \
<region>.ocir.io/<namespace>/tmi:latestThe entrypoint script automatically extracts wallet.zip from the /wallet mount to /tmp/wallet, fixes the sqlnet.ora paths, and sets TNS_ADMIN and TMI_ORACLE_WALLET_LOCATION accordingly.
docker run -p 6379:6379 \
-e REDIS_PASSWORD=your_secure_password \
-v redis-data:/var/lib/redis \
<region>.ocir.io/<namespace>/tmi-redis:latestservices:
tmi:
image: us-ashburn-1.ocir.io/<namespace>/tmi:latest
ports:
- "8080:8080"
volumes:
- ./wallet:/wallet:ro
environment:
- TMI_DATABASE_URL=oracle://${DB_USER}:${DB_PASSWORD}@${ORACLE_TNS}
- TMI_REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
depends_on:
- redis
redis:
image: us-ashburn-1.ocir.io/<namespace>/tmi-redis:latest
ports:
- "6379:6379"
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD}
volumes:
- redis-data:/var/lib/redis
volumes:
redis-data:The recommended way to deploy TMI to OCI is using the Terraform modules. See Terraform-Deployment for complete instructions.
The Terraform deployment creates a multi-container architecture optimized for OCI Free Tier:
Container Instance #1: TMI API + Redis (combined)
Container Instance #2: TMI-UX (optional)
Load Balancer: Hostname-based routing
For manual deployment using OCI Container Instances:
# Create combined TMI API + Redis container instance
oci container-instances container-instance create \
--compartment-id <compartment-ocid> \
--display-name tmi-api-redis \
--availability-domain <ad> \
--shape CI.Standard.A1.Flex \
--shape-config '{"ocpus": 2, "memoryInGBs": 6}' \
--containers '[
{
"imageUrl": "<region>.ocir.io/<namespace>/tmi:latest",
"displayName": "tmi-server",
"environmentVariables": {
"TMI_DATABASE_URL": "oracle://admin:<password>@tmi_high",
"TMI_REDIS_URL": "redis://:password@localhost:6379/0"
}
},
{
"imageUrl": "<region>.ocir.io/<namespace>/tmi-redis:latest",
"displayName": "redis",
"environmentVariables": {
"REDIS_PASSWORD": "your-redis-password"
}
}
]'# Create TMI-UX container instance (optional)
oci container-instances container-instance create \
--compartment-id <compartment-ocid> \
--display-name tmi-ux \
--availability-domain <ad> \
--shape CI.Standard.A1.Flex \
--shape-config '{"ocpus": 1, "memoryInGBs": 2}' \
--containers '[{
"imageUrl": "<region>.ocir.io/<namespace>/tmi-ux:latest",
"displayName": "tmi-ux",
"environmentVariables": {
"PORT": "8080",
"NODE_ENV": "production"
}
}]'For Oracle Kubernetes Engine deployment, see Deploying-TMI-Server.
The TMI server requires an Oracle wallet for ADB authentication:
- Download the wallet ZIP from OCI Console (Autonomous Database > DB Connection > Download Wallet)
- Place the
wallet.zipfile in a directory - Mount that directory as a read-only volume at
/wallet
The container entrypoint script automatically:
- Extracts
wallet.zipto/tmp/wallet - Fixes the
sqlnet.oraDIRECTORYpath to point to the extraction directory - Sets
TNS_ADMINandTMI_ORACLE_WALLET_LOCATIONenvironment variables
Alternatively, you can pre-extract the wallet and mount the directory. The wallet should contain:
-
tnsnames.ora- TNS aliases -
sqlnet.ora- SQL*Net configuration -
cwallet.sso- Auto-login wallet
- Non-root users in all containers
- Security patches applied during build
- Minimal runtime dependencies
- Dangerous Redis commands disabled
- Use OCI VCN security lists to restrict access
- Enable TLS for Redis in production
- Use OCI Vault for secrets management
The build script supports Grype vulnerability scanning and Syft SBOM generation:
# Build with scanning (OCI target includes --scan by default)
make build-app-oci
# Scan existing images without rebuilding
make scan-containers
# Or scan directly
uv run scripts/build-app-containers.py --scan-only --target ociSecurity reports (SARIF, text, and CycloneDX SBOMs) are saved to security-reports/.
If you see 403 Forbidden when pushing:
- Verify your Auth Token is valid
- Check username format:
<namespace>/<email> - Ensure repository exists in the correct compartment
- Verify wallet is mounted correctly
- Check TNS alias matches
tnsnames.ora - Ensure
TNS_ADMINpoints to wallet directory - Verify database user has required permissions
For architecture-related build errors:
- The Dockerfile auto-detects architecture (amd64/arm64)
- Ensure Docker buildx is available for cross-platform builds
The TMI-UX frontend is built from a separate repository (tmi-ux). It uses:
- Base Image: Oracle Linux 10-slim
- Runtime: Node.js 22 LTS with Express.js
- Port: 8080
-
Health Check: HTTP GET on
/
From the tmi-ux repository:
# Build the OCI-optimized container
docker build -f Dockerfile.oci -t tmi-ux:latest .
# Push to OCI Container Registry
docker tag tmi-ux:latest <region>.ocir.io/<namespace>/tmi-ux:latest
docker push <region>.ocir.io/<namespace>/tmi-ux:latestOr use the provided script:
./scripts/push-oci.sh [tag]The Angular application is built with the API URL baked in at build time. The OCI build uses environment.oci.ts:
apiUrl: 'https://api.tmi.dev',If you need a different API URL, update src/environments/environment.oci.ts before building.
- Terraform-Deployment -- Infrastructure-as-code deployment across cloud providers
- Deploying-TMI-Server -- General server deployment instructions
- Database-Setup -- Database installation and configuration
- Setting-Up-Authentication -- OAuth provider configuration
- Configuration-Reference -- Full configuration variable reference
- Using TMI for Threat Modeling
- Accessing TMI
- Authentication
- Creating Your First Threat Model
- Understanding the User Interface
- Working with Data Flow Diagrams
- Managing Threats
- Collaborative Threat Modeling
- Using Notes and Documentation
- Timmy AI Assistant
- Metadata and Extensions
- Planning Your Deployment
- Terraform Deployment (AWS, OCI, GCP, Azure)
- Deploying TMI Server
- OCI Container Deployment
- Certificate Automation
- Deploying TMI Web Application
- Setting Up Authentication
- Database Setup
- Component Integration
- Post-Deployment
- Branding and Customization
- Monitoring and Health
- Cloud Logging
- Database Operations
- Security Operations
- Performance and Scaling
- Maintenance Tasks
- Getting Started with Development
- Architecture and Design
- API Integration
- Testing
- Contributing
- Extending TMI
- Dependency Upgrade Plans
- DFD Graphing Library Reference
- Migration Instructions