Skip to content

Commit 04e11eb

Browse files
committed
Adds Docker-based CI/CD for Azure
Automates building and deployment of the React app in Docker containers. Triggers deployments to Azure on successful builds or manual runs, enabling faster and more consistent releases. Introduces supporting documentation and configurations for container-based hosting, simplifying setup and maintenance.
1 parent 6133284 commit 04e11eb

File tree

6 files changed

+251
-0
lines changed

6 files changed

+251
-0
lines changed

.github/workflows/deploy-azure.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Deploy to Azure App Service
2+
3+
on:
4+
workflow_run:
5+
workflows: ["Build and Push Docker Image"]
6+
types:
7+
- completed
8+
branches: [ main ]
9+
10+
# Allow manual trigger
11+
workflow_dispatch:
12+
13+
env:
14+
AZURE_WEBAPP_NAME: 'your-app-name' # Replace with your App Service name
15+
REGISTRY: ghcr.io
16+
IMAGE_NAME: ${{ github.repository }}/app-scripting-editor
17+
18+
jobs:
19+
deploy:
20+
runs-on: ubuntu-latest
21+
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
22+
23+
environment:
24+
name: 'production'
25+
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
26+
27+
steps:
28+
- name: Lowercase repository name
29+
run: echo "IMAGE_NAME_LOWER=$(echo ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
30+
31+
- name: Deploy to Azure Web App
32+
id: deploy-to-webapp
33+
uses: azure/webapps-deploy@v2
34+
with:
35+
app-name: ${{ env.AZURE_WEBAPP_NAME }}
36+
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
37+
images: '${{ env.IMAGE_NAME_LOWER }}:latest'

.github/workflows/docker-build.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: Build and Push Docker Image
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
paths:
7+
- 'editor/**'
8+
- '.github/workflows/docker-build.yml'
9+
pull_request:
10+
branches: [ main ]
11+
paths:
12+
- 'editor/**'
13+
14+
# Allow manual trigger
15+
workflow_dispatch:
16+
17+
env:
18+
REGISTRY: ghcr.io
19+
IMAGE_NAME: ${{ github.repository }}/app-scripting-editor
20+
21+
jobs:
22+
build-and-push:
23+
runs-on: ubuntu-latest
24+
permissions:
25+
contents: read
26+
packages: write
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
32+
- name: Set up Docker Buildx
33+
uses: docker/setup-buildx-action@v3
34+
35+
- name: Log in to Container Registry
36+
uses: docker/login-action@v3
37+
with:
38+
registry: ${{ env.REGISTRY }}
39+
username: ${{ github.actor }}
40+
password: ${{ secrets.GITHUB_TOKEN }}
41+
42+
- name: Extract metadata
43+
id: meta
44+
uses: docker/metadata-action@v5
45+
with:
46+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
47+
tags: |
48+
type=ref,event=branch
49+
type=ref,event=pr
50+
type=sha,prefix={{branch}}-
51+
type=raw,value=latest,enable={{is_default_branch}}
52+
53+
- name: Build and push Docker image
54+
uses: docker/build-push-action@v5
55+
with:
56+
context: ./editor
57+
file: ./editor/Dockerfile
58+
push: true
59+
tags: ${{ steps.meta.outputs.tags }}
60+
labels: ${{ steps.meta.outputs.labels }}
61+
cache-from: type=gha
62+
cache-to: type=gha,mode=max
63+
platforms: linux/amd64,linux/arm64
64+
65+
- name: Image digest
66+
run: echo ${{ steps.build.outputs.digest }}

DOCKER_DEPLOYMENT.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Docker Deployment Guide
2+
3+
## Overview
4+
This repository includes GitHub Actions workflows to automatically build and deploy the React application as a Docker container.
5+
6+
## Workflows
7+
8+
### 1. Build and Push Docker Image (`docker-build.yml`)
9+
- **Triggers**: Push to main/develop, PRs to main, manual dispatch
10+
- **Output**: Docker image pushed to GitHub Container Registry (ghcr.io)
11+
- **Tags**:
12+
- `latest` (for main branch)
13+
- `<branch-name>` (for branch pushes)
14+
- `<branch>-<sha>` (for commit-specific builds)
15+
16+
### 2. Deploy to Azure App Service (`deploy-azure.yml`)
17+
- **Triggers**: After successful Docker build, manual dispatch
18+
- **Target**: Azure App Service with container deployment
19+
20+
## Setup Instructions
21+
22+
### For GitHub Container Registry (Automatic)
23+
The workflow uses `GITHUB_TOKEN` which is automatically available - no additional setup needed.
24+
25+
### For Azure App Service Deployment
26+
27+
1. **Create Azure App Service with Container support:**
28+
```bash
29+
# Create resource group
30+
az group create --name myResourceGroup --location "East US"
31+
32+
# Create App Service plan (Linux with container support)
33+
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku B1 --is-linux
34+
35+
# Create web app with container
36+
az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name your-app-name --deployment-container-image-name nginx
37+
```
38+
39+
2. **Get Publish Profile:**
40+
```bash
41+
az webapp deployment list-publishing-profiles --name your-app-name --resource-group myResourceGroup --xml
42+
```
43+
44+
3. **Add GitHub Secrets:**
45+
- Go to your GitHub repository → Settings → Secrets and variables → Actions
46+
- Add `AZURE_WEBAPP_PUBLISH_PROFILE` with the XML content from step 2
47+
48+
4. **Update workflow file:**
49+
- Edit `.github/workflows/deploy-azure.yml`
50+
- Replace `your-app-name` with your actual Azure App Service name
51+
52+
## Local Development
53+
54+
### Build Docker image locally:
55+
```bash
56+
cd editor
57+
docker build -t app-scripting-editor .
58+
```
59+
60+
### Run locally:
61+
```bash
62+
docker run -p 8080:80 app-scripting-editor
63+
```
64+
65+
Then visit http://localhost:8080
66+
67+
## Container Registry
68+
69+
Images are pushed to: `ghcr.io/trackman/tps-app-scripting/app-scripting-editor`
70+
71+
You can pull and run the latest image:
72+
```bash
73+
docker pull ghcr.io/trackman/tps-app-scripting/app-scripting-editor:latest
74+
docker run -p 8080:80 ghcr.io/trackman/tps-app-scripting/app-scripting-editor:latest
75+
```
76+
77+
## Environment Variables
78+
79+
For production deployment, you may need to configure environment variables in your Azure App Service:
80+
- `WEBSITES_PORT=80` (required for Azure App Service)
81+
- Any React environment variables (prefixed with `REACT_APP_`)
82+
83+
## Troubleshooting
84+
85+
1. **Build fails**: Check the Actions tab for detailed logs
86+
2. **Deployment fails**: Ensure Azure App Service is configured for Linux containers
87+
3. **App doesn't load**: Check that `WEBSITES_PORT=80` is set in App Service configuration

editor/.dockerignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
node_modules
2+
npm-debug.log
3+
.git
4+
.gitignore
5+
README.md
6+
.env
7+
.nyc_output
8+
coverage
9+
.vscode
10+
dist

editor/Dockerfile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Build stage
2+
FROM node:18-alpine as build
3+
WORKDIR /app
4+
5+
# Copy package files
6+
COPY package*.json ./
7+
RUN npm ci
8+
9+
# Copy source code
10+
COPY . .
11+
12+
# Build the application
13+
RUN npm run build
14+
15+
# Production stage
16+
FROM nginx:alpine
17+
COPY --from=build /app/dist /usr/share/nginx/html
18+
19+
# Copy custom nginx config if needed
20+
COPY nginx.conf /etc/nginx/nginx.conf
21+
22+
# Expose port 80
23+
EXPOSE 80
24+
25+
CMD ["nginx", "-g", "daemon off;"]

editor/nginx.conf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
events {
2+
worker_connections 1024;
3+
}
4+
5+
http {
6+
include /etc/nginx/mime.types;
7+
default_type application/octet-stream;
8+
9+
server {
10+
listen 80;
11+
server_name localhost;
12+
root /usr/share/nginx/html;
13+
index index.html;
14+
15+
# Handle client-side routing
16+
location / {
17+
try_files $uri $uri/ /index.html;
18+
}
19+
20+
# Cache static assets
21+
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
22+
expires 1y;
23+
add_header Cache-Control "public, immutable";
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)