Run a container in Docker
Learn how to run Docker containers from images, map ports, use detached mode, and assign custom container names.
Lesson Content
Docker images contain everything needed to run an application. You can think of them as a pre-configured operating system sitting on your hard drive. But images themselves don't do anything until you start them up.
To actually run a service, we can create a container from an image. A container is just a running instance of an image, and it’s fully isolated from other running containers.
Run a Docker container
Let's spin up an Nginx web server to see this in action:
docker container run nginx
This is such a common command, that we can leave off the “container” part and just run:
docker run nginx
Docker first checks if you have the Nginx image locally. If you don’t, Docker automatically pulls it down from Docker Hub and fires it up.
What you're seeing in terminal is called STDOUT (standard out). It's basically the output from whatever command the container runs:
2025/09/12 14:52:41 [notice] 1#1: using the "epoll" event method
2025/09/12 14:52:41 [notice] 1#1: nginx/1.29.1
2025/09/12 14:52:41 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14+deb12u1)
2025/09/12 14:52:41 [notice] 1#1: start worker processes
2025/09/12 14:52:41 [notice] 1#1: start worker process 29
2025/09/12 14:52:41 [notice] 1#1: start worker process 30
[...]
We can see that the Nginx service started, and it kicked off some worker processes to handle web requests.
Expose Docker ports
Now normally, you'd hit http://localhost and see your web server. But Docker is built to be secure out-of-the-box, and locks down all services by default.
This means we need to explicitly expose a port to access our service.
Hit Ctrl+C to stop the container. Now let's restart it with port mapping using the -p
flag:
docker run -p 8000:80 nginx
Here, we are mapping port 8000 on our machine to port 80 inside the container, which is the port that Nginx runs on.
Now when we visit http://localhost:8000/ in our web browser, we’ll see the “Welcome to nginx!” page. And if we check terminal, we’ll see the request logs streaming in.
Note: Not every container needs ports exposed. Some Docker images just run a task and exit, such as a database migration or a batch job.
Run Docker services in the background
Having logs stream right to your terminal is great for debugging, but it also hogs up a terminal window.
Lets stop the container with Ctrl+C, and then restart it with the -d
flag for detached mode:
docker run -p 8000:80 -d nginx
You'll get back a long string of characters (which is your container ID), then you're back at the prompt.
But the container is still running in the background. If you visit http://localhost:8000/ again you’ll see that it still responds to requests, but the logs aren’t cluttering up your terminal anymore.
Name Docker containers
Let’s see all of the running Docker containers:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
46419ee3e580 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:8000->80/tcp, [::]:8000->80/tcp thirsty_visvesvaraya
You get the container ID, status, port mappings, and... wait, what's up with that name?
Docker’s got a sense of humor. When you don't name your container, it generates one for you — and they're always really unique, fun and bizarre.
Lets start another container, but this time we will tone things down a bit by giving it a proper name using the --name
flag:
docker run --name myapp -p 8001:80 -d nginx
Now, check your containers again:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a83448c5881 nginx "/docker-entrypoint.…" 49 seconds ago Up 49 seconds 0.0.0.0:8001->80/tcp, [::]:8001->80/tcp myapp
46419ee3e580 nginx "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 0.0.0.0:8000->80/tcp, [::]:8000->80/tcp crazy_stonebraker
This is much better! Named containers make a lot more sense, and make containers way easier to reference later, as you can now reference the name rather than the container ID.