DevelUp Technology: Technical Documentation
Everything the team needs to understand our projects, run them locally, and deploy them to production, without outside help.
1. Overview
We maintain two product environments plus a scraping service. The first is Dev Career Copilot, an AI career assistant built from three connected repositories: a Next.js frontend, a Node.js main server, and a Python vector server. The second is Aelio, which has a landing page and a documentation site, both Next.js. The third is the Scraper Server, a Node.js service that runs every job scraper and feeds job data into our databases.
Frontends are hosted on Vercel and deploy from GitHub. Backends run as Docker containers on Microsoft Azure, using Azure Container Registry to store images and Azure Container Apps to run them. Backend deployment is deliberately manual: a push to GitHub does not deploy anything. Read sections 5 to 7 before your first release.
| Layer | Technology | Hosting |
|---|---|---|
| Frontends (3) | Next.js, pnpm | Vercel, DevelUp Technology account |
| Main server | Node.js | Azure Container Apps |
| Vector server | Python | Azure Container Apps |
| Scraper server | Node.js | Azure Container Apps |
| Databases (4) | Redis, Neon, MongoDB, Qdrant | Managed services |
2. Architecture
Dev Career Copilot
The user interacts with the Dev frontend. The frontend calls the Main Node Server for everything account related: sign up, login, resume builder, job listings and user data. When the user chats with the copilot, the conversation is handled by the Python Vector Server, which stores messages and memory in Neon and searches job embeddings in Qdrant to give relevant answers. The three repos together form one environment, so a change in one (for example an API shape) may need a matching change in another.
Scrapers
The Scraper Server runs the real-time scrapers that collect jobs. Collected jobs feed the job data used by the main server, and their embeddings are what Qdrant stores for the copilot's semantic search. It is deployed exactly like the other two backends.
Aelio
Aelio has two independent frontends: the public landing page and the documentation site. They are static-style Next.js apps with no backend repo listed here.
3. Repositories
Frontends (all Next.js, working branch: main)
| Project | Repository | Role |
|---|---|---|
| Dev Frontend | develup-tech/client-new | User interface of Dev Career Copilot |
| Aelio Landing Page | develup-tech/aelio-client | Public marketing page for Aelio |
| Aelio Docs | develup-tech/aelio-docs | Documentation site for Aelio |
Backends
| Project | Tech | Repository | Responsibility |
|---|---|---|---|
| Main Node Server | Node.js | DevelUp-Technology/new-main-server | Authentication, resume builder, core backend systems |
| Python Vector Server | Python | DevelUp-Technology/vector-embeddings-python-server | Career copilot conversations, memory, vector search |
| Scraper Server | Node.js | DevelUp-Technology/scraper-server | All job scrapers |
Branch to start from (backends)
The latest code for each backend lives in a specific branch, not main. Pull from the branch below, then create your own branches from it.
| Repository | Latest branch |
|---|---|
new-main-server | rajkumar-dev |
vector-embeddings-python-server | rishabh-dev-new-archi-with-neon-db |
scraper-server | rajkumar-dev |
4. Frontend: run and deploy
Run locally
This applies to all three frontend repos. Always start from main and never commit straight to it while experimenting.
git clone <repo-url>
cd <repo-folder>
git checkout -b your-branch-name
pnpm install # one time, installs node modules
pnpm run dev # starts the local dev serverMake your changes, commit, push your branch, then merge it into main.
Deployment on Vercel
All three frontends are deployed on the DevelUp Technology Vercel account (technology@develup.in). Each repo is one Vercel project: Dev Frontend, Aelio Landing Page, and Aelio Docs. Log in with the company account to view builds, domains, logs and environment variables. Environment variables (API base URLs and similar) are managed in each Vercel project's settings, never in the repo.
5. Backend deployment: how it works
Pushing code to GitHub does not deploy the backends. A release has two parts:
- Build and push an image. On your own machine, Docker builds the application into an image, which is then pushed to Azure Container Registry (ACR). Each backend has its own registry.
- Activate the image. In Azure Container Apps you select the new image as the active one and submit. Azure deploys it automatically.
Prerequisites
- Docker Desktop installed and running before you start.
- Azure CLI (
az) installed, and access to the company Azure account. - The latest code checked out from the correct branch, with the
Dockerfileat the repo root.
The tag rule
Every release needs a new image tag in the format v{version}-{message}, for example v0.0.2-fix-auth or v0.0.3-realtime-scrappers. The same tag must appear in both the build command and the push command. Never reuse a tag: unique tags let you see what is deployed and roll back to any earlier version.
The builds use --platform linux/amd64 so the image runs on Azure's servers even if you build on an Apple Silicon Mac. --load keeps the image in your local Docker so you can push it next.
6. Commands per server
Run these from the repo root. Replace the tag with your new one.
Main Node Server
az login
az acr login --name mainnodeserver2
docker buildx build --platform linux/amd64 -t mainnodeserver2.azurecr.io/main-node-server:v0.0.1-backend --load .
docker push mainnodeserver2.azurecr.io/main-node-server:v0.0.1-backendPython Vector Server
az login
az acr login --name vectorembeddings2
docker buildx build --platform linux/amd64 -t vectorembeddings2.azurecr.io/vector-embedding:v0.0.1-python-server --load .
docker push vectorembeddings2.azurecr.io/vector-embedding:v0.0.1-python-serverScraper Server
az login
az acr login --name jobsscraper2
docker buildx build --platform linux/amd64 -t jobsscraper2.azurecr.io/job-scrapper-service:v0.0.1-realtime-scrappers --load .
docker push jobsscraper2.azurecr.io/job-scrapper-service:v0.0.1-realtime-scrappers| Step | What it does |
|---|---|
az login | Signs you in to Azure in your browser. |
az acr login | Lets Docker push to that specific registry. |
docker buildx build | Builds the image locally. This can take 10 to 15 minutes, so wait for it to finish. |
docker push | Uploads the image to the registry so Azure can use it. |
| Server | Registry | Image name |
|---|---|---|
| Main Node Server | mainnodeserver2 | main-node-server |
| Python Vector Server | vectorembeddings2 | vector-embedding |
| Scraper Server | jobsscraper2 | job-scrapper-service |
7. Activate the image in Azure Container Apps
- Open the Azure Portal and go to Container Apps.
- Open the app you just pushed for (Node, Python or Scraper).
- Go inside the container settings of that app.
- Select the active image and choose your new tag.
- Click Review, then Submit.
- Azure deploys the image automatically. Wait until the new revision shows as running, then test the service.
Rolling back: repeat steps 1 to 5 but choose the previous tag. Because tags are never reused, the old image is still in the registry.
8. Databases
We use four databases. Each exists for a different kind of data, and they are not interchangeable.
| Database | What it stores | Why we use it |
|---|---|---|
| Redis | Cached data and scheduled jobs | In-memory and very fast. Speeds up repeated reads and coordinates background and scheduled work. |
| Neon (Postgres) | All conversation messages, conversation memory, and user context for the copilot | Relational and durable, suited to ordered chat history and structured memory. |
| MongoDB | Authenticated account data, resume builder data, basic job data, other user-related data | Flexible documents fit resumes and user profiles whose fields vary. |
| Qdrant | Vectors of all job data | Vector database that finds jobs by meaning, powering the copilot's job matching. |
How they work together
The Main Node Server uses MongoDB for accounts, resumes and jobs, and Redis for caching and scheduled jobs. The Python Vector Server uses Neon for conversations and memory, and Qdrant to search job vectors. The Scraper Server collects jobs that end up in the job data and in the vector store. Keeping responsibilities separate means a slow vector search never blocks login, and chat history never competes with resume data.
9. Team workflow
- Pull the designated latest branch (
mainfor frontends, the confirmed branch for each backend). - Create your own branch for every change.
- Test locally, push, and merge into the shared branch.
- Frontends deploy through Vercel. Backends follow sections 5 to 7.
- After every deployment, test the live service before moving on.
10. Troubleshooting
| Problem | Likely cause and fix |
|---|---|
| Docker cannot connect or build fails immediately | Docker Desktop is not running. Start it and retry. |
| Push is denied or unauthorized | Run az login and the matching az acr login again. Check that you used the right registry name. |
| New tag not visible in Container Apps | The push did not finish, or you pushed to a different registry. Re-run the push and confirm the tag matches. |
| Image will not start on Azure | Built without --platform linux/amd64. Rebuild with it. |
| Change not live after pushing to GitHub | Expected for backends. Complete the image steps and activation. |
| Build seems stuck | It can take 10 to 15 minutes. Wait before cancelling. |
11. Security
- Never commit
.envfiles, database connection strings or API keys to GitHub. - Keep secrets in Vercel project settings and Azure Container App settings.
- Use the shared company accounts only for company work, and rotate any key that is ever exposed.
12. Release checklist
- Latest code pulled from the correct branch
- Docker Desktop is running
az loginand the correctaz acr logindone- New, unused tag chosen
- Image built, then pushed with the same tag
- New image selected in Container Apps and submitted
- Service tested after deployment