Refine Docker, docker-compose, and EC2 deploy
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
284fb12576
commit
dfebb51bd2
50
.github/workflows/deploy-ec2.yml
vendored
50
.github/workflows/deploy-ec2.yml
vendored
@ -37,6 +37,8 @@ jobs:
|
||||
|
||||
- name: Deploy to EC2 with rollback
|
||||
uses: appleboy/ssh-action@v1.2.0
|
||||
env:
|
||||
EC2_ENV: ${{ secrets.EC2_ENV }}
|
||||
with:
|
||||
host: ${{ secrets.EC2_HOST }}
|
||||
username: ${{ secrets.EC2_USER }}
|
||||
@ -51,11 +53,7 @@ jobs:
|
||||
mkdir -p "$APP_DIR"
|
||||
cd "$APP_DIR"
|
||||
|
||||
echo "Writing .env file from EC2_ENV secret..."
|
||||
# Overwrite .env on the server with the contents of the EC2_ENV variable
|
||||
# EC2_ENV is provided by GitHub as a multi-line secret matching your local .env
|
||||
printf '%s\n' "$EC2_ENV" > .env
|
||||
|
||||
# Initialize git repo if needed
|
||||
if [ ! -d ".git" ]; then
|
||||
echo "Cloning repository for the first time..."
|
||||
git clone ${{ github.repositoryUrl }} .
|
||||
@ -71,15 +69,33 @@ jobs:
|
||||
git checkout ${{ github.ref_name }}
|
||||
git reset --hard ${{ github.sha }}
|
||||
|
||||
echo "Pulling docker images and rebuilding containers..."
|
||||
if command -v docker-compose >/dev/null 2>&1; then
|
||||
DC="docker-compose"
|
||||
else
|
||||
DC="docker compose"
|
||||
echo "Writing .env file from EC2_ENV secret..."
|
||||
# Write .env file AFTER pulling latest code so it's in the right location
|
||||
# EC2_ENV is provided by GitHub as a multi-line secret matching your local .env
|
||||
printf '%s\n' "$EC2_ENV" > .env
|
||||
|
||||
echo "Checking Docker and Docker Compose..."
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "Error: Docker is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$DC pull || true
|
||||
if command -v docker-compose >/dev/null 2>&1; then
|
||||
DC="docker-compose"
|
||||
elif docker compose version >/dev/null 2>&1; then
|
||||
DC="docker compose"
|
||||
else
|
||||
echo "Error: Docker Compose is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using: $DC"
|
||||
$DC version
|
||||
|
||||
echo "Stopping existing containers..."
|
||||
$DC down || true
|
||||
|
||||
echo "Building and starting containers with docker-compose..."
|
||||
set +e
|
||||
$DC up -d --build
|
||||
DEPLOY_EXIT=$?
|
||||
@ -89,26 +105,32 @@ jobs:
|
||||
echo "Deployment failed, attempting rollback..."
|
||||
if [ -n "$PREV_COMMIT" ]; then
|
||||
git reset --hard "$PREV_COMMIT"
|
||||
printf '%s\n' "$EC2_ENV" > .env
|
||||
$DC up -d --build || true
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Waiting for containers to be healthy..."
|
||||
sleep 10
|
||||
|
||||
echo "Running health check..."
|
||||
HEALTH_URL="${HEALTH_URL:-http://localhost:3000/api/health}"
|
||||
|
||||
for i in {1..10}; do
|
||||
for i in {1..15}; do
|
||||
if curl -fsS "$HEALTH_URL" >/dev/null 2>&1; then
|
||||
echo "Health check passed."
|
||||
echo "Health check passed on attempt $i."
|
||||
echo "Deployment successful!"
|
||||
exit 0
|
||||
fi
|
||||
echo "Health check attempt $i failed, retrying..."
|
||||
echo "Health check attempt $i failed, retrying in 5 seconds..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "Health check failed after multiple attempts, rolling back..."
|
||||
if [ -n "$PREV_COMMIT" ]; then
|
||||
git reset --hard "$PREV_COMMIT"
|
||||
printf '%s\n' "$EC2_ENV" > .env
|
||||
$DC up -d --build || true
|
||||
fi
|
||||
exit 1
|
||||
|
||||
11
Dockerfile
11
Dockerfile
@ -2,13 +2,20 @@ FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json prisma.config.ts ./
|
||||
COPY prisma ./prisma
|
||||
|
||||
RUN npm install && npx prisma generate
|
||||
# Install dependencies and generate Prisma client
|
||||
RUN npm install --only=production && npx prisma generate
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Build the Next.js application
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["npm", "run", "dev"]
|
||||
# Use production start command
|
||||
CMD ["npm", "start"]
|
||||
|
||||
@ -11,21 +11,34 @@ services:
|
||||
- "5444:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
restart: always
|
||||
ports:
|
||||
- "3000:3000"
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
# Override DATABASE_URL to use internal docker network hostname
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-password}@db:5432/${POSTGRES_DB:-dropshipping}?schema=public
|
||||
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
|
||||
NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000}
|
||||
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
|
||||
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
|
||||
NODE_ENV: production
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1) }).on('error', () => process.exit(1))"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
||||
26
src/app/api/health/route.ts
Normal file
26
src/app/api/health/route.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { NextResponse } from "next/server"
|
||||
import { prisma } from "@/lib/prisma"
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
// Simple database connectivity check
|
||||
await prisma.$queryRaw`SELECT 1`
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
status: "ok",
|
||||
timestamp: new Date().toISOString()
|
||||
},
|
||||
{ status: 200 }
|
||||
)
|
||||
} catch (error) {
|
||||
console.error("Health check failed:", error)
|
||||
return NextResponse.json(
|
||||
{
|
||||
status: "error",
|
||||
message: "Database connection failed"
|
||||
},
|
||||
{ status: 503 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user