In fact, in such an era of cloud computing, Docker has long been well known. It has changed the traditional physical machine. The virtualization method makes efficient use of machine resources. Because the application running in Docker actually runs on the host, it does not need to perform hardware-level virtualization and run a complete operating system. Supported. Therefore, the execution efficiency of application code, memory usage and file reading speed are better than traditional virtualization methods. Moreover, its startup speed is very fast, often at the millisecond level, which can greatly save It reduces the time for development, testing and deployment.
In fact, for developers, a greater significance of Docker is to ensure a consistent operating environment. The most common thing for programmers is that when the development, testing and deployment environments are inconsistent, they often It will trigger some inexplicable bugs. In order to eliminate problems such as "this code works fine on my machine", this is one of the reasons why we should learn Docker.
The Internet is filled with a large number of tutorials and information on various aspects of Docker, and due to the rapid development of Docker, many tutorials are actually outdated, for beginners It is difficult to distinguish and grasp, and what follows is a series of pitfalls and problems, which gradually erodes the motivation of learners. In fact, the best way to learn a new technology is always to start with the official documentation, and then GitHub. A technician’s study notes. The most important thing is to explore practice and take study notes. In fact, when learning a new technology, if you have the correct learning method, you can avoid a lot of detours. I will write an article about this if I have the opportunity. Experience.
This article is limited by the length and author’s level, and will not talk about the underlying principles and technical implementation of Docker, nor will it I will teach you how to write a tedious Dockerfile, but I will start as an ordinary developer and take you to build a Docker-based Laravel application from scratch. Our system environment uses Ubuntu17.04, and other systems are similar. Of course Window may be a different matter.
The installation of Docker under Ubuntu is the same as that of regular software, but due to With Chinese characteristics, there are many points to pay attention to, which will be explained in detail later. There are many ways to install Docker. It is recommended to use the official one-click installation script to avoid a series of tedious operations.
<span style="font-size: 14px;"> curl -fsSL get.docker.com -o get-docker.sh<br></span>
and then install it, and choose to download from the Ali mirror source:
<span style="font-size: 14px;">sudo sh get-docker.sh --mirror Aliyun<br></span>
In fact, it can basically be used after installation. The main thing is to configure some mirror sources and user groups. The purpose of configuring the mirror source is not much to say. The user group is mainly used to run it without using super administrator privileges.
Join the user group
<span style="font-size: 14px;">sudo usermod -aG docker $USER<br></span>
PS. After configuring the user group, the problem may still occur If it still prompts that there is no permission, then restart the machine
Configure the mirror source
<span style="font-size: 14px;">sudo mkdir -p /etc/docker<br>sudo tee /etc/docker/daemon.json <<-'EOF'<br/>{<br/> "registry-mirrors": ["https://be62qq2e.mirror.aliyuncs.com"]<br/>}<br/>EOF<br/></span>
PS. The image source here is from my own Alibaba Cloud. Students can go to Alibaba Cloud to obtain the private image source address
Restart
<span style="font-size: 14px;">sudo systemctl daemon-reload<br/>sudo systemctl restart docker<br/></span>
docker-compose is similar to a package management tool to facilitate us to manage images.
<span style="font-size: 14px;">curl -L https://github.com/docker/compose/releases/download/1.17.1/run.sh > /usr/local/bin/docker-compose<br>chmod +x /usr/local/bin/docker-compose<br></span>
Docker has two very important basic concepts: mirroring and containers. These two are actually similar to object-oriented Classes and instances. After the image is built, it becomes a container, and then the container can be started and stopped. The data generated by the application running in the container can actually be retained as long as the container is not destroyed. If it is destroyed or restarted After building the container, the data will naturally no longer exist, so the official recommendation is to use mounting for persistence, which will be discussed next.
docker-compose 可以说是真正的让 Docker 现代化了. 它就类似于 PHP 的 Composer 包管理工具一样, 是用来管理多个镜像的. 它极大的降低了学习 Docker 的难度. 我们在日常的开发中, 经常会碰到需要多个容器相互配合来完成某项任务的情况,比如 Web 容器和数据库容器之间的通信,我们可以单独的把一个项目中需要的所有容器和配置写到一个 docker-compose.yml 文件中,来统一管理.来看一下一个简单的配置文件格式:
<span style="font-size: 14px;">version: '3'<br>services:<br> nginx:<br> build: .<br> ports:<br> - "80:80"<br><br> redis:<br> image: "redis:alpine"<br></span>
一个项目可以由多个服务(容器)工程,而 docker-compose 是面向项目进行管理.
这是 Docker 比较复杂的一块,简单介绍一下. Docker 里面的文件系统其实很真实宿主机的一样, 可以用同样的命令去操作, 只是要注意的一点就是我们在容器中运行的应用配置文件的路径全部都是基于 Docker 的,不是基于宿主机的,很多文件不存在的问题都是这个引起来的.比如我们在运行一个 Nginx 容器和 PHP-FPM 容器的时候,不仅要把宿主机的项目路径映射到 Nginx 容器中,还要映射到 PHP-FPM 容器中,否则就会是一系列的 File not found.
Docker 中的网络是有多种模式的, 在默认情况下是会创建一个虚拟网桥的, 实际上是 Linux 的一个 bridge,它会在挂载到它的网口之间进行转发。并且会随机分配一个本地未被使用的属于 172.17.0.0/16 网段的 IP 到各个容器中.这是一个网络拓扑图:
基本介绍后我们会通过一个简单的实例来加深理解, 就是部署一个 Laravel 应用. Web 服务器我们会使用 Nginx, 并且通过 PHP-FPM 来处理动态请求,用 MySQL 来存储数据, Redis 作为我们的缓存和队列驱动. 不同于网上的通过 Supervisor 来把所有服务运行在同一个容器中,我们会把这四个服务运行在四个容器中,这也是官方推荐的一种做法,然后我们会通过 docker-compose 来管理所有的服务(容器).
直接上配置文件:
<span style="font-size: 14px;">version: '2'<br>services:<br> nginx:<br> image: nginx<br> ports:<br> - "8090:80"<br> links:<br> - php-fpm<br> volumes:<br> - ./nginx/www:/var/www/html<br> - ./nginx/sites:/etc/nginx/sites-enabled<br> - ./nginx/nginx.conf:/etc/nginx/nginx.conf<br> command: [nginx-debug, '-g', 'daemon off;']<br></span>
其中的 services 节点下每一个表示一个服务;然后 nginx 这是个服务名可以随便取;image 指定使用哪个镜像来构建; ports 表示要暴露的端口,其中 8090 是指宿主机的端口,80 是指容器中的端口;volumes 表示挂载的目录和文件,我们这里挂载了代码目录,虚拟主机目录以及配置文件;command 表示容器启动后要运行的命令。我们还要在当前目录下创建一个 nginx 的目录,用来存放一系列的文件,还需要把配置文件新建并且写入配置内容(具体配置内容可以去官网查看,这里不说明),最后的目录结构是这样
<span style="font-size: 14px;">Docker<br> - docker-compose.yml<br> - nginx<br> - www<br> - sites<br> - nginx.conf<br></span>
可以把日志一起挂载,这里没有表述出来
然后执行启动容器的命令:
<span style="font-size: 14px;">docker-compose up nginx<br></span>
以上不会在后台启动,而是会直接在当前的 shell 上,然后我们访问应该就可以看到 Welcome to nginx!
同理我们再次配置 PHP-FPM,MySQL 以及 Redis 的容器了,具体过程不多讲,这里贴出配置:
<span style="font-size: 14px;"> php-fpm:<br> image: 'bitnami/php-fpm:7.1'<br> volumes:<br> - ./nginx/www:/var/www/html<br> - ./php-fpm/php.ini:/bitnami/php/conf/php.ini<br> links:<br> - mysql<br> - redis<br><br> mysql:<br> image: mysql<br> restart: always<br> environment:<br> MYSQL_ROOT_PASSWORD: example<br> volumes:<br> - /var/lib/mysql:/var/lib/mysql<br><br> redis:<br> image: redis<br></span>
有一点要注意的是,在配置PHP-FPM容器的时候是需要把代码目录也挂载到容器里面的,这一点很容易被遗忘,网上很多教程都没提到,导致最后虽然按照步骤走了但就是跑不起来。其中的 links 就是配置要连接到哪个容器中。比如配置了 Nginx 容器连接到 PHP-FPM 的容器,这样我们在 Nginx 的容器中就可以直接 ping php-fpm,在配置的时候也可以这样 php-fpm:9000 来配置了。
Nginx 的配置文件,然后还要修改一下本地的 hosts 文件。
<span style="font-size: 14px;">server {<br> listen 80;<br> listen [::]:80;<br> root /var/www/html/laravel/public;<br> index index.html index.php;<br> server_name laravel-docker.app;<br> location / {<br> try_files $uri $uri/ /index.php?$query_string;<br> }<br> location ~ \.php$ {<br> fastcgi_split_path_info ^(.+\.php)(/.+)$;<br> fastcgi_pass php-fpm:9000;<br> fastcgi_index index.php;<br> include fastcgi_params;<br> fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;<br> }<br>}<br></span>