Skip to content

chore: standardize Docker setup for dev and production#279

Merged
RUKAYAT-CODER merged 1 commit into
rinafcode:mainfrom
TS-mfon:chore/docker-standardization
Apr 28, 2026
Merged

chore: standardize Docker setup for dev and production#279
RUKAYAT-CODER merged 1 commit into
rinafcode:mainfrom
TS-mfon:chore/docker-standardization

Conversation

@TS-mfon
Copy link
Copy Markdown
Contributor

@TS-mfon TS-mfon commented Apr 27, 2026

closes #239

Add multi-stage production Docker build, dedicated dev Dockerfile, compose configs, and deployment docs. Enable Next.js standalone output for optimized runtime images.

Summary

Related Issue

Closes #

Type of change

  • Feature
  • Bug fix
  • Chore / Refactor
  • Docs

Screenshots / Recording (if UI)

Testing

  • npm run type-check
  • npm run lint
  • npm run test
  • npm run build

Quality gate checklist

  • CI checks pass (Frontend CI)
  • At least 1–2 approvals (per branch protection rules)
  • Branch is up-to-date with the base branch
  • All conversations resolved
  • PR description includes Closes #<issue-number>

Add multi-stage production Docker build, dedicated dev Dockerfile, compose configs, and deployment docs. Enable Next.js standalone output for optimized runtime images.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 27, 2026 23:58
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Apr 27, 2026

@TS-mfon Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Standardizes Docker workflows for development and production, introducing multi-stage builds and documentation, and enabling Next.js standalone output to produce smaller/cleaner runtime images.

Changes:

  • Enable Next.js output: 'standalone' to support minimal production runtime images.
  • Add production multi-stage Dockerfile, dev Dockerfile.dev, and split Compose configs for prod vs dev.
  • Add .dockerignore and a deployment guide describing build/run/deploy flows.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
next.config.ts Enables standalone output required by the runtime image approach.
docker-compose.yml Adds production Compose service definition, runtime build target, and healthcheck.
docker-compose.dev.yml Adds dev overrides for hot-reload workflow using Dockerfile.dev.
Dockerfile.dev Defines a dev image with dependencies for next dev.
Dockerfile Adds multi-stage build with a minimal runtime stage using standalone output.
DOCKER_DEPLOYMENT.md Documents dev/prod Docker usage, healthchecks, and CI/CD suggestions.
.dockerignore Reduces build context size and avoids copying local artifacts into images.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker-compose.yml
context: .
dockerfile: Dockerfile
target: runtime
container_name: teachlink-app
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

container_name prevents scaling the service (e.g., docker compose up --scale app=3) and can cause name collisions across environments. Consider removing container_name and relying on Compose’s autogenerated names, especially since the docs discuss running multiple instances.

Suggested change
container_name: teachlink-app

Copilot uses AI. Check for mistakes.
Comment thread docker-compose.yml
Comment on lines +33 to +35

volumes:
logs:
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A named volume logs: is declared but the service mounts a bind mount (./logs:/app/logs) instead, so the logs volume is unused. Either remove the unused named volume declaration or switch the service to use logs:/app/logs (and update the docs accordingly).

Suggested change
volumes:
logs:

Copilot uses AI. Check for mistakes.
Comment thread Dockerfile
Comment on lines +14 to +17
# Run build-time validations
RUN npm run check-locales && npm run check-i18n

# Build the Next.js application (lint is handled separately in CI)
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The builder stage runs check-locales/check-i18n explicitly, but npm run build already triggers the prebuild script (which also runs these checks). This duplicates work during Docker builds; consider removing the explicit checks here or adjusting scripts so the validations run only once.

Suggested change
# Run build-time validations
RUN npm run check-locales && npm run check-i18n
# Build the Next.js application (lint is handled separately in CI)
# Build the Next.js application (lint is handled separately in CI)
# `npm run build` also runs the npm `prebuild` lifecycle, which performs
# the build-time validations without duplicating work in the Docker build.

Copilot uses AI. Check for mistakes.
Comment thread Dockerfile
EXPOSE 3000

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image-level HEALTHCHECK hits /api/health, but the repository doesn’t currently include that route under src/app/api. This will cause the container to be marked unhealthy in production. Either add the endpoint or update the healthcheck to a route that exists.

Suggested change
CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"
CMD node -e "const net = require('net'); const socket = net.connect({ host: '127.0.0.1', port: 3000 }, () => { socket.end(); process.exit(0); }); socket.setTimeout(2000); socket.on('timeout', () => { socket.destroy(); process.exit(1); }); socket.on('error', () => process.exit(1));"

Copilot uses AI. Check for mistakes.
Comment thread DOCKER_DEPLOYMENT.md
Comment on lines +118 to +127
The container includes a built-in health check that calls `/api/health`.

Ensure your app has this endpoint:

```typescript
// src/app/api/health/route.ts
export async function GET() {
return Response.json({ status: 'healthy' }, { status: 200 });
}
```
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This health check section references /api/health and shows an example implementation at src/app/api/health/route.ts, but that route doesn’t exist in the current codebase. Since the Dockerfile/compose healthchecks depend on it, consider adding the route as part of this PR or documenting the exact existing endpoint to use instead.

Copilot uses AI. Check for mistakes.
Comment thread DOCKER_DEPLOYMENT.md
Comment on lines +158 to +174
```yaml
# docker-compose.yml example
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- app

app:
build: .
deploy:
replicas: 3
```
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scaling example uses deploy.replicas, which is only honored by Docker Swarm; docker compose ignores deploy in non-swarm mode. To avoid misleading readers, either document swarm explicitly or switch the example to docker compose up --scale app=3 (and drop container_name in compose).

Copilot uses AI. Check for mistakes.
Comment thread docker-compose.yml
Comment on lines +16 to +21
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compose healthcheck calls http://localhost:3000/api/health, but there is no /api/health route in src/app/api (and no other match in the repo). As-is, containers will be reported unhealthy. Either add the endpoint (e.g., src/app/api/health/route.ts) or change the healthcheck to an existing path.

Copilot uses AI. Check for mistakes.
@RUKAYAT-CODER RUKAYAT-CODER merged commit 85ad0ac into rinafcode:main Apr 28, 2026
4 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docker Deployment Configuration

3 participants