This guide walks you through deploying a Next.js application to an Infomaniak Ubuntu VPS with automatic CI/CD using GitHub Actions.
Prerequisites
- A domain name with DNS access
- A GitHub account
- VS Code installed on your local machine (for remote development)
0. Order Your Infomaniak VPS
0.1 Choose Your Plan
- Go to Infomaniak VPS Order Page
-
Recommended plan: VPS Start at 3.60 € / month
- 1 vCore
- 2 GB RAM
- 20 GB SSD
- Perfect for small to medium Next.js applications
0.2 VPS Configuration
During the order process:
- Operating System: Select Ubuntu 24.04 LTS
- Datacenter: Choose the location closest to your users (Geneva or Zurich recommended)
- SSH Key (optional but recommended): Add your public SSH key for secure access
-
Hostname: Give your VPS a meaningful name (e.g.,
my-nextjs-app
)
0.3 Complete Your Order
- Review your configuration
- Complete the payment process
- You'll receive an email with:
- VPS IP address
- Root password (if you didn't add an SSH key)
- Access to Infomaniak Manager
0.4 Access Infomaniak Manager
- Log in to manager.infomaniak.com
- Navigate to Web & Domain → VPS
- Select your newly created VPS
- Note your VPS IP address (you'll need it throughout this guide)
1. Infomaniak Firewall Configuration
Before connecting to your VPS, configure the firewall in the Infomaniak Manager interface.
1.1 Access Firewall Settings
- In Infomaniak Manager, go to your VPS
- Click on Firewall in the left sidebar
- Click Add Rule to create new firewall rules
1.2 Required Firewall Rules
Create the following rules (in this order):
Rule 1: SSH Access
- Protocol: TCP
- Port: 22
- Source: Your IP address (or 0.0.0.0/0 for access from anywhere)
- Action: Accept
- Description: SSH access
Rule 2: HTTP Access
- Protocol: TCP
- Port: 80
- Source: 0.0.0.0/0 (anywhere)
- Action: Accept
- Description: HTTP traffic
Rule 3: HTTPS Access
- Protocol: TCP
- Port: 443
- Source: 0.0.0.0/0 (anywhere)
- Action: Accept
- Description: HTTPS traffic
Rule 4: Ping/ICMP (optional)
- Protocol: ICMP
- Source: 0.0.0.0/0
- Action: Accept
- Description: Ping requests
1.3 Verify Firewall Status
- Ensure the firewall is Enabled
- Rules should be listed in order
- Save your configuration
Note: The Infomaniak firewall works at the network level before your VPS. You'll also configure UFW (Ubuntu's firewall) later for an additional layer of security.
2. VS Code SSH Configuration
Configure VS Code for remote development on your VPS.
2.1 Install Remote SSH Extension
- Open VS Code
- Go to Extensions (Ctrl+Shift+X or Cmd+Shift+X)
- Search for "Remote - SSH"
- Install the extension by Microsoft
2.2 Generate SSH Key (if you don't have one)
On macOS/Linux:
ssh-keygen -t ed25519 -C "your-email@example.com"
# Press Enter to accept default location (~/.ssh/id_ed25519)
# Set a passphrase (optional but recommended)
On Windows (PowerShell):
ssh-keygen -t ed25519 -C "your-email@example.com"
# Press Enter to accept default location
2.3 Copy SSH Key to VPS
First-time connection:
ssh-copy-id your-username@your-vps-ip
# Enter the password provided by Infomaniak
Alternative method (if ssh-copy-id is not available):
# Display your public key
cat ~/.ssh/id_ed25519.pub
# Then manually add it to your VPS:
ssh your-username@your-vps-ip
mkdir -p ~/.ssh
nano ~/.ssh/authorized_keys
# Paste your public key, save and exit
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
exit
2.4 Configure VS Code SSH
- In VS Code, press
Ctrl+Shift+P
(orCmd+Shift+P
on macOS) - Type "Remote-SSH: Open SSH Configuration File"
- Select your SSH config file (usually
~/.ssh/config
) - Add this configuration:
Host infomaniak-vps
HostName your-vps-ip
User your-username
Port 22
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
ServerAliveCountMax 3
Replace:
-
your-vps-ip
with your actual VPS IP address -
your-username
with your VPS username
2.5 Connect to VPS from VS Code
- Press
Ctrl+Shift+P
(orCmd+Shift+P
) - Type "Remote-SSH: Connect to Host"
- Select
infomaniak-vps
- VS Code will open a new window connected to your VPS
- You can now browse files and use the integrated terminal
2.6 VS Code Tips for Remote Development
-
Open folder: Click "Open Folder" and select
~/w3pk-playground
-
Terminal: Use
Ctrl+
to open integrated terminal - Extensions: Install extensions on the remote server (Node.js, ESLint, etc.)
- Port forwarding: VS Code automatically forwards ports - useful for testing
3. Fork the Repository
- Go to https://github.com/w3hc/w3pk-playground
- Click the Fork button in the top right
- Clone your forked repository to your local machine:
git clone https://github.com/YOUR_USERNAME/w3pk-playground.git
cd w3pk-playground
4. VPS Initial Setup
4.1 Connect to your VPS
Via VS Code (recommended):
- Use the Remote-SSH connection you configured above
Via terminal:
ssh your-username@your-vps-ip
4.2 Update System
sudo apt update && sudo apt upgrade -y
4.3 Install Node.js via NVM
# Install NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# Reload shell configuration
source ~/.bashrc
# Install Node.js (latest LTS)
nvm install --lts
# Verify installation
node -v
npm -v
4.4 Install pnpm
npm install -g pnpm
4.5 Install PM2 (Process Manager)
pnpm add -g pm2
# Setup PM2 to start on system reboot
pm2 startup
# Follow the instructions provided by the command
4.6 Clone your repository on the VPS
cd ~
git clone https://github.com/YOUR_USERNAME/w3pk-playground.git
cd w3pk-playground
4.7 Install dependencies and build
pnpm install
pnpm build
4.8 Start the app with PM2
pm2 start pnpm --name "your-app-name" -- start
pm2 save
Verify it's running:
pm2 list
pm2 logs your-app-name
5. Domain and DNS Configuration
5.1 Configure DNS
In your domain provider's DNS settings (e.g., Infomaniak DNS panel):
-
Add an A Record:
-
Name:
subdomain
(e.g.,app
forapp.yourdomain.com
) - Type: A
- Value: Your VPS IP address
- TTL: 300 (or default)
-
Name:
Wait for DNS propagation (can take up to 24 hours, usually 5-15 minutes)
7.2 Verify DNS
dig subdomain.yourdomain.com +short
# Should return your VPS IP
6. Nginx Configuration
6.1 Install Nginx
sudo apt update
sudo apt install nginx -y
6.2 Create Nginx configuration
sudo nano /etc/nginx/sites-available/your-app
Add this configuration:
server {
listen 80;
listen [::]:80;
server_name subdomain.yourdomain.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_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
6.3 Enable the site
# Create symbolic link
sudo ln -s /etc/nginx/sites-available/your-app /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
7. SSL Certificate Setup
7.1 Install Certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
7.2 Obtain SSL certificate
sudo certbot --nginx -d subdomain.yourdomain.com
Follow the prompts:
- Enter your email address
- Agree to terms of service
- Choose to redirect HTTP to HTTPS (recommended)
7.3 Verify SSL certificate
# Check certificate status
sudo certbot certificates
# Test auto-renewal
sudo certbot renew --dry-run
Your site should now be accessible at https://subdomain.yourdomain.com
8. UFW Firewall Configuration (Additional Layer)
Configure Ubuntu's UFW firewall for additional security.
# Install UFW (usually pre-installed)
sudo apt install ufw -y
# Allow SSH (IMPORTANT: do this first!)
sudo ufw allow 22/tcp
# Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Enable UFW
sudo ufw enable
# Check status
sudo ufw status verbose
Important: Always allow SSH (port 22) before enabling UFW, or you'll lose access to your VPS!
9. GitHub Actions CI/CD Setup
9.1 Create SSH key for GitHub Actions
On your VPS:
# Generate SSH key WITHOUT passphrase (important!)
ssh-keygen -t ed25519 -C "github-actions" -f ~/.ssh/github-actions -N ""
# Add public key to authorized_keys
cat ~/.ssh/github-actions.pub >> ~/.ssh/authorized_keys
# Set correct permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/github-actions
9.2 Copy the private key
cat ~/.ssh/github-actions
Copy the entire output including -----BEGIN
and -----END
lines.
9.3 Create GitHub workflow file
In your local repository, create .github/workflows/deploy.yml
:
name: Deploy to VPS
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to VPS
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USERNAME }}
key: ${{ secrets.VPS_SSH_KEY }}
script: |
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
export PATH="$HOME/.local/share/pnpm:$PATH"
cd ~/w3pk-playground
git pull origin main
pnpm install
pnpm build
pm2 restart your-app-name
pm2 save
9.4 Add GitHub Secrets
Go to your GitHub repository:
- Click Settings → Secrets and variables → Actions
- Click New repository secret
- Add three secrets:
VPS_HOST
your-vps-ip-address
VPS_USERNAME
your-vps-username
VPS_SSH_KEY
(paste the entire private key from ~/.ssh/github-actions)
9.5 Commit and push
git add .github/workflows/deploy.yml
git commit -m "Add CI/CD workflow"
git push origin main
10. Test Your Deployment
- Make a change to your code
- Commit and push to the
main
branch - Go to your GitHub repository → Actions tab
- Watch the deployment workflow run
- Visit
https://subdomain.yourdomain.com
to see your changes
Useful Commands
PM2 Management
pm2 list # List all apps
pm2 logs your-app-name # View logs
pm2 restart your-app-name # Restart app
pm2 stop your-app-name # Stop app
pm2 delete your-app-name # Remove app
pm2 monit # Monitor all apps
Nginx Management
sudo nginx -t # Test configuration
sudo systemctl reload nginx # Reload configuration
sudo systemctl restart nginx # Restart Nginx
sudo systemctl status nginx # Check status
SSL Certificate Management
sudo certbot certificates # List all certificates
sudo certbot renew # Renew certificates
sudo certbot delete # Delete a certificate
Checking Open Ports
sudo ss -tulpn # Show all listening ports
sudo lsof -i :3000 # Check specific port
Firewall Management
# Infomaniak Firewall: Manage via Infomaniak Manager web interface
# UFW Firewall
sudo ufw status verbose # Check UFW status
sudo ufw allow 3000/tcp # Allow specific port
sudo ufw deny 3000/tcp # Deny specific port
sudo ufw delete allow 3000/tcp # Remove rule
sudo ufw reset # Reset all rules (careful!)
Troubleshooting
Cannot Connect via SSH
- Check Infomaniak firewall: Ensure port 22 is allowed
-
Check UFW: Run
sudo ufw allow 22/tcp
if you have terminal access - Use Infomaniak Console: Access your VPS through the web console in Infomaniak Manager
- Verify IP: Ensure you're using the correct VPS IP address
502 Bad Gateway
- Check if your app is running:
pm2 list
- Check app logs:
pm2 logs your-app-name
- Verify the port in Nginx config matches your app's port
- Restart the app:
pm2 restart your-app-name
Build Fails in CI/CD
- Check GitHub Actions logs for specific errors
- Verify SSH key is correct in GitHub secrets
- Ensure NVM and pnpm paths are correct in workflow
- Test commands manually on VPS first
SSL Certificate Issues
- Verify DNS is pointing to your VPS:
dig subdomain.yourdomain.com
- Check if port 80 and 443 are open in both Infomaniak firewall and UFW
- Review Certbot logs:
sudo cat /var/log/letsencrypt/letsencrypt.log
Permission Denied Errors
# Fix SSH permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/github-actions
# Fix file ownership
sudo chown -R your-username:your-username ~/w3pk-playground
Port Already in Use
# Check what's using the port
sudo lsof -i :3000
# Kill the process if needed
sudo kill -9 PID
Security Best Practices
-
Two-Layer Firewall:
- Infomaniak firewall (network level)
- UFW firewall (system level)
SSH Security:
sudo nano /etc/ssh/sshd_config
# Set: PasswordAuthentication no
# Set: PermitRootLogin no
sudo systemctl restart sshd
- Regular Updates:
sudo apt update && sudo apt upgrade -y
- Fail2Ban (optional but recommended):
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
-
Backups:
- Use Infomaniak's backup service
- Regularly backup your application and database
-
Monitoring:
- Check Infomaniak Manager for resource usage
- Monitor PM2 logs regularly
Infomaniak-Specific Features
VPS Snapshots
- Go to Infomaniak Manager → Your VPS
- Click Snapshots
- Create snapshots before major changes
- Restore from snapshots if needed
Resource Monitoring
- View CPU, RAM, and disk usage in Infomaniak Manager
- Set up alerts for resource thresholds
- Upgrade your VPS plan if needed
Support
- Infomaniak provides 24/7 support
- Access support through the Manager interface
- Community forum: community.infomaniak.com
Next Steps
- Set up monitoring with tools like UptimeRobot
- Configure database backups
- Add staging environment
- Implement health checks in your workflow
- Set up logging with a service like Logtail or Papertrail
- Consider using Infomaniak's CDN for static assets
Cost Estimation
VPS Start Plan (3.60 € / month):
- Suitable for: 1-3 small Next.js apps
- Traffic: Up to moderate traffic levels
- Storage: 20 GB (sufficient for code and small databases)
When to upgrade:
- High traffic (> 10,000 monthly visitors per app)
- Resource-intensive applications
- Multiple production applications
Resources
- Infomaniak VPS Documentation
- Next.js Documentation
- PM2 Documentation
- Nginx Documentation
- Let's Encrypt Documentation
- GitHub Actions Documentation
Congratulations! 🎉 Your Next.js app is now deployed on Infomaniak VPS with automatic CI/CD!
Top comments (0)