A full-stack digital asset marketplace for discovering, filtering, and purchasing creative digital assets.
PixelVault V2 is a full-stack web application designed as a digital marketplace for creative assets. The platform allows users to explore and discover different categories of digital content, including:
- Photography
- Graphics
- Illustrations
- Templates
- Videos
- Audio assets
The application provides an interactive frontend for browsing and filtering assets, along with a backend API for handling application logic and database operations.
PixelVault V2 is deployed using AWS EC2 with a Node.js and Express.js backend, a React and Vite frontend, and a MySQL database.
The application follows a client-server architecture:
┌─────────────────────┐
│ │
│ React + Vite │
│ Frontend │
│ │
└──────────┬──────────┘
│
│ HTTP Requests
│
▼
┌─────────────────────┐
│ │
│ Node.js + Express │
│ Backend │
│ │
└──────────┬──────────┘
│
│ Database Queries
│
▼
┌─────────────────────┐
│ │
│ MySQL │
│ Database │
│ │
└─────────────────────┘
User
│
▼
AWS EC2 Instance
│
├── React Frontend
│ Port: 5173
│
├── Express Backend
│ Port: 3000
│
└── MySQL Database
Port: 3306
PM2 is used to manage and keep the frontend and backend processes running.
- React — User interface development
- Vite — Frontend build tool and development environment
- React Router — Client-side routing and navigation
- CSS — Application styling
- Node.js — JavaScript runtime environment
- Express.js — Backend web framework
- PM2 — Production process management
- MySQL — Relational database management system
- AWS EC2 — Cloud virtual machine hosting
- Ubuntu Linux — Server operating system
- AWS Security Groups — Network access control
- SCP — Secure file transfer
- mysqldump — Database export and migration
- Browse a marketplace of digital creative assets
- Explore multiple asset categories
- Filter and search available content
- View asset information
- Purchase digital assets
- Persistent database storage using MySQL
- REST API-based communication between frontend and backend
- Cloud deployment on AWS EC2
- Process management using PM2
Before deploying PixelVault V2, ensure that the following software and services are available:
- Node.js
- npm
- MySQL Server
- PM2
- AWS EC2 instance running Ubuntu
- SSH access to the EC2 instance
- AWS Security Group configured for the required ports
Connect to your AWS EC2 instance using SSH:
ssh -i your-key.pem ubuntu@your-ec2-public-ipReplace:
your-key.pemwith your EC2 private key fileyour-ec2-public-ipwith the public IP address or DNS of your EC2 instance
Free-tier or memory-constrained EC2 instances can experience memory limitations while running services such as MySQL, Node.js, and the operating system simultaneously.
To provide additional virtual memory, create a persistent 2 GB swap file.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfileTo ensure that the swap file remains active after the server restarts:
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstabVerify the available memory and swap:
free -hLog in to MySQL as the root user:
sudo mysql -u root -pCreate the PixelVault database:
CREATE DATABASE pixelvault;Create a dedicated MySQL user for the application:
CREATE USER 'pixeluser'@'localhost'
IDENTIFIED WITH caching_sha2_password
BY 'your_password';Grant the required privileges:
GRANT ALL PRIVILEGES ON pixelvault.* TO 'pixeluser'@'localhost';Apply the privilege changes:
FLUSH PRIVILEGES;Exit MySQL:
EXIT;Important: Replace
your_passwordwith a strong and secure password. Do not commit real credentials to version control.
On the local development machine, export the database schema and records using mysqldump:
mysqldump -u root -p pixelvault > pixelvault_dump.sqlThis creates a SQL dump file named:
pixelvault_dump.sql
Securely copy the database dump to the EC2 instance using scp:
scp -i your-key.pem pixelvault_dump.sql ubuntu@your-ec2-public-ip:/home/ubuntu/After connecting to the EC2 instance, import the SQL dump:
mysql -u root -p pixelvault < pixelvault_dump.sqlAlternatively, if the dump was uploaded to another location:
mysql -u root -p pixelvault < /path/to/pixelvault_dump.sqlVerify that the tables were successfully restored:
mysql -u root -pThen:
USE pixelvault;
SHOW TABLES;Create a .env file inside the /backend directory:
PORT=3000
DB_HOST=localhost
DB_USER=pixeluser
DB_PASSWORD=your_password
DB_NAME=pixelvault
The environment variables are used to configure the backend server and database connection.
| Variable | Description |
|---|---|
PORT |
Port on which the Express backend runs |
DB_HOST |
MySQL database host |
DB_USER |
MySQL application username |
DB_PASSWORD |
Password for the MySQL user |
DB_NAME |
Name of the PixelVault database |
Security Note: The
.envfile should be added to.gitignoreto prevent sensitive credentials from being pushed to GitHub.
Example:
.env
node_modules/
dist/Navigate to the backend directory:
cd backendInstall all required dependencies:
npm installStart the Express server:
pm2 start server.js --name "pixelvault-backend"Check the process status:
pm2 statusView backend logs:
pm2 logs pixelvault-backendRestart the backend when necessary:
pm2 restart pixelvault-backendNavigate to the frontend directory:
cd ../frontendInstall the dependencies:
npm installCreate a production build:
npm run buildThis generates the production-ready static files inside the:
dist/
directory.
Serve the production build on port 5173:
pm2 start npx --name "pixelvault-frontend" -- serve -s dist -l 5173Check the PM2 processes:
pm2 statusThe expected result should include:
pixelvault-backend
pixelvault-frontend
To ensure that the application processes restart automatically after the EC2 instance reboots:
pm2 startupPM2 will provide a command. Run the command displayed in the terminal.
Then save the current process list:
pm2 saveThis ensures that both the frontend and backend can be restored automatically after a system restart.
The backend server should listen on all available network interfaces.
Example:
app.listen(process.env.PORT || 3000, '0.0.0.0', () => {
console.log(`Server running on port ${process.env.PORT || 3000}`);
});Binding to 0.0.0.0 allows the Express application to accept external requests.
If the frontend and backend run on different origins or ports, configure CORS in the Express backend.
Example:
const cors = require('cors');
app.use(cors());For production, it is recommended to restrict requests to the frontend origin:
app.use(
cors({
origin: 'http://your-ec2-public-ip:5173'
})
);Replace the example URL with the actual frontend URL.
The AWS EC2 Security Group must allow inbound traffic to the ports required by the application.
| Port | Protocol | Purpose |
|---|---|---|
22 |
TCP | SSH access |
3000 |
TCP | Express Backend API |
5173 |
TCP | React Frontend |
3306 |
TCP | MySQL — only if external database access is required |
Security Recommendation: Port
3306should generally not be publicly exposed. Keep MySQL accessible only from the EC2 instance whenever possible.
For the application to work externally, ensure that the Security Group allows inbound access to:
Port 3000 → Backend API
Port 5173 → Frontend
PixelVault-V2/
│
├── backend/
│ ├── node_modules/
│ ├── routes/
│ ├── controllers/
│ ├── models/
│ ├── server.js
│ ├── package.json
│ └── .env
│
├── frontend/
│ ├── src/
│ ├── public/
│ ├── dist/
│ ├── package.json
│ └── vite.config.js
│
├── pixelvault_dump.sql
├── README.md
└── .gitignore
The exact folder structure may vary depending on the implementation of PixelVault V2.
Free-tier or memory-constrained EC2 instances may provide only 1 GB of RAM. Running the Ubuntu operating system, MySQL, Node.js processes, and other services simultaneously can exhaust the available memory.
This can result in:
- MySQL failing to start
- Out-of-Memory (OOM) errors
- Processes being unexpectedly terminated
- Slow application performance
A persistent 2 GB swap file was created to provide additional virtual memory.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfileThe swap file was also configured in /etc/fstab so that it remains active after system reboots.
Swap memory is not a replacement for physical RAM, but it can provide important memory headroom for small cloud instances and prevent services from immediately failing when RAM usage temporarily increases.
MySQL installations on Ubuntu can use authentication configurations that prevent the application from connecting in the expected way.
The Node.js backend requires a dedicated database account with credentials that can be used by the MySQL client library.
A dedicated application user was created:
CREATE USER 'pixeluser'@'localhost'
IDENTIFIED WITH caching_sha2_password
BY 'your_password';The user was granted privileges only for the PixelVault database:
GRANT ALL PRIVILEGES ON pixelvault.* TO 'pixeluser'@'localhost';Using a dedicated database account is preferable to connecting an application directly as the MySQL root user. It improves separation between administrative and application-level access.
The cloud-hosted EC2 instance initially did not contain the database records available in the local development environment.
The application required both the database structure and existing records to function correctly after deployment.
The local database was exported using:
mysqldump -u root -p pixelvault > pixelvault_dump.sqlThe resulting SQL dump was securely transferred to the EC2 instance using scp:
scp -i your-key.pem pixelvault_dump.sql ubuntu@your-ec2-public-ip:/home/ubuntu/The database was then restored using:
mysql -u root -p pixelvault < pixelvault_dump.sqlDatabase migration is a critical deployment step. The application code alone is often insufficient because relational applications also depend on database schemas, relationships, and existing data.
The application initially failed to respond to requests from outside the EC2 server.
Possible causes included:
- Express binding only to localhost
- Missing AWS Security Group rules
- Frontend-backend communication issues
- Cross-Origin Resource Sharing restrictions
The Express server was configured to bind to:
0.0.0.0
The AWS Security Group was configured to allow the required inbound ports:
3000 → Backend API
5173 → Frontend
CORS middleware was also configured to allow the frontend to communicate with the backend.
Successful cloud deployment requires correct configuration across multiple layers:
- Application server binding
- Operating system networking
- Cloud firewall or Security Group rules
- Browser security and CORS policies
A problem at any one of these layers can prevent the application from functioning correctly.
pm2 statuspm2 logspm2 logs pixelvault-backendpm2 logs pixelvault-frontendpm2 restart allfree -hswapon --showsudo systemctl status mysqlRestart MySQL if required:
sudo systemctl restart mysqlsudo ss -tulpn | grep :3000sudo ss -tulpn | grep :5173After making changes to the application, the deployment can generally be updated using the following process.
cd backend
npm install
pm2 restart pixelvault-backendcd frontend
npm install
npm run build
pm2 restart pixelvault-frontendCheck the updated processes:
pm2 statusBefore using the application in a production environment, consider the following improvements:
- Use strong database passwords
- Never commit
.envfiles to GitHub - Restrict MySQL access to trusted hosts
- Do not publicly expose MySQL port
3306unless absolutely necessary - Configure CORS to allow only trusted frontend origins
- Use HTTPS for encrypted communication
- Place the application behind a reverse proxy such as Nginx
- Use a domain name instead of relying directly on an EC2 IP address
- Regularly update Ubuntu packages and application dependencies
- Follow the principle of least privilege for database users
- Enable proper logging and monitoring
Potential improvements for future versions of PixelVault include:
- User authentication and authorization
- Secure payment gateway integration
- Shopping cart functionality
- Wishlist and favorites
- Advanced search functionality
- Improved category-based filtering
- User profiles
- Asset upload functionality for creators
- Order history
- Admin dashboard
- Image optimization and CDN integration
- Object storage using Amazon S3
- Nginx reverse proxy
- HTTPS using SSL/TLS certificates
- CI/CD deployment pipeline
- Docker containerization
- Automated database backups
- Monitoring and alerting
The PixelVault V2 deployment process involved:
- Creating and configuring an AWS EC2 instance.
- Installing and configuring MySQL.
- Creating a persistent 2 GB swap file to address memory limitations.
- Creating the
pixelvaultdatabase. - Creating a dedicated
pixeluserMySQL account. - Migrating the local database using
mysqldump. - Securely transferring the database dump using
scp. - Restoring the database on the EC2 instance.
- Configuring backend environment variables.
- Installing backend dependencies.
- Running the Express backend using PM2.
- Building the React frontend for production.
- Serving the frontend using PM2.
- Configuring Express networking and CORS.
- Opening the required ports through the AWS Security Group.
- Configuring PM2 persistence for automatic process recovery.
This project is currently intended for educational and development purposes.
PixelVault V2 Full-Stack Digital Asset Marketplace