Skip to content

Commit ffba4c6

Browse files
committed
feat: Add production Docker Compose configuration and implement production CI/CD triggered by tags or releases.
1 parent 32165d4 commit ffba4c6

File tree

2 files changed

+116
-5
lines changed

2 files changed

+116
-5
lines changed

.github/workflows/ci_cd.yml

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
pull_request:
55
push:
66
branches: [ main ]
7+
tags: [ 'v*' ]
8+
release:
9+
types: [ published ]
710

811
jobs:
912
scan_ruby:
@@ -129,6 +132,7 @@ jobs:
129132
images: ghcr.io/${{ github.repository }}
130133
tags: |
131134
type=raw,value=latest,enable={{is_default_branch}}
135+
type=raw,value=production,enable=${{ github.event_name == 'release' || startsWith(github.ref, 'refs/tags/v') }}
132136
type=ref,event=branch
133137
type=ref,event=tag
134138
type=sha
@@ -143,7 +147,7 @@ jobs:
143147
labels: ${{ steps.meta.outputs.labels }}
144148
no-cache: true
145149

146-
deploy:
150+
deploy_uat:
147151
runs-on: ubuntu-latest
148152
needs: build_and_push_docker_image
149153
if: github.ref == 'refs/heads/main'
@@ -160,18 +164,18 @@ jobs:
160164
source: "docker-compose.yml,nginx.conf"
161165
target: "/root"
162166

163-
- name: Deploy to server
167+
- name: Deploy to server (UAT)
164168
uses: appleboy/[email protected]
165169
with:
166170
host: ${{ secrets.SERVER_HOST }}
167171
username: ${{ secrets.SERVER_USER }}
168172
key: ${{ secrets.SERVER_SSH_KEY }}
169173
script: |
170174
cd /root
171-
docker compose pull
172-
docker compose up -d
175+
docker compose -f docker-compose.yml pull
176+
docker compose -f docker-compose.yml up -d
173177
# Clean up old images from ghcr.io registry (keep only the latest)
174-
docker images 'ghcr.io/oddsteam/dailynews-e-newspaper' --format '{{.ID}} {{.Tag}}' | grep -v 'latest' | awk '{print $1}' | xargs -r docker rmi -f || true
178+
docker images 'ghcr.io/oddsteam/dailynews-e-newspaper' --format '{{.ID}} {{.Tag}}' | grep -v 'latest' | grep -v 'production' | awk '{print $1}' | xargs -r docker rmi -f || true
175179
176180
- name: Health check
177181
run: |
@@ -190,4 +194,52 @@ jobs:
190194
191195
echo "✗ Health check failed after 5 attempts"
192196
exit 1
197+
198+
deploy_production:
199+
runs-on: ubuntu-latest
200+
needs: build_and_push_docker_image
201+
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'release'
202+
steps:
203+
- name: Checkout code
204+
uses: actions/checkout@v4
205+
206+
- name: Copy docker-compose.prod.yml to server
207+
uses: appleboy/[email protected]
208+
with:
209+
host: ${{ secrets.SERVER_PRODUCTION_HOST }}
210+
username: ${{ secrets.SERVER_PRODUCTION_USER }}
211+
key: ${{ secrets.SERVER_PRODUCTION_SSH_KEY }}
212+
source: "docker-compose.prod.yml,nginx.conf"
213+
target: "/home/${{ secrets.SERVER_PRODUCTION_USER }}"
214+
215+
- name: Deploy to server (Production)
216+
uses: appleboy/[email protected]
217+
with:
218+
host: ${{ secrets.SERVER_PRODUCTION_HOST }}
219+
username: ${{ secrets.SERVER_PRODUCTION_USER }}
220+
key: ${{ secrets.SERVER_PRODUCTION_SSH_KEY }}
221+
script: |
222+
cd /home/${{ secrets.SERVER_PRODUCTION_USER }}
223+
docker compose -f docker-compose.prod.yml pull
224+
docker compose -f docker-compose.prod.yml up -d
225+
# Clean up old images from ghcr.io registry (keep only the latest and production)
226+
docker images 'ghcr.io/oddsteam/dailynews-e-newspaper' --format '{{.ID}} {{.Tag}}' | grep -v 'latest' | grep -v 'production' | awk '{print $1}' | xargs -r docker rmi -f || true
227+
228+
- name: Health check
229+
run: |
230+
echo "Waiting for services to start..."
231+
sleep 15
232+
233+
echo "Checking application health..."
234+
for i in {1..5}; do
235+
if curl -f -s http://${{ secrets.SERVER_PRODUCTION_HOST }}/e-newspaper/up > /dev/null; then
236+
echo "✓ Health check passed!"
237+
exit 0
238+
fi
239+
echo "Attempt $i failed, retrying in 10 seconds..."
240+
sleep 10
241+
done
242+
243+
echo "✗ Health check failed after 5 attempts"
244+
exit 1
193245

docker-compose.prod.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
services:
2+
db:
3+
image: postgres:17.2-alpine
4+
volumes:
5+
- 'postgres:/var/lib/postgresql/data'
6+
restart: always
7+
environment:
8+
POSTGRES_USER: postgres
9+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
10+
POSTGRES_DB: dailynews_production
11+
ports:
12+
- '5432:5432'
13+
healthcheck:
14+
test: [ "CMD-SHELL", "pg_isready -U postgres -d dailynews_production" ]
15+
interval: 10s
16+
timeout: 5s
17+
retries: 5
18+
networks:
19+
- rails_network
20+
21+
rails:
22+
image: ghcr.io/oddsteam/dailynews-e-newspaper:production
23+
platform: linux/amd64
24+
depends_on:
25+
db:
26+
condition: service_healthy
27+
expose:
28+
- "3000"
29+
ports:
30+
- "3000:3000"
31+
environment:
32+
- RAILS_MASTER_KEY=${RAILS_MASTER_KEY}
33+
- APP_ENV=production
34+
- SCRIPT_NAME=/e-newspaper
35+
- SOLID_QUEUE_IN_PUMA=true
36+
- WEB_CONCURRENCY=auto
37+
- RAILS_MAX_THREADS=8
38+
networks:
39+
- rails_network
40+
41+
nginx:
42+
image: nginx:alpine
43+
ports:
44+
- "80:80"
45+
volumes:
46+
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
47+
depends_on:
48+
- rails
49+
networks:
50+
- rails_network
51+
restart: always
52+
53+
networks:
54+
rails_network:
55+
56+
57+
volumes:
58+
postgres:
59+
bundle:

0 commit comments

Comments
 (0)