-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy-using-github-actions.txt
More file actions
182 lines (144 loc) · 7.22 KB
/
deploy-using-github-actions.txt
File metadata and controls
182 lines (144 loc) · 7.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
================================================================================
SERVER & CI/CD SETUP GUIDE (LARAVEL + GITHUB ACTIONS)
Project: example.com
================================================================================
This document outlines the manual steps required to prepare a DigitalOcean
Ubuntu 24.04 server to work with the provided deploy.yml workflow.
--------------------------------------------------------------------------------
1. SERVER-SIDE PREPARATION (SSH & DIRECTORY)
--------------------------------------------------------------------------------
Run these commands as root on your DigitalOcean Droplet:
A. Generate the Deployment SSH Key:
ssh-keygen -t ed25519 -f /root/.ssh/github-actions-deploy.id_ed25519 -C "github-actions-deploy"
# Press Enter for no passphrase.
B. Authorize the Key for GitHub Actions:
# This allows GitHub to log into your server.
cat /root/.ssh/github-actions-deploy.id_ed25519.pub >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
chmod 700 /root/.ssh/
C. Initialize the Application Directory:
mkdir -p /app && cd /app
# Perform the initial clone using the custom key
GIT_SSH_COMMAND="ssh -i /root/.ssh/github-actions-deploy.id_ed25519 -o IdentitiesOnly=yes -o StrictHostKeyChecking=no" git clone git@github.com:username/example.com.git .
D. Configure Local Git for the /app folder:
# This ensures "git pull" inside the workflow always uses the correct key.
git config core.sshCommand "ssh -i /root/.ssh/github-actions-deploy.id_ed25519 -o IdentitiesOnly=yes"
--------------------------------------------------------------------------------
2. GITHUB REPOSITORY CONFIGURATION
--------------------------------------------------------------------------------
A. Add Deploy Key (Allows Server to pull code from GitHub):
1. Run: cat /root/.ssh/github-actions-deploy.id_ed25519.pub
2. Go to: GitHub Repo > Settings > Deploy keys > Add deploy key.
3. Paste the key and name it "Staging Server Pull Key".
4. Check "Allow write access" (optional, but recommended for some git operations).
B. Add Action Secrets (Allows GitHub to control the Server):
Go to: GitHub Repo > Settings > Secrets and variables > Actions.
Add the following New Repository Secrets:
HOST : [Your Droplet IP]
USERNAME : root
SSH_PRIVATE_KEY : [Paste the content of /root/.ssh/github-actions-deploy.id_ed25519]
WEBSITE_DOWN_SECRET : [Any random string for maintenance mode]
SLACK_WEBHOOK : [Your Slack Incoming Webhook URL]
--------------------------------------------------------------------------------
3. FINAL SERVER ENVIRONMENT CHECKS
--------------------------------------------------------------------------------
Before running the first deployment, ensure these are ready on the server:
1. Environment File:
cp /app/.env.example /app/.env
nano /app/.env # Update with production DB/App credentials.
2. Services:
Ensure PHP 8.2-FPM and Nginx are installed.
Ensure the Nginx root points to: /app/public
3. Permissions:
The workflow will attempt to run "chown -R www-data:www-data /app/".
Ensure the 'www-data' user exists on your system.
4. Manual Verification:
Test the SSH connection manually from the server to GitHub:
ssh -T -i /root/.ssh/github-actions-deploy.id_ed25519 -o IdentitiesOnly=yes git@github.com
--------------------------------------------------------------------------------
DEPLOYMENT FLOW SUMMARY:
1. GitHub Runner builds assets (npm run build).
2. Runner logs into Server via SSH.
3. Server pulls latest code using its local SSH key.
4. Runner uploads 'public/build' folder via SCP.
5. Server runs migrations, clears caches, and reloads PHP-FPM.
================================================================================
Here is an example of /.github/workflows/deploy.yml file to commit to your source code:
name: Deploy Website to DigitalOcean via SSH
on:
workflow_dispatch: # This enables the manual trigger
push: # This is an automatic deployment on every push to the branch
branches: [ "staging" ]
jobs:
deploy:
runs-on: "ubuntu-24.04"
environment: staging
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies and build
env:
VITE_APP_NAME: "Example website"
run: |
npm ci --legacy-peer-deps
npm run build
- name: Take website down and clean node_modules folder
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: 22
script: |
cd /app/
php artisan down --secret="${{ secrets.WEBSITE_DOWN_SECRET }}" --refresh=60 || true
# Remove node_modules to prevent ENOTEMPTY errors
rm -rf ./node_modules/
# Maybe we would need to delete public/build/ directory in the future. For now,
# since old visitors might reference the assets from the previous builds,
# let's keep the old assets
# Remove /public/build/ to free space
# rm -rf ./public/build/
# Upload the compiled 'public/build' folder to the server
- name: Copy build files to server
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: 22
source: "./public/build/"
target: "/app/"
- name: Deploy to DigitalOcean via SSH
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: 22
script: |
cd /app/
git config core.sshCommand "ssh -i ~/.ssh/github-actions-deploy.id_ed25519 -o IdentitiesOnly=yes -o StrictHostKeyChecking=no"
git fetch origin
git checkout ${{ github.ref_name }}
git pull origin ${{ github.ref_name }}
composer install --no-interaction --prefer-dist --optimize-autoloader
php artisan migrate --force
php artisan responsecache:clear
php artisan cache:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache
find /var/cache/nginx/ -mindepth 1 -delete
chown -R www-data:www-data /app/
chmod -R 775 /app/storage /app/bootstrap/cache
systemctl reload php8.2-fpm.service
php artisan up
- name: Notify Slack on Failure
if: failure()
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_TITLE: "Deployment to STAGING failed!"
SLACK_MESSAGE: "The deployment for ${{ github.repository }} to STAGING failed. ❌"
SLACK_COLOR: "#ff0000"