{"id":26469823,"url":"https://github.com/ocdbytes/docker_basics","last_synced_at":"2025-09-15T07:05:46.628Z","repository":{"id":113749471,"uuid":"500564827","full_name":"ocdbytes/Docker_Basics","owner":"ocdbytes","description":"This is a Docker Cheatsheet kind of to revise the concepts time to time and contains all the basic operations performed in docker and all the basic features","archived":false,"fork":false,"pushed_at":"2022-06-10T20:39:26.000Z","size":26,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-19T17:09:27.349Z","etag":null,"topics":["container","docker","docker-container","docker-image","dockerfile"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ocdbytes.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-06-06T19:20:45.000Z","updated_at":"2022-06-11T09:23:20.000Z","dependencies_parsed_at":"2023-03-15T11:30:52.341Z","dependency_job_id":null,"html_url":"https://github.com/ocdbytes/Docker_Basics","commit_stats":null,"previous_names":["ocdbytes/docker_basics"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ocdbytes/Docker_Basics","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocdbytes%2FDocker_Basics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocdbytes%2FDocker_Basics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocdbytes%2FDocker_Basics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocdbytes%2FDocker_Basics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ocdbytes","download_url":"https://codeload.github.com/ocdbytes/Docker_Basics/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocdbytes%2FDocker_Basics/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275219688,"owners_count":25425929,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-15T02:00:09.272Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["container","docker","docker-container","docker-image","dockerfile"],"created_at":"2025-03-19T17:09:30.753Z","updated_at":"2025-09-15T07:05:46.607Z","avatar_url":"https://github.com/ocdbytes.png","language":null,"readme":"# Docker Basics 🐳\n\n### What is Docker ?\n\nDocker is a platform as a service (PaaS) that provides us the instances of the services which we need to run on our system without getting into too much trouble of getting latest versions and all but to just simply do a \"docker run\" 🚀\n\n### Docker Commands :\n\n- Run (start a container)\n```bash\ndocker run \u003cimage_name\u003e\n\n# Eg: docker run nginx\n```\n\n- PS (list all the running containers)\n```bash\n# To get all the container currently running\ndocker ps\n\n# To get all the containers currently and previously running\ndocker ps -a\n```\n\n- Stop (to stop the docker container)\n```bash\ndocker stop \u003ccontainer id / container name\u003e\n```\n\n- Rm (to remove a container permanently)\n```bash\ndocker rm \u003ccontainer id / container name\u003e\n```\n\n- images (to list images)\n```bash\ndocker images\n\n# to delete images\ndocker rmi \u003cimage_name\u003e\n\n!!remember to first delete the containers used by the image you are going to delete!!\n```\n\n- pull (to download the image)\n```bash\ndocker pull \u003cimage_name\u003e\n```\n\n\n----------------------------------------------------------\n**IMPORTANT :**\nIn case of os images when we run it using \"docker run ubuntu\" it will not show up in the running containers because the container is not configured to run operating systems so it will exit as soon as it runs. So we can also use **sleep** command to just sleep the container after running\n```bash\ndocker run ubuntu sleep 100\n```\n----------------------------------------------------------\n\n\n\n- Exec (execute a command)\nSuppose we need to find the contents of the file in the running image\n```bash\n# To get the container id / container name\ndocker ps -a\n\n# We want to see the /etc/hosts file\ndocker exec \u003ccontainer_name / container_id\u003e cat /etc/hosts\n```\n\n\n### Attach and Detach \nIn docker we can run our applications in both attach and detach modes like in detach mode we can run our application in background and vice versa\n```bash\n# Run a web application for example\ndocker run \u003ccontainer_name\u003e/\u003capplication\u003e\n\n# for running in detach mode\ndocker run -d \u003ccontainer_name\u003e/\u003capplication\u003e\n\n# To attach to the container anytime\ndocker attach \u003ccontainer_id\u003e\n```\n\n### Run Command\n\n- **TAG**\n\nThis is to specify the version of the image we need to run or pull in our docker by default it is set to latest\n```bash\ndocker run redis:\u003cversion\u003e\n```\n\n- **STDIN**\n\nBy default docker doesn't allow us to take the input as it is for taking an input we need to specify our stdin (-i = interactive mode) tag to allow inputs and (-t = psuedo terminal mode) to show the prompt\n```bash\n# This will run in interactive mode\ndocker run -i \u003cimage_name\u003e/\u003cprogram\u003e\n\n# This will run in terminal mode (will show prompt as well)\ndocker run -it \u003cimage_name\u003e/\u003cprogram\u003e\n```\n\n- **PORT MAPPING**\n\nIn docker every container is assigned its own IP and is only accessible from inside or locally in docker host now to make that application accessible to everyone we can use port forwarding and we can also create multiple instances of a single application on different ports.\n```bash\n# Suppose when we run our application it runs on port 5000\ndocker run \u003cdocker_image_name\u003e/\u003capplication\u003e\n\n# PORT FORWARDING\ndocker run -p 80:5000 \u003cdocker_image_name\u003e/\u003capplication\u003e\n# Now this application will be avialable on port 80 of the docker host's IP\n# MULTIPLE INSTANCES\ndocker run -p 8000:5000 \u003cdocker_image_name\u003e/\u003capplication\u003e\n```\n\n- **VOLUME MAPPING**\n\nIn docker if we delete our container our data will get lost so in order to cut that possibility out we will use volume mapping this will map our data in our container with a storage in our docker host. For eg : \nWhen we run our mysql the data we put in it is stored in container location of /var/lib/mysql now we will map this container with a local folder at path /opt/datadir\n\n```bash\ndocker run -v /var/lib/mysql:/opt/datadir mysql\n```\n\n- **INSPECT**\n\nTo get more details about a container\n```bash\ndocker inspect \u003ccontainer_name\u003e\n```\n\n- **LOGS**\n\nTo display container logs in stdout (if application is running in detached mode)\n```bash\ndocker logs \u003ccontainer_name\u003e\n```\n\n### Docker Environment Variables\n\nNow if we need to set some environment variables such as some value or API keys for an application so for that we will set our ENV variable in our docker container Now if we want to run our application using different variables we can use it using -e tag\n```bash\n# We can also run multiple instances of an application with different ENV variables\ndocker run -e APP_COLOR=blue \u003ccontainer_name\u003e\ndocker run -e APP_COLOR=red \u003ccontainer_name\u003e\n```\n\n\n### How to create a Docker image ?\n\nIn order to create a docker image we need to create a file in our code folder which will execute the commands in which docker can understand.\n\n```Dockerfile\nFROM Ubuntu\n\nRUN apt-get update\nRUN apt-get install python\n\nRUN pip install flask\nRUN pip install flask-mysql\n\nCOPY . ./opt/source-code\n\nENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run\n```\n\nTo make our image we will use docker build command and then push to deploy it\n```bash\ndocker build Dockerfile -t \u003cimage_name\u003e/\u003ccustom_name\u003e\ndocker push \u003cimage_name\u003e/\u003ccustom_name\u003e\n```\n\n### ENTRYPOINT \u0026 CMD\n\nHere while making our Dockerfile we can set our command which we want to run on the system. Now we can set the command using CMD and entrypoint both Now for example we have a Ubuntu machine (ubuntu-sleeper) which is going to sleep for 5 secs and then close so the Dockerfile for this machine will look as :\n```Dockerfile\nFROM Ubuntu\n\nENTRYPOINT [\"sleep\"]\n\nCMD [\"5\"]\n```\n\nHere we can modify the CMD input which is 5 (hard coded) by using:\n```bash\ndocker run ubuntu-sleeper 10\n\n# here 10 will replace the hard coded 5\n```\n\nWe can also modify the entrypoint using the (--entrypoint) tag:\n```bash\ndocker run --entrypoint sleep2.0 ubuntu-sleeper 10\n```\nNow this will run ubuntu-sleeper with entry point sleep2.0 and CMD variable as 10\n\n\n### Networking in Docker containers\n\nIn docker the containers are given their own IP generally in range of 172.x.x.x and all the containers in a network can access each other and if you want them to be avialable to external hosts we can map the ports using the method discussed above. Some examples :\n\n```bash\n# This will run in default network\ndocker run ubuntu\n\n# This will run the container in none of the network\ndocker run ubuntu --network=none\n\n# This will run the container directly on the host we don't need to map it to the host ports\ndocker run ubuntu --network=host\n```\n\n#### User Defined Networks\n\nWe can also define internal networks according to our need.\n```bash\ndocker network ls\n```\nOUTPUT:\n```bash\nNETWORK ID     NAME      DRIVER    SCOPE\n0549525f4ad0   bridge    bridge    local\n3a74ad9d9a15   host      host      local\nc9ff82a29e73   none      null      local\n```\n\nNow to create our own network we can use command to create custom network with our own defined subnet.\n```bash\ndocker network create \\\n  --driver bridge \\\n  --subnet 182.18.0.0/16\n  \u003ccustom_network_name\u003e\n```\n\nTo get network details of a container\n```bash\ndocker inspect \u003ccontainer_name\u003e\n# there will be saperate section for it\n```\n\nNow if we need to connect two services running in docker so instead of using the docker assigned IP we can simply use container name directly and it is managed by docker itself -\u003e\n\nFor Eg : \n```bash\n---------------------------\n|    HOST    |     IP     |\n|--------------------------\n|  mysql_A   | 172.x.x.1. |\n|--------------------------\n|  nodejs1   | 172.x.x.2  |\n---------------------------\n```\n\n### Storage\n\nIn docker when we build a container we cannot edit it further and it becomes a read only layer (image layer). Now if we run the container if forms a read-write layer (container layer) and that layer is modifiable but it's data will be lost if container is crashed or closed. Now the folder structure that docker uses is something like this:\n\n```bash\n/var/lib/docker\n         |\n         ---- /image\n         |\n         ---- /containers\n         |\n         ---- /network\n         |\n         ---- /volumes\n         |\n         .....\n```\n\nThis directory is not accessible directly in MacOS so we need to run:\n```bash\ndocker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh\n```\n\nNow if we create a volume in docker it will create a new one in /volumes directory\n```bash\ndocker volume create \u003cvolume_name\u003e\n```\n\nNow we can map our storage with any container's storage so that our data will get stored in that\n```bash\ndocker run -v \u003cvolume_name\u003e:\u003cimage_volume_path\u003e \u003cimage_name\u003e\n```\nThis whole volume map is known as **Volume Mounting**\n\n\nNow the another form of mounting is called **Data Mounting / Bind Mounting**\nIn this situation if I have some data on the docker host and i want to mount it to my docker container then we will use :\n```bash\ndocker run -v /data/\u003cfile_name\u003e:\u003cimage_volume_path\u003e \u003cimage_name\u003e\n\n# using -v is an old way of doing things\n# We can use --mount a more prefferable way of doing the same thing\n\ndocker run --mount type=bind,source=/data/\u003cfile_name\u003e,target=\u003cimage_volume_path\u003e \u003cimage_name\u003e\n```\n\n## Docker Compose\n\nInstead of running the services saperately we can define a docker-compose.yml file which will contain all the configs which we want to run the file as. This file looks as :\n```yml\nservices:\n  web:\n    image: \"\u003cimage_name\u003e/\u003capp_folder\u003e\"\n  database:\n    image: \"redis\"\n```\nThis file above is a version 1 of docker_compose with no network support\n\nhttps://github.com/dockersamples/example-voting-app\n\nLet's take an exmaple of a simple voting application with 5 services to be linked together :\n- Redis DB\n- PostgreSQL\n- Python Application\n- Node Js Application\n- .Net service worker\n\nNow if we first write our run commands in order to generate our yml file:\n```bash\ndocker run -d --name=redis redis\ndocker run -d --name=db postgresql:9.4\ndocker run -d --name=vote -p 5000:80 --link=redis voting-app\ndocker run -d --name=result -p 5001:80 --link=db result-app\ndocker run -d --name=worker --link=redis --link=db\n```\n\nNow let's generate the yml file for this \n```yml\nredis:\n  image: redis\ndb:\n  image: postgresql\nvote:\n  image: voting-app\n  ports:\n    - 5000:80\n  links:\n    - redis\nresult:\n  image: result-app\n  ports:\n    - 5001:80\n  links:\n    - db\nworker:\n  image: worker\n  links:\n    - redis\n    - db\n```\n\nNow if we want to first build our image using Dockerfile then we can also use the build option here instead of using the image name. So our new YML file will be something like this:\n```yml\nredis:\n  image: redis\ndb:\n  image: postgresql\nvote:\n  build: ./vote\n  ports:\n    - 5000:80\n  links:\n    - redis\nresult:\n  build: ./result\n  ports:\n    - 5001:80\n  links:\n    - db\nworker:\n  build: ./worker\n  links:\n    - redis\n    - db\n```\n\nNow we also have different versions for docker-compose files v1,v2 and v3 :\nMajor difference between the versions is the support of networks etc.\n\nOur same above file will become as this in version 2 of docker-compose.yml :\n```yml\nversion: 2\nservices:\n  redis:\n    image: redis\n  db:\n    image: postgresql\n  vote:\n    build: ./vote\n    ports:\n      - 5000:80\n    depends_on:\n      - redis\n  result:\n    build: ./result\n    ports:\n      - 5001:80\n    depends_on:\n      - db\n  worker:\n    build: ./worker\n    depends_on:\n      - redis\n      - db\n```\n\nNow if we want to add two networks front-end and back-end in our compose as:\n- Redis DB (back-end)\n- PostgreSQL (back-end)\n- Python Application (front-end)\n- Node Js Application (front-end)\n- .Net service worker (backend)\n\n```yml\nversion: 2\nservices:\n  redis:\n    image: redis\n    networks:\n      - back-end\n  db:\n    image: postgresql\n    networks:\n      - back-end\n  vote:\n    build: ./vote\n    ports:\n      - 5000:80\n    depends_on:\n      - redis\n    networks:\n      - back-end\n      - front-end\n  result:\n    build: ./result\n    ports:\n      - 5001:80\n    depends_on:\n      - db\n    networks:\n      - back-end\n      - front-end\n  worker:\n    build: ./worker\n    depends_on:\n      - redis\n      - db\n    networks:\n      - back-end\n\nnetworks:\n  - back-end\n  - front-end\n```\n\n\n## Docker Registery\n\nNow we must be thinking about where do we get our docker images when we pull or run our image. \nFor eg:\n```bash\ndocker pull nginx\n```\nHere let's elaborate **nginx**\n\noriginally the image looks like :\n\n```bash\ndocker.io/nginx/nginx\n# Registry/(User,Account)/(Image,Repository)\n```\n\ndocker.io is the default Registery for all the images we pull suppose we want to get image other than the docker.io registery we have to write the full address unlike when pulling from the docker hub.\nFor eg:\n\n```bash\ndocker pull gcr.io/kubernetes-e2e-test-images/dnsutils\n```\n\n### Private Registery\n\nIf we want to host our private images and we don't ant anyone to access it docker provides us with private registeries that we can use which are provided with Azure and GCD platform\n\nNow to Access our private registery \n```bash\ndocker login private-registery.io\ndocker run private-registory.io/apps/internal-app\n```\n\n### Deploy Your Own Private Registery\n\nNow if we want to deploy our own registery in our own docker host we can do it by using the following steps:\n```bash\n# Running our registery with a port mapping to the host\ndocker run -d -p 5000:5000 --name registery registery:2\n\n# Now we will tag our image with the registery running\ndocker image tag my-image localhost:5000/my-image\n\n# Pushing our image\ndocker push localhost:5000/my-image\n```\n\nIf we want to pull the image we can do it by\n```bash\n# If we want to pull image locally\ndocker pull localhost:5000 my-image\n\n# If we want to pull image from within the network but from different host\ndocker pull 192.168.56.100:5000/my-image\n```\n\n## Docker Engine\n\nDocker engine is the engine running in the system that consist of \n- Docker CLI\n- Docker REST API\n- Docker Deamon\n\nHere CLI is what we use and Docker deamon is the process that runs with the shared resources of the system and REST API connects the both services.\n\nNow we can access the docker CLI from anywhere just by specifying the -H tag\n```bash\ndocker -H=10.134.23.90:3450 run nginx\n```\n\nNow in docker the application runs own it's own by specifying the root PID to 1 but when our system runs the PID 1 is already taken so what happens is our container maps it's processes with the processes outside the container to avoid any errors and giving the independency of our host. We can also limit our resources to the container by using specific commands while running the image\n\n```bash\n# Not to exceed the CPU above 50%\ndocker run --cpus=.5 ubuntu\n\n# Not to exceed the Memory 100 MB\ndocker run --memory=100m ubuntu\n```\n\n## Container Orchestration\n\nIf we need a stable application we need to ensure that our application is running all the time we need to make sure that our host is always reachable and If one image crashes then it should be replaced by the another instance instantly. So solution for this problem is :\n- Docker swarm\n- Mesos\n- Kubernetes\n\n\n\n## Docker Swarm\n\nDocker swarm can produce hundreds or thousands of replicas of your container on multiple hosts :\n```bash\n\n# Write this in master host\ndocker swarm init\n\n# This command will provide us a command which we have to write in our worker nodes\n```\n\nNow to run the services in a swarm\n```bash\ndocker services create --replicas=3 my-web-server\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Focdbytes%2Fdocker_basics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Focdbytes%2Fdocker_basics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Focdbytes%2Fdocker_basics/lists"}