- Developers who want to
understand what the hell islearn Docker but not sure where to begin
Note : PHP is used in most examples/samples below, and you can replace that with any other language/runtime environment
- Get a new system (Desktop/Laptop)
- Power it up / Switch it on
- Run-some-commands/install-some-stuff so that you can execute your program/code (in your choice of programming language/run-time environment)
There will be more steps involved here, like:- Update the system
sudo apt update
(or justapt update
if logged in as root) - Install PHP (or Node.js/Java/RoR - whatever) - I don't remember the command to install (Google it please)
- Install
git
by runningsudo apt install git
- considering that you would be using GitHub, BitBucket, GitLab or some othergit
provider - Install
zip
by runningsudo apt install zip
- required for a lot of stuf (especially by package managers) - Install
composer
(ornpm
, if using Node.js) - the package managers itself - Install a whole lot of other dependencies for the language (PHP/Node.js) or the extensions/helpers - DB/Cache/JSON and what not
- Update the system
And THEN you clone/copy your code in the above machine and start adding bugs to the code.
- Get a docker image from hub.docker.com (also called "Docker hub") or build a new one on your own - Equivalent of "Getting a new system"
- Run the docker image : A running docker image is called "container" - Equivalent of "Powering up a system"
- Run-some-commands/install-some-stuff so that you can execute your program/code - Equivalent of executing your program/code on your system (same sub-steps are applicable)
And THEN you clone/copy your code in the above machine and start adding bugs to the code.
(Yeah, that still happens)
Because that's what programming/coding is - adding bugs to a system.
Oh!
If you have to run more than 1 projects with different PHP(or Node.js ...) versions then you would not go ahead and get a new system.
- Of course not
- In such a scenario, I will usually install multiple versions of the language
But there are other dependencies as well (not just the language version) e.g. Apache/Express versions, extensions (like DB/Cache/JSON etc), conflicting/complicated config issues (and more such issues)
- Ok, I think I get it
- I have faced issues when trying to manage multiple versions of something
- So, Docker keeps everything separate, and not just the language version?
Yes!
- At first you had my curiousity but now you have my attention!
- I request elaboration
The fun / practical stuff
Prerequisite : Install Docker
CLI
Installing Docker is enough for the sake of this post, but install docker-compose
as well, since that will be needed very soon
-
Know what you need : E.g. "PHP 7.4 or 8.0 on Apache or Nginx" or "Nodejs 14 or 16 on Express" or any other variant/combination
-
Go shopping at hub.docker.com : This is the official Docker hub containing the "docker images" (the "system", that is), and find the image that you have identified
E.g.
I need the most recent PHP 8.x machine with Apache and I found the following docker image - "php:8-apache" -
Run the command
docker pull php:8-apache
to download the docker image from hub.docker.com to your local system so that you can start using it (by "switching it on")
Now you have got yourself a "new system" that you can start using.
Note : You can build your own Docker image, just like you would "build" your own system, with specific software already installed. More on this soon.
Now that we have downloaded the PHP 8 image, power it up by running the command:
docker run --detach --name my-php8-apache-system php:8-apache
When docker "runs" an "image", it is called a "container".
Command breakdown, along with flags:
docker
: Obviouslyrun
: Again, obviously--detach
or-d
: Run the image as a "container" in the "detached" mode so that CLI can be used for something else--name my-php8-apache-system
: We give the running container a name, and if not provided, then Docker will assign a random namephp:8-apache
: The "image" that should be used to "run" the container
Same command with short-format and without the custom name becomes as follow:
docker run -d php:8-apache
This will run the container in "detach" mode, and will be assigned a random name by Docker.
To check the running containers, you run the command:
docker ps
Since this is a command and the "system" that is "Powered up" is "virtual/software based", you can run as many systems as you want
So, basically, everytime you run docker run -d php:8-apache
a new and independent system/container is created
From this point onward, I will call "container" a "container", and not "system"
Running image = Container
Analogy in programming would be that "An image is to a container" what "A class is to an object".
Object is a "running / instantiated" class
Container is a "running / instantiated" image
While we have a PHP enabled system available to us, we might need to install more things on the system depending on the project requirements.
E.g.
- Extensions like JSON/XML/zip/mbstring etc
- PDO for MySQL, Postgres, MariaDB etc
- Xdebug (or any other debugger)
- Enable/disable certain Apache modules, like mod-rewrite (the most common one)
- Composer (the package manager)
- Some more stuff like this (you get the idea)
The simplest command to run would be to check the PHP version
php -v
To run this command on the running docker container, the command needs to be sent to the docker container, as follow:
docker exec -it my-php8-apache-system php -v
Command breakdown, along with flags:
docker
: Obviouslyexec
: Again, obviously-it
: To allow showing output of the given commands : - execute the command in interactive (-i
)/pseudo-TTY (-t
) modemy-php8-apache-system
: The running container's name (or ID fromdocker ps
)php -v
: The command that is supposed to run on the container
The result that I got was PHP 8.0.9
(and some more meta info)
While running the command php -v
on my local system the output is PHP 7.4.5
Clearly showing that the given command (php -v
) has been executed on the container, using the image that was downloaded, and not using my local system
Probable next step would be to use the command format to run-command/install-stuff on the container
At first you had my curiousity but now you have my attention!