Overview
This documentation details the deployment process of the backend of an Express.js boilerplate application to a production environment on an EC2 Ubuntu server using a GitHub Actions workflow. The deployment process includes setting up necessary dependencies, pulling the latest code, running tests, building the backend, and ensuring it runs as a service.
Prerequisites
- EC2 Ubuntu Server: Running Ubuntu, with SSH access.
- Node.js 20 installed on the server.
- npm installed on the server.
- Nginx installed and configured as a reverse proxy.
- GitHub Repository: Hosting the Express.js boilerplate code.
- GitHub Actions Runner: Installed and configured on the server to execute the deployment workflow.
- Certbot for SSL certificate management.
Dependencies
- Node.js 20
- npm
- Nginx
- Yarn (for managing Node.js dependencies)
- GitHub Actions Runner (self-hosted runner)
Deployment Workflow
name: Deploy to production
on:
push:
branches:
- prod
jobs:
deploy:
runs-on: bp_runner
defaults:
run:
working-directory: /var/www/aihomework/boilerplate/prod
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Remove old actions remote URL
continue-on-error: true
run: |
git remote rm action
- name: Stash or remove local changes
run: |
if git diff --quiet; then
echo "No local changes to stash."
else
echo "Stashing local changes..."
git stash --include-untracked || echo "Failed to stash changes. Attempting to reset..."
git reset --hard || exit 1
fi
- name: Pull from GitHub
id: pull
run: |
remote_repo="https://${GITHUB_ACTOR}:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git"
git remote add action $remote_repo
git pull $remote_repo prod
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Run tests
run: yarn test
- name: Build the application
run: yarn build && sudo rm -rf build
- name: Setup and restart service
run: |
sudo cp server-script/aihomeworkprod.service /etc/systemd/system
sudo systemctl daemon-reload
sudo systemctl restart aihomeworkprod.service
- name: Verify deployment
run: |
echo "Waiting for service to start..."
sleep 10
if sudo systemctl is-active --quiet aihomeworkprod.service; then
echo "Deployment successful!"
else
echo "Deployment failed!"
exit 1
fi
1. Triggering the Workflow
- The workflow is triggered by a push to the
prod
branch.
2. Checking Out the Code
- The
actions/checkout@v3
action pulls the latest code from theprod
branch, ensuring the full history is retrieved (fetch-depth: 0
).
3. Setting Up Node.js
- The workflow installs Node.js version 20 using the
actions/setup-node@v3
action.
4. Managing Git Remotes and Local Changes
- Remove Old Remote URL: Deletes any existing remote URL to prevent conflicts.
- Stash or Remove Local Changes: Uncommitted changes are stashed or reset to maintain a clean working directory.
5. Pulling Latest Changes
- The latest changes are pulled from the
prod
branch using the GitHub token for authentication.
6. Installing Dependencies
- Node.js dependencies are installed using
yarn install --frozen-lockfile
to ensure consistency with theyarn.lock
file.
7. Running Tests
- Tests are executed using
yarn test
to verify the stability of the backend before deployment.
8. Building the Backend
- The backend is built using
yarn build
, and previous build artifacts are removed to prevent conflicts.
9. Setting Up and Restarting the Service
- The service file (
aihomeworkprod.service
) is copied to the/etc/systemd/system
directory, and the systemd manager configuration is reloaded. The service is restarted to apply the latest changes.
10. Verifying Deployment
- The workflow waits for the service to start and checks its status. If the service is active, the deployment is successful; otherwise, it fails.
Service Configuration (aihomeworkprod.service
)
The service file defines how the backend of the Express.js application runs on the server. Below is a sample service configuration:
[Unit]
Description=Express.js Backend Application - Production
After=network.target
[Service]
ExecStart=/usr/bin/node /var/www/aihomework/boilerplate/prod/build/index.js
WorkingDirectory=/var/www/aihomework/boilerplate/prod
Restart=always
User=www-data
Group=www-data
Environment=NODE_ENV=production
Environment=PORT=3000
[Install]
WantedBy=multi-user.target
Nginx Configuration
Nginx is used as a reverse proxy to route incoming traffic to the Express.js backend application. The following Nginx configuration includes the SSL setup using Certbot:
server {
listen 80;
server_name your-domain.com;
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;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
SSL Certificate Setup
To obtain SSL certificates and configure Nginx with HTTPS, you can use the following command with Certbot:
sudo certbot --nginx -d your-domain.com
This command will automatically configure Nginx with SSL, obtaining certificates from Let’s Encrypt.
Final Steps
- Ensure Nginx is configured to point to the backend’s port.
-
Enable and start the systemd service:
sudo systemctl enable aihomeworkprod.service
andsudo systemctl start aihomeworkprod.service
. -
Monitor the service using
sudo systemctl status aihomeworkprod.service
.
NOTE
- Ensure that you update the .env file with the required variables in order to ensure the application runs successfully.
Conclusion
This documentation outlines the automated deployment process for the backend of the Express.js boilerplate application, ensuring that the latest changes are consistently deployed to the production environment. By following the above steps, the backend can be reliably updated and maintained on the EC2 Ubuntu server with SSL-secured access.
Top comments (0)