برنامه‌نویسی

آموزش نصب و استفاده از Docker بر روی Ubuntu 18.04


۱۶ اسفند ۱۳۹۹
آموزش نصب و استفاده از docker بر روی ubuntu 18.04

مقدمه

Docker پلتفرمی است که فرایند مدیریت برنامه‌های توسعه داده شده توسط برنامه‌نویسان را با ارائه Docker container آسان می‌کند زیرا برنامه‌ها به‌طور ایزوله شده و جداگانه از هم در یک Docker Host، میزبانی می‌شوند. همچنین می‌توانید Docker containerها را شبیه Virtual machineها بدانید اما آن‌ها قابل حمل‌تر، سازگارتر با منابع کم و وابسته به سیستم‌عامل میزبان هستند.

در این آموزش به نصب Docker Community Edition (CE) در Ubuntu 18.04 می‌پردازیم و سپس با برخی دستورهای این ابزار آشنا خواهیم شد.

پیش‌نیازها

پیش‌نیازهای زیر برای دنبال کردن ادامه‌ی این آموزش مورد نیاز هستند:

  • یک سرور Ubuntu نسخه‌ی 18.04
  • اگر بخواهید Docker image شخصی‌سازی شده‎‌ی خود را به‌صورت عمومی منتشر کنید بنابراین به یک حساب کاربری در Docker Hub احتیاج خواهید داشت.

نصب Docker

در این مقاله از روش اضافه کردن ریپازیتوری رسمی Docker برای نصب آخرین نسخه‌ی این پلتفرم استفاده خواهیم کرد. بنابراین در وهله‌ی اول بایستی پکیج‌های فعلی موجود در سیستم‌عامل را آپدیت کرد:

sudo apt update

سپس برخی پکیج‌هایی که اجازه می‌دهند از apt در حالت HTTPS استفاده کنیم را نصب می‌کنیم:

sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg-agent

کلید GPG ریپازیتوری رسمی Docker را به سیستم خود اضافه کرده:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

و پس از آن بایستی ریپازیتوری Docker را به package sourceهای apt اضافه ‌کنیم:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

در مرحله‌ی بعد با اجرای دستور زیر دیتابیس پکیج‌ها را آپدیت خواهیم کرد:

sudo apt update

حال بایستی apt را ملزم کنیم که از ریپازیتوری رسمی Docker برای نصب این پلتفرم استفاده کند:

apt-cache policy docker-ce

خروجی دستور فوق به شکل زیر است:

docker-ce:
  Installed: (none)
  Candidate: 18.03.1~ce~3-0~ubuntu
  Version table:
     18.03.1~ce~3-0~ubuntu 500
        500 https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages

در نهایت با اجرای دستور زیر، Docker نصب می‌شود:

sudo apt install docker-ce

اکنون که این پلتفرم را نصب کردید بایستی از فعال بودن فرایند اجرای سرویس Docker در boot سیستم‌عامل اطمینان حاصل کنید:

sudo systemctl status docker

اگر این سرویس فعال باشد، خروجی‌ای مشابه خروجی زیر به شما نمایش داده می‌شود:

● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2018-07-05 15:08:39 UTC; 2min 55s ago
     Docs: https://docs.docker.com
 Main PID: 10096 (dockerd)
    Tasks: 16
   CGroup: /system.slice/docker.service
           ├─10096 /usr/bin/dockerd -H fd://
           └─10113 docker-containerd --config /var/run/docker/containerd/containerd.toml

اجرای دستورهای Docker بدون نیاز به Sudo

به‌طور پیش‌فرض فقط کاربر root می‌تواند دستور docker را اجرا کند اما شما می‌توانید یک کاربر جدید را حین نصب Docker تعریف کنید. اگر دستور docker را بدون پیشوند sudo اجرا کنید، خروجی زیر را دریافت خواهید کرد:

docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
See 'docker run --help'.

حال اگر تصمیم داشته باشید که از اجرای docker با sudo خودداری کنید می‌توانید یک نام کاربری جدید را به docker group اضافه کنید:

sudo usermod -aG docker ${USER}

برای اعمال تغییرها می‌توانید از سرور خارج شده و دوباره وارد آن شوید یا دستور زیر را اجرا کنید:

su - ${USER}

پس از اجرای دستور فوق برای ادامه‌ی کار با سرور، رمز عبور حساب از شما خواسته می‌شود. برای اطمینان از اضافه شدن کاربر جدید به docker group دستور زیر را اجرا کنید:

id -nG

که خروجی آن به شکل زیر است:

sammy sudo docker

همچنین اگر می‌خواهید کاربری را به docker group اضافه کنید که با آن وارد سرور نشده‌اید می‌توانید به شکل زیر عمل کنید:

sudo usermod -aG docker username

نحوه‌ی اجرای دستورهای Docker

سینتکس دستور docker به شکل زیر است:

docker [option] [command] [arguments]

و پس از اجرای دستور docker در Terminal، خروجی زیر نمایش داده می‌شود:

Options:
      --config string      Location of client config files (default
                           "C:\\Users\\Genius\\.docker")
  -c, --context string     Name of the context to use to connect to the
                           daemon (overrides DOCKER_HOST env var and
                           default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level
                           ("debug"|"info"|"warn"|"error"|"fatal")
                           (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default
                           "C:\\Users\\Genius\\.docker\\ca.pem")
      --tlscert string     Path to TLS certificate file (default
                           "C:\\Users\\Genius\\.docker\\cert.pem")
      --tlskey string      Path to TLS key file (default
                           "C:\\Users\\Genius\\.docker\\key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  app*        Docker App (Docker Inc., v0.9.1-beta3)
  builder     Manage builds
  buildx*     Build with BuildKit (Docker Inc., v0.5.1-docker)
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  scan*       Docker Scan (Docker Inc., v0.5.0)
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

برای مشاهده‌ی راهنمای subcommandها می‌توانید به‌صورت زیر عمل کنید:

docker docker-subcommand --help

همچنین می‌توانید برای مشاهده‌ی اطلاعات جامع Docker از دستور زیر استفاده کنید:

docker info

نحوه‌ی استفاده از Docker image

Docker containerها با استفاده از Docker imageها ساخته می‌شوند و Docker این Docker imageها را از Docker Hub بارگیری می‌کند. البته هر کسی می‌تواند image شخصی‌سازی شده خودش را در این ریپازیتوری آنلاین میزبانی کند بنابراین اکثر برنامه‌ها و توزیع‌های Linux محبوب را می‌توانید در این ریپازیتوری پیدا کنید.

دستور زیر را برای اطمینان از اینکه به imageهای Docker Hub دسترسی داشته باشید، اجرا کنید:

docker run hello-world

اگر دستور فوق با موفقیت اجرا شود، خروجی زیر را دریافت خواهید کرد:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
9bb5a5d4561a: Pull complete
Digest: sha256:3e1764d0f546ceac4565547df2ac4907fe46f007ea229fd7ef2718514bcec35d
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

همان‌طور که مشاهده می‌کنید، Docker در وهله‌ی اول وجود image مورد نظر ما یعنی hello-world را بر روی Docker Host فعلی بررسی می‌کند. اگر وجود نداشت، سعی می‌کند در مرحله‌ی بعد آن را در Docker Hub جستجو کند و اگر آن image موجود بود، سپس آن را بر روی Docker Host فعلی دانلود و اجرا خواهد کرد.

با اجرای دستور زیر می‌توانید image مورد نظر خود را در Docker Hub جستجو کنید:

docker search ubuntu

که خروجی آن به شکل زیر است:

NAME                                                      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
ubuntu                                                    Ubuntu is a Debian-based Linux operating sys…   11859     [OK]
dorowu/ubuntu-desktop-lxde-vnc                            Docker image to provide HTML5 VNC interface …   497                  [OK]
websphere-liberty                                         WebSphere Liberty multi-architecture images …   268       [OK]
rastasheep/ubuntu-sshd                                    Dockerized SSH service, built on top of offi…   250                  [OK]
consol/ubuntu-xfce-vnc                                    Ubuntu container with "headless" VNC session…   232                  [OK]
ubuntu-upstart                                            Upstart is an event-based replacement for th…   110       [OK]
neurodebian                                               NeuroDebian provides neuroscience research s…   80        [OK]
1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5      ubuntu-16-nginx-php-phpmyadmin-mysql-5          50                   [OK]
ubuntu-debootstrap                                        debootstrap --variant=minbase --components=m…   44        [OK]
open-liberty                                              Open Liberty multi-architecture images based…   42        [OK]
i386/ubuntu                                               Ubuntu is a Debian-based Linux operating sys…   24
nuagebec/ubuntu                                           Simple always updated Ubuntu docker images w…   24                   [OK]
1and1internet/ubuntu-16-apache-php-5.6                    ubuntu-16-apache-php-5.6                        14                   [OK]
1and1internet/ubuntu-16-apache-php-7.0                    ubuntu-16-apache-php-7.0                        13                   [OK]
1and1internet/ubuntu-16-nginx-php-phpmyadmin-mariadb-10   ubuntu-16-nginx-php-phpmyadmin-mariadb-10       11                   [OK]
1and1internet/ubuntu-16-nginx-php-5.6-wordpress-4         ubuntu-16-nginx-php-5.6-wordpress-4             8                    [OK]
1and1internet/ubuntu-16-nginx-php-5.6                     ubuntu-16-nginx-php-5.6                         8                    [OK]
1and1internet/ubuntu-16-apache-php-7.1                    ubuntu-16-apache-php-7.1                        6                    [OK]
1and1internet/ubuntu-16-nginx-php-7.0                     ubuntu-16-nginx-php-7.0                         4                    [OK]
pivotaldata/ubuntu                                        A quick freshening-up of the base Ubuntu doc…   4
pivotaldata/ubuntu16.04-build                             Ubuntu 16.04 image for GPDB compilation         2
smartentry/ubuntu                                         ubuntu with smartentry                          1                    [OK]
1and1internet/ubuntu-16-php-7.1                           ubuntu-16-php-7.1                               1                    [OK]
pivotaldata/ubuntu-gpdb-dev                               Ubuntu images for GPDB development              1
pivotaldata/ubuntu16.04-test                              Ubuntu 16.04 image for GPDB testing             0

اگر OK را در ستون OFFICIAL مشاهده کردید یعنی آن image توسط تیم توسعه‌دهنده اصلی آن تکنولوژی پشتیبانی می‌شود. پس از یافتن image مورد نظر خود می‌توانید با اجرای دستور docker pull آن را دریافت کنید.

مثلا با اجرای دستور زیر، image رسمی ubuntu بر روی Docket Host فعلی شما دانلود می‌شود:

docker pull ubuntu

خروجی دستور فوق به شکل زیر است:

Using default tag: latest
latest: Pulling from library/ubuntu
6b98dfc16071: Pull complete
4001a1209541: Pull complete
6319fc68c576: Pull complete
b24603670dc3: Pull complete
97f170c87c6f: Pull complete
Digest: sha256:5f4bdc3467537cbbe563e80db2c3ec95d548a9145d64453b06939c4592d67b6d
Status: Downloaded newer image for ubuntu:lates

پس از تکمیل دانلود image مورد نظرتان می‌توانید یک Docker container را با استفاده از image بارگیری شده با دستور docker run راه‌اندازی کنید.

علاوه‌براین‌ها می‌توانید برای مشاهده‌ی imageهای موجود در Docker Host فعلی دستور زیر را اجرا کنید:

docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              113a43faa138        4 weeks ago         81.2MB
hello-world         latest              e38bc07ac18e        2 months ago        1.85kB

راه‌اندازی Docker container

در بخش قبل ما با استفاده از hello-world image یک container را راه‌اندازی کردیم که پیامی آزمایشی را برای ما چاپ می‌کرد اما Docker containerها می‌توانند بسیار مفیدتر باشند و همچنین شما می‌توانید با آن‌ها تعامل داشته باشید. به‌هرحال آن‌ها شبیه virtual machineهایی هستند که به منابع سخت‌افزاری کم‌تری نیاز دارند.

برای مثال بیایید یک container را با استفاده از آخرین نسخه‌ی ubuntu image راه‌اندازی کنیم. سوئیچ‌های -i و -t در کنار هم یک interactive tty در اختیار شما قرار می‌دهند که به کمک آن می‌توانید با container خود تعامل داشته باشید:

docker run -it ubuntu

پس از اجرای دستور فوق، تغییرهایی در ظاهر Terminal شما ایجاد می‌شود:

root@d9b100f2f636:/#

حال با این interactive tty می‌توانید هر دستوری را درون container خود اجرا کنید. به‌عنوان مثال بیایید پکیج‌های فعلی را آپدیت کنیم، توجه داشته باشید که نیازی به استفاده از پیشوند sudo نیست:

root@d9b100f2f636:/# apt update

همچنین می‌توانید هر برنامه‌ای که دوست دارید را نصب کنید:

root@d9b100f2f636:/# apt install nodejs

برای خروج از این interactive tty نیز می‌توانید دستور exit را اجرا کنید.

مدیریت Docker container

پس از مدتی استفاده از Docker به‌احتمال زیاد containerهای فعال زیادی خواهید داشت که می‌توانید با اجرای دستور زیر تمام آن‌ها را مشاهده کنید:

docker ps

که خروجی آن به شکل زیر است:

CONTAINER ID        IMAGE               COMMAND             CREATED

شما در این مقاله دو container با استفاده از imageهای ubuntu و hello-world اجرا کرده‌اید. هر دوی آن‌ها متوقف شده‌اند اما همچنان فضای دیسک شما را اشغال کرده‌اند. حال برای مشاهده‌ی تمام containerهای فعال و غیرفعال می‌توانید از سوئیچ -a در دستور docker ps استفاده کنید:

docker ps -a

که خروجی‌ای شبیه خروجی زیر را برای شما به نمایش در می‌آورد:

d9b100f2f636        ubuntu              "/bin/bash"         About an hour ago   Exited (0) 8 minutes ago                           sharp_volhard
01c950718166        hello-world         "/hello"            About an hour ago   Exited (0) About an hour ago                       festive_williams

برای مشاهده‌ی جدیدترین containerهایی که ایجاد کرده‌اید می‌توانید از سوئیچ -l استفاده کنید:

docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
d9b100f2f636        ubuntu              "/bin/bash"         About an hour ago   Exited (0) 10 minutes ago                       sharp_volhard

برای راه‌اندازی مجدد یک container متوقف شده می‌توانید از دستور docker start استفاده کنید:

docker start d9b100f2f636

با اجرای دستور فوق، یک container که قبلا با استفاده از ubuntu image ساخته بودیم مجددا راه‌اندازی می‌شود.

حال برای متوقف کردن این container می‌توانید از دستور docker stop استفاده کنید:

docker stop sharp_volhard

اگر توجه کرده‌ باشید ما این container را با استفاده از CONTAINER ID راه‌اندازی کرده و با استفاده از NAME، آن را متوقف کردیم. بنابراین شما هستید که تصمیم می‌گیرید از کدام مقدار استفاده کنید.

برای حذف کردن یک یا چند container می‌توانید از دستور docker rm استفاده کنید:

docker rm festive_williams

نام containerها به‌صورت تصادفی انتخاب می‌شوند اما شما می‌توانید با استفاده از سوئیچ --name نام دلخواه خود را در زمان راه‌اندازی آن‌ها انتخاب کنید.

commit کردن تغییرهای درون container به Docker image

زمانی که یک container را با استفاده از Docker image مورد نظر خود راه‌اندازی می‌کنید دقیقا مانند یک virtual machine می‌توانید فایل‌ها را در آن ایجاد، حذف یا اصلاح کنید. تغییرهای شما در Docker container فعلی اعمال می‌شود اما با حذف کردن این container تمام تغییرهای شما از بین می‌رود.

قبل‌تر در ubuntu container خود برنامه‌ی Node.js را نصب کردیم بنابراین Node.js در آن container قابل استفاده است اما اگر یک container جدید را با استفاده از ubuntu image ایجاد کنید بایستی Node.js را مجددا نصب کنید تا برای شما قابل استفاده باشد.

بنابراین در این بخش تصمیم گرفتیم تا به شما نشان دهیم چگونه می‌توانید container فعلی خود را به‌عنوان یک Docker image جدید ذخیره کنید. برای commit کردن تغییرهای جدید یک container به یک Docker image جدید می‌توانید به شکل زیر عمل کنید:

docker commit -m "What you did to the image" -a "Author Name" container_id repository/new_image_name

سوئیچ -m برای تعریف پیامی است که به شما و دیگران کمک می‌کند بدانید چه تغییرهایی ایجاد کرده‌اید. -u برای مشخص کردن نام author استفاده می‌شود. container_id نیز شناسه‌ی container مورد نظر شما است و در آخر repository/new_image_name، نام ریپازیتوری شما در Docker Hub است. مثلا برای کاربری با نام کاربری sammy و شناسه‌ d9b100f2f636 می‌توان به شکل زیر عمل کرد:

docker commit -m "added Node.js" -a "sammy" d9b100f2f636 sammy/ubuntu-nodejs

پس از اجرای موفقیت آمیز دستور فوق یک Docker image جدید در Docker Host فعلی ذخیره می‌شود که در مرحله‌ی بعد به شما آموزش می‌دهیم چگونه این image جدید را در Docker Hub میزبانی کنید.

حال برای مشاهده‌ی تمام imageهای موجود در Docker Host فعلی می‌توانید دستور زیر را اجرا کنید:

docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
sammy/ubuntu-nodejs   latest              7c1f35226ca6        7 seconds ago       179MB
ubuntu                   latest              113a43faa138        4 weeks ago         81.2MB
hello-world              latest              e38bc07ac18e        2 months ago        1.85kB

push کردن Docker image شخصی‌سازی شده در Docker Hub

ممکن است بخواهید imageهای شخصی‌سازی شده‌ی خودتان را با دوستان خود به‌اشتراک بگذارید یا حتی آن‌ها را برای استفاده‌ی عموم در Docker Hub منتشر کنید. در وهله‌ی اول برای اشتراک image در Docker Hub یا هر ریپازیتوری عمومی Docker به یک حساب کاربری نیاز دارید.

برای push کردن image خود به Docker Hub بایستی وارد حساب کاربریتان شوید:

docker login -u docker-registry-username

پس از اجرای دستور فوق، رمزعبور حساب از شما خواسته می‌شود. توجه داشته باشید که اگر نام کاربری Docker Hub شما با نام ریپازیتوری که برای ایجاد image شخصی‌سازی استفاده کرده‌اید، یکی نباشد بایستی به شکل زیر عمل کنید:

docker tag sammy/ubuntu-nodejs docker-registry-username/ubuntu-nodejs

سپس می‌توانید برای push کردن image خود، دستور docker push را به‌صورت زیر اجرا کنید:

docker push docker-registry-username/docker-image-name

مثلا برای push کردن یک image با نام ubuntu-nodejs به ریپازیتوری sammy بایستی دستور زیر را اجرا کنید:

docker push sammy/ubuntu-nodejs
The push refers to a repository [docker.io/sammy/ubuntu-nodejs]
e3fbbfb44187: Pushed
5f70bf18a086: Pushed
a3b5c80a4eba: Pushed
7f18b442972b: Pushed
3ce512daaf78: Pushed
7aae4540b42d: Pushed

...

پس از push کردن image جدید می‌توانید آن را در حساب کاربری Docker Hub خود مشاهده کنید و دوستان شما با اجرا دستور docker pull sammy/ubuntu-nodejs می‌توانند این image را دریافت کنند.

منبع: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04