Skip to content

Commit c0c041d

Browse files
committed
fix: Use CORS_ORIGINS env variable in WebSocket gateway
1 parent 804edc0 commit c0c041d

8 files changed

Lines changed: 313 additions & 4 deletions

File tree

.github/SECRETS.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# GitHub Secrets Configuration
2+
3+
To enable automated deployment, you need to configure the following secrets in your GitHub repository:
4+
5+
## Required Secrets
6+
7+
### Docker Hub Credentials
8+
- **`DOCKERHUB_USERNAME`**: Your Docker Hub username
9+
- **`DOCKERHUB_TOKEN`**: Your Docker Hub access token (not password)
10+
- Generate at: https://hub.docker.com/settings/security
11+
12+
### EC2 Server Access
13+
- **`EC2_HOST`**: Your EC2 server's public IP address
14+
- Example: `3.76.214.67`
15+
- **`EC2_PRIVATE_KEY`**: Your EC2 private key content
16+
- Copy the entire content of your `~/.ssh/housescanner-key.pem` file
17+
18+
## How to Add Secrets
19+
20+
1. Go to your GitHub repository
21+
2. Click on **Settings**
22+
3. In the left sidebar, click **Secrets and variables****Actions**
23+
4. Click **New repository secret**
24+
5. Add each secret with the exact name and value
25+
26+
## Workflow Files
27+
28+
### Main Deployment (`deploy.yml`)
29+
- **Trigger**: Automatically runs on push to `main` branch
30+
- **Process**:
31+
1. **Step 2**: Build and push Docker images to Docker Hub
32+
2. **Step 3**: Deploy to EC2 server using docker-compose
33+
34+
### Quick Update (`quick-update.yml`)
35+
- **Trigger**: Manual execution via GitHub Actions tab
36+
- **Options**:
37+
- Choose specific component to update (all/client/backend/agents)
38+
- Skip build step to just redeploy existing images
39+
40+
## Example Secret Values
41+
42+
```bash
43+
# DOCKERHUB_USERNAME
44+
your_dockerhub_username
45+
46+
# DOCKERHUB_TOKEN
47+
dckr_pat_1234567890abcdef...
48+
49+
# EC2_HOST
50+
3.76.214.67
51+
52+
# EC2_PRIVATE_KEY
53+
-----BEGIN RSA PRIVATE KEY-----
54+
MIIEpAIBAAKCAQEA...
55+
(your full private key content)
56+
...
57+
-----END RSA PRIVATE KEY-----
58+
```
59+
60+
## Security Notes
61+
62+
- Never commit these secrets to your repository
63+
- Regularly rotate your Docker Hub tokens
64+
- Keep your EC2 private key secure
65+
- Monitor GitHub Actions logs for any exposed sensitive information
66+
67+
## Testing the Workflow
68+
69+
1. Make a change to your code
70+
2. Push to the `main` branch
71+
3. Check the **Actions** tab in GitHub to monitor the deployment
72+
4. The workflow will:
73+
- Build new Docker images with your changes
74+
- Push them to Docker Hub
75+
- Deploy to your EC2 server
76+
- Report success/failure status

.github/workflows/deploy.yml

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
name: 🚀 Deploy to Production
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
workflow_dispatch:
7+
inputs:
8+
force_rebuild:
9+
description: 'Force rebuild all images'
10+
required: false
11+
default: 'false'
12+
type: boolean
13+
14+
env:
15+
IMAGE_TAG: ${{ github.sha }}
16+
17+
jobs:
18+
step2-build-images:
19+
name: 🏗️ Step 2 - Build & Push Images
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- name: 📥 Checkout code
24+
uses: actions/checkout@v4
25+
26+
- name: 🐍 Set up Python
27+
uses: actions/setup-python@v4
28+
with:
29+
python-version: '3.11'
30+
31+
- name: 📦 Install Ansible
32+
run: |
33+
python -m pip install --upgrade pip
34+
pip install ansible
35+
36+
- name: � Read infrastructure outputs
37+
run: |
38+
if [ -f "infrastructure_outputs.txt" ]; then
39+
cat infrastructure_outputs.txt
40+
echo "EC2_IP=$(grep 'ec2_public_ip:' infrastructure_outputs.txt | cut -d' ' -f2)" >> $GITHUB_ENV
41+
else
42+
echo "EC2_IP=${{ secrets.EC2_HOST }}" >> $GITHUB_ENV
43+
fi
44+
45+
- name: 🐳 Login to DockerHub
46+
run: |
47+
echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin
48+
49+
- name: 🏗️ Step 2 - Build and Push Images
50+
working-directory: ./ansible
51+
run: |
52+
ansible-playbook step2-build-images.yml \
53+
-e "dockerhub_username=${{ secrets.DOCKERHUB_USERNAME }}" \
54+
-e "dockerhub_password=${{ secrets.DOCKERHUB_TOKEN }}" \
55+
-e "image_tag=${{ env.IMAGE_TAG }}" \
56+
-e "ec2_public_ip=${{ env.EC2_IP }}"
57+
58+
step3-deploy:
59+
name: 🚀 Step 3 - Deploy to EC2
60+
runs-on: ubuntu-latest
61+
needs: step2-build-images
62+
63+
steps:
64+
- name: 📥 Checkout code
65+
uses: actions/checkout@v4
66+
67+
- name: 🐍 Set up Python
68+
uses: actions/setup-python@v4
69+
with:
70+
python-version: '3.11'
71+
72+
- name: 📦 Install Ansible
73+
run: |
74+
python -m pip install --upgrade pip
75+
pip install ansible
76+
77+
- name: 🔑 Setup SSH key
78+
run: |
79+
mkdir -p ~/.ssh
80+
echo "${{ secrets.EC2_PRIVATE_KEY }}" > ~/.ssh/housescanner-key.pem
81+
chmod 600 ~/.ssh/housescanner-key.pem
82+
ssh-keyscan -H ${{ secrets.EC2_HOST }} >> ~/.ssh/known_hosts
83+
84+
- name: 📂 Create inventory file
85+
working-directory: ./ansible
86+
run: |
87+
cat > inventory.yml << EOF
88+
all:
89+
hosts:
90+
production:
91+
ansible_host: ${{ secrets.EC2_HOST }}
92+
ansible_user: ubuntu
93+
ansible_ssh_private_key_file: ~/.ssh/housescanner-key.pem
94+
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
95+
EOF
96+
97+
- name: 🚀 Step 3 - Deploy Application
98+
working-directory: ./ansible
99+
run: |
100+
ansible-playbook -i inventory.yml step3-deploy-application.yml \
101+
-e "dockerhub_username=${{ secrets.DOCKERHUB_USERNAME }}" \
102+
-e "image_tag=${{ env.IMAGE_TAG }}"
103+
104+
- name: ✅ Deployment Success
105+
run: |
106+
echo "🎉 Deployment completed successfully!"
107+
echo "🔖 Image tag: ${{ env.IMAGE_TAG }}"
108+
echo "🌐 Application URL: http://${{ secrets.EC2_HOST }}:8080"
109+
echo "🔧 Backend API: http://${{ secrets.EC2_HOST }}:3000"
110+
echo "🤖 Agents Service: http://${{ secrets.EC2_HOST }}:8000"
111+
112+
notify:
113+
name: 📢 Notify Status
114+
runs-on: ubuntu-latest
115+
needs: [step2-build-images, step3-deploy]
116+
if: always()
117+
118+
steps:
119+
- name: 📢 Success Notification
120+
if: needs.step3-deploy.result == 'success'
121+
run: |
122+
echo "✅ Deployment successful!"
123+
echo "🔖 Image tag: ${{ github.sha }}"
124+
echo "👤 Author: ${{ github.actor }}"
125+
echo "💾 Commit: ${{ github.event.head_commit.message }}"
126+
127+
- name: ❌ Failure Notification
128+
if: needs.step2-build-images.result == 'failure' || needs.step3-deploy.result == 'failure'
129+
run: |
130+
echo "❌ Deployment failed!"
131+
echo "🔖 Image tag: ${{ github.sha }}"
132+
echo "👤 Author: ${{ github.actor }}"
133+
echo "💾 Commit: ${{ github.event.head_commit.message }}"
134+
if [[ "${{ needs.step2-build-images.result }}" == "failure" ]]; then
135+
echo "🏗️ Failed at: Step 2 - Build Images"
136+
fi
137+
if [[ "${{ needs.step3-deploy.result }}" == "failure" ]]; then
138+
echo "🚀 Failed at: Step 3 - Deploy"
139+
fi
140+
exit 1

.github/workflows/quick-update.yml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: 🔄 Quick Update
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
component:
7+
description: 'Component to update'
8+
required: true
9+
default: 'all'
10+
type: choice
11+
options:
12+
- all
13+
- client
14+
- backend
15+
- agents
16+
skip_build:
17+
description: 'Skip build and just deploy existing images'
18+
required: false
19+
default: 'false'
20+
type: boolean
21+
22+
env:
23+
IMAGE_TAG: ${{ github.sha }}
24+
25+
jobs:
26+
quick-update:
27+
name: 🔄 Quick Update - ${{ inputs.component }}
28+
runs-on: ubuntu-latest
29+
30+
steps:
31+
- name: 📥 Checkout code
32+
uses: actions/checkout@v4
33+
34+
- name: 🐍 Set up Python
35+
uses: actions/setup-python@v4
36+
with:
37+
python-version: '3.11'
38+
39+
- name: 📦 Install Ansible
40+
run: |
41+
python -m pip install --upgrade pip
42+
pip install ansible
43+
44+
- name: 🔑 Setup SSH key
45+
run: |
46+
mkdir -p ~/.ssh
47+
echo "${{ secrets.EC2_PRIVATE_KEY }}" > ~/.ssh/housescanner-key.pem
48+
chmod 600 ~/.ssh/housescanner-key.pem
49+
ssh-keyscan -H ${{ secrets.EC2_HOST }} >> ~/.ssh/known_hosts
50+
51+
- name: 🐳 Login to DockerHub
52+
if: inputs.skip_build != 'true'
53+
run: |
54+
echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin
55+
56+
- name: 🏗️ Build Images
57+
if: inputs.skip_build != 'true'
58+
working-directory: ./ansible
59+
run: |
60+
ansible-playbook -i inventory.yml step2-build-images.yml \
61+
-e "dockerhub_username=${{ secrets.DOCKERHUB_USERNAME }}" \
62+
-e "dockerhub_password=${{ secrets.DOCKERHUB_TOKEN }}" \
63+
-e "image_tag=${{ env.IMAGE_TAG }}" \
64+
-e "component_filter=${{ inputs.component }}"
65+
66+
- name: 🚀 Deploy Update
67+
working-directory: ./ansible
68+
run: |
69+
ansible-playbook -i inventory.yml step3-deploy-application.yml \
70+
-e "dockerhub_username=${{ secrets.DOCKERHUB_USERNAME }}" \
71+
-e "image_tag=${{ env.IMAGE_TAG }}" \
72+
-e "component_filter=${{ inputs.component }}" \
73+
--private-key ~/.ssh/housescanner-key.pem
74+
75+
- name: ✅ Update Complete
76+
run: |
77+
echo "🎉 Update completed for: ${{ inputs.component }}"
78+
echo "🔖 Image tag: ${{ env.IMAGE_TAG }}"
79+
echo "🌐 Application: http://${{ secrets.EC2_HOST }}:8080"

backend/src/main.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ValidationPipe, VersioningType } from '@nestjs/common';
22
import { NestFactory } from '@nestjs/core';
33
import { ConfigService } from '@nestjs/config';
4+
import { IoAdapter } from '@nestjs/platform-socket.io';
45
import { AppModule } from './app.module';
56
import { SwaggerSetup } from './docs/swagger.module';
67

@@ -13,6 +14,9 @@ async function bootstrap() {
1314
'http://localhost:5173',
1415
];
1516

17+
// Configure Socket.IO adapter for WebSocket support
18+
app.useWebSocketAdapter(new IoAdapter(app));
19+
1620
app.setGlobalPrefix(`${globalPrefix}/v1`);
1721
app.enableVersioning({ type: VersioningType.URI });
1822
app.enableCors({

backend/src/scans/scans.gateway.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { Logger } from '@nestjs/common';
2424
*/
2525
@WebSocketGateway({
2626
cors: {
27-
origin: process.env.CORS_ORIGIN || 'http://localhost:5173',
27+
origin: process.env.CORS_ORIGINS?.split(',').map(o => o.trim()) || ['http://localhost:5173'],
2828
credentials: true,
2929
},
3030
namespace: '/scans',

client-pwa/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# API Configuration
44
VITE_API_BASE_URL=http://localhost:3000/api/v1
5+
VITE_WS_URL=http://localhost:3000
56

67
# App Configuration
78
VITE_APP_NAME="House Scanner"

client-pwa/.env.example

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Client PWA Environment Configuration
22

33
# API Configuration
4-
VITE_API_URL=http://localhost:3000
5-
VITE_WS_URL=ws://localhost:3000
4+
VITE_API_BASE_URL=http://localhost:3000/api/v1
5+
VITE_WS_URL=http://localhost:3000
6+
7+
# App Configuration
8+
VITE_APP_NAME="House Scanner"
9+
VITE_APP_VERSION="1.0.0"
10+
11+
# Feature Flags
12+
VITE_ENABLE_CAMERA=true
13+
VITE_ENABLE_FILE_UPLOAD=true
14+
VITE_ENABLE_NOTIFICATIONS=false

image_tag.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
57eac5c
1+
804edc0

0 commit comments

Comments
 (0)