Skip to content

Commit 14f1183

Browse files
authored
Chore/blue green deployment (#264)
* ci: add initial blue-green deployment * ci: init deployment using blue-green * ci: remove nginx operation * ci: check npm existence * ci: re-run after creating symlink directly on machine * ci: export nvm * ci: perform nginx reload * ci: use target_port as env.PORT * ci: fix env * ci: fix sed * ci: comment out sed nginx * ci: remove nginx * ci: remove port * ci: inject port directly during pm2 startup * ci: disable env first * ci: disable env first * ci: write env via ssh * ci: enable nginx update * ci: use master branch
1 parent 423d9fc commit 14f1183

File tree

2 files changed

+76
-60
lines changed

2 files changed

+76
-60
lines changed

.github/workflows/deploy.yml

Lines changed: 75 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,82 +8,99 @@ on:
88
jobs:
99
deploy:
1010
runs-on: ubuntu-latest
11-
11+
env:
12+
PROJECT_REPO: [email protected]:wildan3105/github-langs.git
13+
BLUE_NAME: "blue"
14+
GREEN_NAME: "green"
15+
BLUE_PORT: 3000
16+
GREEN_PORT: 3001
17+
NGINX_CONF: /etc/nginx/sites-available/gitstats.wildans.site
18+
BLUE_DIR: /var/www/html/blue
19+
GREEN_DIR: /var/www/html/green
1220
steps:
1321
- name: Check out the code
1422
uses: actions/checkout@v3
1523

16-
- name: Verify SSH connection and deploy
17-
uses: appleboy/[email protected]
24+
- name: Deployment
25+
uses: appleboy/[email protected]
26+
env:
27+
ACTIVE_ENV: ""
28+
TARGET_ENV: ""
29+
TARGET_DIR: ""
30+
TARGET_PORT: ""
31+
TOKEN: ""
32+
ENV: ""
1833
with:
1934
host: ${{ secrets.VPS_HOST }}
2035
username: ${{ secrets.VPS_USERNAME }}
2136
password: ${{ secrets.VPS_PASSWORD }}
2237
port: 22
38+
envs: ACTIVE_ENV,TARGET_ENV,TARGET_DIR,TARGET_PORT, TOKEN, ENV
2339
script: |
24-
# Set paths for npm and node
25-
export PATH=$PATH:/root/.nvm/versions/node/v18.10.0/bin
26-
27-
# Define directories
28-
TARGET_DIR="/var/www/html"
29-
TEMP_DIR="${TARGET_DIR}/tmp"
30-
SYMLINK="${TARGET_DIR}/current"
31-
32-
# Prepare the temporary area
33-
echo "Preparing the temporary deployment directory..."
34-
sudo rm -rf $TEMP_DIR
35-
sudo mkdir -p $TEMP_DIR
36-
37-
# Clone the repo into the temporary directory
38-
echo "Cloning repository to the temporary directory..."
39-
git clone [email protected]:wildan3105/github-langs.git $TEMP_DIR
40-
41-
# Ensure necessary files are present
42-
if [ -f "$TEMP_DIR/src/index.js" ]; then
43-
echo "Entry point found in the temporary directory"
40+
echo "Deployment using blue-green is started..."
41+
export NVM_DIR=~/.nvm
42+
source ~/.nvm/nvm.sh
43+
echo "Determining the current active environment..."
44+
if grep -q "proxy_pass http://localhost:${{ env.BLUE_PORT }};" "${{ env.NGINX_CONF }}"; then
45+
export ACTIVE_ENV="${{ env.BLUE_NAME }}"
46+
elif grep -q "proxy_pass http://localhost:${{ env.GREEN_PORT }};" "${{ env.NGINX_CONF }}"; then
47+
export ACTIVE_ENV="${{ env.GREEN_NAME }}"
4448
else
45-
echo "Error: Entry point not found in the temporary directory!"
49+
echo "error: could not determine active environment" >&2
4650
exit 1
4751
fi
48-
49-
# Set environment variables
50-
export ENV=${{ secrets.ENV }}
51-
export TOKEN=${{ secrets.TOKEN }}
52-
53-
# Install dependencies
54-
echo "Installing dependencies..."
55-
cd $TEMP_DIR
56-
npm install
57-
58-
# Gracefully stop the existing application if it's running on port 5000
59-
if lsof -i:5000; then
60-
echo "Stopping existing application running on port 5000..."
61-
PID=$(lsof -t -i:5000)
62-
sudo kill -9 $PID || echo "Failed to kill process with PID $PID"
52+
echo "Active env is $ACTIVE_ENV"
53+
54+
echo "Set the target environment..."
55+
if [ "$ACTIVE_ENV" == "blue" ]; then
56+
export TARGET_ENV="${{ env.GREEN_NAME }}"
57+
export TARGET_PORT="${{ env.GREEN_PORT }}"
58+
export TARGET_DIR="${{ env.GREEN_DIR }}"
59+
elif [ "$ACTIVE_ENV" == "green" ]; then
60+
export TARGET_ENV="${{ env.BLUE_NAME }}"
61+
export TARGET_PORT="${{ env.BLUE_PORT }}"
62+
export TARGET_DIR="${{ env.BLUE_DIR }}"
63+
else
64+
echo "error: could not determine target environment" >&2
65+
exit 1
6366
fi
6467
65-
# Start the application in the background using Node
66-
echo "Starting the application..."
67-
ENV=$ENV TOKEN=$TOKEN npm run start-prod
68+
echo "The upcoming target environment is as follows:"
69+
echo "Target env: $TARGET_ENV"
70+
echo "Target port: $TARGET_PORT"
71+
echo "Target dir: $TARGET_DIR"
6872
69-
# Switch symlink atomically
70-
echo "Updating symlink to point to the new temporary directory..."
71-
sudo ln -sfn $TEMP_DIR $SYMLINK
73+
echo "Cloning the repository..."
74+
rm -rf $TARGET_DIR
75+
mkdir -p $TARGET_DIR
76+
git clone ${{ env.PROJECT_REPO }} $TARGET_DIR
77+
echo "Repository cloned"
7278
73-
# Verify that the symlink points to the latest deployment
74-
echo "Deployment verification:"
75-
ls -l $SYMLINK
76-
77-
# delay before performing healthcheck
78-
sleep 10s
79+
echo "Writing to environment variables..."
80+
export ENV="${{ secrets.ENV }}"
81+
export TOKEN="${{ secrets.TOKEN }}"
82+
echo "Environment variables written"
7983
80-
# perform healthcheck
81-
echo "Performing health check on http://localhost:5000..."
82-
STATUS_CODE=$(curl -o /dev/null -s -w "%{http_code}" http://localhost:5000)
84+
echo "Install and build application..."
85+
cd $TARGET_DIR
86+
npm install
87+
echo "Dependencies installed and app built"
8388
84-
if [ "$STATUS_CODE" -ne 200 ]; then
85-
echo "Health check failed with status code: $STATUS_CODE"
86-
exit 1
89+
echo "Start or restart application via PM2..."
90+
if pm2 list | grep -q "$TARGET_ENV"; then
91+
echo "App detected. Restarting the app..."
92+
pm2 restart "$TARGET_ENV" || { echo "Failed to restart app"; exit 1; }
8793
else
88-
echo "Health check passed with status code: $STATUS_CODE"
94+
echo "App is not started yet. Starting the app..."
95+
PORT=$TARGET_PORT pm2 start npm --name "$TARGET_ENV" -- run start || { echo "Failed to start app"; exit 1; }
8996
fi
97+
echo "Application started/restarted"
98+
99+
echo "Adding delay to ensure the app is ready..."
100+
sleep 10s
101+
echo "Delay finished"
102+
103+
echo "Update nginx port..."
104+
sudo sed -i "s|proxy_pass http://localhost:[0-9]*;|proxy_pass http://localhost:$TARGET_PORT;|" "${{ env.NGINX_CONF }}"
105+
sudo nginx -s reload
106+
echo "Nginx updated"

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
},
99
"main": "index.js",
1010
"scripts": {
11-
"start-dev": "node_modules/.bin/pm2 start src/index.js --watch --name githublangs | gulp",
12-
"start-prod": "node_modules/.bin/pm2 stop githublangs || true && node_modules/.bin/pm2 start -f src/index.js --name githublangs | gulp",
11+
"start": "node src/index.js | gulp",
1312
"lint": "eslint '**/*.js' --ignore-pattern node_modules/",
1413
"lint:fix": "eslint --fix '**/*.js' --ignore-pattern node_modules/",
1514
"mocha": "mocha",

0 commit comments

Comments
 (0)