Hello Docker 😄 
Tags: docker, devops, bash, linux
Published: 2020-12-25 18:58:54

In this story i will share my docker experience, so, be ready ! to know the most used container technologies in the hole world ! . I will help you to get started in docker also we will deep dive into cool features … , and by the end of this story you will be able to make your own projects using docker

## Common Docker commands
In this section I am going to show you the most used docker commands so let’s begin :

* To get info about your docker environment use : `docker info`
* To remove a container use : `docker rm <name | ID>`
* To remove an entire image use : `docker rmi <name | ID>`
* To remove a container after run use : `docker run --rm <name|ID>`
* To view current running containers use : `docker ps`
* To view all running and exited containers use: d`ocker ps -a`
* To view all and only the IDs of containers use : `docker ps -a -q`
* To get all images use : `docker images`
* To remove all images use : `docker rm $(docker ps -a -q)`
* To view the <none> images use : `docker images -f"dangling=true"`
* To remove them use : `docker rmi $(docker images -f"dangling=true" -q)`
* To run the container in background use : `docker run -d ... <name|ID>`
That’s enough for now 😆, no lets build a simple python project with flask

## The Flask app

Flask is a simple and powerful Framework for python like apache or tomcat... So let's begin :

app.py
```python
from flask import Flask
app = Flask(__name__)

@app.route("/")
    def hello():
        return "Hello My Name is Hatem"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)
```

Make sure to install `flask` with `pip install flask` and run the script with python `app.py` and open your browser on `localhost:8080/` .

Let’s generate the `requirements.txt` , we will not use `pip freeze` here (we are not in a virtual environment) but we will use pipreqs and make sure to install it with `pip install pipreqs` .
use `pipreqs <path to the python project>` to generate it.
Now let’s write the Dockerfile :

Dockerfile
```dockerfile
FROM python:latest
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
CMD python app.py
```

`FROM python:latest` : using python as a base image.
`WORKDIR /app` : using /app as a default directory.
`COPY requirements.txt .` copy this file to /app
`RUN pip install -r req..txt` : install the required dependencies
`COPY app.py .` : copy the app script to /app
`CMD python app.py` : The container entry point when we run it

Run the build process with docker build -t hello_flask .
Run the container `docker rn --rm -p 8080: 8080 hello_flask` , the `-p 8080:8080` : will map the port 8080 on your host to the port 8080 in your container → this is the port mapping in docker, you can change the host port to any port you want and must be > 1024 ( ports < 1024 are reserved by the system).

## Environment variables in Docker

An environment variable is a variable whose value is set outside the program, typically through the functionality built into the operating system or microservice. An environment variable is made up of a name/value pair, and any number may be created and available for reference at a point in time.
→ [source](https://medium.com/chingu/an-introduction-to-environment-variables-and-how-to-use-them-f602f66d15fa) for more information.
let’s use them in our example :
```python
import os 
...
@app.route("/")
def hello():
    return "Hello My Name is {}".format(os.environ['NAME'])
```
the `os.environ['NAME']` will fetch the NAME variable and get its value and return it in the browser.
make sure to build the container again and run it like this :
`docker run --rm -p 8080:8080 -e "NAME=steve" hello_flask`

##Volumes with Docker

In order to be able to save (`persist`) data and also to share data between containers, Docker came up with the concept of volumes. Quite simply, volumes are directories (or files) that are outside of the default Union File System and exist as normal directories and files on the host filesystem.
→ [source](https://blog.container-solutions.com/understanding-volumes-docker)
let’s make some change to our script :

```python
@app.route("/name_from_file")
def name_from_file():
    with open("files/name.txt","r") as file :
        name= file.readline()
    return "Hello My Name is {}".format(name)
```

Make sure to add a directory named “files” and add a file named “name.txt” that contains your name or whatever you want.
Now make the build again ! and run it with this command :
`docker run --rm -v ${PWD}/files:/app/files -e "NAME=steve" -p 8080:8080 hello_flask`

Now open your browser and type `localhost:8080/name_from_file` , you should see the name that you already add it in the name.txt file. In this case, you can change the content of the file in real-time and reload the page, you should see the changes 😆.

## Saving and publishing images

After finalizing your work there are two things you should do :

* Saving images to tarballs or compressed archives
* Publishing images to registries to be used in public or private…

Let's begin by saving our example image to a tarball by running this command `docker save --output hello_flask.tar hello_flask` , now, check your current directory and type in the terminal `ls -sh hello_flask.tar` to get the archive size. if you want to reduce the archive size use the gzip command which is compression tools. Execute this command :

`docker save hello_flask | gzip > hello_flask.tar.gz`
 
and check the size again 😃. you can now upload them to your cloud storage or wherever you want. Now if you want to load the tar file to the docker engine simply run :

`docker image load -i=hello_flask.tar`

Docker hub is our target now, to publish images in it you have to make an account first. the image name must be with this syntax `account_name/image_name:image_tag` so let's rename our image by running this command :

`docker tag hello_flask hatembt/hello_flask:latest`

Now you have to log in to your account and push the image to the public :

`docker login` 
`docker push hatembt/hello_flask:latest`

To pull the image just run `docker pull hatembt/hello_flask:latest` , no need for credentials here 😃 .

Finally, I hope that this tutorial is helpful to everyone who wants to know docker.
Thank you 😃