Welcome to Soul Friends Application, a robust and scalable full-stack project built using modern technologies and best practices. This monorepo leverages TurboRepo for efficient build management, pnpm for package management, and integrates a suite of tools for seamless development, testing, and deployment.
- Soul Friends Application
This project is a full-stack application with the following tech stack:
- Frontend: Next.js, Tailwind CSS
- Backend: Nest.js, TypeORM
- Database: MySQL (managed via Docker)
- Monorepo Management: TurboRepo
- Package Manager: pnpm
- CI/CD: GitHub Actions following Gitflow workflow
- Hosting: Virtual Machine on Naver Cloud Platform
- Process Management: PM2
TurboRepo optimizes build and development workflows, while pnpm ensures efficient dependency management. The project adheres to best practices for scalability, security, and maintainability.
/my-fullstack-app
├── apps
│ ├── frontend
│ │ ├── public
│ │ ├── src
│ │ ├── styles
│ │ ├── next.config.js
│ │ ├── tailwind.config.js
│ │ ├── postcss.config.js
│ │ ├── tsconfig.json
│ │ └── package.json
│ └── backend
│ ├── src
│ ├── test
│ ├── nest-cli.json
│ ├── ormconfig.ts
│ ├── tsconfig.json
│ └── package.json
├── packages
│ └── shared (optional)
│ ├── src
│ └── package.json
├── docker
│ └── docker-compose.yml
├── .github
│ └── workflows
│ └── ci-cd.yml
├── ecosystem.config.js
├── turbo.json
├── pnpm-workspace.yaml
├── package.json
└── README.md
Before getting started, ensure you have the following installed on your machine:
- Node.js (v18.x or later)
- pnpm (v8.x or later)
- Docker (for managing MySQL)
- Git
- PM2 (for process management)
- SSH Access (for deploying to the VM)
git clone https://github.com/yourusername/my-fullstack-app.git
cd my-fullstack-app
pnpm install
This command installs all dependencies for the frontend, backend, and shared packages as defined in the pnpm-workspace.yaml
.
Ensure Docker is installed and running on your machine.
-
Navigate to the
docker
directory:cd docker
-
Start the MySQL service using Docker Compose:
docker-compose up -d
This command will pull the official MySQL image and start the container with the specified environment variables.
Return to the root directory and start the development servers:
cd ..
pnpm dev
TurboRepo will run both the frontend and backend in parallel. By default:
- Frontend: http://localhost:3000
- Backend: http://localhost:4000/api
To build both frontend and backend applications:
pnpm build
TurboRepo optimizes the build process by caching and parallelizing tasks.
Run tests for all packages:
pnpm test
For example, to run tests only for the frontend:
pnpm --filter frontend test
Ensure code quality by running linting:
pnpm lint
For example, to lint only the backend:
pnpm --filter backend lint
Deployment involves provisioning a VM, setting up the server environment, deploying the application, and configuring a reverse proxy with SSL.
-
Create a VM Instance:
- Choose an OS (e.g., Ubuntu 22.04 LTS).
- Allocate sufficient resources based on your application's needs.
-
Configure Security Groups:
- Open necessary ports:
- SSH: Port 22
- HTTP: Port 80
- HTTPS: Port 443
- Application Ports: E.g., 4000 for backend
- Open necessary ports:
-
Set Up SSH Access:
- Generate SSH keys if not already done.
- Add your public key to the VM's authorized keys.
-
SSH into the VM:
ssh your_username@your_vm_ip
-
Update and Install Dependencies:
sudo apt update && sudo apt upgrade -y sudo apt install -y git curl build-essential
-
Install Node.js and pnpm:
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt-get install -y nodejs npm install -g pnpm
-
Install PM2 Globally:
sudo npm install -g pm2
-
Clone Your Repository:
git clone https://github.com/yourusername/my-fullstack-app.git cd my-fullstack-app
-
Install Dependencies:
pnpm install
-
Set Up Environment Variables:
- Create
.env
files for frontend and backend based on the sample below.
- Create
PORT=4000
DB_HOST=db
DB_PORT=3306
DB_USERNAME=myapp_user
DB_PASSWORD=myapp_password
DB_NAME=myapp_db
JWT_SECRET=your_jwt_secret
NEXT_PUBLIC_API_URL=http://your-backend-api-url/api
Note: Ensure .env
files are added to .gitignore
to prevent sensitive information from being committed.
-
Build the Application:
pnpm build
-
Run Database Migrations:
pnpm --filter backend typeorm migration:run
-
Start Applications with PM2:
pm2 start ecosystem.config.js pm2 save pm2 startup
Note: The
pm2 startup
command will output a command that you need to run withsudo
to configure PM2 to start on system boot.
-
Install NGINX:
sudo apt install -y nginx
-
Configure NGINX:
sudo nano /etc/nginx/sites-available/myapp
Example NGINX Configuration:
server { listen 80; server_name your_domain.com; location /api/ { proxy_pass http://localhost:4000/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } location / { proxy_pass http://localhost:3000/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }
-
Enable the Configuration and Restart NGINX:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx
-
Install Certbot:
sudo apt install -y certbot python3-certbot-nginx
-
Obtain and Install SSL Certificates:
sudo certbot --nginx -d your_domain.com
Follow the prompts to complete the SSL setup.
Automate your build, test, and deployment processes using GitHub Actions following the Gitflow workflow.
The CI/CD pipeline is defined in .github/workflows/ci-cd.yml
. It performs the following steps:
-
Build and Test:
- Checks out the code.
- Sets up Node.js and pnpm.
- Installs dependencies.
- Runs linting, testing, and building for both frontend and backend.
-
Deploy:
- Triggered only on the
main
branch. - Builds the application.
- Copies files to the VM via SSH.
- Runs database migrations.
- Restarts PM2 processes for zero-downtime deployment.
- Triggered only on the
Sample Workflow Configuration:
name: CI/CD Pipeline
on:
push:
branches:
- main
jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
package: [frontend, backend]
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Verify pnpm Installation
run: pnpm --version
- name: Install Dependencies
run: pnpm install
- name: Lint
run: pnpm turbo run lint --filter=${{ matrix.package }}
- name: Test
run: pnpm turbo run test --filter=${{ matrix.package }}
- name: Build
run: pnpm turbo run build --filter=${{ matrix.package }}
deploy:
needs: build-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Verify pnpm Installation
run: pnpm --version
- name: Install Dependencies
run: pnpm install
- name: Build Frontend and Backend
run: pnpm build
- name: Copy Files via SSH
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.VM_HOST }}
username: ${{ secrets.VM_USER }}
key: ${{ secrets.VM_SSH_KEY }}
source: '.'
target: '/home/${{ secrets.VM_USER }}/app'
debug: true
- name: Restart PM2 Processes
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.VM_HOST }}
username: ${{ secrets.VM_USER }}
key: ${{ secrets.VM_SSH_KEY }}
script: |
cd /home/${{ secrets.VM_USER }}/app
pnpm install --prod
pm2 reload ecosystem.config.js
Secrets Required:
VM_HOST
: IP address or hostname of your Naver Cloud VM.VM_USER
: SSH username.VM_SSH_KEY
: Private SSH key for authentication.
Notes:
- Ensure that the SSH key has the necessary permissions to access the VM.
- Adjust the
source
andtarget
paths based on your deployment strategy.
Manage environment-specific variables using .env
files for both frontend and backend.
PORT=4000
DB_HOST=db
DB_PORT=3306
DB_USERNAME=myapp_user
DB_PASSWORD=myapp_password
DB_NAME=myapp_db
JWT_SECRET=your_jwt_secret
NEXT_PUBLIC_API_URL=http://your-backend-api-url/api
Note: Add .env
files to .gitignore
to prevent committing sensitive information.
Contributions are welcome! Please follow the Gitflow workflow for managing branches and submitting pull requests.
-
Fork the Repository
-
Create a Feature Branch
git checkout -b feature/your-feature-name
-
Commit Your Changes
git commit -m "feat: add your feature description"
-
Push to the Branch
git push origin feature/your-feature-name
-
Open a Pull Request
Navigate to the repository on GitHub and open a pull request against the
develop
branch.
This project is licensed under the MIT License.
- TurboRepo Documentation
- pnpm Documentation
- Next.js Documentation
- Nest.js Documentation
- TypeORM Documentation
- GitHub Actions Documentation
By following this guide, you'll have a fully functional full-stack application with optimized build processes, efficient dependency management, and automated CI/CD pipelines. Customize configurations as needed to fit the specific requirements of your project.
Happy Coding! 🚀