Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Dependencies
node_modules

# Git
.git
.gitignore

# Environment files
.env
.env.*

# Documentation
*.md
README.md

# IDE/Editor
.vscode
.idea
*.swp
*.swo

# Config files
.eslintrc.js
.editorconfig
.prettierrc

# Example and test files
example
images
test
tests
__tests__

# Build artifacts (will be created in builder stage)
dist

# Logs
*.log
npm-debug.log*

# OS files
.DS_Store
Thumbs.db
29 changes: 29 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI Build

on:
push:
branches:
- main
- master
paths:
- 'Dockerfile'
- 'src/**'
- 'package.json'
- 'package-lock.json'
pull_request:
branches:
- main
- master

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
uses: Buzzvil/workflows/.github/workflows/build_ecr.yaml@main
secrets: inherit
with:
repository: devtools-remote-debugger
dockerfile: Dockerfile
tags: ${{ github.sha }},latest
113 changes: 113 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
name: Deploy to ECS

on:
workflow_dispatch:
inputs:
image_tag:
description: 'Image tag to deploy (default: latest commit SHA)'
required: false
default: ''
push:
branches:
- main
- master
paths:
- 'Dockerfile'
- 'src/**'
- 'package.json'
- 'package-lock.json'

concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: false

env:
AWS_REGION: ap-northeast-1
ECR_REPOSITORY: devtools-remote-debugger
ECS_CLUSTER: devtools-remote-debugger
ECS_SERVICE: devtools-remote-debugger
TASK_DEFINITION_FAMILY: devtools-remote-debugger
CONTAINER_NAME: devtools-remote-debugger

jobs:
build:
uses: Buzzvil/workflows/.github/workflows/build_ecr.yaml@main
secrets: inherit
with:
repository: devtools-remote-debugger
dockerfile: Dockerfile
tags: ${{ github.sha }},latest

deploy:
name: Deploy to ECS
needs: build
runs-on: self-hosted
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_REGION }}

- name: Determine image tag
id: image-tag
run: |
if [ -n "${{ github.event.inputs.image_tag }}" ]; then
echo "tag=${{ github.event.inputs.image_tag }}" >> $GITHUB_OUTPUT
else
echo "tag=${{ github.sha }}" >> $GITHUB_OUTPUT
fi

- name: Download current task definition
run: |
aws ecs describe-task-definition \
--task-definition ${{ env.TASK_DEFINITION_FAMILY }} \
--query taskDefinition > task-definition.json

- name: Update task definition with new image
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: ${{ env.CONTAINER_NAME }}
image: 591756927972.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.ECR_REPOSITORY }}:${{ steps.image-tag.outputs.tag }}

- name: Register new task definition
id: register-task-def
run: |
# Remove fields that can't be in RegisterTaskDefinition
jq 'del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy)' \
${{ steps.task-def.outputs.task-definition }} > cleaned-task-def.json

TASK_DEF_ARN=$(aws ecs register-task-definition \
--cli-input-json file://cleaned-task-def.json \
--query 'taskDefinition.taskDefinitionArn' \
--output text)
echo "task-definition-arn=$TASK_DEF_ARN" >> $GITHUB_OUTPUT

- name: Update ECS service
run: |
aws ecs update-service \
--cluster ${{ env.ECS_CLUSTER }} \
--service ${{ env.ECS_SERVICE }} \
--task-definition ${{ steps.register-task-def.outputs.task-definition-arn }} \
--force-new-deployment

- name: Wait for service stability
run: |
echo "Waiting for ECS service to stabilize..."
aws ecs wait services-stable \
--cluster ${{ env.ECS_CLUSTER }} \
--services ${{ env.ECS_SERVICE }}

- name: Deployment summary
run: |
echo "## Deployment Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Item | Value |" >> $GITHUB_STEP_SUMMARY
echo "|------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Cluster | ${{ env.ECS_CLUSTER }} |" >> $GITHUB_STEP_SUMMARY
echo "| Service | ${{ env.ECS_SERVICE }} |" >> $GITHUB_STEP_SUMMARY
echo "| Image Tag | ${{ steps.image-tag.outputs.tag }} |" >> $GITHUB_STEP_SUMMARY
echo "| Task Definition | ${{ steps.register-task-def.outputs.task-definition-arn }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Deployment completed successfully!" >> $GITHUB_STEP_SUMMARY
45 changes: 45 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Stage 1: Build
FROM node:18-alpine AS builder

WORKDIR /app

# Install dependencies
COPY package.json package-lock.json ./
RUN npm ci

# Copy source and build
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:18-alpine AS production

WORKDIR /app

# Install production dependencies only
COPY package.json package-lock.json ./
RUN npm ci --omit=dev && npm cache clean --force

# Copy built assets and server files
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/devtools-frontend ./devtools-frontend
COPY --from=builder /app/src/server ./src/server

# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001 && \
chown -R nodejs:nodejs /app

USER nodejs

# Environment
ENV NODE_ENV=production
ENV DEBUG_PORT=9876

# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:9876/remote/debug/json || exit 1

EXPOSE 9876

CMD ["node", "src/server/index.js"]