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:
- Setting up the VPS
- Installing and configuring Nginx
- Installing Docker and setting up your environment.
- Setting up GitHub Actions for continuous deployment.
- Setting up SSL certificates with Let’s Encrypt and auto-renewal.
Pre-requisites
Before we get started, you'll need the following:
- A VPS with root access. I'll be using a VPS from RackNerd (but you can use any provider: Hertzner, DigitalOcean, AWS ...).
- A domain name. I'll be using a domain from Namecheap (required for SSL setup).
- 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.
- SSH into your VPS using the root user.
ssh root@your_vps_ip
- Update the package list and upgrade the packages.
sudo apt update && sudo apt upgrade -y
Installing and configuring Nginx
- Install Nginx.
sudo apt install nginx -y
- Start and enable Nginx.
sudo systemctl start nginx
sudo systemctl enable nginx
- Check the status of Nginx.
sudo systemctl status nginx
Open your browser and navigate to your VPS IP address. You should see the Nginx welcome page.
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;
}
}
- Save the file and exit the editor. Test the Nginx configuration.
sudo nginx -t
- If the test is successful, reload Nginx.
sudo systemctl reload nginx
Installing Docker
(From Docker's official documentation)
- 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
- Install Docker:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- 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.
- Install Certbot with Nginx plugin:
bash
sudo apt install certbot python3-certbot-nginx -y
- 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.
- Verify SSL installation:
Once Certbot completes the process, you can verify that your site is running with HTTPS by visiting https://yourdomain.com
.
- 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
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/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.