Setting Up a VPS with Nginx, Docker, and GitHub Actions

Intro

In this article, we’ll be walking through setting up a VPS using Nginx, Docker and Github Actions.
This setup will allow you to deploy your web projects seamlessly as soon as you push code to Github repos.

We’ll be covering up the fol…


This content originally appeared on DEV Community and was authored by Mohamed Gallah

Intro

In this article, we'll be walking through setting up a VPS using Nginx, Docker and Github Actions.
This setup will allow you to deploy your web projects seamlessly as soon as you push code to Github repos.

We'll be covering up the following:

  1. Setting up the VPS
  2. Installing and configuring Nginx
  3. Installing Docker and setting up your environment.
  4. Setting up GitHub Actions for continuous deployment.
  5. Setting up SSL certificates with Let’s Encrypt and auto-renewal.

Pre-requisites

Before we get started, you'll need the following:

  1. A VPS with root access. I'll be using a VPS from RackNerd (but you can use any provider: Hertzner, DigitalOcean, AWS ...).
  2. A domain name. I'll be using a domain from Namecheap (required for SSL setup).
  3. Basic knowledge of SSH, Linux commands, and GitHub.

Setting up the VPS

For this article, I’ll assume you’re using Ubuntu as the OS.

  1. SSH into your VPS using the root user.
ssh root@your_vps_ip
  1. Update the package list and upgrade the packages.
sudo apt update && sudo apt upgrade -y

Installing and configuring Nginx

  1. Install Nginx.
sudo apt install nginx -y
  1. Start and enable Nginx.
sudo systemctl start nginx
sudo systemctl enable nginx
  1. Check the status of Nginx.
sudo systemctl status nginx
  1. Open your browser and navigate to your VPS IP address. You should see the Nginx welcome page.

  2. Configure Nginx to serve your web projects. Create a new configuration file for your project.

sudo nano /etc/nginx/sites-available/default

Update the configuration with your domain:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}
  1. Save the file and exit the editor. Test the Nginx configuration.
sudo nginx -t
  1. If the test is successful, reload Nginx.
sudo systemctl reload nginx

Installing Docker

(From Docker's official documentation)

  1. Setup Docker's apt repo:
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
  1. Install Docker:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  1. Verify the installation:
sudo docker --version
docker-compose --version

Setup GH Actions

In your project's root, create a Dockerfile and a docker-compose.yml file.

FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
version: '3'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: production

Now, create a .github/workflows/deploy.yml file in your project's root.

name: Deploy to VPS

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Build Docker image
        run: |
          docker build -t your-app:latest .
          docker save your-app:latest > your-app.tar
          chmod 664 your-app.tar

      - name: Transfer Docker image to VPS
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USERNAME }}
          key: ${{ secrets.VPS_SSH }}
          port: ${{ secrets.VPS_PORT }}
          source: "your-app.tar"
          target: "/tmp"

      - name: Deploy to VPS
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USERNAME }}
          key: ${{ secrets.VPS_SSH }}
          port: ${{ secrets.VPS_PORT }}
          script: |
            docker load < /tmp/your-app.tar
            docker stop your-app || true
            docker rm your-app || true
            docker run -d --name your-app -p 8003:8003 your-app:latest

Important 1: Replace your-app with your actual values.

Important 2: Add your VPS IP, ssh key and username as secrets in your GitHub repo. You'll need to redo this step with each new repo.

Testing the Deployment

Push a new commit to the main branch, and GitHub Actions should automatically build and deploy your application to your VPS.

Setting up SSL

We’ll use Let’s Encrypt, a free SSL/TLS certificate authority, to get a free certificate and set up auto-renewal using `certbot.

  1. Install Certbot with Nginx plugin:

bash
sudo apt install certbot python3-certbot-nginx -y

  1. Generate the SSL certificate:

bash
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

With Nginx plugin installed earlier, Certbot will configure Nginx to use the SSL certificate and set up redirects from HTTP to HTTPS. You’ll be prompted to enter your email address and agree to the terms of service.

  1. Verify SSL installation:

Once Certbot completes the process, you can verify that your site is running with HTTPS by visiting https://yourdomain.com.

  1. Set up auto-renewal:

Certbot will automatically set up a cron job to renew your SSL certificate. You can verify this by running:

bash
sudo crontab -l

You should see a cron job similar to the following:

bash
0 */12 * * * certbot renew --quiet

Setup projects after deployment

After deploying your projects, you need to update your nginx configuration to point to the new containers.

First of all, make sure to change port used by your apps to avoid conflicts.

Now, given you deployed your app with the name your-app-container, using the port 8002, you can update your nginx configuration to point to the new container.

nginx
server {
# Your previous configuration
# ...
location /your-app-container {
rewrite ^/your-app-container/(.*) /$1 break;
proxy_pass http://localhost:8002;
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;
}
# ...
# SSL configuration
}

Conclusion

You now have a fully automated deployment pipeline for your projects. Every time you push a new commit to the main/master branch, GitHub Actions will build and deploy your application to your VPS. You also have an SSL certificate installed on your server, which will automatically renew every 90 days.

Next Steps

You can take this basic setup further by adding more features like:

  • Setup an advanced Nginx configurtation to handle multiple domains and subdomains or complex load balancing.
  • Use Coolify or similar to create a vercel like deployment pipeline.
  • Adding firewall rules for additional security.

See ya! 🚀

Cover image: Photo by Kvistholt Photography on Unsplash


This content originally appeared on DEV Community and was authored by Mohamed Gallah


Print Share Comment Cite Upload Translate Updates
APA

Mohamed Gallah | Sciencx (2024-08-24T10:33:41+00:00) Setting Up a VPS with Nginx, Docker, and GitHub Actions. Retrieved from https://www.scien.cx/2024/08/24/setting-up-a-vps-with-nginx-docker-and-github-actions/

MLA
" » Setting Up a VPS with Nginx, Docker, and GitHub Actions." Mohamed Gallah | Sciencx - Saturday August 24, 2024, https://www.scien.cx/2024/08/24/setting-up-a-vps-with-nginx-docker-and-github-actions/
HARVARD
Mohamed Gallah | Sciencx Saturday August 24, 2024 » Setting Up a VPS with Nginx, Docker, and GitHub Actions., viewed ,<https://www.scien.cx/2024/08/24/setting-up-a-vps-with-nginx-docker-and-github-actions/>
VANCOUVER
Mohamed Gallah | Sciencx - » Setting Up a VPS with Nginx, Docker, and GitHub Actions. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/08/24/setting-up-a-vps-with-nginx-docker-and-github-actions/
CHICAGO
" » Setting Up a VPS with Nginx, Docker, and GitHub Actions." Mohamed Gallah | Sciencx - Accessed . https://www.scien.cx/2024/08/24/setting-up-a-vps-with-nginx-docker-and-github-actions/
IEEE
" » Setting Up a VPS with Nginx, Docker, and GitHub Actions." Mohamed Gallah | Sciencx [Online]. Available: https://www.scien.cx/2024/08/24/setting-up-a-vps-with-nginx-docker-and-github-actions/. [Accessed: ]
rf:citation
» Setting Up a VPS with Nginx, Docker, and GitHub Actions | Mohamed Gallah | Sciencx | https://www.scien.cx/2024/08/24/setting-up-a-vps-with-nginx-docker-and-github-actions/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.