Zero icon indicating copy to clipboard operation
Zero copied to clipboard

feat: multi-stage docker image, migrations container, 96.35% smaller

Open adiologydev opened this issue 7 months ago β€’ 6 comments

Description

This PR introduces an optimised multi-stage Docker image for the main app and an additional image + container to run migrations every time a new version is deployed.

All the images are built as context in the Docker Compose file to avoid requiring external registries.

  • 96.35% Image Size Reduction (5.91GB to 216MB) on the main container.
  • Avoids the need for an env file when deploying via docker since they can now be applied via CLI.
  • Removes exposed ports since they're no longer required besides the main app.
  • Additional migrations image and container to stay up-to-date per deployment.
  • Code cleanup to better organize dockerfiles.
  • Healthchecks on every container.

Type of Change

Please delete options that are not relevant.

  • [ ] πŸ› Bug fix (non-breaking change which fixes an issue)
  • [x] ✨ New feature (non-breaking change which adds functionality)
  • [ ] πŸ’₯ Breaking change (fix or feature with breaking changes)
  • [ ] πŸ“ Documentation update
  • [ ] 🎨 UI/UX improvement
  • [ ] πŸ”’ Security enhancement
  • [x] ⚑ Performance improvement

Areas Affected

Please check all that apply:

  • [ ] Email Integration (Gmail, IMAP, etc.)
  • [ ] User Interface/Experience
  • [ ] Authentication/Authorization
  • [ ] Data Storage/Management
  • [ ] API Endpoints
  • [ ] Documentation
  • [ ] Testing Infrastructure
  • [ ] Development Workflow
  • [x] Deployment/Infrastructure

Testing Done

Describe the tests you've done:

  • [ ] Unit tests added/updated
  • [ ] Integration tests added/updated
  • [x] Manual testing performed
  • [ ] Cross-browser testing (if UI changes)
  • [ ] Mobile responsiveness verified (if UI changes)

Checklist

  • [x] I have read the CONTRIBUTING document
  • [x] My code follows the project's style guidelines
  • [x] I have performed a self-review of my code
  • [x] I have commented my code, particularly in complex areas
  • [ ] I have updated the documentation
  • [ ] My changes generate no new warnings
  • [x] I have added tests that prove my fix/feature works
  • [ ] All tests pass locally
  • [ ] Any dependent changes are merged and published

Screenshots/Recordings

image


By submitting this pull request, I confirm that my contribution is made under the terms of the project's license.

Summary by CodeRabbit

  • New Features

    • Added new services for application runtime and database migrations in the container orchestration setup.
    • Introduced health checks for improved service monitoring and reliability.
    • Added multi-stage Dockerfiles for optimized application and database container builds.
  • Chores

    • Updated ignore rules to exclude unnecessary files from Docker build contexts, reducing image size and build time.
    • Switched to a lighter database image for improved efficiency.
    • Enhanced environment variable management with sensible defaults.

adiologydev avatar May 04 '25 19:05 adiologydev

@adiologydev is attempting to deploy a commit to the Zero Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar May 04 '25 19:05 vercel[bot]

[!IMPORTANT]

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This set of changes introduces a new multi-stage Docker build system for a Bun-based Next.js application, replacing the previous Dockerfile with a more modular approach. The new Dockerfiles are organized under docker/app and docker/db for application and database components, respectively. The docker-compose.yaml is extensively revised to add new services for the application and database migrations, update existing services with healthchecks, and improve environment variable handling. The .dockerignore file is added to optimize Docker build contexts by excluding unnecessary files and directories. Additionally, the Next.js configuration in the mail app is updated to conditionally enable standalone output for Docker builds.

Changes

File(s) Change Summary
.dockerignore New file to exclude dependency directories, build outputs, environment files, logs, IDE configs, and other unnecessary files from Docker build contexts.
Dockerfile Removed the original Dockerfile for the Bun-based Next.js application.
apps/mail/next.config.ts Added conditional output: 'standalone' property to Next.js config, enabled when DOCKER_BUILD env variable is set.
docker-compose.yaml Major revision: added zero (app) and migrations services, updated db, valkey, and upstash-proxy services with healthchecks and improved env handling, removed explicit container names and some port mappings, switched db image to Alpine, and declared named volumes.
docker/app/Dockerfile New multi-stage Dockerfile for building and running the Bun-based Next.js app, with separate stages for dependencies, build, and runtime, using non-root user and standalone Next.js output.
docker/db/Dockerfile New multi-stage Dockerfile for database/migrations, separating dependency installation and runtime, and setting up environment variables for database connection.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant Docker as Docker Build System
    participant App as Bun Next.js App
    participant DB as Database (Postgres)
    participant Migrate as Migrations Service

    Dev->>Docker: docker-compose up
    Docker->>DB: Start Postgres container
    Docker->>DB: Run healthcheck (pg_isready)
    Docker->>Migrate: Start migrations container (runs bun run db:migrate)
    Migrate->>DB: Apply migrations
    Docker->>App: Build App image (multi-stage Dockerfile)
    App->>App: Run build (bun run build, output standalone)
    Docker->>App: Start App container
    App->>DB: Connect to database
    App->>App: Expose port 3000, serve requests

Possibly related PRs

  • Mail-0/Zero#591: Replaced the original single Dockerfile with a new multi-stage Dockerfile at docker/app/Dockerfile, directly evolving the previous Docker build setup.

Suggested reviewers

  • MrgSub

Poem

In Docker fields where containers grow,
A rabbit hops where new configs flow.
Compose now sings with healthchecks bright,
And Bun builds apps through day and night.
With .dockerignore, our loads are lightβ€”
Standalone, secure, and oh so neat,
This Docker dance is quite a feat!

πŸ‡βœ¨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share
πŸͺ§ Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

coderabbitai[bot] avatar May 04 '25 19:05 coderabbitai[bot]

Can you separate out the deploy docker-compose from the db and redis, While I am developing locally I don't need to build the app. You can do a docker-compose.yaml for services used in dev and a docker-compose.deploy.yaml for deployment

BlankParticle avatar May 05 '25 03:05 BlankParticle

Hey @adiologydev I just tested it!

The Dockerfile is working fine but compose is not.

The app services depends on upstash-proxy, and the upstash-proxy is failing the healthcheck due to curl not present in the upstash-proxy container.

Could you please update the CMD on upstash-proxy service on the compose (or do something to make the health check pass)?

image

image

ShadowArcanist avatar May 05 '25 04:05 ShadowArcanist

All resolved, ready for merge. Had an old upstream merge before causing conflict.

adiologydev avatar May 06 '25 23:05 adiologydev

Pushing an update with seperate backend soon

adiologydev avatar May 12 '25 21:05 adiologydev