사실 이러한 클라우드 컴퓨팅 시대에 Docker는 기존의 물리적 머신의 가상화 방식을 바꾸어 머신의 리소스를 효율적으로 활용할 수 있게 해준 것으로 오랫동안 잘 알려져 왔습니다. Docker에서 실행되는 애플리케이션은 실제로 호스트 시스템에서 실행되므로 하드웨어 수준의 가상화와 이를 지원하기 위한 완전한 운영 체제 실행이 필요하지 않습니다. 따라서 애플리케이션 코드의 실행 효율성, 메모리 사용량 및 파일 사용량이 모두 중요합니다. 읽기 속도는 기존 가상화 방법보다 강력하며 시작 속도는 종종 밀리초 수준으로 매우 빠르므로 개발, 테스트 및 배포 시간을 크게 절약할 수 있습니다.
사실 개발자에게 Docker의 더 큰 의미는 다음과 같습니다. 프로그래머에게 가장 흔한 것은 개발, 테스트 및 배포 환경이 일관되지 않을 때 "이 코드는 내 컴퓨터에 있습니다" "문제 없습니다"를 방지하기 위해 설명할 수 없는 BUG가 종종 발생한다는 것입니다. Docker를 배워야 하는 이유 중 하나
인터넷은 Docker의 다양한 측면에 대한 수많은 튜토리얼과 정보로 가득 차 있습니다. 기술, 많은 튜토리얼은 실제로 구식이며 초보자가 구별하고 파악하기가 어렵습니다. 다음은 일련의 함정과 문제이며 실제로 학습자의 동기를 제거합니다. 가장 좋은 것은 항상입니다. 공식 문서부터 시작하여 GitHub의 기술 직원의 연구 노트를 작성하는 것이 가장 중요합니다. 실제로 새로운 기술을 배울 때 올바른 연구가 있다면 이 방법입니다. 많은 우회로를 절약할 수 있습니다. 기회가 있을 때 내 경험에 대한 기사를 작성하겠습니다.
이 기사는 길이와 작성자의 수준에 따라 제한됩니다. Docker의 원리와 기술적 구현에 대해 설명하지 않으며, 지루한 Dockerfile을 작성하는 방법을 가르쳐주지는 않겠습니다. 하지만 일반 개발자로 시작하여 Docker 기반 Laravel 애플리케이션을 처음부터 구축하도록 안내하겠습니다. 우리 시스템 환경은 Ubuntu17.04를 사용합니다. 물론, Windows의 경우에는 다를 수 있습니다.
Ubuntu에서의 Docker 설치는 일반 소프트웨어와 동일하지만 중국 특성상 나중에 자세히 설명할 주의 사항이 많습니다. 참고: Docker를 설치하는 방법은 다양합니다. 일련의 지루한 작업을 피하기 위해 공식 원클릭 설치 스크립트를 사용하는 것이 좋습니다.
<span style="font-size: 14px;"> curl -fsSL get.docker.com -o get-docker.sh<br></span>
을 다운로드하여 설치한 다음 Ali 미러 소스에서 다운로드하도록 선택합니다:
<span style="font-size: 14px;">sudo sh get-docker.sh --mirror Aliyun<br></span>
사용자 그룹에 가입하세요
<span style="font-size: 14px;">sudo usermod -aG docker $USER<br></span>
미러 소스 구성
<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>
Restart
<span style="font-size: 14px;">sudo systemctl daemon-reload<br/>sudo systemctl restart docker<br/></span>
<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-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>