#Review#Docker#BeginnerDocker#VirtualMachine
What is docker 🚢
Docker is a platform for building, running and shipping applications. If it works from development then in production it definitely work .
Why the heck can something run in development but not in production ?
- ✅ One or more files missing when going in production
- ✅ Software version mismatch
- ✅ Different configuration settings
With Docker We can package up our application with everything it needs and run it anywhere, with any machine that has docker.
- ✅ All your package running in one plage
- ✅ Django 4
- ✅ Mysql 8
- ✅ Vue js
How does it work
#Container Docker Provides a container where your application runs from and when you give it to somebody, they will not even spend any time installing dependencies or shit like that. he will just run one command and everything installs like by magic. When we don’t need an application anymore, we can remove it with all it’s dependencies in one go
Docker Is really good at helping us
- 💡 Build
- 🔥 run
- [p] ship
virtual Machine Vs Container
Virtual Machine vs Container
- 💡 Virtaul Machine An abstraction of a machine (phisical hardware) Using a hypervisor such as virtaul box , vmware ,hyper-v you van create virtual machine
- [d] Cons with VM
- Each vm needs a full blown os
- slow to start
- Resource Intensive
- 🔥 Container An isolated Environment for running an application
- [u] Pros with Containers
- ✅ Allow running multiple apps in isolation
- ✅ Are lightweight
- ✅ Use os of the host
- ✅ start quickly
- ✅ Need less hardware resources
Docker Architecture
Docker has A Client -> Server architecture. The Server, also called Docker Engine Sits in the back and is in charge of creating containers. Unlike VM containers do not contain a full os , instead all containers, share the os of the host, The kernel of the os.
Windows Docker Containers
From windows 10, Windows Support A custom built linux kernel therefore, can run Windows and Linux Containers
Linux Docker Containers
On a linux machine we can only run Linux Containers.
Mac
Mac os has it’s own kernel and has not have native support for containers, so on mac we use A light Linux VM to run docker.
INSTALL DOCKER.
#installation#setup#Docker#command Simply go on docker website and follow the instructions! After Install Docker, Check wheter it is installed or not.
Development work flow
Your application and Docker
To start of, we take an application, regardless of where it is build from and we Dockerize it. You simply add a docker file. The Docker FIle Is simply a text file that has instructions to help docker backages your applicaiton into an image.
Docker Image
This image contains everything our app needs to run.
- [p] A cut-down Os
- [p] A runtime Environement (Node)
- [p] Application Files
- [p] Third-Party Libraries
- [p] Environment variables Once we have an Image, we tell docker to start a container, and that is how we run the app on our development server on our machine.
What about the image
Once we have the image we can push it to a docker registry such as docker hub which is just like pushing from git to github in it’s simple form. then we can move from The registry to the production.
- 💡 Local Computer
- [p] Docker Registry
- 🔥 Test/Production
Let’s Imagine A scenario.
Let’s Say you have a simple js program to print hello world in the console. and you would like to go to production. here are the steps you will need to follow on the computes.
- ✅ Start With an os
- ✅ Install Node
- ✅ Copy App files
- ✅ Run node appname.js
Docker to the Rescue
Sample Program Process to use Docker.
In our dir/ We have a file app.js And this file contains a hello word program. I would like to ship it up to production.
step1 Create a docker config file
#configfile#Dockerfile Create a file in your working directory and call it Dockerfile and in the file write your configurations so that docker can create an image using the instructions of that file
Step2 Your Configuration file
#script In your config file, write your config.
Step 3 Building Our image
#command Now we want to tell docker to package up our application,
Node alpine and size
Because we used node from Linux alpine we ended up using 112 mb, This image contains , Alpine linux, Node, and our file.
List All Images on my computer
Step 4 Running the Image
#command To run our application we simply run
and our program will run perfectly. and we can publish that application anywhere we want ! amazing !
Linux Review
#linux#comman#ubuntu Docker is really built on top of linux, therefore, it’s highly recommended to have some basics in linux
Installing ubuntu
#command To install ubuntu, simply get it from the hub with the command bellow , which will pull the image from the hub to your computer.
Shortcut
Instead of pull, you can also simply run :
The command above will run the ubuntu file if it is on your local machine otherwise, it will download it and then run it.
Running in the interactive mode
When we run the docker image of ubuntu with docker run ubuntu it started it but closed it after a while. To open a container you must use the interactive mode
docker run -it ubuntu
Docker Commands
List Running Processes
list running proccesses
TO List running proccesses you simply type
- [?] This will show the list of all running proccesses. Sometimes you want to see the list of all proccesses even stopped ones , That is when you use the flag -a
Running Ubuntu
Running ubuntu image
To run the ubuntu image you simply type docker run with the name of the image
Where
- 💡
root
: is the currently logged in use, by default is root who has the highest privilege- 💡
19a5..
: id is simply like the name of the machine/
: simply where we are at in the system#
: represent the highest privilege, in this case # is the root privilege
Running Containers vs Running images
When using docker you can run an image, which creates a new container, or simply run the previous container you had
Starting a new container with the run command
Starting a previously used container with the start command
Managing package manages
In this days, most os comes with package manages, such as
- pip
- npm
- yarn ..
- 💡 In ubuntu there is a package manager called
apt
: advanced package tool.
Install our first package
We want to install nano which is a basic text editor, then we simply type
The package database
In linux we have a package datatbase, it contains packages but none of them are installed. if you type
apt list
you will see a list of packages, you need to update the database so that new packages can be imported
Linux file system
In windows you have things like c:\windows , c:\users … In linux too you have directories too .
- 🔥
/
Is on the top of the hierarchy and it it the root- 💡 bin : Include binaries or programs
- 💡 boot : all the files for booting are in here
- 💡 dev: short for devices`(In linux everything is a file, so files that are need to acess devices are here)
- 💡 etc: Short for editable text configurations
- 💡 home: where users are installed
- 💡 root: home directory of the root user
- 💡 var: variables, where we have fiels that are updated freakwently
- 💡 lib: keeps library files
- 💡 proc: Include files that represent running processes
Environment Variables
just like we have variables in our programming languages, in linux you have environment variables that you can set to store config settings for our applications. so our application can read variables from the system
Commands to interact enviroment variables
- 💡 printenv
- This command is used to print all environment variables
- 💡 Here you will get variables like
- 💡 HOSTNAME
- PWD
- HOME
- PATH
- 💡 Here you will get variables like
PATH Environment variable
The path variable is there to help your os identify where programs are located at, to find a program in your computer, the os won’t look through your entire disk, it will simply read the path and know where to look at.
it list the paths separating the different sources by :
Print the value of a environment variable
Set Environemnt variables
#commans#export This is the command used to set the environment varaible.
- [!] Note This variable is only available in the current session
- 💡 To make it very consistent, then you have to add it to the .bashrc
Start, Stop, Restart a container
Listing All the containers
To list the running Containers you simply use
Sometimes you want to list all the containers even the stopped ones, and to do that you simply run the commans:
Start A previously opened container
To start a contain you simply use it’s id with the start comman, first you must list to know the id of the container you want to start then use the start command with -i to interact with it.
Reload the .bashrc file
Once you set a variable, alias or anything in the .bashrc file you need to restart it for the changes to take place, if you don’t want this you can simply restart it whith the source commans.
Managing Processes
A process is an instence of a running program, To see all the running processes or program we can use the ps command
Killing a program or process.
#commans#kill To Kill a process you must know it’s id Let’s run a process in the background with the & Command
Managing users
Login with a different user in docker
docker exec -it -u danielerat 2fder bash
Step 1
Check the id of the running containers
- 💡
docker ps
step2
Execute a bash session inside of the container
- 💡
Managing user
you can create a group and add users to certain groups. Users in a group have same permissions.
Adding new user
To add a new user you simply type the groupadd command
Adding user to group
List group of a user
TO list the groups the user is apart of you simply use the command
Permissions
Docker images, Building images
Having a solid understanding of building images is a must with docker You must have a solid understanding of
- 🔥 Creating docker files
- 🔥 versioning images
- 🔥 sharing images
- 🔥 saving and loading images
- 🔥 Reducing image size
- 🔥 Speeding up builds
Image Vs Containers
Image
An image contains all the files and application configurations needed to run an application, once we have an image we can start a container from it Contains:
- ✅ A cut down os
- ✅ Third-party libraries
- ✅ Application files
- ✅ Envrironment variables etc..
Container
A container it’s kinda like a virtual Machine, it provies an isolated environment for executing an application. so that we can start and stop a container, it’s just a process.
- ✅ Provides An isolated envrironment to run your apps
- ✅ Can be Stoppd and restarted as need
- ✅ It’s just a proccess in it’s simple form
Starting a container from the same image
When you start a container from the same image, by default you don’t inherit anything from that image, therefore , everything you have in the first container is not gonna be included in your second container.
- [!] A container gets all it’s file system from an image, but each container has it’s own right layer, what we write from one continer is invisible to the other container
- [p] Of course there is a way you can share data from one container to another.
The Container universe
Each container is an isolated universe.
Dockerizing your applications.
- 💡 Without Docker the steps of running a node project on a new machine looks like this:
- ✅ Install Node
- ✅ npm install (install all packages of the project)
- ✅ npm start (run the server)
- [u] This is very tidious, repetitive and time consuming. Now lets see how we can dockerize our app.
Docker File Instruction
The first step to dockerizing an application is to add a docker file to it. The Dockerfile contains instructions for building an image
Docker file Instructions
- 🔥 FROM : This is used to specify the base image
- 🔥 WORKDIR : Specify the working directory, so that all commands get runned within
- 🔥 COPY : Copying files and directory
- 🔥 ADD : Copying files and directory
- 🔥 RUN : For running linux commands
- 🔥 ENV : For setting environment variables
- 🔥 EXPOSE : For telling docker that our container is starting on a given port
- 🔥 USER : Specify who will run the application
- 🔥 CMD : Specify the command that should be executed when we start a container
- 🔥 ENTRYPOIN
Base image
Specify the base image, the base image can be an os or os+ a runtime environment if you are a c# developer, you want to start form a .net image, If you are from python developer, the from a python image, and js from a node image. you can find more from
Docker Configuration file:
Example steps of building your image.
Example of creating a docker image without application files.
Building An image
Building an image for your application
To Build an image for your application, you simply need to go in the directory where there is your docker config file then you execute the buld command .
You can list the images you have and the one you created will be apart
Starting the container with the created image
Running the image you created
Since you created your image from node:alpine , if you run the image, it will start a container with node environement
Running Container specigying a command
You can run an image by specifying the command you want to run, IN the case above , it would help you run the bash script when running your container instead of the node one.
In this container, We also have node, cause it is combined with alpine
Copying application files and directories to your docker image
- [!] For copying your application files you have two options to your hand: Copy and Add
- 💡 With the copy command we can copy one or many files within the same directory or sub dir you are working on. there is not way to copy files from other locations, just files from where there is the Dockerfile
Copy files and directory
Example of creating a docker image without application files.
- 💡 as you can see, we are using an absolute path /app/ when specifying the destination folder, sometimes you want to set a relative path from a certain point. that is when you use the WORKDIR command.
Setting the working dir for relative path
We set the WORKDIR configuration to set our relative path .
Ignoring some files in docker
#dockerignore#gitignore#ignore Sometimes you just wan to ignore files, either it is for optimization or simply to reduce your build
- 💡 Let’s say you have your node modules file, you simply don’t add them to your image,cause it will make those images big and hard to sharee.
- [p] Instead you want to ignore the file and install the dependencies after the image is done building!
dockerignore file
Files you would wan to be ignored when executing your builds should be added in a file called .dockerignore, this way these files in dockerignore are not going to be added to our image when building.
[!success ] you can install the files if it’s node module let’s say you ignore a node_module file, you can easily get these files back after starting your image
Reinstalling node modules
Since you ignored a file such as node modules to make your bilds faster, you might want to reinstall it to your image otherwise your app simply won’t run! To execute commands we use the RUN Command. #run
Executing with the run commna
FROM node:19.0.1-alpine3.16 WORKDIR /app COPY . . RUN npm install # the line above will install our node_modules and dependencies
Adding environment variables
#env#venv#variables let’s say you are wokring on your front end, and you would like to access the api for your backend over a specific url , then you might want to use environment variables #EVN
Executing with the run commna
FROM node:19.0.1-alpine3.16 WORKDIR /app COPY . . RUN npm install ENV API_URL='HTTP://api.myapp.com/' # Setting my environment variables.
Creating users and using them
- 💡 Sometimes you want to create a user so that even if a hacker somehow gets access to our container, they won’t be having root user permissions, this not be bale to write on our app
- 💡 For that we need to create a user and user that user inside of our app instead.
Running our image
To run our image to a new container we simply will have to run
docker run vuejs-app npm start
Command Instruction
#cmd#CMD#instructions Using the command instruction we can specify a default instruction to be executed. Meaning, instead of doing docker run veujs-app npm start to run the npm command we can use the CMD do help use be more clean
Running our image
Now running our image will simply look something like this
docker run vuejs-app
Docker layers
An image is simply a collection of several layers that are chained and executed one after another one, To view the build layers simply use:
docker history vuejs-app
Docker Cache
- 💡 In the implementation bellow we make use of the docker optimization to allow it not to install npm every time
- 🔥 To optimize your dockerfile you must
- 💡 Order Instructions that don’t change often on the top
- 💡 Order Instructions that does cange often on the bottom.
- 🔥 To optimize your dockerfile you must
Docker optimzation
Docker has an optimization built into it,
- 💡 If a layer Did not change, Then docker is gonna use it’s cash
RUN vs CMD
Why would we even want to use CMD looks like run can perfectly do that job
- 💡 RUN the run instruction is a built time instruction, it is executing at the time of building the image
- 💡 CMD This is a run time instruction, it is executed when starting the container
Add files and directories
Copy vs Add
- 🔥 Copy does the same thing as add but it has two more additional commands
- With add we can:
- Add a file from a url
- Add a zip file and add will uncompress it for you.
Add command
Add does what copy does with the ability of doing the above
Rebuilding your image
#build#rebuild To rebuild your image you simply use the build command
Running to see our copied files
- 💡 To run our application we simply use the run command
Docker run vs start
- 💡 The main difference between run and start docker is that
- 🔥 run creates a new container from an image and starts it,
- 🔥 start only starts an existing container that was previously created or stopped
Create a container and start it
To create and start a new container you simply use:
Start your previously created containers
To start the containers you previously had you simply run:
Revoming images
- 🔥 Sometimes when working in docker, you see those images with
<none>
in front of them, those are called, those are layers that are loose, when you rebuild your image docker create those layers and some point they lost relationship with your app
Removing those dangling images
To get ride of those zombies you simply use the prune command
Removing docker images
- 💡 All docker image management commads start with image
docker image your_cmd
To see the list of all commands you simply type
Removing Particular image
#rm To remove a particular image you must either have a name or id
Docker Tags
- 💡 Docker Tags are there to help use identify the version we are running in our environment, by default docker uses latest which is terrible, if you have a problem you won’t really know what version you are having issues with, therefore you should always add tags to your images
How to tag an image
- 🔥 You have several ways of tagging your images,
- 💡 You can tag them with
- 💡 name: beaver,buster : Your team knows what this is
- 💡 semantic versioning : 3.4.2 : common to team that does not release often
- 💡 build numbers: 77 : team that build very often
- 💡 You can tag them with
Adding your tag
To ass your tag you simply add it after your image name
Adding your tag after creating your image
Yes, you can add your tag after you have created your image, for that you simply use the tag command
docker image tag vuejs-app:latest vuejs-app:1
Removing your tag
Sometimes you might want to remove your image tag for that you use the remove command
docker image remove vuejs-app:1
Different version vs the lastest
- 💡 We have an image with tag 1 which is supposed to mean first version of our applicaiton.
- 💡 We made some changes and create another image with tag 2
- 💡 Now we have 3 images, first with 1 tag, second with 2 and last with latest tag, which simply points to 1
- 🔥 Listing our images
- 🔥 Creating a new image so simulate a new version (version2)
- 💡
docker build -t vuejs-app:2 .
- 💡
- 🔥 Listing our images again
- 💡 Now we have 3 versoin with the latest one simply pointing to the versoin 1
Change where latest is pointing to
As you can see the latest image is pointing to an older verison which is one, ther is a way you change where the image is pointing to with the tag command
- 💡 Now latest is pointing to the second version
Pushing our image to hub
- 💡 You can push your docker app to hub in simple steps - ✅ Step0: Create a repo in our hub(danielerat/vue-app) - 🔥 step1: Rename your image wit the name of your repo form hub - 🔥 step2: Login to docker terminal - 🔥 step3: push your docker file #push#login#hub
Docker Saving vs loading
- [p] Let’s say you want to save your docker image offline so that you can be able to reuse it on another machine. you can use docker hub but also there are command to do this offline
- 💡 This is simple you simply use the save to save it offline and load to load it in our docker
Saving your docker file offline
You can save your docker file offline using the save command
docker image save -o 'output_file_name image_name'
docker image save -o vue-app.tar vuejs-app:3
tar is simple the compressed version of the thing
Load your docker file to docker
You can also load your docker file to docker, you simply need to use the load command docker image load -i vue-app.tar
Working with containers
- 💡 Now let’s have a look on how we can work with containers in details
- 💡 Starting and Stopping containers
- 💡 Publishing ports
- 💡 vieweing logs
- 💡 Executing commands in containers
- 💡 removing containers
- 💡 Persisting data using volumes
- 💡 Sharing source code
Container Basics
Run a container
To run a given container from an image you use the run command.
Running a container in the detached mode aka Background
To run an image in the background you use the -d flag
Running a container with your favorite name
Docker automatically runs an image and assings a name to it, you can run a container and give it your favorite name.
How do i see the running containers
To see the running containers you simply use the ps comman
Viewing Logs
You have running containers, that is good, now what about them , they are in the background, you don’t know what’s happening , what is our server generates an error? What if something wrong happens, that is where we use the log command.
View Logs of docker
You can use the log command to view the logs of a running container in docker.
Publishing ports
you have an application running on a ginve port in your docker container let’s say localhost@3000 and you would like to access the application in your host computer, you simply can publish the port and access it to your machine.
- ✅ You need to publish a port to send trafic from your container to your host pc
Run container and publishing a part at the same time
You can run a container publishing a port at the same time. you just need the -p
Execute a command in a running container
#exec#execute What if you want to execute a command in a running container how do you do that ? You use the the exec command. differently from the docker run command you start a new container and run a command , docker exec we execute a command inside of a running container.
Execute a command in a running container
If you want to run a command in a running container you can use the exec command.
Stopping and running containers
#start#stop A container is such alight weight virtual machine, you can stop or start it! . for this you simply use the start or stop command.
Starting and stopping a container
You can start or stop a container using the approach bellow.
Docker start vs docker run
With docker run we create a new container and with docker start we start a stopped container
Removing a container
- 🔥 Yup, you can remove a running container, yes it is possible and for that you use the rm command.
Removing a container
Deleting all the stoppen
To delete all the running containers we use the prune command.
Container file system
#volumes Each container has it own file system that is invisible to other containers. If you have data that you would like not to delete, then you should not store them in a container, That is what volumes
Persisting data using volumes
#volume Volumes are storages outside of containers, It can be on the host or somewhere in the cloud. For that we use the volume command.
- 💡 With the Docker volume Command we ca
- 💡 create: create a volume
- 💡 inspect: Display detailed di
- 💡 ls: list volumes
- 💡 prune: Remove all unused local volumes
- 💡 rm: remove one or more volumes
Creating a new volume
To create a new volume we use the create command.
Inspecting a volume
To inspect a volume you use the inspect command
Using our volume in our container
We use the -v flag to set our volum
- [p] The beauty of volumes is that, if you delete a container, the data from the volume would still remain.
- 💡 We can share volumes between multiple containers
Copying files between the host and the container.
Sometimes we wan to copy files between the host and the container. lets say you have this huge log file you would lilke to analyse . and the best way of doing so is by bringing the file offline to your host computer.
- 💡 Docker has a copy command.
You can copy from host to container and container to host
To copy you simply use the copy command.
Sharing the resource code with a container.
- [?] So, you have a vue application running at localhost:8080 in your container, mapped to your port 8080 on your host and you would like to modify your codes. there are many approached you can fix this issue with:
- [!] You modify codes in your Host Computer and to your surprise nothing is working, if you are suprised you might want to revise the basics you piece of shit , you can fix the issue by rebuilding the immage and running a new container or also do something else:
Publishing Changes
This is just a way you can overcome the issue above,
- 🔥 For production: Build a new Image tag it properly and publish it.
- 🔥 For development :
- [-] you don’t want to build a new image it is simply time consuming
- [-] You don’t want to Copy file files too
- 🔥 Mapping: you can create a mapping between host and container
To create the mapping we can simply use the -v flag, used to map a volume.
- 🔥 You can map the host directory containing your project to the app directory inside of your container in development environemnt to avoid you create images all the time .
- 💡 TO share our source code with a container we use the -v to map the project directory to a directory in the container’s file system.
Running multi Container Apps
- 🔥 We saw all those commans to understand how docker compose works under the hood. now time to use the real stuff.
- 💡 In this sectoin we are going to cover
- 🔥 Docker Compose
- 🔥 Docker Networking
- 🔥 Database Migrations
- 🔥 Running Automated Test.
Docker Compose
- 💡 Docker compose, a tool built on top of docker engine, It makes it easy to start apps with multiple containers.
JSON and YAML format
- JSON : is a human readeable language for representing data
- Yaml : just used to represent data too but less clustered compared to json
- 🔥 Quite often we use yml for configurations and js for exchanging data
Compose file
building the docker images
To build the images of your app you simply run th ecommand bellow
Starting the application
- 🔥 Do run an application you simply use the up command, if our image are ready docker will start running them inside containers otherwise it will build the images automatically.
Viewing logs
To view logs we use the logs command to view logs accross all our apps
Deploying your Applicaiton
Installing docker machine
To install docker machine you must make sure to be on a linux or if you are using windows to simply use git bach
Checking your installation
Creating your driver to digital ocean
To provision a driver or a computer from digital ocean which is simply a computer where your container will be running from you can use the command bellow
Listing your created machine
Connecting to our remove machine
To connect to our remove machine we did provision with docker machine is as simple as SSHING into it!
Docker ReminderCommands
Command | Descritpion |
---|---|
docker pull package_name | Command To get an image from the docker hub to your pc |
docker ps | List of running containers |
docker ps -a | We see the list of running containers and the stopped ones too |
docker run -it package_name | This is to run a package in the interactive mode |
docker start -i container_id | This is to run a docker container of which you know the id |