Running Your First Container
Let's get hands-on. We'll run real containers that you'd actually use in an e-commerce project.
Your First Container
Start with a simple web server:
docker run nginx
You'll see:
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
...
The container is running, but your terminal is attached to it. Press Ctrl+C to stop.
Running in the Background
For real work, run containers in detached mode:
docker run -d nginx
Output:
a3f5c7d8e9b1234567890abcdef...
That long string is the container ID. The container is running in the background.
Listing Containers
See what's running:
docker ps
Output:
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
a3f5c7d8e9b1 nginx "/docker-entrypoint.…" Up 30 seconds 80/tcp quirky_newton
- CONTAINER ID - Unique identifier (use first few characters)
- IMAGE - What image it's running
- STATUS - Running, stopped, etc.
- PORTS - Network ports (not accessible yet!)
- NAMES - Auto-generated name (or custom)
Port Mapping
The nginx container runs on port 80, but we can't access it yet. Containers are isolated.
Let's map a port:
# Stop the old container first
docker stop a3f5 # Use your container ID
# Run with port mapping
docker run -d -p 8080:80 nginx
Now open http://localhost:8080 - you'll see the nginx welcome page!
The -p 8080:80 means: "Connect my port 8080 to the container's port 80"
Your browser → localhost:8080 → Container's port 80 → nginx
Running a Database
Let's run PostgreSQL - you'd need this for an e-commerce product catalog:
docker run -d \
--name shopflow-db \
-e POSTGRES_USER=shopflow \
-e POSTGRES_PASSWORD=secretpass \
-e POSTGRES_DB=products \
-p 5432:5432 \
postgres:15
Let's break this down:
| Flag | Purpose |
|---|---|
-d | Run in background |
--name shopflow-db | Give it a memorable name |
-e POSTGRES_USER=... | Set environment variable |
-p 5432:5432 | Map PostgreSQL port |
postgres:15 | Image name and version tag |
Check it's running:
docker ps
Connect to it:
docker exec -it shopflow-db psql -U shopflow -d products
You're now in the PostgreSQL shell! Try:
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2)
);
INSERT INTO products (name, price) VALUES ('Wireless Headphones', 79.99);
SELECT * FROM products;
Type \q to exit.
Running Redis (For Shopping Carts)
E-commerce apps often use Redis for session storage and carts:
docker run -d \
--name shopflow-cache \
-p 6379:6379 \
redis:7-alpine
The alpine tag means a smaller, lightweight version.
Test it:
docker exec -it shopflow-cache redis-cli
127.0.0.1:6379> SET cart:user123 '{"items":["SKU001","SKU002"]}'
OK
127.0.0.1:6379> GET cart:user123
"{\"items\":[\"SKU001\",\"SKU002\"]}"
127.0.0.1:6379> exit
Container Lifecycle Commands
# List running containers
docker ps
# List ALL containers (including stopped)
docker ps -a
# Stop a container
docker stop shopflow-db
# Start a stopped container
docker start shopflow-db
# Restart a container
docker restart shopflow-db
# Remove a stopped container
docker rm shopflow-db
# Force remove a running container
docker rm -f shopflow-db
# View container logs
docker logs shopflow-db
# Follow logs in real-time
docker logs -f shopflow-db
# Execute a command in a running container
docker exec -it shopflow-db bash
Quick Container Cleanup
After experimenting, clean up:
# Stop all running containers
docker stop $(docker ps -q)
# Remove all stopped containers
docker container prune
# Remove unused images
docker image prune
Naming Containers
Always name your containers for easier management:
# Without name - Docker generates one
docker run -d nginx
# Result: "quirky_newton" or some random name
# With name - you choose
docker run -d --name product-api nginx
# Result: "product-api" - easy to remember
# Reference by name
docker stop product-api
docker logs product-api
docker rm product-api
Interactive Containers
Sometimes you need a shell inside a container:
# Run a container and get a shell
docker run -it ubuntu bash
You're now inside an Ubuntu container! Try ls, pwd, etc. Type exit to leave (this stops the container).
For an already-running container:
docker exec -it shopflow-db bash
This opens a shell without stopping the container.
What We're Building Toward
Right now we have isolated containers:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ nginx │ │ postgres │ │ redis │
│ :8080 │ │ :5432 │ │ :6379 │
└─────────────┘ └─────────────┘ └─────────────┘
(isolated) (isolated) (isolated)
In upcoming lessons, we'll:
- Build custom images for our e-commerce APIs
- Connect containers together on a network
- Make data persist across restarts
- Orchestrate everything with Docker Compose
Key Takeaways
- docker run creates and starts containers
- -d runs in background, -p maps ports
- -e sets environment variables
- --name gives containers memorable names
- docker exec -it opens a shell in a container
- docker ps lists running containers
- docker logs shows container output
Next, let's write our first Dockerfile and build a custom image!