Skip to content

feat: add dev container configuration for development experience#15895

Open
djunehor wants to merge 2 commits intonestjs:masterfrom
djunehor:feat/devcontainer-support
Open

feat: add dev container configuration for development experience#15895
djunehor wants to merge 2 commits intonestjs:masterfrom
djunehor:feat/devcontainer-support

Conversation

@djunehor
Copy link

@djunehor djunehor commented Nov 9, 2025

Adds comprehensive VS Code dev container configuration to enable one-click development environment setup. The devcontainer includes Node.js 20 LTS, TypeScript tooling, and essential development services (Redis, NATS, MySQL) with pre-configured VS Code extensions and settings.

Closes #15864

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe:

What is the current behavior?

Contributors need to manually set up their local development environment, including Node.js version, dependencies, services (Redis, NATS, MySQL), and VS Code extensions/settings. This creates friction for new contributors and can lead to inconsistent development environments.

Issue Number: #15864

What is the new behavior?

Contributors can now use VS Code's "Reopen in Container" feature to automatically set up a complete, consistent development environment with:

  • Node.js 20 LTS with npm
  • Pre-installed dependencies with legacy peer deps handling
  • Essential development services (Redis, NATS, MySQL) in isolated containers
  • 15+ pre-configured VS Code extensions for TypeScript, ESLint, Prettier, Docker, etc.
  • Optimized VS Code settings for the NestJS codebase
  • Automated workspace permission handling
  • Comprehensive documentation in .devcontainer/README.md
  • Manual integration test services startup to maintain reliability

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

The devcontainer configuration is purely additive and doesn't affect existing development workflows. Developers can continue using their local setup if preferred. Integration test services are available via npm run test:docker:up but are not started automatically to ensure container reliability.

The implementation follows VS Code dev container best practices and includes robust error handling for permission issues and npm installation failures that commonly occur in containerized environments.

Adds comprehensive VS Code dev container configuration to enable one-click development environment setup. The devcontainer includes Node.js 20 LTS, TypeScript tooling, and essential development services (Redis, NATS, MySQL) with pre-configured VS Code extensions and settings.

Closes nestjs#15864
@coveralls
Copy link

coveralls commented Nov 9, 2025

Pull Request Test Coverage Report for Build a79e1bef-a856-4cb1-8b31-900ac30e3cbf

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 88.927%

Totals Coverage Status
Change from base Build a397f2a5-d066-4bae-a4e2-52cdc757a397: 0.0%
Covered Lines: 7324
Relevant Lines: 8236

💛 - Coveralls

nodemon \
# Testing tools
mocha \
nyc \
Copy link
Member

@kamilmysliwiec kamilmysliwiec Dec 5, 2025

Choose a reason for hiding this comment

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

do we really need some of these packages to be installed globally?

Copy link
Author

Choose a reason for hiding this comment

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

You're right - these don't need to be global. They're already in devDependencies and can be accessed via npm scripts or npx. I'll update the Dockerfile to remove the global installations of mocha, nyc, nodemon, ts-node, and other dev tools.

The only global package that might be justified is npm-check-updates for convenience, but I can remove that too if you prefer. Would you like me to keep just the base Node image and rely entirely on the local node_modules?

Copy link
Member

Choose a reason for hiding this comment

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

yeah i'd say the fewer global deps the better

Copy link
Author

Choose a reason for hiding this comment

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

Done! I've removed all global npm package installations from the Dockerfile. The devcontainer now relies entirely on local node_modules - all tools (typescript, ts-node, mocha, nyc, eslint, prettier, concurrently, cross-env, lerna, gulp-cli) are accessible via npx or npm scripts.

Removed global npm package installations (typescript, ts-node, mocha, nyc, eslint, prettier, concurrently, cross-env, lerna, gulp-cli) from the devcontainer Dockerfile. These packages are already available in devDependencies and can be accessed via npm scripts or npx, eliminating the need for global installations.

This change aligns with the principle of minimizing global dependencies and relying on local node_modules instead.
Copy link
Contributor

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

This PR adds comprehensive VS Code dev container configuration to enable one-click development environment setup for NestJS contributors. The devcontainer provides Node.js 20 LTS, essential development services, and pre-configured VS Code extensions to simplify onboarding and ensure environment consistency.

Changes:

  • Adds complete devcontainer configuration with Dockerfile, docker-compose setup, and lifecycle scripts
  • Configures development services (Redis, NATS, MySQL) in isolated containers
  • Includes 15+ VS Code extensions and optimized editor settings for TypeScript/NestJS development
  • Updates .gitignore to allow .devcontainer directory in version control

Reviewed changes

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

Show a summary per file
File Description
.gitignore Removes .devcontainer from ignore list to include devcontainer config in repo
.devcontainer/devcontainer.json Main configuration for VS Code devcontainer with extensions, settings, ports, and lifecycle hooks
.devcontainer/Dockerfile Custom image based on Node 20 with build tools, Docker CLI, and proper user permissions
.devcontainer/docker-compose.yml Service definitions for Redis, NATS, and MySQL development dependencies
.devcontainer/scripts/post-create.sh Post-creation script for dependency installation and workspace setup
.devcontainer/scripts/post-start.sh Post-start script for service health checks
.devcontainer/README.md Comprehensive documentation for devcontainer usage and troubleshooting

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

Comment on lines +45 to +49
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test
MYSQL_USER: nestjs
MYSQL_PASSWORD: nestjs
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The MySQL container creates both a root user (MYSQL_ROOT_PASSWORD: root) and a dedicated user (MYSQL_USER: nestjs, MYSQL_PASSWORD: nestjs), but the devcontainer documentation doesn't explain which credentials should be used for connecting to MySQL. Applications need to know which user/password to use for database connections. Add documentation specifying the recommended MySQL connection credentials.

Copilot uses AI. Check for mistakes.
## What's Included

### Development Environment
- **Node.js 20 LTS** with npm configured for legacy peer dependencies (meets requirement >= 10.13.0)
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The documentation incorrectly states the Node.js requirement is ">= 10.13.0", but according to the package.json in the repository, the actual engine requirement is "node": ">= 20". The comment should reflect the accurate requirement of Node.js 20 or higher.

Suggested change
- **Node.js 20 LTS** with npm configured for legacy peer dependencies (meets requirement >= 10.13.0)
- **Node.js 20 LTS** with npm configured for legacy peer dependencies (requires Node.js >= 20)

Copilot uses AI. Check for mistakes.
# NATS for messaging
nats:
container_name: nestjs-dev-nats
image: nats:2.10-alpine
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The NATS container uses a specific pinned version (nats:2.10-alpine) while the integration test docker-compose.yml uses the 'nats' image without a version tag (which defaults to 'latest'). This version mismatch could lead to inconsistencies between devcontainer development and integration test environments. Consider using the same NATS image version as integration tests or documenting why different versions are used.

Suggested change
image: nats:2.10-alpine
image: nats

Copilot uses AI. Check for mistakes.
Comment on lines +157 to +160
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker-host.sock,type=bind"
],

Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

Docker socket is mounted twice with different configurations. In devcontainer.json line 158, it's mounted via the "mounts" property, and in docker-compose.yml line 8, it's mounted via the volumes property. While this might work, it's redundant and could cause confusion. The docker-compose.yml mount should be sufficient, so consider removing the duplicate mount specification in devcontainer.json.

Suggested change
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker-host.sock,type=bind"
],

Copilot uses AI. Check for mistakes.
Comment on lines +48 to +49
&& usermod -aG docker $USERNAME \
&& echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The Dockerfile grants passwordless sudo access to the node user with "NOPASSWD:ALL" which is a security risk. While this is for a development environment, it's still a bad security practice that could be exploited if the container is exposed or if malicious code is run. Consider either removing sudo access entirely if not needed, or requiring a password, or limiting sudo access to specific commands that are actually needed.

Suggested change
&& usermod -aG docker $USERNAME \
&& echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
&& usermod -aG docker $USERNAME

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +35
- **MQTT/Mosquitto** (ports 11883, 19001) - IoT messaging with WebSocket support

## Getting Started

1. **Open in Dev Container**: VS Code will prompt to reopen in container when opening this repository
2. **Wait for Setup**: The container will automatically install dependencies and build packages
3. **Services will start automatically**: Integration services (Redis, NATS, etc.) start during setup
4. **Start Development**: All services will be available and ready for development

**Note**: Integration services start after the main container is ready, not during container creation. This ensures reliable startup.
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

Documentation states "Services will start automatically" but this contradicts the actual implementation and the PR description. According to the docker-compose.yml, only Redis, NATS, and MySQL services are defined, not MQTT/Mosquitto or PostgreSQL which are mentioned in the README. Additionally, the post-create.sh script explicitly notes that integration services are NOT started automatically (lines 64-69).

Suggested change
- **MQTT/Mosquitto** (ports 11883, 19001) - IoT messaging with WebSocket support
## Getting Started
1. **Open in Dev Container**: VS Code will prompt to reopen in container when opening this repository
2. **Wait for Setup**: The container will automatically install dependencies and build packages
3. **Services will start automatically**: Integration services (Redis, NATS, etc.) start during setup
4. **Start Development**: All services will be available and ready for development
**Note**: Integration services start after the main container is ready, not during container creation. This ensures reliable startup.
## Getting Started
1. **Open in Dev Container**: VS Code will prompt to reopen in container when opening this repository
2. **Wait for Setup**: The container will automatically install dependencies and build packages
3. **Start integration services**: Start integration services (Redis, NATS, MySQL, etc.) manually (for example, using Docker Compose) after setup completes
4. **Start Development**: After integration services are running, they will be available and ready for development
**Note**: Integration services are not started automatically. Start them manually after the main container is ready to ensure reliable startup.

Copilot uses AI. Check for mistakes.
- **Redis** (port 16379) - Caching and session storage
- **NATS** (ports 14223, 16222, 18222) - Message broker with monitoring
- **MySQL** (port 13306) - Primary database for testing
- **MQTT/Mosquitto** (ports 11883, 19001) - IoT messaging with WebSocket support
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The README documents MQTT/Mosquitto services (ports 11883, 19001) and PostgreSQL (port 5432), but these services are not defined in docker-compose.yml. Only Redis, NATS, and MySQL are actually configured. Either add these services to docker-compose.yml or remove them from the documentation.

Suggested change
- **MQTT/Mosquitto** (ports 11883, 19001) - IoT messaging with WebSocket support

Copilot uses AI. Check for mistakes.
"leizongmin.node-module-intellisense",
"christian-kohler.path-intellisense",
"formulahendry.auto-rename-tag",
"bradlc.vscode-tailwindcss",
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The devcontainer includes the TailwindCSS extension (bradlc.vscode-tailwindcss) which is not relevant to NestJS backend development. NestJS is a backend framework and doesn't use TailwindCSS (which is a CSS framework for frontend). This extension should be removed to keep the devcontainer focused on relevant tools.

Suggested change
"bradlc.vscode-tailwindcss",

Copilot uses AI. Check for mistakes.
Comment on lines +52 to +70
# Run the prepare script to set up packages and samples
if [ -f "scripts/prepare.sh" ]; then
echo "Running prepare script..."
# bash scripts/prepare.sh
echo "Prepare script execution commented out for debugging"
else
echo "Warning: Prepare script not found, running manual setup..."

# Build packages
# npm run build
echo "Manual build commented out for debugging"

# Integration services are not started automatically to ensure robust devcontainer setup.
echo ""
echo "Integration services are NOT started automatically."
echo "If you need integration services for testing, run:"
echo " npm run test:docker:up"
echo "from the workspace root after the container starts."
fi
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The logic checks if 'scripts/prepare.sh' exists and then comments out its execution, but then provides fallback logic (lines 58-70) that assumes it doesn't exist. This creates confusing control flow. If the prepare script exists (which it does in the repository), the first branch executes but does nothing useful. Either execute the prepare script when it exists, or restructure the logic to clearly indicate what should happen in each case.

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +76
## Port Forwarding

The following ports are automatically forwarded for easy access:
- **3000-3010**: Sample applications
- **8080-8082**: Additional development servers
- **16379**: Redis
- **14223, 16222, 18222**: NATS services
- **11883, 19001**: MQTT services
- **13306**: MySQL
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The devcontainer services are on a separate Docker network ('nestjs-dev') and will be accessible from the devcontainer using their service names (redis, nats, mysql) on their internal ports (6379, 4222, 3306), NOT the host-mapped ports (16379, 14223, 13306). The port forwarding documentation is misleading because it lists the host-mapped ports, but code running inside the devcontainer should connect to the service names with standard ports. The README should clarify: (1) services are accessed via service name with standard ports from inside the container, (2) host-mapped ports are only for accessing services from the host machine.

Copilot uses AI. Check for mistakes.
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.

[discussion]: Add .devcontainer for simplified development setup

5 participants