diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ca50dd..d983961 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,8 @@ on: push: branches: - production + tags: + - "v*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index ae9fac7..036102c 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -21,74 +21,73 @@ jobs: - name: Validate image tag format run: | TAG="${{ inputs.image_tag }}" - - # rc-{sha} 또는 semVer 형식 검증 if [[ $TAG =~ ^rc-[a-f0-9]{7}$ ]] || [[ $TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Valid tag format: $TAG" + echo "✅ Valid tag format: $TAG" else - echo "Error: Invalid tag format. Expected rc-{sha} or v{major}.{minor}.{patch}" + echo "❌ Error: Invalid tag format. Expected rc-{sha} or v{major}.{minor}.{patch}" exit 1 fi - - - name: Setup SSH - run: | - mkdir -p ~/.ssh - echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key - chmod 600 ~/.ssh/deploy_key - ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts - - - name: Copy deployment files to server + - name: Create .env file run: | - scp -i ~/.ssh/deploy_key \ - docker-compose.yml \ - .env.example \ - ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DEPLOY_PATH }}/ + echo "${{ secrets.ENV_PRODUCTION }}" > .env + + - name: Copy files to server + uses: appleboy/scp-action@v1.0.0 + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USER }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + port: ${{ secrets.SSH_PORT || 22 }} + source: "docker-compose.yml,.env" + target: "${{ secrets.DEPLOY_PATH }}" + + - name: Cleanup local .env + if: always() + run: rm -f .env + # docker hub 계정이 다른데 협업 기능은 유료이므로 두 번에 걸쳐서 이미지를 가져와야함. - name: Deploy with Docker Compose - run: | - ssh -i ~/.ssh/deploy_key ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH' - cd ${{ secrets.DEPLOY_PATH }} - - # Create .env file if it doesn't exist - if [ ! -f .env ]; then - echo "Creating .env file from .env.example" - cp .env.example .env - echo "⚠️ Please update .env file with actual values" - fi - - # Export environment variables - export IMAGE_TAG=${{ inputs.image_tag }} - - # Pull latest images - echo "Pulling Docker images..." - docker-compose pull - - # Stop and remove old containers - echo "Stopping old containers..." - docker-compose down - - # Start new containers - echo "Starting new containers..." - docker-compose up -d - - # Show running containers - echo "Deployment complete! Running containers:" - docker-compose ps - - # Clean up old images - echo "Cleaning up old images..." + uses: appleboy/ssh-action@1.2.4 + env: + IMAGE_TAG: ${{ inputs.image_tag }} + DOCKERHUB_WEB_USERNAME: ${{ secrets.DOCKERHUB_WEB_USERNAME }} + DOCKERHUB_WEB_TOKEN: ${{ secrets.DOCKERHUB_WEB_TOKEN }} + DOCKERHUB_SERVER_USERNAME: ${{ secrets.DOCKERHUB_SERVER_USERNAME }} + DOCKERHUB_SERVER_TOKEN: ${{ secrets.DOCKERHUB_SERVER_TOKEN }} + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USER }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + port: ${{ secrets.SSH_PORT || 22 }} + envs: IMAGE_TAG,DOCKERHUB_WEB_USERNAME,DOCKERHUB_WEB_TOKEN,DOCKERHUB_SERVER_USERNAME,DOCKERHUB_SERVER_TOKEN + command_timeout: 30m + script: | + cd ${{ secrets.DEPLOY_PATH }} || exit 1 + + chmod 600 .env + + echo "🚀 Starting deployment for tag: $IMAGE_TAG" + + echo "$DOCKERHUB_WEB_TOKEN" | docker login -u "$DOCKERHUB_WEB_USERNAME" --password-stdin + IMAGE_TAG=$IMAGE_TAG docker compose pull web + docker logout + + echo "$DOCKERHUB_SERVER_TOKEN" | docker login -u "$DOCKERHUB_SERVER_USERNAME" --password-stdin + IMAGE_TAG=$IMAGE_TAG docker compose pull server + docker logout + + IMAGE_TAG=$IMAGE_TAG docker compose up -d + + echo "✅ Deployment complete! Current status:" + docker compose ps + + echo "🧹 Cleaning up unused images..." docker image prune -f - ENDSSH - - - name: Cleanup SSH key - if: always() - run: | - rm -f ~/.ssh/deploy_key - name: Deployment notification if: success() run: | - echo "### Deployment Successful! :rocket:" >> $GITHUB_STEP_SUMMARY + echo "### Deployment Successful! 🚀" >> $GITHUB_STEP_SUMMARY echo "**Environment:** Production" >> $GITHUB_STEP_SUMMARY echo "**Image tag:** ${{ inputs.image_tag }}" >> $GITHUB_STEP_SUMMARY echo "**Deployed at:** $(date)" >> $GITHUB_STEP_SUMMARY diff --git a/docker-compose.yml b/docker-compose.yml index cba6985..7075823 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,19 @@ -version: '3.8' +version: "3.8" services: + nginx: + image: nginx:alpine + container_name: web29-nginx + restart: always + ports: + - "80:80" + volumes: + - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro + depends_on: + - web + - server + networks: + - app-network web: image: ${WEB_IMAGE_NAME}:${IMAGE_TAG:-latest} container_name: web29-web