A modern full-stack web application to create and customize your personal developer portfolio. Built in TypeScript with React and Next.js.
Contributing: See CONTRIBUTING.md
- ✅ Important Functionalities (FE/BE Split & CV): 06.07.2025
- ✅ Feature Complete (at-least medium & high): 10.08.2025
- ✅ In-depth Documentation: 22.08.2025
- Personal information management with avatar and social links
- Skills showcase with proficiency levels
- GitHub integration for repository display
- CV builder with work experience and education
- AI-powered bio generation with Gemini
- API key management for AI services
- Dark/light theme support
- JWT-based authentication
- Real-time editing with unsaved changes detection
- React 19 with TypeScript
- Vite for development
- HeroUI component library
- Tailwind CSS for styling
- Framer Motion for animations
- Next.js 15 with API routes
- JWT authentication with bcryptjs
- JSON file-based data storage
- Visit the latest Release and download the build.zip (for the latest version, visit Deploy Actions and download the "build" artifact from the top pipeline)
- Unzip it in a new directory
- Make the subdirectory /frontend available via a web server e.g. nginx
- Run the Backend via
npm start - The backend is not needed once the data has been configured and can be turned off
This project is deployed as a Docker container, you will need Docker installed on your server.
-
Pull the Docker Image
docker pull ghcr.io/phillipc0/wa-dp:latest
-
Run the Docker Container
docker run -d --name WA-DP -p 3000:80 --restart always ghcr.io/phillipc0/wa-dp:latest
-
Configure a Reverse Proxy (Nginx)
The Docker container opens the application on port
3000. You need a web-server like Nginx as a reverse proxy. https://nginx.org/en/docs/beginners_guide.htmlHere is an example Nginx configuration:
server { listen 443 ssl; server_name wa-dp.your-domain.com; # SSL-certificate and keys etc... location / { proxy_pass http://127.0.0.1:3000; } } server { listen 80; server_name wa-dp.your-domain.com; return 301 https://$host$request_uri; }
You have two options for managing your portfolio data (portfolio.json and users.json), to persist manual updates
to the wa-dp-container:
Option A: Manual Export/Import
With this method, you use WA-DP's built-in export feature to back up your data before updating.
- Before updating the container:
- Log into WA-DP
- Go to the "Edit" page
- Use the "Export Portfolio Data" button to download your
portfolio-data.json
- After updating the container:
- Log in again (you need to create a new admin user)
- Use the "Import Portfolio Data" button to upload your saved
portfolio-data.json
Option B: Using Docker Volumes (Recommended)
This method persists your data on the host machine, throughout container updates automatically
-
First, create a directory on your server to store your data:
mkdir -p /path/on/your/server/wa-dp-data
-
Run the container with a volume: Replace
/path/on/your/server/wa-dp-datawith the actual path you just created.docker run -d --name WA-DP -p 3000:80 --restart always \ -v /path/on/your/server/wa-dp-data:/app/data \ ghcr.io/phillipc0/wa-dp:latest
Now, all updates to your portfolio and user data will be saved in the specified directory on your server.
-
Stop and remove the old container:
docker stop wa-dp-container docker rm wa-dp-container
-
Pull the latest image from the registry:
docker pull ghcr.io/phillipc0/wa-dp:latest
-
Start the new container:
Run the same
docker runcommand you used initially, depending on whether you are using volumes or not. -
(Optional) Clean up old images:
After a few updates, you might have old, unused images. You can clean them up with:
docker rmi $(docker images -q --filter "dangling=true" --filter="reference=ghcr.io/phillipc0/wa-dp")
Install all dependencies:
npm run install-devStart development servers:
npm run devThe app will be available at:
- Frontend: http://localhost:5173
- Backend API: http://localhost:3000
npm run dev # Start both frontend and backend
npm run dev:frontend # Frontend only (port 5173)
npm run dev:backend # Backend only (port 3000)
npm run test # Run unit tests
npm run test:cov # Run tests with coverage
npm run e2e:open # Open Cypress test runner
npm run build # Build for production
npm run lint # Lint and fix codeThis project includes a CI/CD pipeline powered by GitHub Actions.
Checks for every push on a pull request or the the main branch:
All branches:
- Linting & Formatting using ESLint
- Unit tests using Vitest
including coverage (>80%) - E2E tests using Cypress
- Lighthouse report, score over 80
- SonarCloud static code analysis (not required)
Only main branch:
- Build the project for production
- Push the docker image
Manual jobs:
- Lines of code are measurement
- File Dependency Graph
The dependencies between the pipelines are as follows:
The pipeline configuration is located in .github/workflows/test-build-deploy.yml.
src/ # Frontend React application
backend/ # Next.js API routes and backend logic
tests/ # Unit tests with Vitest
cypress/ # E2E tests with Cucumber
- Path aliases:
@/*maps to./src/* - API proxy: Frontend proxies
/api/*to backend on port 3000 - Authentication: JWT tokens stored in secure cookies
- Data storage: JSON files for users and portfolio data
- Unit tests: Vitest
- E2E tests: Cypress with Cucumber/Gherkin
- Coverage reports available with
npm run test:cov
Madge is included to visualize module dependencies and compute simple metrics. Run the following command to generate an
SVG graph and metrics file under docs/:
npm run deps:madgeThis creates docs/dependency-graph.svg and docs/dependency-metrics.json with coupling and cohesion values for each
module.
The generated files are excluded from version control via .gitignore.
Make sure Graphviz is installed locally so Madge can create the SVG image.
This project includes SonarQube integration for code quality analysis and coverage reporting.
-
Start SonarQube locally using Docker:
docker-compose -f docker-compose.sonar.yml up -d
-
Access SonarQube:
- Open http://localhost:9000 in your browser
- Login with default credentials:
admin/admin - Change password when prompted
- Generate Authentication Token:
- Go to: User → My Account → Security → Generate Tokens
- Enter a name and select "User Token" in the dropdown then click "Generate"
- Copy the generated token
-
Configure Authentication:
# Copy the template file for local development cp sonar-project-local.properties.template sonar-project-local.properties # Edit sonar-project-local.properties and replace "your-token-here" with your actual token
# Run analysis only
npm run sonar
# Run tests with coverage + analysis
npm run sonar:coveragedocker-compose -f docker-compose.sonar.yml downLicensed under the MIT license.