Caution: This tutorial is written supposed that you are installing a Node.js application
FROM
: Specify the base image (base image)RUN
: Run commands while creating the imageCOPY/ADD
: Copy files or folders to the containerWORKDIR
: Set default working directory.CMD/ENTRYPOINT
: Specifies the command to be run when the container startsEXPOSE
: Opens a port so the container can receive connections
myapp/
|-- Dockerfile
|-- app
First, create a file named Dockerfile
in your project directory
Base image is the foundation of your application. Base images are loaded from Docker Hub, which is the most popular registry for storing and sharing Docker images. For example: node, python, ubuntu, nginx, etc.
# Using Node.js version 16
FROM node:16
Base Image Classification
- Official Base Images (Official Image): Provided and maintained by Docker or reputable organizations. For example:
ubuntu:
Provides the Ubuntu operating system.python
: Includes Python and necessary tools.node
: Includes Node.js and npm.
- Minimal Base Images: Images are optimized for capacity and contain only basic components. For example:
alpine
: A lightweight Linux image (~5MB), suitable for small applications.
- Custom Base Images (Custom Image): Built by users to serve specific needs. For example: A base image contains company-specific tools or libraries.
Set up the working directory in the container. All the following commands will be executed in this directory.
# Create application folder in container
WORKDIR /usr/src/app
Copy the necessary files from your local machine to the container. In this step, you can now install the necessary denpencies for the environment
# Copy package.json and package-lock.json to the working directory
COPY app/package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of the application code to the working directory
COPY app/ ./
Expose the port that your application will run on.
# Expose the port the app runs on
EXPOSE 3000
Specify the command to run your application when the container starts.
# Define the command to run the application
CMD ["npm", "start"]
- Build Docker image: From the myapp directory (containing the dockerfile), run the command:
docker build -t my-node-app -f Dockerfile .
- Run container:
docker run -d -p 3000:3000 my-node-app
- Use the following command to log in to Docker Hub:
docker login
- Enter the username and password of the Docker Hub account.
Docker Hub requires images to be named in the format: <username>/<repository>:<tag>
For example: If your username is myusername
and you want to create a myapp
repository, then you need to name the image as follows:
docker tag my-node-app myusername/myapp:latest
my-node-app
: Local image name.myusername/myapp:latest
:myusername
: Docker Hub account name.myapp
: Name of the repository (application) you want to create.latest
: Tag of image version (default).
To push the image to Docker Hub, use the command:
docker push myusername/myapp:latest
After the image is public, you can download it from any computer with the command:
docker pull myusername/myapp:latest
Then run the container as usual
-
Layer cache from builds
- Docker saves image layers for reuse in future builds.
- Old classes are not automatically deleted, even if you rebuild or delete the container.
-
Dangling images: Images that are not tagged or have no containers in use still exist on the system.
-
Stopped containers: Stopped containers are not automatically deleted unless you use the
--rm
command when running the container. -
Volume has not been deleted: Docker stores data in volumes, even when the container is deleted. This is very useful for preserving data, but if you don't manage it well, the volume will take up a lot of memory.
-
Build cache: When building an image, Docker creates a cache for each step of the Dockerfile. If you don't clear the cache, the capacity will increase.
- Clean up all redundant data Use the command below to clean up all unused images, containers, volumes and networks
docker system prune -a --volumes
-a
: Delete all untagged or unused images.--volumes
: Delete volumes that are no longer in use by any containers
-
Delete stopped containers
- List of stopped containers:
docker ps -a
- Delete all stopped containers:
docker container prune
-
Delete unnecessary images
- List of all images:
docker images
- Delete a specific image:
docker rmi <image_id>
-
Delete dangling images Images without tags or no longer in use:
docker image prune
- Delete volumes that are no longer in use
- List of volumes:
docker volume ls
- Delete unused volumes:
docker volume prune
Docker Compose is a tool used to define and manage multi-container applications in Docker. Instead of running individual containers with the docker run command, Docker Compose allows you to define the configuration of all containers in a YAML file, typically named docker-compose.yml
. You can then start, stop, or manage the entire application with just a few commands.
version: '3.8' # Specify the Docker Compose file version (ensure compatibility with your Docker Engine)
services: # Define the services (containers) that make up your application
service_name: # Name of the service (e.g., "web", "db", etc.)
image: image_name:tag # The Docker image and its version/tag (e.g., nginx:latest)
build: # (Optional) If building the image from a Dockerfile, specify the context or Dockerfile
context: ./path_to_context # Path to the build context
dockerfile: Dockerfile # (Optional) Specify the Dockerfile if not named "Dockerfile"
ports: # Map container ports to host ports
- "host_port:container_port"
environment: # Set environment variables
- ENV_VAR_NAME=value
volumes: # Mount host directories or volumes into the container
- ./local_path:/container_path
depends_on: # Define service dependencies (ensures this service starts after the dependencies)
- dependent_service_name
command: # (Optional) Override the default command of the Docker image
- "custom_command"
networks: # (Optional) Specify custom networks for the services
default: # Define a default network or custom ones as needed
driver: bridge # Network driver type
Example:
version: '3.8'
services:
web: # Define a web server service
image: nginx:latest # Use the official Nginx image
ports:
- "8080:80" # Map host port 8080 to container port 80
volumes:
- ./html:/usr/share/nginx/html # Mount local "html" folder to the Nginx HTML directory
depends_on:
- db # Start the "db" service before this service
db: # Define a database service
image: mysql:5.7 # Use the MySQL 5.7 image
environment:
- MYSQL_ROOT_PASSWORD=rootpassword # Set root password
- MYSQL_DATABASE=mydatabase # Create a default database
volumes:
- db_data:/var/lib/mysql # Persist MySQL data using a named volume
volumes: # Define named volumes
db_data:
Detailed Explanation of Each Section:
version
: Specifies the version of the Docker Compose file format. The most common version is 3.8. Ensure compatibility with your Docker Engineservices
: Defines the services (containers) in your application. Each service represents a container and includes its image, ports, volumes, and other settings.image
: Specifies the Docker image to use for the service.ports
: Maps ports from the container to the host. Structure:host_port:container_port
- Open a terminal and navigate to the directory containing the
docker-compose.yml file
. - Run the command:
docker-compose up
Use the -d flag to run in detached mode (background):
docker-compose up -d
- Check service status:
docker-compose ps
- Stop all services:
docker-compose down
- Remove services but retain data (volumes):
docker-compose down --volumes
- View logs:
docker-compose logs -f