Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored DockerFile to improve efficiency #2607

Merged

Conversation

adithyanotfound
Copy link

@adithyanotfound adithyanotfound commented Dec 5, 2024

What kind of change does this PR introduce?

Refactoring

Issue Number:

Fixes #2596

Did you add tests for your changes?

Not required

Snapshots/Videos:

CPU and RAM utilization

Screenshot 2024-12-05 at 9 18 20 PM

Docker image size

Screenshot 2024-12-05 at 11 07 07 PM

Summary

  1. Reduce Docker image size from 1.75gb to 66mb
  2. Improved performance of app using docker
  3. Used nginx and multi-stage build for scaling the app and reduce image size

Does this PR introduce a breaking change?

Yes

Other information

TO-DO

  1. Add ssl certificate to nginx.conf
  2. Configure nginx reverse proxy properly to handle api requests

Have you read the contributing guide?

Yes

Summary by CodeRabbit

  • New Features

    • Introduced a new service configuration in Docker for streamlined application deployment.
    • Added a new Nginx configuration to enhance server performance and security.
  • Bug Fixes

    • Improved health check for the application to ensure better reliability.
  • Chores

    • Updated dependencies in the project to maintain compatibility and improve functionality.
    • Added entries to .eslintignore to exclude specific files from linting.

Copy link

coderabbitai bot commented Dec 5, 2024

Walkthrough

The pull request introduces several modifications primarily focused on optimizing the Docker configuration for the Talawa-Admin application. Key changes include updates to the Dockerfile, the addition of a new service in docker-compose.yml, and the introduction of a new Nginx configuration file. Additionally, the .eslintignore file is updated to exclude specific files from linting. These changes aim to enhance resource utilization and streamline the build and production processes.

Changes

File Change Summary
.eslintignore Added entries: docker-compose.yml, Dockerfile, nginx.conf to be excluded from ESLint linting.
Dockerfile Renamed build stage to builder, changed working directory, set NODE_ENV to production, updated commands, adjusted exposed port, and added Nginx configuration copy.
docker-compose.yml Introduced a new service app, defined environment variables, and added a health check for the service.
package.json Removed customize-cra, added vite-plugin-svgr and cross-env, modified prepare script for environment handling.
config/docker/setup/nginx.conf Added a new Nginx configuration file with server block, security headers, and proxy settings for GraphQL.

Assessment against linked issues

Objective Addressed Explanation
Lower CPU and RAM utilization by at least 75% for Docker configurations (#2596)
Ensure acceptable usage information for running Talawa-Admin on mid-range laptops (#2596) It is unclear if performance metrics are provided.

Possibly related PRs

Suggested labels

ignore-sensitive-files-pr, test

Suggested reviewers

  • palisadoes
  • varshith257
  • pranshugupta54

🐰 "In a world of code and Docker dreams,
We hop along with our clever schemes.
With Nginx set and resources trimmed,
Talawa-Admin, our hopes are brimmed!
Let’s build and run, oh what a sight,
Hopping through code, everything feels right!" 🐇


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 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.

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.

Copy link

github-actions bot commented Dec 5, 2024

Our Pull Request Approval Process

Thanks for contributing!

Testing Your Code

Remember, your PRs won't be reviewed until these criteria are met:

  1. We don't merge PRs with poor code quality.
    1. Follow coding best practices such that CodeRabbit.ai approves your PR.
  2. We don't merge PRs with failed tests.
    1. When tests fail, click on the Details link to learn more.
    2. Write sufficient tests for your changes (CodeCov Patch Test). Your testing level must be better than the target threshold of the repository
    3. Tests may fail if you edit sensitive files. Ask to add the ignore-sensitive-files-pr label if the edits are necessary.
  3. We cannot merge PRs with conflicting files. These must be fixed.

Our policies make our code better.

Reviewers

Do not assign reviewers. Our Queue Monitors will review your PR and assign them.
When your PR has been assigned reviewers contact them to get your code reviewed and approved via:

  1. comments in this PR or
  2. our slack channel

Reviewing Your Code

Your reviewer(s) will have the following roles:

  1. arbitrators of future discussions with other contributors about the validity of your changes
  2. point of contact for evaluating the validity of your work
  3. person who verifies matching issues by others that should be closed.
  4. person who gives general guidance in fixing your tests

CONTRIBUTING.md

Read our CONTRIBUTING.md file. Most importantly:

  1. PRs with issues not assigned to you will be closed by the reviewer
  2. Fix the first comment in the PR so that each issue listed automatically closes

Other

  1. 🎯 Please be considerate of our volunteers' time. Contacting the person who assigned the reviewers is not advised unless they ask for your input. Do not @ the person who did the assignment otherwise.
  2. Read the CONTRIBUTING.md file make

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (2)
nginx.conf (1)

1-27: Add SSL configuration and performance optimizations

The configuration needs SSL support and performance optimizations for production use.

Add the following configurations:

# At the top of the file
limit_req_zone $binary_remote_addr zone=graphql:10m rate=10r/s;

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # Modern configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # HSTS (uncomment if you're sure)
    # add_header Strict-Transport-Security "max-age=63072000" always;

    # Optimize file serving
    location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
        expires 1M;
        access_log off;
        add_header Cache-Control "public";
    }
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com;
    return 301 https://$server_name$request_uri;
}
package.json (1)

90-90: LGTM! Improved Docker build efficiency.

The modified prepare script now skips husky installation in production environments. This change:

  • Reduces Docker image size by preventing git hooks installation
  • Aligns with the PR's goal of optimizing Docker resource usage
  • Maintains development workflow while improving production builds

Consider documenting this optimization in the Dockerfile or deployment docs to help other contributors understand the importance of this change.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f9e10b8 and a88ead5.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • .eslintignore (1 hunks)
  • Dockerfile (1 hunks)
  • docker-compose.yml (1 hunks)
  • nginx.conf (1 hunks)
  • package.json (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .eslintignore

docker-compose.yml Outdated Show resolved Hide resolved
docker-compose.yml Outdated Show resolved Hide resolved
Dockerfile Outdated Show resolved Hide resolved
Dockerfile Outdated Show resolved Hide resolved
nginx.conf Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
Copy link

codecov bot commented Dec 5, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 83.78%. Comparing base (f9e10b8) to head (c1ed0f9).
Report is 1 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff              @@
##           develop    #2607       +/-   ##
============================================
- Coverage    95.82%   83.78%   -12.04%     
============================================
  Files          295      312       +17     
  Lines         7037     8117     +1080     
  Branches      1520     1776      +256     
============================================
+ Hits          6743     6801       +58     
- Misses          98     1177     +1079     
+ Partials       196      139       -57     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
docker-compose.yml (1)

7-12: Document environment variables

Please add documentation for the required environment variables, including:

  • Format and example values
  • Whether they are required or optional
  • Any default values

Consider creating a .env.example file with commented documentation.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 617c2e0 and a601832.

📒 Files selected for processing (3)
  • Dockerfile (1 hunks)
  • docker-compose.yml (1 hunks)
  • package.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🧰 Additional context used
📓 Learnings (1)
Dockerfile (1)
Learnt from: adithyanotfound
PR: PalisadoesFoundation/talawa-admin#2607
File: Dockerfile:4-12
Timestamp: 2024-12-06T03:20:57.597Z
Learning: The project uses npm instead of yarn.
🔇 Additional comments (6)
Dockerfile (4)

1-3: LGTM! Good choice of base image

Using node:20.10.0-alpine as the builder base image is optimal for reducing image size while maintaining reproducibility.


10-13: LGTM! Proper build configuration

Setting NODE_ENV=production before build is correct for optimizing the build process.


4-9: 🛠️ Refactor suggestion

Optimize dependency installation and file copying

Several optimizations can improve build efficiency and reduce image size:

WORKDIR /talawa-admin

COPY package*.json ./
-RUN npm install
+RUN npm ci --production=false

-COPY . .
+COPY package-lock.json ./
+COPY public ./public
+COPY src ./src

Also, create a .dockerignore file:

node_modules
npm-debug.log*
.git
.gitignore
.env*
README.md

Likely invalid or redundant comment.


14-22: ⚠️ Potential issue

Enhance security and monitoring in production stage

  1. The production stage should run with a non-root user for better security
  2. Add basic health check configuration to nginx
FROM nginx:1.27.3-alpine AS production

ENV NODE_ENV=production

+RUN addgroup -S appgroup && adduser -S appuser -G appgroup
+
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /talawa-admin/build /usr/share/nginx/html
+
+RUN chown -R appuser:appgroup /usr/share/nginx/html /var/cache/nginx /var/run /var/log/nginx
+
+# Add health check location to nginx config
+RUN echo "location /health { return 200 'healthy\n'; }" >> /etc/nginx/conf.d/default.conf
+
+USER appuser

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Likely invalid or redundant comment.

docker-compose.yml (2)

1-6: LGTM! Good service configuration

The service configuration with dynamic port mapping provides good flexibility for different environments.


13-18: 🛠️ Refactor suggestion

Add resource limits to prevent excessive usage

Given the PR's objective to improve resource utilization, add resource limits:

    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:80']
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped
+    deploy:
+      resources:
+        limits:
+          cpus: '0.50'
+          memory: 512M
+        reservations:
+          cpus: '0.25'
+          memory: 256M

Likely invalid or redundant comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (2)
nginx.conf (2)

8-10: Add performance optimizations for static content

The root location block should include caching and compression configurations for better performance.

Consider adding these optimizations:

     location / {
+        # Enable compression
+        gzip on;
+        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
+        
+        # Cache static assets
+        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
+            expires 30d;
+            add_header Cache-Control "public, no-transform";
+        }
+        
         try_files $uri /index.html;
     }

32-32: Enhance error handling and logging

The current error handling is minimal. Consider adding comprehensive error pages and logging configuration.

Add these configurations:

+    # Error pages
     error_page 404 /index.html;
+    error_page 500 502 503 504 /50x.html;
+    
+    # Logging
+    access_log /var/log/nginx/talawa_admin_access.log combined buffer=512k flush=1m;
+    error_log /var/log/nginx/talawa_admin_error.log warn;
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a601832 and ec767e7.

📒 Files selected for processing (1)
  • nginx.conf (1 hunks)
🔇 Additional comments (2)
nginx.conf (2)

12-30: 🛠️ Refactor suggestion

Add timeout and rate limiting configurations

While security headers are in place, the GraphQL proxy needs additional protections:

Add these configurations:

     location /graphql/ {
+        # Timeouts
+        proxy_connect_timeout 60;
+        proxy_send_timeout 60;
+        proxy_read_timeout 60;
+        
+        # Rate limiting zone (add at http context)
+        # limit_req_zone $binary_remote_addr zone=graphql:10m rate=5r/s;
+        # Apply rate limiting
+        limit_req zone=graphql burst=10 nodelay;
+        
         proxy_pass http://127.0.0.1:4000/graphql/;
         # Existing configuration...
     }

1-34: Verify Docker integration and environment setup

Let's ensure the Nginx configuration aligns with the Docker setup and environment variables.

✅ Verification successful

Let me gather more information about the environment setup and Docker configuration.


Docker integration and Nginx configuration are properly set up

The verification shows that:

  • Nginx configuration is correctly integrated with Docker setup
  • The Dockerfile properly copies the nginx.conf to the correct location
  • Static files are correctly mounted from the build output
  • Environment variables are properly handled through the build process

No issues found with the current setup. The configuration follows standard practices for a React application served through Nginx in a Docker container.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify Docker integration and environment setup

# Check Docker-related files for nginx configuration
echo "Checking Dockerfile for nginx setup..."
rg -A 5 "nginx.conf" 

echo "Checking docker-compose for volume mounts and env variables..."
rg -A 10 "nginx" docker-compose.yml

echo "Checking for environment variable definitions..."
fd -t f ".env"

Length of output: 726


Script:

#!/bin/bash
# Check the content of environment-related files and Docker setup

# Check environment setup files
echo "Checking environment setup files..."
cat src/setup/checkEnvFile/checkEnvFile.ts

# Check Dockerfile content
echo -e "\nChecking Dockerfile content..."
cat Dockerfile

# Check if there are any other nginx config files
echo -e "\nChecking for additional nginx configs..."
fd -t f nginx

Length of output: 1254

nginx.conf Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
nginx.conf (2)

5-14: Enable SSL and configure HTTPS

The SSL configuration is currently commented out. As per the PR objectives, enabling HTTPS is crucial for secure communication. Consider uncommenting and properly configuring the SSL settings.

If you need assistance setting up SSL certificates and configuring HTTPS, I can help generate the necessary configuration steps.


23-23: Enable and configure the Content-Security-Policy header

To enhance security against cross-site scripting and other attacks, consider enabling the Content-Security-Policy header.

Apply this diff to enable the header:

-    # add_header Content-Security-Policy "default-src 'self'; connect-src 'self' https://your-graphql-server.com;";
+    add_header Content-Security-Policy "default-src 'self'; connect-src 'self' https://your-graphql-server.com;";
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ec767e7 and d3d51fa.

📒 Files selected for processing (1)
  • nginx.conf (1 hunks)
🔇 Additional comments (3)
nginx.conf (3)

3-3: 🛠️ Refactor suggestion

Parameterize the server_name directive via an environment variable

Currently, the server_name is hard-coded to domain.com. To make the configuration adaptable across different environments, consider parameterizing it.

Apply this diff to parameterize the server_name:

-    server_name domain.com;
+    server_name ${NGINX_SERVER_NAME};

32-32: 🛠️ Refactor suggestion

Parameterize the proxy_pass URL

The proxy_pass directive is hard-coded to http://127.0.0.1:4000/graphql/. To allow flexibility for different back-end services or environments, consider parameterizing this value.

Apply this diff to parameterize the proxy_pass URL:

-        proxy_pass http://127.0.0.1:4000/graphql/;
+        proxy_pass ${GRAPHQL_BACKEND_URL};

33-33: 🛠️ Refactor suggestion

Parameterize the Access-Control-Allow-Origin header

The Access-Control-Allow-Origin header is set to a specific domain. To accommodate different front-end domains or environments, consider parameterizing this value.

Apply this diff to parameterize the header:

-        add_header Access-Control-Allow-Origin https://your-react-app-domain.com;
+        add_header Access-Control-Allow-Origin ${ALLOWED_ORIGINS};

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
Copy link
Contributor

@palisadoes palisadoes left a comment

Choose a reason for hiding this comment

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

Please move the nginx.conf to a config/docker/setup directory so that it is very clearly a part of the setup / installation process. That way it is less likely to be deleted or edited in error

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d3d51fa and c1ed0f9.

📒 Files selected for processing (2)
  • Dockerfile (1 hunks)
  • config/docker/setup/nginx.conf (1 hunks)
🧰 Additional context used
📓 Learnings (1)
Dockerfile (1)
Learnt from: adithyanotfound
PR: PalisadoesFoundation/talawa-admin#2607
File: Dockerfile:4-12
Timestamp: 2024-12-06T03:20:57.597Z
Learning: The project uses npm instead of yarn.
🔇 Additional comments (5)
Dockerfile (3)

1-3: Good choice of base image and stage naming!

Using the Alpine-based Node.js image and proper stage naming helps minimize the image size.


14-18: Add non-root user for production stage

Running nginx as root in production is a security risk. Consider adding a non-root user.


4-13: 🛠️ Refactor suggestion

Optimize build process for better efficiency

Several optimizations can improve build time and reduce image size:

  1. Use npm ci instead of npm install for reproducible builds
  2. Copy only necessary files
  3. Add .dockerignore to exclude unnecessary files
WORKDIR /talawa-admin

COPY package*.json ./
-RUN npm install
+RUN npm ci --production=false

-COPY . .
+COPY public ./public
+COPY src ./src
+COPY package-lock.json ./

ENV NODE_ENV=production

Create a .dockerignore file:

node_modules
npm-debug.log*
.git
.gitignore
.env*
README.md
coverage
.vscode

Likely invalid or redundant comment.

config/docker/setup/nginx.conf (2)

20-22: LGTM! Correct configuration for Single Page Application

The location block properly handles static file serving with fallback to index.html.


40-48: LGTM! Good compression and error handling configuration

The gzip compression settings and error handling are well configured for optimal performance.

Dockerfile Show resolved Hide resolved
config/docker/setup/nginx.conf Show resolved Hide resolved
config/docker/setup/nginx.conf Show resolved Hide resolved
config/docker/setup/nginx.conf Show resolved Hide resolved
@palisadoes palisadoes merged commit 4bef093 into PalisadoesFoundation:develop Dec 7, 2024
11 of 14 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.

2 participants