
Images & Containers
Images
Images are one of the two core building blocks Docker is all about (the other one is Containers).
- Images are blueprints / templates for containers.
-
They are read-only and contain:
- The application
- Operating system
- Runtimes
- Tools and dependencies
- Images do not run themselves; they are executed as containers.
-
Images can be:
- Pre-built (e.g. official images from DockerHub)
- Custom-built using a Dockerfile
-
Dockerfiles contain instructions executed when an image is built using:
docker build . - Each instruction in a Dockerfile creates a layer. Layers help in efficient rebuilding and sharing of images.
-
The
CMDinstruction is special:- Not executed when the image is built
- Executed when a container is created and started
Containers
- Containers are the other key building block Docker is all about.
- Containers are running instances of images.
-
When a container is created using
docker run, a thin read-write layer is added on top of the image. - Multiple containers can be created from the same image.
-
All containers run in isolation:
- No shared application state
- No shared written data
-
To start an application, you must:
- Create a container
- Start the container
- Containers are what actually run in both development and production.
Key Docker Commands
For a full list of commands, use --help:
docker --help,
docker run --help
Official documentation: Docker Run Reference
Note: You only need a small subset of commands in real-world usage.
-
docker build .– Build a Dockerfile and create an image -
-t NAME:TAG– Assign a name and tag to an image -
docker run IMAGE_NAME– Create and start a container -
--name NAME– Assign a name to a container -
-d– Run container in detached mode -
-it– Run container in interactive mode (stop with CTRL + C) -
--rm– Automatically remove the container after stopping -
docker ps– List running containers -
docker ps -a– List all containers (including stopped) -
docker images– List all local images -
docker rm CONTAINER– Remove a container -
docker rmi IMAGE– Remove an image -
docker container prune– Remove all stopped containers -
docker image prune– Remove dangling images -
docker image prune -a– Remove all local images -
docker push IMAGE– Push image to DockerHub or registry -
docker pull IMAGE– Pull image from DockerHub
.NET 8 Web API – Multi-Stage Docker Build
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY InternifyWebAPI.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish /p:UseAppHost=false
# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
ENV ASPNETCORE_URLS=http://+:8085
ENV ASPNETCORE_ENVIRONMENT=Production
COPY --from=build /app/publish .
EXPOSE 8085
ENTRYPOINT ["dotnet", "InternifyWebAPI.dll"]
What This Dockerfile Does
- Builds the .NET 8 Web API in a separate build stage
- Publishes optimized release output
- Runs the app in a lightweight runtime image
- Keeps final image small and production-ready
Build Stage (SDK Image)
dotnet restore
Restores NuGet dependencies using the project file. This step is cached to speed up future builds.
dotnet publish
Creates a production-ready build in the
/app/publish folder.
The Release configuration ensures better performance.
Runtime Stage (ASP.NET Image)
ASPNETCORE_URLS
Configures the application to listen on port
8085 inside the container.
ASPNETCORE_ENVIRONMENT
Sets the environment to Production for optimized runtime behavior.
Port Exposure
Exposes port 8085 so the API can be accessed externally.
Application Startup
Starts the Web API using
dotnet InternifyWebAPI.dll.
Key Benefits
- Smaller Docker image
- Faster startup time
- Clean separation of build and runtime
- Ideal for Docker, Render, and cloud deployment
Ignored Files & Folders
These entries are excluded to keep the project clean, secure, and lightweight during builds and version control.
Development Tools
- .vs/ – Visual Studio local settings
- .vscode/ – VS Code editor configuration
Build Output
- bin/ – Compiled binaries
- obj/ – Temporary build files
User-Specific Files
- *.user – User-specific IDE settings
- *.suo – Visual Studio solution options
Logs
- *.log – Application and build logs
Environment & Secrets
- *.env – Environment variables and secrets
OS-Specific Files
- Thumbs.db – Windows system file
- .DS_Store – macOS system file
Docker Files
- docker-compose* – Local orchestration files
- Dockerfile* – Build instructions (not needed inside image)
Result
Ignoring these files reduces clutter, improves security, and speeds up Docker builds and repository management.
Angular Docker Multi-Stage Build with Nginx
Build Stage (Angular App)
- Node Image: Uses
node:20-alpineto build Angular app - Working Directory:
/app - Dependencies: Installs using
npm install - Build: Runs production build
- Output: Generates optimized files in
dist/
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build -- --configuration production
Serve Stage (Nginx)
- Nginx Image: Lightweight
nginx:alpine - Cleanup: Removes default Nginx page
- Routing: Custom Nginx config for Angular routing
- Deploy: Copies Angular build to Nginx web folder
FROM nginx:alpine
RUN rm -rf /usr/share/nginx/html/*
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist/InternifyUI/browser/ /usr/share/nginx/html/
Container Runtime
- Port: Exposes port
80 - Start: Runs Nginx in foreground
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Key Notes
- InternifyUI = Angular project name
- browser folder is used in Angular’s new build structure
- Multi-stage build keeps image small and secure
What is .dockerignore?
.dockerignore tells Docker which files and folders should NOT be copied into the Docker image during build.
Benefits
- Faster Docker builds
- Smaller image size
- More secure containers
Important .dockerignore Entries
node_modules
Prevents copying local Node.js dependencies. Docker installs fresh dependencies inside the container, avoiding OS compatibility issues and reducing image size.
dist
Excludes Angular build output. The app is built inside Docker to ensure clean and reproducible builds.
.git
Removes Git history from the image. This reduces size and improves security.
.angular
Excludes Angular cache and local build files to avoid unexpected behavior during Docker builds.
.env
Prevents sensitive environment variables from being included in the image. Environment values should be provided at runtime.
Commonly Ignored (Optional but Recommended)
- .vscode – editor-specific settings
- README.md – documentation only
- npm-debug.log – local error logs
- docker-compose.yml – used only for local setup
- Dockerfile – already used by Docker during build
- .gitignore – relevant only for Git
Nginx Configuration for Angular SPA
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
What This Configuration Does
- Listens on port 80
- Serves Angular static files
- Supports Angular client-side routing
- Prevents 404 errors on page refresh
Key Configuration Explained
listen 80;
Tells Nginx to accept HTTP requests on port 80, the standard port for web applications.
server_name localhost;
Defines the hostname this server responds to. Works for Docker containers, Render, and local testing.
root /usr/share/nginx/html;
Specifies the directory where Angular build files are stored
(index.html, JavaScript, assets).
index index.html;
Sets index.html as the default file served at /.
Angular Routing Support (Most Important)
location /
Handles all incoming routes such as
/, /home, /about, /login.
try_files $uri $uri/ /index.html;
Ensures Angular SPA routing works correctly:
- Serves static files if they exist
- Falls back to
index.htmlfor client-side routes - Lets Angular Router handle navigation
Result
- No 404 error on page refresh
- Direct URL access works (
/home,/about) - Angular app loads correctly every time
Create and Run a Container
docker run -d --name mycontainer -p 8080:80 myimage:latest
- docker run – Create and start a container
- -d – Run in background (detached mode)
- --name – Assign container name
- -p 8080:80 – Map host port to container port
- myimage:latest – Image name and tag
Create Container Only
docker create --name mycontainer -p 8080:80 myimage:latest
Start Created Container
docker start mycontainer
Build a Docker Image
docker build -t myimagename:latest .
- docker build – Build image from Dockerfile
- -t – Tag image (name:version)
- . – Current directory (Dockerfile location)
Example
docker build -t shadabalamcse0/myappui:latest .
Build with Version
docker build -t shadabalamcse0/myappui:v1 .
Verify Images
docker images
Run Container with Interactive Terminal
docker run -it --name mycontainer ubuntu
- -it – Interactive terminal mode
- ubuntu – Base image
Example: Angular Nginx Container
docker run -d --name angular-app -p 8080:80 shadabalamcse0/myappui:latest
Result
These commands allow you to build images, create containers, run applications, and manage Docker deployments efficiently.
Tagging and Pushing a Docker Image to Docker Hub
After building a Docker image locally, you must tag it and push it to Docker Hub so it can be deployed or shared.
Step 1: Tag the Docker Image
docker tag myapp:latest shadabalamcse0/myappui:latest
Explanation:
- myapp:latest – Local Docker image
- shadabalamcse0 – Docker Hub username
- myappui – Repository name
- latest – Image tag (version)
Docker Hub image naming format:
username/repository:tag
Tagging does not create a new image; it only creates a new reference.
Step 2: Push the Image to Docker Hub
docker push shadabalamcse0/myappui:latest
What happens during push:
- Docker verifies login credentials
- Image layers are uploaded to Docker Hub
- Image becomes available on Docker Hub
No comments:
Post a Comment