Docker is a tool that help us to work with the containers. We can pull the images from it's public docker hub repo and run the images in our machine to work with softwares like nodejs, mongodb, linux which otherwise needs to be installed on our Operating System manually.
Containers are the isolated environments in your system that runs on the top of your systems infrastructure but are in isolation. Containers itself doesn't contain the full operating system but rather it contains some binaries. Docker sits in between our machine Operating system and the Container to manage how we use the our computer resources.
to share the container we create the Images of our container which can be replicted on other machine.
Images can also be created from Dockerfile.
Image contain set of instruction about how to create the container. Think this as image is an Class and Container is it's Object/Instance.
Docker follows Client Server architecture under the hood. So there are three things :
- docker cli <- This is our client
- docker daemon <- This is the server
- REST API <- This sets communication between cli commands and the daemon.
docker --version: To know the version of the dockerdocker ps: To list the running containersdocker ps -a: To list all the containers running/stopped.
docker run ubuntu:latest: This will start running our ubuntu container, replace latest withversionnumber if required, if the iamge is not present it will look in the container registry and then download it.docker run -it ubuntu:latest /bin/bash: start container while opening an interactive terminal session inside the container.docker run -d ubuntu: Run the container in detached mode.docker run -dit --name my-ubuntu ubuntu:latest: If you want the container to stay alive silently in the background so you can connect to it later, combine detached (-d) and interactive flagsdocker exec -it my-ubuntu bash: if you started the container with previous command then you can enter into it with this command. container when running we use theexeccommand.
docker pull node:<version>: To pull the image from remote registrydocker stop containerId: stop the running container.docker container prune: delete all the stopped containers.
We can run them one by one too.
docker pull node:22-alpine: Ran the container from local image, otherwise pull from the docker hub.docker create node:22-alpine: Creates a new writeable container layer over the specified image and prepares its execution configuration.docker start <container>: Boots up the newly created container, assigns it a process ID, and executes its main startup application or custom script we can attach the flags to these commands to mimic behaviour ofdocker run
NOTE: AI Generated Notes of my actual problems I faced and resolved using different sources on Internet.
π Port Mapping and Data Persistence in Docker Containers
By default, Docker containers are isolated from the host machine and the outside network. If a container runs a process (like a web server) on an internal port, you cannot access it from your computer's browser unless you explicitly map an external port to that internal port.
This guide walks you through a common beginner scenario: creating an app entirely inside an isolated container, running into the "missing port" problem, and fixing it without losing your code.
π Part 1: Setting Up the Isolated Container
Let's simulate the problem by creating an isolated container and writing an Express application inside it from scratch.
1. Pull the Image
Alpine Linux is used here because it is a lightweight alternative to heavier distributions like Ubuntu.
2. Run the Container in the Background
Run the container using the detached (
-d) and interactive (-it) flags so it stays alive silently in the background.3. Enter the Container Terminal
Open an interactive shell inside your running container.
docker exec -it alpine-01 shπ οΈ Part 2: Building the Express App Inside the Container
Now that you are inside the container's terminal (
/ #), perform the following commands to set up a Node.js web server.1. Install Node.js and NPM
Alpine uses the
apkpackage manager. Update the repository lists and install Node.js:2. Initialize the Project
Create a new directory for your app, navigate into it, and initialize NPM:
mkdir express-app cd express-app npm init -y3. Install Dependencies
Install Express for the server and Nodemon to automatically restart the server during code changes:
4. Create and Edit
main.jsCreate a server script file using the
vitext editor:Press
ito enter Insert Mode, paste the following code, then pressEsc, type:wqor:x, and pressEnterto save and exit:5. Update
package.jsonOpen
package.jsonusingvi:Modify the
"scripts"section to include the start script. Ensure your JSON format is strict (do not leave a trailing comma at the end of the last script line, or NPM will crash!):6. Start the Server
The terminal will show that your app is listening on internal port
3000.π The Problem:
If you open your host computer's browser and go to
http://localhost:3000, it will not load. The container is isolated, and no external port is listening to the internal process.ποΈ Part 3: Solving the Problem with Port Mapping
Docker does not allow you to add port mappings to a container that is already running or created(IMP Read It again.). However, you can save your current container state (including all your written code and installed packages) into a new image.
1. Exit the Container
Stop your running node server with
Ctrl + C, then typeexitto go back to your laptop's terminal:exit2. Commit the Container into a New Image
Freeze your current container state (with your code inside) and name this custom image
express-app-container-image:3. Stop the Old Container
Stop the old isolated container to free up system resources and names:
4. Run the New Image with Port Mapping (
-p)Spin up a brand-new container from your saved image. Use the
-pflag to map an external port (e.g.,8080) to the container's internal port (3000):5. Start Your App and Verify
Enter the new, fixed container terminal:
docker exec -it alpine-01-fixed shNavigate back to your project directory and start the server:
cd express-app npm startNow, open your computer's browser and visit:
http://localhost:8080You will see the
"Hello World from Inside Docker!"message!When working with containers, keep these filesystem rules in mind:
docker stop/docker start): You will not lose your data. If you stopalpine-01-fixedand start it tomorrow, your code and configurations remain safe inside that container instance.docker rm): You will lose your data. If you delete a container instance, the isolated file system inside it is permanently destroyed. To avoid losing code permanently in production, developers link folders from their host computer using Volumes or Bind Mounts (-v). (We will cover Volumes and Bind Mounts on some other day).β‘ Alternative: The Docker Way (Fast & Automated)
If your primary goal is simply to build a Node.js application, installing Node manually inside a blank Linux OS container is slow and repetitive.
Professionals use official, pre-configured images to keep their environment entirely disposable, automated, and ready to go in a single command line:
Why this is better:
node:alpineimage comes with Alpine Linux, Node.js, andnpmalready fully optimized and configured out of the box.-p 8080:3000right from the beginning, you never have to worry about running into an isolation issue or committing custom images later.