1. Introduction
Deploying a web application can often feel like a daunting task, especially when striving for a seamless user experience. Nuxt 2, a popular framework for building Vue.js applications, is no exception. Ensuring a smooth deployment process with zero downtime is crucial for maintaining user trust and satisfaction. This guide walks you through deploying a Nuxt 2 application using GitLab CI/CD and DigitalOcean, ensuring efficiency and reliability.
GitLab CI/CD provides a robust and flexible platform for automating the deployment pipeline, while DigitalOcean offers scalable and straightforward hosting solutions. Combined with tools like PM2 for process management and Nginx for serving your application, you can achieve a production-ready deployment with zero downtime.
Whether you’re deploying for the first time or looking to refine your existing workflow, this guide will help you master the process step-by-step, from setting up your server to configuring continuous integration and deployment. By the end, your Nuxt 2 application will be live and running seamlessly on DigitalOcean, ready to handle production traffic.
2. Prerequisites
Before diving into the deployment process, ensure you have these essential components for successfully deploying your Nuxt 2 application using GitLab CI/CD and DigitalOcean.
2.1 Development Environment
-
Nuxt 2 Application: Production-ready with configured
nuxt.config.js
-
Node.js and Package Manager:
- Node.js 18.x LTS
- Yarn or NPM for package management
2.2 GitLab Repository
- GitLab repository with your Nuxt 2 project
- CI/CD pipeline configuration access
- Version control best practices implemented
2.3 DigitalOcean Account
- Active DigitalOcean account
- Droplet specifications:
- Ubuntu 22.04 or 24.04 LTS
- 1 vCPU, 1 GB RAM, 25 GB SSD
- Optional: Registered domain name
2.4 Server Requirements
- Operating System: Ubuntu 22.04 or 24.04 LTS
-
Minimum Hardware:
- 1 vCPU
- 1 GB RAM
- 25 GB SSD storage
2.5 Essential Tools
- Process Management: PM2 (v5.x recommended)
- Web Server: Nginx (v1.18 or later)
-
Security:
- SSH
- Certbot for Let's Encrypt SSL
2.6 Required Knowledge
Helpful background in:
- Basic Linux terminal commands
- Git workflows
- GitLab CI/CD concepts
- Nuxt 2 application structure
With these prerequisites met, you're prepared to implement a professional deployment pipeline for your Nuxt 2 application.
3. Setting Up the DigitalOcean Server
Setting up a reliable server is the foundation for a seamless deployment process. Follow these steps to prepare your
DigitalOcean droplet:
3.1 Create a Droplet
- Log in to your DigitalOcean account and navigate to the Create menu.
- Select Droplets and choose Ubuntu 22/24.04 as the operating system.
- Select the appropriate plan for your application. A basic plan with 1 GB RAM and 1 vCPU is sufficient for small projects. Upgrade as needed for larger applications.
- Add your SSH key to enable secure access to the server. If you don’t have one, generate an SSH key pair using the following command on your local machine:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Add the public key (~/.ssh/id_rsa.pub
) to your droplet. Follow the instruction
from how to add SSH keys to Droplets.
cat ~/.ssh/id_rsa.pub
- Finalize and create the droplet. Name your DigitalOcean droplet based on its purpose, environment, and region for clarity, such as web-prod-nyc1 or db-staging-ams3. Use short, descriptive, and consistent names to make management easier. Avoid generic names like server1 to ensure quick identification. We called our droplet: demo-deploy-nuxt2-app. Take note of the droplet’s public IP address.
3.2 Secure the Server
After creating the droplet, secure it to prevent unauthorized access:
- Connect to the droplet using SSH:
ssh root@your_droplet_ip
- Update the system packages:
apt update && apt upgrade -y
- Set up a basic firewall using UFW (Uncomplicated Firewall):
ufw allow OpenSSH
ufw enable
- Create a dedicated deployment user with sudo privileges:
adduser deployer
usermod -aG sudo deployer
- Disable root login and password-based authentication for SSH by editing the SSH configuration file:
nano /etc/ssh/sshd_config
Change the following lines:
PermitRootLogin no
PasswordAuthentication no
Restart the SSH service:
systemctl restart ssh
3.3 Install Node.js and PM2
- Install Node.js (18 LTS version):
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
apt install -y nodejs
- Verify the installation:
node -v
npm -v
- Install PM2 globally to manage your Nuxt 2 application:
npm install -g pm2
3.4 Install and Configure Nginx
- Install Nginx:
apt install nginx -y
- Configure Nginx as a reverse proxy for your application. When naming Nginx configuration files, use lowercase
letters and descriptive names for clarity, such as
example-site.conf
orapi-backend.conf
. For environment-specific files, add suffixes like-dev
,-stg
, or-prod
(e.g.,example-site-prod.conf
). Shared or reusable configurations should have clear prefixes likeshared-headers.conf
. Avoid redundancy by omitting terms like "nginx" in file names and use.bak
or.disabled
for backups or inactive files. We name our config file like: demo-deploy-nuxt2-app-prod.
nano /etc/nginx/sites-available/demo-deploy-nuxt2-app-prod
Replace the contents with the following configuration:
server {
listen 80;
server_name your_domain.com;
# Disable server tokens for security
server_tokens off;
# Basic security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
location / {
proxy_pass http://localhost:PORT;
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;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- Enable config file, test the configuration and reload Nginx:
sudo ln -s /etc/nginx/sites-available/demo-deploy-nuxt2-app-prod /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx
Server setup complete! You're now ready to deploy your Nuxt 2 application with enhanced security and performance.
4. Configuring GitLab CI/CD
This section outlines the steps to configure GitLab CI/CD for deploying a Nuxt 2 application to staging and production
environments. The .gitlab-ci.yml
file and ecosystem.config.js
facilitate automated deployment using Node.js and PM2.
4.1 Define CI/CD Variables
Navigate to Settings > CI/CD > Variables in GitLab. Add these variables to securely store sensitive data:
-
STAGING_SSH_PRIVATE_KEY
: Private SSH key for the staging server. -
PRODUCTION_SSH_PRIVATE_KEY
: Private SSH key for the production server.
Ensure these keys match those configured for your DEPLOY_USER
on the respective servers.
4.2 Overview of .gitlab-ci.yml
This file defines the pipeline with the following stages:
- Test: Runs tests to validate the application.
- Build: Compiles the application for deployment.
- Deploy to Staging: Deploys the build to staging.
- Deploy to Production: Deploys the build to production.
image: node:18
stages:
- test
- build
- deploy-production
variables:
PRODUCTION_SERVER: staging-server-ip
DEPLOY_USER: deployer
PRODUCTION_APP_NAME: demo-deploy-nuxt2-app-production
PRODUCTION_PORT: 3200
PRODUCTION_APP_PATH: /var/www/production
DEPLOY_FILES: ".nuxt static nuxt.config.js package.json yarn.lock ecosystem.config.js"
cache:
paths:
- node_modules/
- .yarn-cache/
before_script:
- yarn config set cache-folder .yarn-cache
- yarn install --frozen-lockfile
test:
stage: test
script:
- yarn test
build:
stage: build
script:
- yarn build
artifacts:
paths:
- .nuxt/
- static/
- nuxt.config.js
- package.json
- yarn.lock
- ecosystem.config.js
expire_in: 1 hour
deploy-production:
stage: deploy-production
environment:
name: production
url: https://yourdomain.com
script:
- apt-get update -qy
- apt-get install -y openssh-client
- mkdir -p ~/.ssh
- echo "$PRODUCTION_SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -H $PRODUCTION_SERVER >> ~/.ssh/known_hosts
# Create new release directory
- export RELEASE_DIR=$(date +%Y%m%d%H%M%S)
- |
ssh $DEPLOY_USER@$PRODUCTION_SERVER "
mkdir -p $PRODUCTION_APP_PATH/releases/$RELEASE_DIR;
"
# Copy built artifacts
- scp -r $DEPLOY_FILES $DEPLOY_USER@$PRODUCTION_SERVER:$PRODUCTION_APP_PATH/releases/$RELEASE_DIR/
# Update symlinks and restart application
- |
ssh $DEPLOY_USER@$PRODUCTION_SERVER "
cd $PRODUCTION_APP_PATH;
if [ -L current ]; then mv current previous; fi;
ln -s releases/$RELEASE_DIR current;
cd current;
yarn install --frozen-lockfile --production;
export APP_NAME=$PRODUCTION_APP_NAME;
export NODE_ENV=production;
export PORT=$PRODUCTION_PORT;
export APP_PATH=$PRODUCTION_APP_PATH/current;
pm2 startOrGracefulReload ecosystem.config.js --update-env;
pm2 save;
# Cleanup old releases (keep last 5)
cd releases;
ls -1dt */ | tail -n +6 | xargs rm -rf;
"
only:
- main
Key Highlights
- Caching:
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .yarn-cache/
Speeds up pipelines by caching dependencies.
- Artifacts: Artifacts from the build stage are stored temporarily for deployment.
artifacts:
paths:
- .nuxt/
- static/
- nuxt.config.js
- package.json
- yarn.lock
- ecosystem.config.js
expire_in: 1 hour
- Deployment Scripts: Deployment involves creating a release directory, transferring files, updating symlinks, and restarting the app using PM2.
4.3 Server Configurations
Ensure these server configurations:
-
DEPLOY_USER
has access to/var/www/staging
and/var/www/production
. - PM2 is installed and properly set up.
4.4 ecosystem.config.js
Customization
The ecosystem.config.js
file specifies PM2 settings:
module.exports = {
apps: [
{
name: `demo-deploy-nuxt2-app-${process.env.NODE_ENV}`,
script: './node_modules/nuxt/bin/nuxt.js',
args: 'start',
cwd: process.env.APP_PATH || '/var/www/staging/current',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: process.env.NODE_ENV,
PORT: process.env.PORT || 3100,
},
max_memory_restart: '1G',
error_file: `/var/log/pm2/${process.env.APP_NAME || 'staging'}-error.log`,
out_file: `/var/log/pm2/${process.env.APP_NAME || 'staging'}-out.log`
}
]
}
Adjust paths and variables as necessary.
4.5 Set Up the Pipeline
Commit the .gitlab-ci.yml
and ecosystem.config.js
files to your repository and push changes to trigger the pipeline.
Workflow
-
Staging Deployment: Automatically deploys from the
staging
branch. -
Production Deployment: Automatically deploys from the
main
branch.
4.6 Testing and Troubleshooting
- Push code changes to
staging
and verify deployment athttps://staging.yourdomain.com
. - Merge changes to
main
to test production deployment athttps://yourdomain.com
. - For issues:
- Check GitLab pipeline logs for errors.
- Inspect PM2 logs (
/var/log/pm2
) on the server. - Verify SSH keys and configurations.
This configuration ensures a streamlined deployment process for your Nuxt 2 application.
5. Enabling HTTPS with Let’s Encrypt
Secure your application with HTTPS by setting up Let’s Encrypt:
- Install Certbot:
apt install certbot python3-certbot-nginx -y
- Obtain an SSL certificate:
certbot --nginx -d your_domain
- Test the renewal process:
certbot renew --dry-run
- Reload Nginx:
systemctl reload nginx
6. Results and Repository Access
By following this guide, you now have a fully functional pipeline that automates the deployment of your Nuxt 2
application to a DigitalOcean Droplet using GitLab CI/CD. Here's a quick summary of what we accomplished:
- Continuous Integration: Each commit triggers a pipeline that installs dependencies, builds the Nuxt 2 project, and runs necessary tests.
- Continuous Deployment: Successful builds are deployed automatically to your DigitalOcean Droplet.
- Reliable Environment: Your application runs in a secure and scalable production environment.
Final Results
After deployment, you should observe the following:
- Live Application: Your Nuxt 2 app is accessible via your DigitalOcean server's IP address or domain.
- Automated Workflow: Every push to the main branch seamlessly updates your production environment without manual intervention.
- Error Logs and Monitoring: Logs and CI/CD pipelines provide detailed insights for troubleshooting and performance tracking.
Access the Repository
To explore the full configuration files and pipeline setup, you can access the repository here:
GitLab Repository Link
7. Conclusion
Congratulations! By following this guide, you’ve successfully deployed a Nuxt 2 application with zero downtime using
GitLab CI/CD and DigitalOcean. This setup not only automates repetitive deployment tasks but also ensures a reliable and
scalable environment for your application. As your app grows, you can easily monitor, optimize, and scale to meet
increasing demands.
Take pride in achieving a seamless deployment! As a next step, consider exploring advanced performance tuning,
integrating monitoring tools, or further automating your workflows. The possibilities are endless—happy building!
Let me know if you'd like additional tweaks!
Top comments (0)