Docker Commands Flashcards
Understand Docker Commands
FROM ruby:2.6
Start new container based on ruby:2.6 as base image
FROM ruby:2.6
what registry will this hit?
Docker Hub, most likely, as no other registry is specified
apt-get update -yqq
update apt-get
Update local package manifest with online registry. ` -y ` means say yes to any prompts. -qq
means do it quietly
RUN apt-get install -yqq --no-install-recommends nodejs
Install nodejs, do not install recommended (but not required) packages, say yes to all prompts, do it quietly
COPY . /usr/src/app/
Copy our rails app code at .
, always relative to where Dockerfile is, so it is baked into the image,
WORKDIR /usr/src/app
CD
into /usr/src/app
of image
RUN bundle install
run bundle install
within container’s current working directory
Run Rails Dockerfile
syntax to run test
container Rails server
docker run -p 3000:3000 test bin/rails s -b 0.0.0.0
what is this doing?
docker run -p 3000:3000 test bin/rails s -b 0.0.0.0
Runs docker container named test
, publish container port 3000 mapped to local port 3000, runs rails server on IP address 0.0.0.0
address 0.0.0.0 (localhost) port 3000 mapped to docker container port 30
what is the -b 0.0.0.0
doing here
bin/rails s -b 0.0.0.0
This is telling the rails server in the container to bind to all IPv4 addresses within the container. Our local host @ port 3000 only points to the IP address of the rails server in the container, but we have no idea what that IP address will be ahead of time, so we bind the Rails server to all IP addresses in the container
Docker command to list all images
docker images
Docker command to list running containers
docker ps
last command in Dockerfile to run Rails server as the default action on starting the container
Bonus: What type of command is this?
CMD ["bin/rails", "s", "-b", "0.0.0.0"]
`bin/rail
Exec form! bin/rails
is first command executed by container
The "-b", "0.0.0.0"
part is typically used in the context of a command to bind a service to all available IP addresses on the host machine.
In a Dockerfile, this is often seen in commands that start a server. For example, in a Ruby on Rails application, you might see:
```dockerfile
CMD [“rails”, “server”, “-b”, “0.0.0.0”]
~~~
Here’s what it does:
- -b
is a flag that stands for “bind”.
- 0.0.0.0
is a special IP address that tells the server to listen on all available network interfaces.
This is useful in a Docker container because it allows the service running inside the container to be accessible from outside the container, not just from within the container itself.
How does Dockerfile build caching work?
Docker will build a cache corresponding to each instruciton, or step, in the Dockerfile
What happens if a step or instruction changes in the Dockerfile
Docker must rebuild that step and all subsequent steps, cannot use cache
vim
is added later, why is this an issue?
RUN apt-get update -yqq RUN apt-get install\ -yqq --no-install-recommends\ nodejs ### becomes ... RUN apt-get update -yqq RUN apt-get install\ -yqq --no-install-recommends\ nodejs vim
RUN apt-get update -yqq
this line will be cached, so you never get updates for newly added packages in the next line that changes as packages are added
What does COPY Gemfile* /usr/src/app/
on its own line do for us?
COPY Gemfile* /usr/src/app/ WORKDIR /usr/src/app RUN bundle install
This allows Gemfile
and Gemfile.lock
to be cached in their own layer. This way, changes to the codebase, or other parts of the Dockerfile after this line, will not trigger a gemfile cache rebuild and re-bundle install
, which will happen if docker detects a change to the Gemfiles
what happens when you run docker-compose up
- D creates a speperate network just for the app
- Creates non-locally hosted volumes defined in the app
- Builds an image for any servies with a
build
directive - Creates a container for each services
- Launches a container per servies
Network, volumes, images, containers, launch
what is this line in docker-compose.yml doing?
volumes: - .:/usr/src/app
Mounts the CWD in our local machine to /usr/src/app
is COPY
always relative to where the Dockerfile is located? What about WORKDIR
changing this?
Yes. Even if you do WORKDIR
, this only changes the working dir in the image, RUN
commands are always run in WORKDIR
What does this do for us? Explain the utility. Why the --rm
flag?
docker-compose run --rm web rails db:migrate
This is how we run one-off instructions in our contianerized application. This asks a newly created web service container to run a rails command. It then deletes the spun off container with --rm
, otherwise that one-off container would remain.
Command to rebuild the Rails app (web service) image, with docker-compose
docker-compose build web
docker-compose command to rebuild web service
docker-compose build web
Docker Compose cmd to run command in already running web service container
docker-compose exec web <command>
explain Dockerfile and docker-compose and how they work together
Dockerfile: Defines how to build a single Docker image, specifying the steps to create the image, including the base image, dependencies, and commands to run.
docker-compose.yml: Manages multiple Docker containers as services, organizing them into a network. It specifies how the containers should interact, their configurations, and how they should be linked together.
docker-compose cmd to get into rails console of web service
docker-compose exec web rails console
what does docker-compose up
do?
The docker-compose up command does the following:
Builds Images: If the images specified in the docker-compose.yml file do not exist, it will build them using the specified Dockerfiles.
Creates Containers: It creates the containers as specified in the docker-compose.yml file.
Starts Containers: It starts the containers and runs them in the background.
Creates Networks: It creates any networks specified in the docker-compose.yml file.
Creates Volumes: It creates any volumes specified in the docker-compose.yml file.
In essence, docker-compose
up sets up and runs the entire multi-container Docker application as defined in the docker-compose.yml file.
What does this do? Why don’t we specify a port?
redis: image: "redis"
This adds a new service called redis. Instead of being built from a Dockerfile, it’s sourced from the official redis image directly. We do not publish a port because redis doesn’t need to be externally accessible. And we don’t want it to be for security reasons.
How would we start our Redis service?
docker-compose up -d redis
What does this mean?
docker-compose run --rm redis redis-cli -h redis
This command says, “In a throwaway container (--rm)
for the redis service, run the command redis-cli -h redis
.” On running it, you should see the standard Redis prompt showing the hostname and port it’s running on:
how to list your docker-compose networks?
docker network ls
How do containers on composed network find each other?
All Docker networks (except for the legacy bridge network) have built-in Domain Name System (DNS) name resolution. That means that we can communicate with other containers running on the same network by name. Compose uses the service name (as defined in our docker-compose.yml) as the DNS entry. So if we wanted to reach our web service, that’s accessible via the hostname web. This provides a basic form of service discovery—a consistent way of finding container-based services, even across container restarts.
What does the -h redis
part of this mean?
docker-compose run --rm redis redis-cli -h redis
This is telling Docker to connect the throw-away container to the host named redis. The name works because of Dockers built-in DNS resolution. All services have DNS names based on their service names from the config.
If we add to our Gemfile, what do we need to do to make it take effect?
Docker Compose
Stop running the Rails service. Rebuild the image.docker-compose stop web
and docker-compose build web
This just works, why?
redis = Redis.new(host: "redis", port: 6379)
Because we have a service named redis as per our DC file. Docker made a DNS enable network so that all the services in the app can communicate.
port 6379 is the default redis port we’d expect.
In this command, what does --rm
do?
docker compose run --rm database psql -U postgres -h database
This makes it clear that we want to throw away the container after running it.
What is the database
part?
docker compose run --rm database psql -U postgres -h database
This is asking us to run a container based on the database
service image
what does this part do? psql -U postgres -h database
docker compose run --rm db psql -U postgres -h database
This overwrites the default image CMD. This invokes psql
with user postgres, connecting to host database
what is the d
docker run -d
-d
or --detach
. Run the container in background and print container ID
After running dcomp
, how to start rails console on web
?
docker compose run --rm web rails console
need to verify this works via messing with the models