-
-
Notifications
You must be signed in to change notification settings - Fork 283
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
chore: setup Dockerfile & Docker Compose for project-wide testing #1465
base: master
Are you sure you want to change the base?
chore: setup Dockerfile & Docker Compose for project-wide testing #1465
Conversation
|
WalkthroughThis pull request introduces new Docker configuration files to streamline testing. A Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant DC as Docker Compose
participant Container as Docker Container
Dev->>DC: Run 'docker compose up'
DC->>Container: Build image using Dockerfile
Container->>Container: Execute npm ci & npm test
Container-->>DC: Return test results
DC-->>Dev: Display test results
Assessment against linked issues
Suggested labels
Suggested reviewers
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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
🧹 Nitpick comments (2)
docker-compose.yaml (1)
1-7
: Docker Compose Service Configuration
Thetest
service is clearly defined and aligns with the new Dockerized testing workflow. A couple of suggestions:
- Verify Compatibility: Ensure that the
pull_policy: build
setting is supported by the specific Docker Compose version you are using. In some contexts, this might need to be defined within abuild
block or adapted to the expected schema.- Context Clarity: Since both
image
andbuild
are provided, double-check that the intended build process is triggered as expected and that there’s no ambiguity in which definition takes precedence.Development.md (1)
53-53
: Clarification Note for Docker Testing
The additional note on line 53 clearly explains that tests run in a clean environment with freshly installed dependencies. This is useful for user understanding. Consider adding an optional troubleshooting tip or reference link for users who might not be familiar with Docker environments.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.dockerignore
(1 hunks)Development.md
(2 hunks)Dockerfile
(1 hunks)docker-compose.yaml
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Test generator as dependency with Node 18
- GitHub Check: Test generator as dependency with Node 20
🔇 Additional comments (4)
.dockerignore (1)
1-38
: .dockerignore File Review
The patterns in the.dockerignore
file are comprehensive, covering common Node.js artifacts (likenode_modules
, log files, and environment files), build artifacts, Git files, IDE configurations, OS-generated files, and test outputs. This will help keep the Docker build context lean and efficient.Dockerfile (1)
1-39
: Multi-Stage Dockerfile for Optimized Testing
- The multi-stage build is well-structured: the
installer
stage usesturbo prune
to extract only the necessary package files and source code, which is a smart technique for reducing build context size and enhancing caching.- Using
npm ci
in thefinal
stage ensures a clean, reproducible installation of dependencies based solely on the pruned files.- The final command,
CMD ["npm", "test"]
, aligns perfectly with the intended testing workflow.
Overall, this Dockerfile is well-designed to balance build efficiency with the need for a consistent testing environment.Development.md (2)
50-51
: Simplified Docker Compose Command Update
The change to usedocker compose up
simplifies the testing process and leverages the new service configurations. This reduces complexity for users who previously had to deal with more cumbersomedocker run
commands.
180-180
: Additional Debugging Guidance
Encouraging users to open an issue if persistent problems arise is a good proactive step to support troubleshooting and community engagement. Ensure that your issue template is prepared to capture the necessary details for Docker-related problems.
Regarding SonarCube notes, I believe the notes aren't significant due to this Docker workflow being used only for testing, and not production. |
@derberg What do you think about the new dev workflow? |
the problem is that SonarCloud report is red and blocking merging and actually, Dockerfile is not only used by us for testing, it is also used by people that still use |
nevermind about my comment about Dockerfile, now I get you don't want to use https://github.com/asyncapi/generator/blob/master/apps/generator/Dockerfile but have one for entire monorepo for dev purpose only |
There was a problem hiding this 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
🧹 Nitpick comments (2)
Dockerfile (2)
7-10
: Installer Stage – Copying Project Files
The installer stage copies the entire project into the container viaCOPY . .
, preparing for subsequent pruning. Make sure your.dockerignore
is correctly configured (e.g., to excludenode_modules
and other non-essential files) so that the build context stays lean.
12-19
: Turbo Prune Optimization
The commandRUN npx [email protected] prune @asyncapi/generator @asyncapi/template-js-websocket-client @asyncapi/generator-components --docker --out-dir /out
effectively reduces the project to just the needed
package.json
files and related artifacts. It would be beneficial to document (perhaps via an inline comment or in project documentation) why usingnpx
here is sufficient—clarifying that it auto-installs the required version when missing—and to ensure that the pinned version remains compatible with future changes.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Dockerfile
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Test generator as dependency with Node 18
- GitHub Check: Test generator as dependency with Node 20
- GitHub Check: Test NodeJS PR - macos-13
- GitHub Check: Test NodeJS PR - windows-latest
🔇 Additional comments (5)
Dockerfile (5)
1-3
: Base Image and Working Directory Setup
The Dockerfile usesnode:18-alpine
as a slim base image and sets the working directory to/app
, which is clear and follows best practices.
23-30
: Dependency Installation and Caching Strategy
The second stage copies over the prunedpackage.json
andpackage-lock.json
files, then runsnpm ci --ignore-scripts
. This approach leverages Docker caching to ensure faster dependency installation while maintaining consistency via the lock file.
32-34
: Copying the Remaining Source Code
Copying the full source from/out/full/
ensures that only the essential files—filtered through the prune process—are included in the final image. This helps in keeping the image size minimal and aligns well with the caching strategy.
35-36
: Setting Correct File Permissions
Changing the ownership of/app
to thenode
user viaRUN chown -R node:node /app
is a solid security practice, ensuring that the application does not run as root.
38-41
: Non-Root Execution and Default Command Configuration
Switching to the non-rootnode
user and setting the default command tonpm test
are both in line with the PR objectives. These steps simplify the testing workflow while enhancing container security.
Co-authored-by: Lukasz Gornicki <[email protected]>
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Dockerfile
(1 hunks)
🧰 Additional context used
🪛 Hadolint (2.12.0)
Dockerfile
[error] 10-10: COPY with more than 2 arguments requires the last argument to end with /
(DL3021)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Test generator as dependency with Node 20
- GitHub Check: Test generator as dependency with Node 18
🔇 Additional comments (8)
Dockerfile (8)
1-4
: Base Stage Initialization:
The base image is properly set to Node 18 on Alpine, and the working directory is configured as/app
. This establishes a solid foundation for the multi-stage build.
12-20
: Turbo Prune Command Execution:
TheRUN npx [email protected] prune ...
command efficiently prunes the project down to only the necessarypackage.json
files and source code, optimizing the Docker caching mechanism. Just ensure that the package names and the turbo version remain up to date as the project evolves.
21-28
: Dependency Setup in the Final Stage:
Copying the prunedpackage.json
files andpackage-lock.json
from the installer stage is correctly implemented. This approach leverages Docker caching effectively and minimizes reinstallation overhead during dependency installation.
29-31
: Optimized Dependency Installation:
Usingnpm ci --ignore-scripts
ensures a clean and reproducible installation of dependencies from the copied package files. This not only speeds up builds but also adds a layer of security by ignoring unwanted scripts during installation.
32-34
: Copying Full Source Code:
The commandCOPY --from=installer /out/full/ .
successfully brings over the full source code after dependencies are installed. This separation of concerns aids in efficient caching and clear organization of the build process.
35-37
: File Ownership Adjustment:
TheRUN chown -R node:node /app
command correctly changes the ownership of the/app
directory to thenode
user, ensuring appropriate file permissions when running the container as a non-root user.
38-39
: Non-Root User Execution:
The directiveUSER node
is an excellent security best practice, enforcing that the container runs with non-root privileges.
41-42
: Default Command Configuration:
SettingCMD ["npm", "test"]
as the default command aligns perfectly with the project’s testing objectives. This ensures that tests are run by default, which is key to the streamlined Dockerized testing workflow.
There was a problem hiding this 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
🧹 Nitpick comments (1)
Dockerfile (1)
9-11
: Enhance COPY Command with Inline NOSONAR and Trailing Slash
The COPY command is currently split from its NOSONAR directive and lacks a trailing slash on the destination directory. To satisfy Hadolint rule DL3021 and ensure Sonar warnings are properly suppressed, consider combining them as follows:-# NOSONAR -COPY . . +COPY . ./ // NOSONARThis update explicitly attaches the NOSONAR directive to the command and clarifies the destination directory structure.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Dockerfile
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Test generator as dependency with Node 18
- GitHub Check: Test generator as dependency with Node 20
- GitHub Check: Test NodeJS PR - windows-latest
🔇 Additional comments (4)
Dockerfile (4)
1-3
: Base Image and Working Directory Setup
The Dockerfile correctly starts with a lightweight Node.js 18 Alpine base image and properly sets the working directory to/app
. This provides a solid base for subsequent build stages.
20-20
: Prune Command with NPX for Package Optimization
Usingnpx [email protected] prune ...
effectively prunes the project to the minimal required files for dependency management. NPX will automatically handle the installation if the specified version isn’t already available. Just ensure that the fixed version remains in line with project standards over time.
26-31
: Optimized Dependency Installation for Caching
By copying only the prunedpackage.json
files (and the correspondingpackage-lock.json
) before runningnpm ci --ignore-scripts
, the Dockerfile smartly leverages caching to avoid redundant installations. This approach improves build speed and consistency.
33-42
: Ensuring Secure and Consistent Final Image
The final build stage is well-structured: it copies the complete source code, adjusts the ownership to the non-rootnode
user, and sets the default command to runnpm test
. Running the container as a non-root user enhances security, and coupling this with the testing command aligns with the Dockerized testing workflow goals.
|
There was a problem hiding this 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
🧹 Nitpick comments (3)
Dockerfile (3)
1-3
: Solid Base Image and Workdir Setup.
Lines 1–3 correctly use a lightweightnode:18-alpine
image and set the working directory to/app
. This establishes a proper base for subsequent stages. Optional: Consider setting an environment variable (for example,ENV NODE_ENV test
) if tests need to run under a specific environment.
15-22
: Effective Use of Turbo Prune for Monorepo Organization.
Lines 15–22 use theRUN npx [email protected] prune ...
command to slim down the project to only the necessary package-related files. This is a smart approach to leverage caching by isolating the dependency files. Remember that the list of package names is hardcoded; ensure you update these as your monorepo evolves.
41-44
: Adherence to Security Best Practices with Non-root User and Clear Default Command.
Lines 41–44 switch the running user tonode
(ensuring the container does not run as root) and set the default command to run tests viaCMD ["npm", "test"]
. This matches the PR’s testing focus. Optionally, setting an explicit environment variable (such asENV NODE_ENV test
) here could further clarify the container’s role.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Dockerfile
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
Dockerfile (1)
Learnt from: nightknighto
PR: asyncapi/generator#1465
File: Dockerfile:0-0
Timestamp: 2025-04-09T14:19:06.716Z
Learning: In Dockerfiles, comments must begin with the `#` character and must be on their own line. Inline comments (like `// NOSONAR`) are not supported in Dockerfile syntax and will be interpreted as part of the command. SonarQube suppressions in Dockerfiles should be done using a separate comment line with the `#` prefix.
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Test generator as dependency with Node 20
- GitHub Check: Test generator as dependency with Node 18
- GitHub Check: Test NodeJS PR - windows-latest
🔇 Additional comments (3)
Dockerfile (3)
5-13
: Clear and Commented Installer Stage Initialization.
Lines 5–13 articulate the intent behind the installer stage. The comments explain why the entire project is copied (i.e. for the subsequentturbo prune
process) and underscore that this is primarily for local development and testing. Just ensure that a corresponding.dockerignore
file is in place to exclude unnecessary files (such asnode_modules
) and speed up the build.
24-31
: Optimized Dependency Extraction in Final Stage – Part 1.
Lines 24–31 transition into the final build stage. Copying the prunedpackage.json
files andpackage-lock.json
before runningnpm ci --ignore-scripts
is an effective use of caching that minimizes unnecessary reinstallation of dependencies when unrelated source files change.
32-39
: Efficient Final Stage Execution and Security Enhancements.
Lines 32–39 execute the dependency installation and then copy over the remaining source code. Runningnpm ci --ignore-scripts
guarantees a clean, reproducible dependency tree, and copying the rest of the source afterward leverages cache layers effectively. Thechown -R node:node /app
command on line 39 is a good security practice to ensure proper file ownership.
Description
This PR improves the Dockerized testing workflow by simplifying the command and making use of caching.
docker compose up
.Related issue(s)
Fixes #1423
Screenshots
...
js
andmd
files then re-tested.Notice:
RUN npm ci
is cached, while changed files were only reflected in the next line.Design Choices
Writing the dockerfile in a correct way to cache npm modules was the most difficult part of the PR, due to the monorepo structure. Some possible ways were:
1- Manually copying each package.json file from the project. Ex:
Problem: While manually copying package.json of each package could be ok, the folder structure of the package.json must be written manually and would need manual edit if changed. This problem is very apparent in the js websocket client, which has a deeply nested package.json. Refused this approach.
2- Using
turbo prune
command. Turborepo CLI has a command that can prune a project out of modules and divide it into a folder of package.json with respecting the nested structure, and a folder of source code. The first folder will be used to install npm modules, and the second will be to add source code.A small problem is that the command requires a scope (a package to prune as a target), and there is no
all
option, so we have to specify all package names. Some packages include other packages as dependencies so some names can be skipped. I've opened an issue anyways in their github: vercel/turborepo#10267This approach gave great results, and is the chosen one.
Summary by CodeRabbit
.dockerignore
file to exclude unnecessary files from container builds, enhancing efficiency.