Compare commits
2
Commits
renderBranch
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adf653d0ee | ||
|
|
1a1272649f |
@@ -0,0 +1,6 @@
|
|||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.env
|
||||||
|
Dockerfile
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
FROM node:22-alpine
|
||||||
|
WORKDIR /app
|
||||||
|
RUN npm install -g npm@latest
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm install
|
||||||
|
COPY . .
|
||||||
|
EXPOSE 3000
|
||||||
|
CMD ["npm", "start"]
|
||||||
@@ -388,6 +388,11 @@ The `backend/database` directory can be mounted as a Docker volume so that `urls
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# A 1-Line Setup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up
|
||||||
|
```
|
||||||
# Deployment Sketch
|
# Deployment Sketch
|
||||||
|
|
||||||
## Current MVP Deployment
|
## Current MVP Deployment
|
||||||
@@ -482,26 +487,44 @@ For a production-ready deployment, I would separate the application into managed
|
|||||||
| Registered URLs | | Monitoring History |
|
| Registered URLs | | Monitoring History |
|
||||||
+---------------------+ +----------------------+
|
+---------------------+ +----------------------+
|
||||||
```
|
```
|
||||||
|
## Infrastructure-as-Code (Hypothetical)
|
||||||
|
|
||||||
## Infrastructure-as-Code (Example)
|
If deployed on AWS, the infrastructure could be provisioned using Terraform.
|
||||||
|
|
||||||
A minimal Docker-based deployment could be provisioned using Docker Compose:
|
```hcl
|
||||||
|
provider "aws" {
|
||||||
|
region = "ap-south-1"
|
||||||
|
}
|
||||||
|
|
||||||
```yaml
|
resource "aws_instance" "url_monitor" {
|
||||||
version: "3.9"
|
ami = "ami-xxxxxxxx"
|
||||||
|
instance_type = "t3.micro"
|
||||||
|
|
||||||
services:
|
tags = {
|
||||||
url-health-monitor:
|
Name = "url-health-monitor"
|
||||||
build: .
|
}
|
||||||
ports:
|
}
|
||||||
- "3000:3000"
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- ./backend/database:/app/backend/database
|
|
||||||
```
|
```
|
||||||
|
|
||||||
In a production cloud environment, the JSON files would be replaced by a managed PostgreSQL or MongoDB database, Docker images would be deployed automatically through a CI/CD pipeline, and HTTPS would be provided by the cloud platform.
|
The application Docker image would be deployed to the EC2 instance, with:
|
||||||
|
|
||||||
|
- Docker running the Node.js application
|
||||||
|
- Nginx acting as a reverse proxy
|
||||||
|
- HTTPS enabled using Let's Encrypt
|
||||||
|
- Monitoring data stored in PostgreSQL or MongoDB instead of JSON files
|
||||||
|
|
||||||
|
In a production cloud environment, the JSON files would be replaced by a managed PostgreSQL or MongoDB database, Docker images would be deployed automatically through a CI/CD pipeline, and HTTPS would be provided by the cloud platform.
|
||||||
|
## Deployment Notes
|
||||||
|
|
||||||
|
For a production deployment, I would:
|
||||||
|
|
||||||
|
- Build a Docker image using GitHub Actions.
|
||||||
|
- Push the image to Docker Hub or GitHub Container Registry.
|
||||||
|
- Provision infrastructure using Terraform.
|
||||||
|
- Deploy the container to AWS EC2, ECS, or Google Cloud Run.
|
||||||
|
- Store monitoring data in PostgreSQL or MongoDB.
|
||||||
|
- Configure HTTPS using a cloud load balancer or Nginx.
|
||||||
|
- Use CloudWatch or Prometheus/Grafana for monitoring and logging.
|
||||||
# Future Improvements
|
# Future Improvements
|
||||||
|
|
||||||
- Delete registered URLs
|
- Delete registered URLs
|
||||||
|
|||||||
@@ -9,42 +9,43 @@ const { init, broadcast } = require("./utils/utils");
|
|||||||
const urlPath = path.join(__dirname, "database", "urls.json");
|
const urlPath = path.join(__dirname, "database", "urls.json");
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
const checkAllUrl = async () => {
|
const checkAllUrl = async (Store) => {
|
||||||
try {
|
try {
|
||||||
const urls = await fs.readFile(urlPath, "utf8");
|
const urls = await fs.readFile(urlPath, "utf8");
|
||||||
const parsedUrls = JSON.parse(urls);
|
const parsedUrls = JSON.parse(urls);
|
||||||
|
|
||||||
await Promise.allSettled(
|
await Promise.allSettled(
|
||||||
parsedUrls.map(async (url) => {
|
parsedUrls.map(async (url) => {
|
||||||
const response = await checkUrl(url);
|
const response = await checkUrl(url);
|
||||||
broadcast(response);
|
broadcast(response);
|
||||||
// Store.push(response);
|
Store.push(response);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
// StoreRecord(Store);
|
StoreRecord(Store);
|
||||||
broadcast({ type: "checking" });
|
broadcast({ type: "checking" });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("WebSocket polling error:", err.message);
|
console.error("WebSocket polling error:", err.message);
|
||||||
broadcast({
|
broadcast({
|
||||||
type: "error",
|
type: "error",
|
||||||
message: "Unable to read urls.json or parse data",
|
message: "Unable to read urls.json or parse data",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
async function setupWebSocket(wss) {
|
async function setupWebSocket(wss) {
|
||||||
init(wss);
|
init(wss);
|
||||||
// let Store = [];
|
let Store = [];
|
||||||
wss.on("connection", (ws) => {
|
wss.on("connection", (ws) => {
|
||||||
checkAllUrl();
|
checkAllUrl(Store);
|
||||||
});
|
});
|
||||||
|
|
||||||
setInterval(
|
setInterval(
|
||||||
async () => {
|
|
||||||
// Store = [];
|
async () => {
|
||||||
checkAllUrl();
|
Store = [];
|
||||||
},
|
checkAllUrl(Store);
|
||||||
process.env.TIME || 60 * 1000,
|
},
|
||||||
);
|
process.env.TIME || 60 * 1000,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { setupWebSocket };
|
module.exports = { setupWebSocket };
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
url-health-monitor:
|
||||||
|
build: .
|
||||||
|
container_name: url-health-monitor
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./backend/database:/app/backend/database
|
||||||
Reference in New Issue
Block a user