You will need a server (AWS, GCP, Azure, etc.) running. Make sure the DNS is configured before starting.
We’re going to add a workflow to the repository as a continuous deployment pipeline. In other words, whenever you push to Github’s main branch, the workflow is going to run and automatically upload the repository onto the server and start the container.
In the root directory, create a file under .github/workflows
: main.yml
(honestly any name works).
# This is a basic workflow to help you get started with Actions
name: Deploy to server
# Controls when the action will run.
on:
# Triggers the workflow on a push to the main branch
push:
branches: [main]
# Allow manual trigger
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
deploy:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
# <https://stackoverflow.com/a/61236896>
- name: Tar repository
run: |
mkdir ../build
cp -TR . ../build
tar -cvf deploy.tar ../build/
- name: Cleaning up existing setup
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
# take down docker compose
script: |
cd ~/mern-boilerplate
docker compose -p mern-boilerplate down
rm -rf ~/mern-boilerplate && mkdir ~/mern-boilerplate
# feel free to change the name of the folder created
- name: Adding environment variables
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
# create .env file with env keys
script: |
cd ~/mern-boilerplate
touch .env && rm .env
echo CLIENT_PORT=${{ secrets.CLIENT_PORT }} >> .env
echo SERVER_PORT=${{ secrets.SERVER_PORT }} >> .env
echo MONGO_URI=${{ secrets.MONGO_URI }} >> .env
echo SESSION_SECRET=${{ secrets.SESSION_SECRET }} >> .env
echo JWT_SECRET=${{ secrets.JWT_SECRET }} >> .env
echo REFRESH_TOKEN_SECRET=${{ secrets.REFRESH_TOKEN_SECRET }} >> .env
echo SESSION_EXPIRY=${{ secrets.SESSION_EXPIRY }} >> .env
echo REFRESH_TOKEN_EXPIRY=${{ secrets.REFRESH_TOKEN_EXPIRY }} >> .env
echo MAIL_REFRESH_TOKEN=${{ secrets.MAIL_REFRESH_TOKEN }} >> .env
echo MAIL_CLIENT_ID=${{ secrets.MAIL_CLIENT_ID }} >> .env
echo MAIL_CLIENT_SECRET=${{ secrets.MAIL_CLIENT_SECRET }} >> .env
# add additional env keys
- name: Copy repository to server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
source: 'deploy.tar'
target: '~/mern-boilerplate/'
- name: Setup app
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
script: |
cd ~/mern-boilerplate
tar xf deploy.tar && rm deploy.tar && mv build/* . && rm -rf build/
- name: Start docker
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
command_timeout: 200m
# cd into respective directory and start docker
script: |
cd ~/mern-boilerplate
docker compose -p mern-boilerplate up -d --build
You’ll need to add all of your environment variables as Github SECRETS.
In your repository, go to Settings > Secrets and variables > Actions > New Repository secret
For HOST, USERNAME, PASSWORD, they should be how to SSH into your server. That is, it will try to ssh username@host
with the password.
This step will essentially tar the repository and prepare to upload it to the server.
We’re taking down the Docker container and also deleting the folder where the code is. We’re essentially starting from scratch again because we want a new, clean build.
We’re going to copy all of the Github Secrets into a .env
file. If you have additional environment variables that exist on your server, you can create a .env
elsewhere and then cat /shared/projects.env >> .env
or something.