Docker Compose Files
Docker Compose is a tool for defining and running multi-container Docker applications. This guide covers key concepts, steps to create and manage Docker Compose files, examples, and best practices for using Docker Compose with Express.js applications.
Key Concepts of Docker Compose Files
- Service: Defines a container to run, including the image, ports, volumes, and networks.
- Network: Configures custom Docker networks for inter-container communication.
- Volume: Defines data storage and sharing between containers and the host system.
- Compose File: A YAML file used to configure application services, networks, and volumes.
Setting Up the Project
Initialize a new Express.js project and create a Dockerfile:
// Initialize a new project
// npm init -y
// Install Express
// npm install express
// Create the project structure
// mkdir src
// touch src/index.js Dockerfile .dockerignore .gitignore docker-compose.yml
// .gitignore
node_modules
.env
// .dockerignore
node_modules
npm-debug.log
Creating an Express Application
Create a simple Express application:
Example: index.js
// src/index.js
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello, Docker Compose!');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
Creating a Dockerfile
Create a Dockerfile to containerize your Express application:
Example: Dockerfile
// Dockerfile
FROM node:14
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
# Make port 3000 available to the world outside this container
EXPOSE 3000
# Run app when the container launches
CMD ["node", "src/index.js"]
Creating a Docker Compose File
Create a docker-compose.yml file to define the services for your Docker Compose setup:
Example: docker-compose.yml
// docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
networks:
- webnet
volumes:
- .:/usr/src/app
environment:
- NODE_ENV=development
networks:
webnet:
Running Docker Compose
Use Docker Compose to build and run the services defined in the docker-compose.yml file:
// Build and run the services
docker-compose up --build
// Open http://localhost:3000 in your browser to see the application running
Managing Docker Compose
Use Docker Compose commands to manage your multi-container application:
List Running Services
// List running services
docker-compose ps
Stopping Services
// Stop services
docker-compose stop
Removing Services
// Remove services and associated resources
docker-compose down
Adding a Database Service
Extend your docker-compose.yml file to include a database service:
Example: docker-compose.yml with Database
// docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
networks:
- webnet
volumes:
- .:/usr/src/app
environment:
- NODE_ENV=development
- MONGO_URL=mongodb://mongo:27017/mydatabase
mongo:
image: mongo:latest
networks:
- webnet
volumes:
- mongo-data:/data/db
networks:
webnet:
volumes:
mongo-data:
Best Practices for Using Docker Compose
- Use Volumes for Data Persistence: Use named volumes to persist data across container restarts and removals.
- Use Networks for Inter-Container Communication: Define custom networks to enable communication between containers.
- Use Environment Variables for Configuration: Store configuration data in environment variables to keep your application flexible and secure.
- Separate Development and Production Configurations: Use different Compose files or override configurations for development and production environments.
- Keep Compose Files DRY: Avoid repetition in your Compose files by using YAML anchors and aliases.
Testing Docker Compose Integration
Test your Docker Compose setup to ensure it works correctly:
Example: Testing with Mocha and Chai
// Install Mocha and Chai
// npm install --save-dev mocha chai
// test/app.test.js
const chai = require('chai');
const expect = chai.expect;
const axios = require('axios');
describe('Express App', () => {
it('should return Hello, Docker Compose!', async () => {
const response = await axios.get('http://localhost:3000');
expect(response.data).to.equal('Hello, Docker Compose!');
});
});
// Add test script to package.json
// "scripts": {
// "test": "mocha"
// }
// Run tests
// docker-compose up --build
// npm test
Key Points
- Service: Defines a container to run, including the image, ports, volumes, and networks.
- Network: Configures custom Docker networks for inter-container communication.
- Volume: Defines data storage and sharing between containers and the host system.
- Compose File: A YAML file used to configure application services, networks, and volumes.
- Follow best practices for using Docker Compose, such as using volumes for data persistence, networks for inter-container communication, environment variables for configuration, separating development and production configurations, and keeping Compose files DRY.
Conclusion
Docker Compose is a powerful tool for defining and running multi-container Docker applications. By understanding and implementing the key concepts, steps, examples, and best practices covered in this guide, you can effectively use Docker Compose to manage your Express.js applications. Happy coding!