Skip to content
Merged
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
19 changes: 9 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
# Production image for the static Resume Matcher site
FROM nginx:1.27-alpine AS production
# Production image for MatchlyPro with AI proxy support
FROM node:20-alpine AS production

WORKDIR /app

RUN apk add --no-cache curl

COPY nginx.conf /etc/nginx/nginx.conf
COPY index.html /usr/share/nginx/html/index.html
COPY health.html /usr/share/nginx/html/health.html
COPY package.json package-lock.json ./
RUN npm ci --omit=dev

RUN chown -R nginx:nginx /usr/share/nginx/html /var/cache/nginx /var/log/nginx /etc/nginx/conf.d \
&& touch /var/run/nginx.pid \
&& chown nginx:nginx /var/run/nginx.pid
COPY . .

USER nginx
ENV PORT=8080

EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -fsS http://localhost:8080/health > /dev/null || exit 1

CMD ["nginx", "-g", "daemon off;"]
CMD ["node", "server.mjs"]
41 changes: 30 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# MatchlyPro

MatchlyPro is a production-oriented resume matcher web app that compares a resume against a job description, highlights keyword coverage, surfaces ATS risks, and suggests practical improvements.
MatchlyPro is a production-oriented resume matcher web app that compares a resume against a job description, highlights keyword coverage, surfaces ATS risks, and suggests practical improvements. It now supports server-side AI analysis through the Gemini API.

This repository is designed as a portfolio project that shows both product engineering and delivery discipline:

- product design and implementation
- client-side PDF parsing with PDF.js
- production-ready static hosting with Vercel
- containerized runtime with Nginx and Docker
- production-ready hosting with a lightweight Node server
- containerized runtime with Node and Docker
- CI checks with GitHub Actions
- release-gated production promotion
- basic security scanning and smoke validation
Expand All @@ -25,9 +25,9 @@ This is a strong portfolio example for:
- shipping polished browser-based tools
- practical CI/CD ownership
- containerization and deployment workflows
- release-based production control for a static app
- release-based production control for the app runtime

It is not a full multi-tenant SaaS yet because there is no backend, database, authentication, billing, or persistent user accounts. It is better described as a production-minded web product with DevOps discipline than as a complete SaaS platform.
It is not a full multi-tenant SaaS yet because there is no database, authentication, billing, or persistent user accounts. It is better described as a production-minded web product with AI-assisted analysis and practical DevOps discipline than as a complete SaaS platform.

## What The App Does

Expand All @@ -45,7 +45,7 @@ It is not a full multi-tenant SaaS yet because there is no backend, database, au
- CSS3
- Vanilla JavaScript
- PDF.js
- Nginx
- Node.js
- Docker
- GitHub Actions
- GitHub Releases
Expand All @@ -57,8 +57,9 @@ It is not a full multi-tenant SaaS yet because there is no backend, database, au

```mermaid
flowchart LR
U[User Browser] --> V[Vercel Production Deployment]
V --> S[Static Assets<br/>index.html + health.html]
U[User Browser] --> A[MatchlyPro Node Server]
A --> S[Static App<br/>index.html + health.html]
A --> R[Gemini API<br/>gemini-2.5-flash-lite]
S --> J[Browser App Logic]
J --> P[PDF.js Parsing In Browser]
J --> L[Local Storage Session History]
Expand Down Expand Up @@ -188,13 +189,29 @@ In practical terms, someone can fork the repo and run their own copy, but they c

### Run with Node

1. Create a local env file from the example:

```bash
cp .env.example .env
```

2. Set these values:

- `GEMINI_API_KEY`
- `GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai/`
- `GEMINI_MODEL=gemini-2.5-flash-lite`

3. Start the app:

```bash
npm ci
npm start
```

Open `http://localhost:3000`

If the Gemini env vars are not set, the app still runs and falls back to local heuristic analysis.

### Run with Docker

```bash
Expand Down Expand Up @@ -229,7 +246,7 @@ That release tag triggers the production workflow, publishes release artifacts,

- `vercel.json` disables Git-based Vercel auto deployment
- the app exposes `/health` for deployment verification
- Docker runtime uses Nginx for static delivery
- Docker runtime uses the Node server for app and API delivery
- CI and release jobs depend on repository secrets for external integrations

## Repository Structure
Expand All @@ -249,10 +266,12 @@ That release tag triggers the production workflow, publishes release artifacts,
|-- Dockerfile
|-- LICENSE
|-- README.md
|-- .env.example
|-- health.html
|-- index.html
|-- nginx.conf
|-- package.json
|-- server.mjs
`-- vercel.json
```

Expand All @@ -270,7 +289,7 @@ This repository is portfolio-ready for a production-minded web app because it in

## Current Limitations

- no backend API
- no persistent backend storage
- no persistent database
- no authentication or user accounts
- no billing or subscriptions
Expand All @@ -284,7 +303,7 @@ This repository is portfolio-ready for a production-minded web app because it in
- add Lighthouse and accessibility checks in CI
- add a custom domain
- add analytics and error monitoring
- add a small backend for saved sessions or team features
- add persistent storage for saved sessions or team features

## Author

Expand Down
Loading
Loading