Skip to content

Commit e1c4344

Browse files
author
Marvin Zhang
committed
feat: add Docker configuration and GitHub Actions workflow for containerized deployment
1 parent ed708dc commit e1c4344

File tree

13 files changed

+784
-14
lines changed

13 files changed

+784
-14
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"id": 256,
3+
"key": "create-docker-configuration-and-github-actions-wor",
4+
"title": "Create Docker Configuration and GitHub Actions Workflow for GHCR",
5+
"type": "task",
6+
"description": "Create comprehensive Docker setup including Dockerfile, docker-compose.yml, and GitHub Actions workflow to build and push container images to GitHub Container Registry (GHCR). This will enable containerized deployment of the devlog application.",
7+
"status": "done",
8+
"priority": "medium",
9+
"createdAt": "2025-07-24T03:22:58.306Z",
10+
"updatedAt": "2025-07-24T03:41:19.946Z",
11+
"notes": [
12+
{
13+
"id": "f3a4954c-ccc0-44e2-a99f-c8fa2a9ee775",
14+
"timestamp": "2025-07-24T03:25:46.015Z",
15+
"category": "progress",
16+
"content": "User requested to simplify Docker setup by removing MCP server components and focusing on web application only"
17+
},
18+
{
19+
"id": "4397000a-daa0-412d-9677-23e3e5cc5280",
20+
"timestamp": "2025-07-24T03:40:55.604Z",
21+
"category": "solution",
22+
"content": "Successfully completed Docker configuration with working web application, PostgreSQL database, health endpoint, and GitHub Actions workflow for GHCR",
23+
"files": [
24+
"Dockerfile",
25+
"docker-compose.yml",
26+
"docker-compose.dev.yml",
27+
"Dockerfile.dev",
28+
".dockerignore",
29+
".github/workflows/docker.yml",
30+
"DOCKER.md",
31+
"packages/web/app/api/health/route.ts",
32+
"scripts/init-db.sql"
33+
]
34+
}
35+
],
36+
"files": [],
37+
"relatedDevlogs": [],
38+
"context": {
39+
"businessContext": "Containerization is essential for consistent deployment across environments and enables easy hosting on various platforms. GHCR integration provides seamless CI/CD pipeline for automatic image builds on code changes.",
40+
"technicalContext": "The devlog project is a TypeScript monorepo with Next.js web app, MCP server, and core packages. Docker setup needs to handle the monorepo structure, build dependencies correctly, and optimize for production deployment.",
41+
"dependencies": [],
42+
"decisions": [],
43+
"acceptanceCriteria": [
44+
"Dockerfile creates optimized production image",
45+
"docker-compose.yml supports development and production environments",
46+
"GitHub Actions workflow builds and pushes to GHCR",
47+
"Images are properly tagged with git SHA and latest",
48+
"Multi-stage build reduces final image size",
49+
"Environment variables properly configured"
50+
],
51+
"risks": []
52+
},
53+
"aiContext": {
54+
"currentSummary": "",
55+
"keyInsights": [],
56+
"openQuestions": [],
57+
"relatedPatterns": [],
58+
"suggestedNextSteps": [],
59+
"lastAIUpdate": "2025-07-24T03:22:58.306Z",
60+
"contextVersion": 1
61+
},
62+
"closedAt": "2025-07-24T03:41:19.946Z"
63+
}

.dockerignore

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Git and version control
2+
.git
3+
.gitignore
4+
.github
5+
6+
# Documentation
7+
README.md
8+
*.md
9+
docs/
10+
11+
# Development files
12+
.env*
13+
.vscode/
14+
.idea/
15+
*.log
16+
tmp/
17+
18+
# Dependencies (will be installed in container)
19+
node_modules/
20+
.pnpm-store/
21+
22+
# Build outputs (will be created in container)
23+
.next/
24+
.next-build/
25+
build/
26+
dist/
27+
out/
28+
29+
# Testing
30+
coverage/
31+
.nyc_output/
32+
test-results/
33+
34+
# OS generated files
35+
.DS_Store
36+
.DS_Store?
37+
._*
38+
.Spotlight-V100
39+
.Trashes
40+
ehthumbs.db
41+
Thumbs.db
42+
43+
# Editor files
44+
*~
45+
*.swp
46+
*.swo
47+
.vscode/
48+
.idea/
49+
50+
# Package manager files
51+
.pnpm-debug.log*
52+
npm-debug.log*
53+
yarn-debug.log*
54+
yarn-error.log*
55+
56+
# Runtime files
57+
*.pid
58+
59+
# Database files (for local development)
60+
*.db
61+
*.sqlite
62+
*.sqlite3
63+
.devlog/
64+
65+
# Docker files (not needed in container)
66+
Dockerfile*
67+
docker-compose*.yml
68+
.dockerignore
69+
70+
# Vercel specific
71+
.vercel/
72+
73+
# MCP package (not needed for web-only build)
74+
packages/mcp/

.github/workflows/docker.yml

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
name: Build and Push Docker Image
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
tags: [ 'v*' ]
7+
pull_request:
8+
branches: [ main ]
9+
10+
env:
11+
REGISTRY: ghcr.io
12+
IMAGE_NAME: ${{ github.repository }}
13+
14+
jobs:
15+
build-and-push:
16+
name: Build and Push Docker Image
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
packages: write
21+
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v4
25+
26+
- name: Setup Docker Buildx
27+
uses: docker/setup-buildx-action@v3
28+
29+
- name: Log in to Container Registry
30+
if: github.event_name != 'pull_request'
31+
uses: docker/login-action@v3
32+
with:
33+
registry: ${{ env.REGISTRY }}
34+
username: ${{ github.actor }}
35+
password: ${{ secrets.GITHUB_TOKEN }}
36+
37+
- name: Extract metadata
38+
id: meta
39+
uses: docker/metadata-action@v5
40+
with:
41+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
42+
tags: |
43+
type=ref,event=branch
44+
type=ref,event=pr
45+
type=semver,pattern={{version}}
46+
type=semver,pattern={{major}}.{{minor}}
47+
type=semver,pattern={{major}}
48+
type=sha,prefix={{branch}}-
49+
type=raw,value=latest,enable={{is_default_branch}}
50+
51+
- name: Build Docker image
52+
uses: docker/build-push-action@v5
53+
with:
54+
context: .
55+
file: ./Dockerfile
56+
target: runner
57+
push: false
58+
tags: ${{ steps.meta.outputs.tags }}
59+
labels: ${{ steps.meta.outputs.labels }}
60+
cache-from: type=gha
61+
cache-to: type=gha,mode=max
62+
platforms: linux/amd64,linux/arm64
63+
64+
- name: Test Docker image
65+
run: |
66+
# Get the first tag for testing
67+
IMAGE_TAG=$(echo "${{ steps.meta.outputs.tags }}" | head -n1)
68+
echo "Testing image: $IMAGE_TAG"
69+
70+
# Run a quick test to ensure the image starts correctly
71+
docker run --rm -d --name devlog-test -p 3000:3000 \
72+
-e NODE_ENV=production \
73+
-e DEVLOG_STORAGE_TYPE=json \
74+
$IMAGE_TAG
75+
76+
# Wait for the application to start
77+
sleep 15
78+
79+
# Check if the application is responding
80+
if curl -f http://localhost:3000/ -I 2>/dev/null; then
81+
echo "✅ Application is responding"
82+
else
83+
echo "❌ Application not responding"
84+
docker logs devlog-test
85+
exit 1
86+
fi
87+
88+
# Test health endpoint if available
89+
if curl -f http://localhost:3000/api/health 2>/dev/null; then
90+
echo "✅ Health check passed"
91+
else
92+
echo "⚠️ Health check endpoint not available, but application is running"
93+
fi
94+
95+
# Cleanup
96+
docker stop devlog-test
97+
98+
- name: Push Docker image
99+
if: github.event_name != 'pull_request'
100+
uses: docker/build-push-action@v5
101+
with:
102+
context: .
103+
file: ./Dockerfile
104+
target: runner
105+
push: true
106+
tags: ${{ steps.meta.outputs.tags }}
107+
labels: ${{ steps.meta.outputs.labels }}
108+
cache-from: type=gha
109+
cache-to: type=gha,mode=max
110+
platforms: linux/amd64,linux/arm64
111+
112+
- name: Generate deployment summary
113+
if: github.event_name != 'pull_request'
114+
run: |
115+
echo "## 🐳 Docker Image Published" >> $GITHUB_STEP_SUMMARY
116+
echo "" >> $GITHUB_STEP_SUMMARY
117+
echo "**Registry:** \`${{ env.REGISTRY }}\`" >> $GITHUB_STEP_SUMMARY
118+
echo "**Repository:** \`${{ env.IMAGE_NAME }}\`" >> $GITHUB_STEP_SUMMARY
119+
echo "" >> $GITHUB_STEP_SUMMARY
120+
echo "### 📦 Tags Published:" >> $GITHUB_STEP_SUMMARY
121+
echo "" >> $GITHUB_STEP_SUMMARY
122+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
123+
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
124+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
125+
echo "" >> $GITHUB_STEP_SUMMARY
126+
echo "### 🚀 Usage:" >> $GITHUB_STEP_SUMMARY
127+
echo "" >> $GITHUB_STEP_SUMMARY
128+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
129+
echo "# Pull and run the latest image" >> $GITHUB_STEP_SUMMARY
130+
echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY
131+
echo "docker run -p 3000:3000 ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY
132+
echo "" >> $GITHUB_STEP_SUMMARY
133+
echo "# Or use docker-compose" >> $GITHUB_STEP_SUMMARY
134+
echo "docker-compose up" >> $GITHUB_STEP_SUMMARY
135+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
136+
137+
security-scan:
138+
name: Security Scan
139+
runs-on: ubuntu-latest
140+
needs: build-and-push
141+
if: github.event_name != 'pull_request'
142+
permissions:
143+
contents: read
144+
packages: read
145+
security-events: write
146+
147+
steps:
148+
- name: Checkout code
149+
uses: actions/checkout@v4
150+
151+
- name: Run Trivy vulnerability scanner
152+
uses: aquasecurity/trivy-action@master
153+
with:
154+
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
155+
format: 'sarif'
156+
output: 'trivy-results.sarif'
157+
158+
- name: Upload Trivy scan results to GitHub Security tab
159+
uses: github/codeql-action/upload-sarif@v3
160+
if: always()
161+
with:
162+
sarif_file: 'trivy-results.sarif'

0 commit comments

Comments
 (0)