Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Backend Deployment — Hetzner Cloud + Docker
Containerized the backend and deployed it on a Hetzner Cloud server (Ubuntu) with Nginx reverse proxy and SSL.

## ⚙️ Stack

| Tool | Purpose |
|------|---------|
| ![Docker](https://img.shields.io/badge/Docker-2496ED?style=flat&logo=docker&logoColor=white) | Containerization |
| ![Hetzner](https://img.shields.io/badge/Hetzner-D50C2D?style=flat&logo=hetzner&logoColor=white) | Cloud Server (CPX22, Nuremberg) |
| ![Nginx](https://img.shields.io/badge/Nginx-009639?style=flat&logo=nginx&logoColor=white) | Reverse Proxy |
| ![LetsEncrypt](https://img.shields.io/badge/Let's%20Encrypt-003A70?style=flat&logo=letsencrypt&logoColor=white) | SSL Certificate |
| ![Ubuntu](https://img.shields.io/badge/Ubuntu-E95420?style=flat&logo=ubuntu&logoColor=white) | OS (26.04 LTS) |

## 🐳 Services

| Container | Port |
|-----------|------|
| `devsync-backend` | 8080 |

## 🌐 Live URL

🔗 **https://api1.curiousteamlearning.com**

## 📦 Run Locally

```bash
git clone https://github.com/Akshatsrii/project_codru.git
cd project_codru
git checkout akshatsrii
docker compose up --build -d
```

## 🔄 Update ENV on Server

```bash
nano server/.env
docker compose restart
```

---

> Deployed by [@Akshatsrii](https://github.com/Akshatsrii)
8 changes: 7 additions & 1 deletion client/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ dist-ssr
# Environment variables
.env
*.env
.env.local
.env.local
# Environment variables
.env
.env.*
*.env
.env.local
config.env
168 changes: 84 additions & 84 deletions client/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"postcss": "^8.5.9",
"tailwindcss": "^4.2.2",
"typescript": "^6.0.2",
"vite": "^8.0.8",
"vite": "^8.0.13",
"vite-plugin-pwa": "^1.2.0"
},
"overrides": {
Expand Down
40 changes: 27 additions & 13 deletions cute-mail-service/api/send.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
const nodemailer = require("nodemailer");
import express from "express";
import nodemailer from "nodemailer";

export default async function handler(req, res) {
if (req.method !== 'POST') return res.status(405).send('Method Not Allowed');
const app = express();

app.use(express.json());

app.post("/send", async (req, res) => {
const authHeader = req.headers.authorization;

if (authHeader !== `Bearer ${process.env.MICROSERVICE_SECRET}`) {
return res.status(401).json({ error: "Unauthorized. Invalid API Key." });
return res.status(401).json({
error: "Unauthorized"
});
}

// 🚨 Now it just accepts the raw mailOptions object from your Render backend!
const { mailOptions } = req.body;

try {
Expand All @@ -17,17 +22,26 @@ export default async function handler(req, res) {
port: 465,
secure: true,
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD
user: process.env.EMAIL,
pass: process.env.PASSWORD
}
});

// Vercel plugs your exact mailOptions directly into the real Nodemailer
const info = await transporter.sendMail(mailOptions);

res.status(200).json({ success: true, info });

res.status(200).json({
success: true,
info
});
} catch (error) {
console.error("Microservice Error:", error);
res.status(500).json({ error: "Failed to send email." });
console.log(error);

res.status(500).json({
error: "Failed to send email"
});
}
}
});

app.listen(5001, () => {
console.log("Mail service running on port 5001");
});
Loading