Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e3023a7
chore: enhance build process for static asset management and Docker c…
claudfuen Aug 4, 2025
8f8859d
Merge pull request #1231 from trycompai/claudio/fix-file-upload
claudfuen Aug 4, 2025
1169bf7
chore: update Dockerfiles for streamlined build process and entry poi…
claudfuen Aug 4, 2025
7025fa8
Merge pull request #1233 from trycompai/claudio/fix-file-upload
claudfuen Aug 4, 2025
5555ece
chore: enhance build process and asset management for app and portal
claudfuen Aug 4, 2025
ef92b41
Merge pull request #1234 from trycompai/claudio/fix-file-upload
claudfuen Aug 4, 2025
5871433
chore: refactor asset rewrites in next.config.ts for app and portal
claudfuen Aug 4, 2025
fecd99d
Merge pull request #1235 from trycompai/claudio/fix-file-upload
claudfuen Aug 4, 2025
60ca18b
chore: update buildspec and next.config for improved asset management…
claudfuen Aug 4, 2025
bb6da88
Merge pull request #1236 from trycompai/claudio/fix-file-upload
claudfuen Aug 4, 2025
d454b33
chore: enhance buildspec for app and portal with app-specific standal…
claudfuen Aug 4, 2025
5d8e714
chore: enhance buildspec for app and portal with improved standalone …
claudfuen Aug 4, 2025
958a242
Merge pull request #1237 from trycompai/claudio/fix-file-upload
claudfuen Aug 4, 2025
b5ba377
chore: update buildspec for app and portal to support app-specific st…
claudfuen Aug 4, 2025
2369387
Merge pull request #1238 from trycompai/claudio/fix-file-upload
claudfuen Aug 4, 2025
3e203de
chore: update next.config for app and portal to use STATIC_ASSETS_URL…
claudfuen Aug 4, 2025
8ce1229
Merge pull request #1239 from trycompai/claudio/fix-file-upload
claudfuen Aug 4, 2025
64d4b2c
chore: update buildspec for app and portal to exclude .map files duri…
claudfuen Aug 4, 2025
4f6023a
Merge pull request #1240 from trycompai/claudio/fix-file-upload
claudfuen Aug 4, 2025
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
8 changes: 4 additions & 4 deletions apps/app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
ENV NODE_TLS_REJECT_UNAUTHORIZED=0

# Copy the complete standalone build from CodeBuild
COPY .next/standalone ./
# Copy the standalone build files (already prepared in container-build/)
COPY . ./

# Create non-root user for security
RUN addgroup -g 1001 -S nodejs && \
Expand All @@ -25,5 +25,5 @@ USER nextjs

EXPOSE 3000

# Use node to run the standalone server - handle monorepo structure
CMD ["sh", "-c", "if [ -f apps/app/server.js ]; then node apps/app/server.js; elif [ -f server.js ]; then node server.js; elif [ -f index.js ]; then node index.js; else echo 'No entry point found' && exit 1; fi"]
# Use node to run the standalone server
CMD ["node", "server.js"]
147 changes: 125 additions & 22 deletions apps/app/buildspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ phases:
# Environment setup
- export PATH="/root/.bun/bin:$PATH"
- export PGSSLMODE=require
- export NODE_ENV=production
- export NEXT_TELEMETRY_DISABLED=1
- export UV_THREADPOOL_SIZE=36
- export NODE_OPTIONS="--max-old-space-size=65536"
Expand All @@ -35,6 +36,7 @@ phases:
# Validate environment variables
- echo "Validating environment variables..."
- '[ -n "$NEXT_PUBLIC_PORTAL_URL" ] || { echo "❌ NEXT_PUBLIC_PORTAL_URL is not set"; exit 1; }'
- '[ -n "$STATIC_ASSETS_BUCKET" ] || { echo "❌ STATIC_ASSETS_BUCKET is not set"; exit 1; }'

# Type check
- echo "Type checking..."
Expand All @@ -45,38 +47,139 @@ phases:
- cd apps/$APP_NAME
- NODE_TLS_REJECT_UNAUTHORIZED=0 bun run build

# Prepare standalone build
# Upload Next.js chunks and CSS to S3 for CDN performance
- echo "Uploading Next.js static assets to S3..."
- |
if [ -d ".next/static" ]; then
echo "📦 Uploading .next/static/ files to CDN..."
aws s3 sync .next/static/ s3://$STATIC_ASSETS_BUCKET/_next/static/ \
--cache-control "public, max-age=31536000, immutable" \
--exclude "*.map"
echo "✅ Uploaded Next.js static assets to S3"
else
echo "⚠️ No .next/static directory found"
fi

# Upload public assets to S3 for CDN serving
- |
if [ -d "public" ]; then
echo "📦 Uploading public/ files to S3..."
aws s3 sync public/ s3://$STATIC_ASSETS_BUCKET/ \
--cache-control "public, max-age=86400" \
--exclude "*.map" \
--exclude "_next/*"
echo "✅ Uploaded public assets to S3"
else
echo "⚠️ No public directory found"
fi

# Prepare standalone build for container
- echo "Preparing standalone build..."
- echo "DEBUG - Checking what Next.js built..."
- ls -la .next/
- ls -la .next/standalone/ || echo "No standalone directory"
- echo "DEBUG - Checking if static files exist..."
- ls -la .next/static/ || echo "No static directory found"
- echo "DEBUG - Copying static files to standalone..."
- cp -r public .next/standalone/apps/$APP_NAME/ || echo "No public folder"
- cp -r .next/static .next/standalone/apps/$APP_NAME/.next/ || echo "No .next/static directory"
- echo "DEBUG - Final verification..."
- ls -la .next/standalone/ || echo "Standalone empty"
- find .next/standalone -name "*.css" | head -3 || echo "No CSS files found"
- find .next/standalone -name "*.js" | head -3 || echo "No JS files found"

# Copy Prisma client
- echo "Copying Prisma client..."
- mkdir -p .next/standalone/node_modules/.prisma .next/standalone/node_modules/@prisma
- if [ -d "../../node_modules/.prisma/client" ]; then
cp -r ../../node_modules/.prisma/client .next/standalone/node_modules/.prisma/;
- echo "DEBUG - Checking standalone structure..."
- find .next/standalone -name "server.js" -ls || echo "No server.js found"
- ls -la .next/standalone/apps/$APP_NAME/ || echo "No app directory"
- echo "DEBUG - Checking app's own .next build structure..."
- ls -la .next/server/ || echo "No .next/server directory"
- ls -la .next/standalone/ || echo "No .next/standalone directory"
- echo "DEBUG - Checking for server.js in various locations..."
- test -f .next/standalone/server.js && echo "✅ Standalone server.js exists" || echo "❌ No standalone server.js"
- find .next -name "server.js" | head -5 || echo "No server.js found anywhere"

# Create container build directory
- mkdir -p container-build

# Use the standalone build properly: copy from .next/standalone + app's own build
- echo "DEBUG - Building container from standalone + app build..."

# Copy the app's own built files (server.js, etc.)
- echo "Copying app's own .next build..."
- cp -r .next container-build/ || echo "App .next copy failed"

# Copy shared node_modules from standalone (minimal runtime deps)
- echo "Copying standalone node_modules (runtime dependencies)..."
- cp -r .next/standalone/node_modules container-build/ || echo "Standalone node_modules copy failed"

# Copy or create server.js for standalone
- |
if [ -f ".next/standalone/apps/$APP_NAME/server.js" ]; then
echo "Using app-specific standalone server.js..."
cp .next/standalone/apps/$APP_NAME/server.js container-build/
elif [ -f ".next/standalone/server.js" ]; then
echo "Using global standalone server.js..."
cp .next/standalone/server.js container-build/
else
echo "Creating minimal standalone server.js..."
cat > container-build/server.js << 'EOF'
const { createServer } = require('http')
const next = require('next')

const dev = false
const hostname = process.env.HOSTNAME || '0.0.0.0'
const port = process.env.PORT || 3000

// Use the current directory as the Next.js app
const app = next({ dev, hostname, port, dir: __dirname })
const handle = app.getRequestHandler()

app.prepare().then(() => {
createServer(async (req, res) => {
await handle(req, res)
}).listen(port, hostname, () => {
console.log(`> Ready on http://${hostname}:${port}`)
})
})
EOF
fi

# Verify the app-specific standalone build
- echo "DEBUG - Verifying app-specific standalone build..."
- ls -la container-build/
- test -f container-build/server.js && echo "✅ App server.js exists" || echo "❌ App server.js missing"
- test -d container-build/.next && echo "✅ .next directory exists" || echo "❌ .next directory missing"
- test -d container-build/node_modules && echo "✅ node_modules exists" || echo "❌ node_modules missing"

# Add Dockerfile to the standalone build
- cp Dockerfile container-build/ || echo "No Dockerfile"

# Ensure Prisma client is available (override standalone if needed)
- echo "Ensuring Prisma client is available..."
- mkdir -p container-build/node_modules/.prisma container-build/node_modules/@prisma
- |
if [ -d "../../node_modules/.prisma/client" ]; then
echo "Copying Prisma client from monorepo root..."
cp -r ../../node_modules/.prisma/client container-build/node_modules/.prisma/
elif [ -d "node_modules/.prisma/client" ]; then
cp -r node_modules/.prisma/client .next/standalone/node_modules/.prisma/;
echo "Copying Prisma client from app directory..."
cp -r node_modules/.prisma/client container-build/node_modules/.prisma/
else
echo "Warning: No Prisma client found"
fi
- if [ -d "../../node_modules/@prisma/client" ]; then
cp -r "../../node_modules/@prisma/client" ".next/standalone/node_modules/@prisma/";
- |
if [ -d "../../node_modules/@prisma/client" ]; then
echo "Copying @prisma/client from monorepo root..."
cp -r "../../node_modules/@prisma/client" "container-build/node_modules/@prisma/"
elif [ -d "node_modules/@prisma/client" ]; then
cp -r "node_modules/@prisma/client" ".next/standalone/node_modules/@prisma/";
echo "Copying @prisma/client from app directory..."
cp -r "node_modules/@prisma/client" "container-build/node_modules/@prisma/"
else
echo "Warning: No @prisma/client found"
fi

# Build Docker image
# Debug: Verify container build contents
- echo "DEBUG - Verifying app-specific container build..."
- ls -la container-build/
- ls -la container-build/.next/ || echo "❌ .next directory not found"
- ls -la container-build/node_modules/next/ || echo "❌ Next.js module not found"
- ls -la container-build/node_modules/.prisma/ || echo "❌ Prisma client not found"
- test -f container-build/server.js && echo "✅ App-specific server.js found" || echo "❌ App-specific server.js not found"
- head -10 container-build/server.js || echo "❌ Cannot read server.js"

# Build Docker image (static assets now served from S3)
- echo "Building Docker image..."
- docker build --build-arg BUILDKIT_INLINE_CACHE=1 -f ${DOCKERFILE_PATH:-Dockerfile} -t $ECR_REPOSITORY_URI:$IMAGE_TAG .
- docker build --build-arg BUILDKIT_INLINE_CACHE=1 -f container-build/Dockerfile -t $ECR_REPOSITORY_URI:$IMAGE_TAG container-build/
- docker tag $ECR_REPOSITORY_URI:$IMAGE_TAG $ECR_REPOSITORY_URI:latest

post_build:
Expand Down
9 changes: 6 additions & 3 deletions apps/app/next.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type { NextConfig } from 'next';
import path from 'path';
import './src/env.mjs';

const config: NextConfig = {
// Use S3 bucket for static assets
assetPrefix: process.env.NODE_ENV === 'production' ? process.env.STATIC_ASSETS_URL : '',
poweredByHeader: false,
reactStrictMode: true,
transpilePackages: ['@trycompai/db'],
Expand Down Expand Up @@ -29,6 +32,7 @@ const config: NextConfig = {
},
authInterrupts: true,
},
outputFileTracingRoot: path.join(__dirname, '../../'),
outputFileTracingIncludes: {
'/api/**/*': ['./node_modules/.prisma/client/**/*'],
},
Expand Down Expand Up @@ -99,8 +103,7 @@ const config: NextConfig = {
skipTrailingSlashRedirect: true,
};

if (process.env.VERCEL !== '1') {
config.output = 'standalone';
}
// Always use standalone output
config.output = 'standalone';

export default config;
8 changes: 4 additions & 4 deletions apps/portal/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ ENV PORT=3001
ENV HOSTNAME="0.0.0.0"
ENV NODE_TLS_REJECT_UNAUTHORIZED=0

# Copy the complete standalone build from CodeBuild
COPY .next/standalone ./
# Copy the standalone build files (already prepared in container-build/)
COPY . ./

# Create non-root user for security
RUN addgroup -g 1001 -S nodejs && \
Expand All @@ -25,5 +25,5 @@ USER nextjs

EXPOSE 3001

# Use node to run the standalone server - handle monorepo structure
CMD ["sh", "-c", "if [ -f apps/portal/server.js ]; then node apps/portal/server.js; elif [ -f server.js ]; then node server.js; elif [ -f index.js ]; then node index.js; else echo 'No entry point found' && exit 1; fi"]
# Use node to run the standalone server
CMD ["node", "server.js"]
Loading
Loading