You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A well-configured Dockerfile is essential for containerizing your application:
33
33
***Common Setup – Use a Base Dockerfile**: If multiple projects share a common setup, you can create a base Dockerfile that includes these common steps. Each project's Dockerfile can then start with `FROM` this base image and add project-specific configurations.
34
34
***Parameterization – Build Arguments**: You can use build arguments (`ARG`) in your Dockerfile to make it more flexible. This way, you can pass in different values for these arguments when building for development or production.
35
-
***Optimized Base Image – Node.js Variant**: Ensure you're using an appropriate **Node.js base image**. Consider using smaller, optimized images such as the Alpine variants to reduce overhead.
36
-
***Minimal Files – Copy Only Essentials**: Focus on copying only the necessary files into your container.
35
+
***Optimized Base Image – Node.js Variant**: Ensure you're using an appropriate **Node.js base image**. Consider using smaller, optimized images such as the Alpine variants to reduce overhead. The development environment can add dependencies in its own Dockerfile.
36
+
***Minimal Files – Copy Only Essentials**: Focus on copying only the necessary files into your container. Create a `.dockerignore` file to ensure development files aren't copied in such as `.env` and `node_modules`. This file is helps speed up builds in cases where developers copied in unnecessary files.
37
37
***Multi-stage Builds – Separate Build and Runtime**: Use multi-stage builds to create a lean final image by separating the build environment from the runtime environment.
38
38
***Prebuild Artifacts – Compile/Bundling**: Prebuilding your application artifacts (such as compiling TypeScript or bundling JavaScript) before copying them into the runtime stage can further minimize image size, speed up container deployment, and improve cold start performance. Careful ordering of instructions in your Dockerfile will also optimize caching and rebuild times.
39
39
***Development Environments – Docker Compose**: Use Docker Compose for development environments. Docker Compose allows you to define and run multi-container Docker applications, which can be useful for setting up development environments. You can include the build context and Dockerfile in the compose file, allowing you to use different Dockerfiles for different services if necessary.
40
40
41
41
### Base Dockerfile
42
42
43
-
This file serves as a common starting point for your Node.js images. You can use it with a FROM directive in your other Dockerfiles.
43
+
This file serves as a common starting point for your Node.js images. You can use it with a FROM directive in your other Dockerfiles. Use either a version number or a commit to support the most up to date and secure version of the image.
44
44
45
45
```yaml
46
46
# Dockerfile.base
@@ -81,6 +81,8 @@ docker build \
81
81
82
82
In this build, the environment variables PORT and ENABLE_DEBUG are set to 4000 and true, respectively, instead of their default values.
83
83
84
+
Container image tagging conventions such as the use of `latest` are a convention. Learn more about [recommendations for tagging and versioning container images](/azure/container-registry/container-registry-image-tag-version).
85
+
84
86
### Development environment with Docker Compose
85
87
86
88
This configuration uses a dedicated development Dockerfile (Dockerfile.dev) along with volume mounts for live reloading and local source sync.
@@ -115,7 +117,7 @@ PORT=4000 ENABLE_DEBUG=true docker compose up
115
117
116
118
### Production Dockerfile
117
119
118
-
This multi-stage Dockerfile builds your application and produces a lean runtime image.
120
+
This multi-stage Dockerfile builds your application and produces a lean runtime image. Make sure to have your `.dockerignore` already in our source code so that the `COPY . .` command doesn't copy in any files specific to the development environment you don't need in production.
119
121
120
122
```yaml
121
123
# Stage 1: Builder
@@ -160,6 +162,9 @@ To run a container from the built production image with custom environment varia
For production builds, make sure you use the correct version tag, which may not be `latest`. Container image tagging conventions such as the use of `latest` are a convention. Learn more about [recommendations for tagging and versioning container images](/azure/container-registry/container-registry-image-tag-version).
166
+
167
+
163
168
## Deployment
164
169
* Continuous Integration/Continuous Deployment (CI/CD) - Set up a CI/CD pipeline using GitHub Actions, Azure DevOps, or another CI/CD tool to automate the deployment process.
Properly shutting down your application is crucial to ensure that in-flight requests complete and resources are released correctly. This helps prevent data loss and maintains a smooth user experience during deployments or scale-in events. The following example demonstrates one approach using Node.js and Express to handle shutdown signals gracefully.
269
274
270
-
```javascript
271
-
const express = require('express');
275
+
```typescript
276
+
import express from 'express';
277
+
import healthRouter from './health.js';
278
+
272
279
const app = express();
273
-
const healthRouter = require('./health');
274
280
275
281
app.use(healthRouter);
276
282
@@ -283,7 +289,7 @@ process.on('SIGTERM', () => {
283
289
console.log('Server closed');
284
290
process.exit(0);
285
291
});
286
-
292
+
287
293
// Force close after 30s
288
294
setTimeout(() => {
289
295
console.error('Could not close connections in time, forcing shutdown');
0 commit comments