This guide explains how to deploy the Resgrid IC application using Docker.
# Pull from GitHub Container Registry
docker pull resgridllc/ic:latest
# Or pull from Docker Hub (if configured)
docker pull <dockerhub-username>/resgrid-ic:latest
# Run the container
docker run -d \
-p 8080:80 \
-e IC_BASE_API_URL="https://api.example.com" \
-e IC_APP_KEY="your-app-key" \
--name resgrid-ic \
resgridllc/ic:latest# Build the Docker image
docker build -t resgrid-ic:latest .
# Run the container
docker run -d \
-p 8080:80 \
-e IC_BASE_API_URL="https://api.example.com" \
--name resgrid-ic \
resgrid-ic:latestAll configuration is done via environment variables at runtime. The Docker image does not contain any hardcoded secrets or API keys.
IC_BASE_API_URL- Base URL for the API (e.g.,https://api.resgrid.com)
| Variable | Default | Description |
|---|---|---|
APP_ENV |
production |
Application environment |
IC_NAME |
Resgrid IC |
Application name |
IC_SCHEME |
ResgridIC |
URL scheme |
IC_VERSION |
0.0.1 |
Application version |
IC_API_VERSION |
v4 |
API version |
IC_RESGRID_API_URL |
/api/v4 |
Resgrid API URL path |
IC_CHANNEL_HUB_NAME |
eventingHub |
SignalR channel hub name |
IC_REALTIME_GEO_HUB_NAME |
geolocationHub |
SignalR geolocation hub name |
IC_LOGGING_KEY |
"" |
Logging service key |
IC_APP_KEY |
"" |
Application key |
IC_MAPBOX_PUBKEY |
"" |
Mapbox public key |
IC_SENTRY_DSN |
"" |
Sentry DSN for error tracking |
IC_COUNTLY_APP_KEY |
"" |
Countly app key for analytics |
IC_COUNTLY_SERVER_URL |
"" |
Countly server URL |
Create a docker-compose.yml file:
version: '3.8'
services:
resgrid-ic:
image: resgridllc/ic:latest
ports:
- "8080:80"
environment:
- APP_ENV=production
- IC_NAME=Resgrid IC
- IC_SCHEME=ResgridIC
- IC_VERSION=7.1
- IC_BASE_API_URL=https://api.resgrid.com
- IC_API_VERSION=v4
- IC_RESGRID_API_URL=/api/v4
- IC_CHANNEL_HUB_NAME=eventingHub
- IC_REALTIME_GEO_HUB_NAME=geolocationHub
- IC_LOGGING_KEY=${IC_LOGGING_KEY}
- IC_APP_KEY=${IC_APP_KEY}
- IC_MAPBOX_PUBKEY=${IC_MAPBOX_PUBKEY}
- IC_SENTRY_DSN=${IC_SENTRY_DSN}
- IC_COUNTLY_APP_KEY=${IC_COUNTLY_APP_KEY}
- IC_COUNTLY_SERVER_URL=${IC_COUNTLY_SERVER_URL}
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40sThen run:
docker-compose up -dCreate a .env file (never commit this to version control):
IC_BASE_API_URL=https://api.resgrid.com
IC_APP_KEY=your-secret-app-key
IC_LOGGING_KEY=your-logging-key
IC_MAPBOX_PUBKEY=your-mapbox-public-key
IC_SENTRY_DSN=your-sentry-dsn
IC_COUNTLY_APP_KEY=your-countly-app-key
IC_COUNTLY_SERVER_URL=https://countly.example.comRun with the environment file:
docker run -d \
-p 8080:80 \
--env-file .env \
--name resgrid-ic \
resgridllc/ic:latestCreate a deployment.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: resgrid-ic-config
data:
IC_BASE_API_URL: "https://api.resgrid.com"
IC_API_VERSION: "v4"
IC_NAME: "Resgrid IC"
---
apiVersion: v1
kind: Secret
metadata:
name: resgrid-ic-secrets
type: Opaque
stringData:
IC_APP_KEY: "your-secret-app-key"
IC_LOGGING_KEY: "your-logging-key"
IC_MAPBOX_PUBKEY: "your-mapbox-public-key"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: resgrid-ic
spec:
replicas: 3
selector:
matchLabels:
app: resgrid-ic
template:
metadata:
labels:
app: resgrid-ic
spec:
containers:
- name: resgrid-ic
image: resgridllc/ic:latest
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: resgrid-ic-config
- secretRef:
name: resgrid-ic-secrets
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: resgrid-ic
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: resgrid-icDeploy:
kubectl apply -f deployment.yamlThe Docker image uses a two-stage build:
- Build Stage: Compiles the web application without any environment variables
- Runtime Stage: Uses nginx to serve the application
At container startup, the docker-entrypoint.sh script:
- Generates an
env-config.jsfile with all environment variables - Injects the script tag into
index.html - Starts nginx
This approach allows the same Docker image to be used across multiple environments (dev, staging, production) by simply changing environment variables.
- Never commit secrets: Keep sensitive environment variables in secure storage (e.g., Kubernetes Secrets, AWS Secrets Manager)
- Use read-only containers: Run containers in read-only mode where possible
- Scan for vulnerabilities: Regularly scan the Docker image for security issues
- Use non-root user: The nginx base image already uses a non-root user
- Limit resources: Set appropriate CPU and memory limits
docker logs resgrid-icdocker exec resgrid-ic cat /usr/share/nginx/html/env-config.jsdocker exec -it resgrid-ic shdocker exec resgrid-ic cat /etc/nginx/nginx.confThe CI/CD pipeline builds images for both linux/amd64 and linux/arm64 architectures, ensuring compatibility with:
- x86-64 servers
- ARM-based servers (AWS Graviton, Raspberry Pi, etc.)
- Apple Silicon (M1/M2) development machines
To update to a new version:
# Pull the latest image
docker pull resgridllc/ic:latest
# Stop and remove the old container
docker stop resgrid-ic
docker rm resgrid-ic
# Start a new container with the updated image
docker run -d \
-p 8080:80 \
--env-file .env \
--name resgrid-ic \
resgridllc/ic:latestOr with Docker Compose:
docker-compose pull
docker-compose up -d