Docker和Dockerfile变得简单!

It’s become second nature for developers to use Virtual Machines to configure and manage their working environments. Most professionals who use VMs use Vagrant for dealing with their development environments. In this article, we’ll be moving from Vagrant to Docker, and use a small Laravel application to test that everything is working as expected.

开发人员使用虚拟机来配置和管理其工作环境已成为其第二天性。 大多数使用VM的专业人员都使用Vagrant处理他们的开发环境。 在本文中,我们将从Vagrant迁移到Docker,并使用一个小的Laravel应用程序来测试一切是否按预期进行。

Docker Logo

安装 (Installation)

The installation page contains instructions for almost every popular platform. Docker runs natively on Linux OS, but we can use it on Windows and Mac OS by installing the Docker Toolbox utility. If you run into some problems, you can visit this article which highlights the most common issues. You can verify it’s installed and working by running the following command in your terminal.

安装页面包含几乎所有流行平台的说明。 Docker在Linux操作系统上本地运行,但是我们可以通过安装Docker Toolbox实用程序在Windows和Mac OS上使用它。 如果遇到一些问题,您可以访问本文该文章重点介绍了最常见的问题。 您可以通过在终端中运行以下命令来验证它是否已安装并正常工作。

docker -v
# output
Docker version 1.8.1, build d12ea79

Docker机器 (Docker Machines)

A Docker machine is the VM that holds your images and containers (more on those later). Let’s create our first VM.

Docker机器是用于存放图像和容器的VM(稍后将详细介绍)。 让我们创建我们的第一个VM。

docker-machine create --driver virtualbox docker-vm

You can change the driver option depending on your preference. See here for the list of available drivers.

您可以根据自己的喜好更改driver选项。 请参阅此处以获取可用驱动程序列表

You can print the machine’s configuration by running the docker-machine env docker-vm command. This is how you can switch between machines.

您可以通过运行docker-machine env docker-vm命令来打印机器的配置。 这是您可以在机器之间进行切换的方式。

# Use the docker-vm
eval "$(docker-machine env docker-vm)"

# Switch to the dev machine
eval "$(docker-machine env dev)"

You can read more about the docker-machine command in the documentation and explanation on why we’re using eval here can be found on this page.

您可以在文档中阅读有关docker-machine命令的更多信息,并在此页面上找到我们为什么在这里使用eval说明。

Docker映像 (Docker Images)

Docker images are OS boxes that contain some pre-installed and configured software. You can browse the list of available images on the Docker Hub. In fact, you can create your own image based on another one and push it to the Docker hub so that other users can use it.

Docker映像是OS盒,其中包含一些预安装和配置的软件。 您可以在Docker Hub上浏览可用映像的列表。 实际上,您可以基于另一个映像创建自己的映像,并将其推送到Docker集线器,以便其他用户可以使用它。

The docker images command lists the available images on your machine, and you can download a new one from the hub using the docker pull <image name> command. For our demo application, we pulled the mysql and nimmis/apache-php5 images.

docker images命令列出了计算机上的可用映像,您可以使用docker pull <image name>命令从中心下载一个新docker pull <image name> 。 对于我们的演示应用程序,我们提取了mysqlnimmis/apache-php5映像。

Docker images

Docker容器 (Docker Containers)

Docker containers are separate instances that we create from images. They can also make a good starting point for creating a new personalized image that others can use. You can see the list of available containers using the docker ps command. This only lists running containers, but you can list all available ones by adding the -a flag (docker ps -a).

Docker容器是我们根据映像创建的单独实例。 它们还可以为创建其他人可以使用的新个性化图像提供良好的起点。 您可以使用docker ps命令查看可用容器的列表。 这只会列出正在运行的容器,但是您可以通过添加-a标志( docker ps -a )列出所有可用的容器。

Docker containers

Now, let’s create an Ubuntu container. First, we need to pull the image from the hub, then we create a new container instance from it.

现在,让我们创建一个Ubuntu容器。 首先,我们需要从集线器中提取图像,然后从中创建一个新的容器实例。

# Get image from the hub
docker pull nimmis/apache-php5

# Create the container
docker run -tid nimmis/apache-php5

# List running containers
docker ps

The first command may take a while to finish downloading the image from the hub. The first flag (t) we specified on the second command means that we want to allocate a TTY to interact with the container, the second flag (i) means that we want an interactive STDIN/OUT, and the last one (d) means that we want to run it in the background.

第一条命令可能需要一段时间才能完成从集线器下载映像。 我们在第二个命令上指定的第一个标志( t )表示我们想分配一个TTY与容器交互,第二个标志( i )表示我们要交互式STDIN / OUT,最后一个( d )表示我们想在后台运行它。

Since this container will host our web server documents, you may be thinking, how are we going to access our server from the browser?

由于此容器将托管我们的Web服务器文档,因此您可能在想,我们如何从浏览器访问服务器?

The -P option on the run command will automatically expose any ports needed from the container to the host machine, while the -p option lets you specify ports to expose from the container to the host.

run命令上的-P选项将自动将容器需要的所有端口公开给主机,而-p选项可让您指定要从容器公开给主机的端口。

# Automatically exposes the container ports to an available host port
docker run -tid -P nimmis/apache-php5

# We can also specify ports manually <host port>:<container port>
docker run -tid -p 80:80 nimmis/apache-php5

Now you can access the container using the docker-machine ip docker-vm address and the specified port. If you don’t know the port, you can run the docker ps command and look at the ports column.

现在您可以使用docker-machine ip docker-vm地址和指定端口访问容器。 如果您不知道端口,则可以运行docker ps命令并查看ports列。

Apache server

集装箱体积 (Container Volumes)

Volumes are an easy way to share storage between your host machine and the container. They are initialized during the container’s creation and kept synced. In our case we want to mount /var/www to a local directory ~/Desktop/www/laravel_demo.

卷是在主机和容器之间共享存储的简便方法。 它们在容器的创建过程中被初始化并保持同步。 在我们的例子中,我们想将/var/www挂载到本地目录~/Desktop/www/laravel_demo

# Option syntax
docker run -v <local dir>:<container dir>

Our container creation command will thus look like the following.

因此,我们的容器创建命令将如下所示。

docker run -tid -p 80:80 -v ~/Desktop/www/laravel_demo:/var/www nimmis/apache-php5
Laravel Demo screenshot

Note: The default Apache DocumentRoot directive points to /var/www/html, so you have to change it to /var/www/public inside the /etc/apache2/sites-enabled/000-default.conf configuration file and restart Apache. You can log into the container using the exec command.

注意 :默认的Apache DocumentRoot指令指向/var/www/html ,因此必须在/etc/apache2/sites-enabled/000-default.conf配置文件中将其更改为/var/www/public ,然后重新启动Apache 。 您可以使用exec命令登录到容器。

docker exec -it <container> bash
# Restart Apache
/etc/init.d/apache2 restart

命名容器 (Naming Containers)

Even though you can use the container ID for most commands, it’s always a good idea to name the container for what it does or following a naming convention to avoid looking for the ID (using docker ps) every time you want to do something.

即使您可以对大多数命令使用容器ID,但始终建议将容器的功能命名为容器或遵循命名约定,以避免每次想要执行操作时都要查找ID(使用docker ps )。

# Option syntax
docker run --name <container name>

So, our complete command will look like the following.

因此,我们完整的命令将如下所示。

docker run -tid -p 80:80 -v ~/Desktop/www/laravel_demo:/var/www --name wazo_server nimmis/apache-php5

Now if you want to start, stop, or remove the container, you can use its name instead of the ID. Be sure to check the Docker documentation for more details about containers.

现在,如果您要启动,停止或删除容器,则可以使用其名称而不是ID。 确保检查Docker文档以获取有关容器的更多详细信息。

docker start wazo_server

数据库容器 (Database Container)

At this point, we have our Apache server set up and we will use a separate container to host our database(s). If you ever had to run two or more VMs at the same time, you know that your machine can get a bit slower, and it gets worse when you add more. Adding a separate lightweight container to host our databases and another one for managing background jobs will help a lot in keeping things lightweight, separate and manageable.

至此,我们已经设置了Apache服务器,并且我们将使用一个单独的容器来托管我们的数据库。 如果必须同时运行两个或多个VM,您会知道您的计算机会变慢一些,添加更多会变得更糟。 添加一个单独的轻量级容器来承载我们的数据库,再添加一个用于管理后台作业的容器,将有助于保持事物的轻量级,独立性和可管理性。

We create the MySQL container the same way we did above. We mount the /var/lib/mysql folder to a local one on our host machine to keep the data synced between the two machines. In case of data loss, we can mount the same local folder to another container.

我们以与上面相同的方式创建MySQL容器。 我们将/var/lib/mysql文件夹安装到主机上的本地文件夹中,以使数据在两台计算机之间同步。 万一数据丢失,我们可以将同一本地文件夹挂载到另一个容器。

docker run -p 3306:3306 --name mysqlserver -e MYSQL_ROOT_PASSWORD=root -d mysql

The -e option lets you set an environment variable on the container creation. In this case, the MYSQL_ROOT_PASSWORD will tell the MySQL installation process to use the password we specified in the command.

使用-e选项,可以在容器创建时设置环境变量。 在这种情况下, MYSQL_ROOT_PASSWORD将告知MySQL安装过程使用我们在命令中指定的密码。

Now if you want to connect to the database from outside, you can use the address returned from the docker-machine ip docker-vm command and the exposed port on the docker run command. My database configuration will look like the following.

现在,如果要从外部连接到数据库,则可以使用docker-machine ip docker-vm命令返回的地址和docker run命令上的公开端口。 我的数据库配置如下所示。

// .env

DB_HOST=192.168.59.103
DB_DATABASE=demo
DB_USERNAME=root
DB_PASSWORD=root

You can test that things are working by running the Laravel database migration command, and make sure your mysql container is running.

您可以通过运行Laravel数据库迁移命令来测试一切是否正常,并确保您的mysql容器正在运行。

./artisan migrate
Artisan migrate

Links are a secure way to share connection details between containers through environment variables. The first method to link to a container is to expose it to a specific port and then use the credentials in your application.

链接是通过环境变量在容器之间共享连接详细信息的安全方法。 链接到容器的第一种方法是将其公开到特定端口,然后在应用程序中使用凭据。

The other way is to use Docker links. So, lets do the same thing we did above but using links this time.

另一种方法是使用Docker链接 。 因此,让我们做与上面相同的事情,但是这次使用链接。

# Option syntax
docker run --link <container name or ID>:<alias>
# Create MySQL container first.
docker run -p 3306:3306 --name mysqlserver -e MYSQL_ROOT_PASSWORD=root -d mysql

# Create web server container
docker run -tid -p 80:80 -v ~/Desktop/www/laravel_demo:/var/www --name wazo_server --link mysqlserver:mysqldb nimmis/apache-php5

The new option here is --link <container>:<env alias>. The environment alias will prefix your connection environment variables, in our case mysqldb. You can log into the web server’s container and run printenv | grep MYSQLDB to print all MySQL linking variables.

这里的新选项是--link <container>:<env alias> 。 环境别名将为连接环境变量mysqldb前缀,在本例中为mysqldb 。 您可以登录到Web服务器的容器并运行printenv | grep MYSQLDB printenv | grep MYSQLDB打印所有MySQL链接变量。

# Log into the web server
docker exec --it wazo_server bash

# Print environment variables
printenv | grep MYSQLDB
Link env

The Dotenv package used by Laravel allows for nesting environment variables. That means we can add our environment variable inside the .env file.

Laravel使用的Dotenv包允许嵌套环境变量。 这意味着我们可以在.env文件中添加环境变量。

// .env

DB_HOST="{$MYSQLDB_PORT_3306_TCP_ADDR}"
DB_DATABASE=demo
DB_USERNAME=root
DB_PASSWORD="{$MYSQLDB_ENV_MYSQL_ROOT_PASSWORD}"

Running the ./artisan migrate command from the command line gives the following result.

从命令行运行./artisan migrate命令会得到以下结果。

Artisan migrate

Dockerfiles (Dockerfiles)

Now that we learned how to work with Docker images, containers and how to link them together, we’re going to learn how to use Dockerfiles to create personalized images and Docker compose to manage our containers.

现在,我们学习了如何使用Docker映像,容器以及如何将它们链接在一起,我们将学习如何使用Dockerfiles创建个性化映像以及Docker compose管理我们的容器。

Dockerfiles help you build and share system images similar to Vagrant. We will highlight the main commands used to configure a Docker image. In this example, we’re going to build a Laravel 5 image. You can check out the final code on Github if you want to follow along.

Dockerfiles可帮助您构建和共享类似于Vagrant的系统映像。 我们将重点介绍用于配置Docker映像的主要命令。 在此示例中,我们将构建一个Laravel 5图像。 如果您想继续,可以在Github上查看最终代码。

(FROM)

The FROM instruction lets you choose the base image to start from. We can choose to start from a bare bones image like Ubuntu:14.04 or we can start from an image that already contains Apache/NGINX and PHP installed and configured. We will use the Ubuntu image for our example.

FROM指令使您可以选择要从其开始的基本图像。 我们可以选择从像Ubuntu:14.04这样的简单映像开始,也可以从已经包含已安装和配置的Apache / NGINX和PHP的映像开始。 我们将在示例中使用Ubuntu映像。

FROM ubuntu:14.04

维护者 (MAINTAINER)

Although this is an optional part, it is recommended to specify the image maintainer for reference.

尽管这是一个可选部分,但建议指定映像维护器以供参考。

MAINTAINER RAFIE Younes <younes.rafie@gmail.com>

ENV (ENV)

The ENV instruction lets you define an environment variable that you can access through the setup process. In our case, we’ll use it to specify the Laravel version we want to install, and you can also change it and create a different version for Laravel 4.

ENV指令使您可以定义可在设置过程中访问的环境变量。 在我们的例子中,我们将使用它来指定要安装的Laravel版本,还可以对其进行更改并为Laravel 4创建一个不同的版本。

ENV LARAVEL_VERSION ~5.1.0

(RUN)

The RUN instruction allows us to run commands on the shell (not bash). You can a run command like RUN apt-get update, but if you want to use bash, you should use it as the following RUN ["/bin/bash", "-c", "apt-get update"].

RUN指令使我们可以在shell(而不是bash)上运行命令。 您可以使用RUN apt-get update类的运行命令,但如果要使用bash,则应将其用作以下RUN ["/bin/bash", "-c", "apt-get update"]

RUN apt-get update && \
    apt-get -y install apache2 php5 libapache2-mod-php5 php5-mcrypt php5-json curl git && \
    apt-get clean && \
    update-rc.d apache2 defaults && \
    php5enmod mcrypt && \
    rm -rf /var/www/html && \
    curl -sS https://getcomposer.org/installer | php && \
    mv composer.phar /usr/local/bin/composer

After installing Apache, PHP, and the other extensions, we’ll need to configure the virtualhost and specify our public folder. Let’s create a file called 000-default.conf containing the needed configuration.

安装Apache,PHP和其他扩展之后,我们需要配置virtualhost并指定我们的公用文件夹。 让我们创建一个包含所需配置的文件000-default.conf

<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/laravel/public

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  <Directory /var/www/laravel>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
  </Directory>
</VirtualHost>

复制 (COPY)

The COPY instruction is useful in the case above, we only need to specify the sources file(s) and the destination.

COPY指令在上述情况下很有用,我们只需要指定源文件和目标即可。

COPY 000-default.conf /etc/apache2/sites-available/000-default.conf

You can also use wildcards if you have multiple files that you want to copy over to your image. We may move multiple hosts configuration as the following.

如果您有多个文件要复制到图像中,则也可以使用通配符。 我们可能会如下移动多个主机配置。

COPY *.conf /etc/apache2/sites-available/

工作目录 (WORKDIR)

You can use WORKDIR to move to another directory to continue the image creation. We use it to move to the /var/www directory to install Laravel using Composer.

您可以使用WORKDIR移至另一个目录以继续创建映像。 我们使用它移动到/var/www目录以使用Composer安装Laravel。

WORKDIR /var/www

RUN composer create-project laravel/laravel laravel $LARAVEL_VERSION --prefer-dist --no-interaction && \
    php laravel/artisan key:generate && \
    chown www-data:www-data -R laravel/storage

After moving to /var/www we install Laravel and make the necessary folders writable by the Apache user www-data. If you noticed, we used the --no-interaction flag on Composer to avoid any installation questions.

移至/var/www我们安装Laravel并使Apache用户www-data可写必要的文件夹。 如果您注意到了,我们在Composer上使用了--no-interaction标志来避免任何安装问题。

暴露 (EXPOSE)

Because we’re creating small service containers, it makes sense that we expose those containers through a specific port to allow other services to consume it.

因为我们正在创建小型服务容器,所以有意义的是,我们通过特定的端口公开那些容器,以允许其他服务使用它。

EXPOSE 80
EXPOSE 443

We expose our server through the standard HTTP port 80, and we also allow HTTPS connections through port 443.

我们通过标准的HTTP端口80公开服务器,并且还允许通过端口443进行HTTPS连接。

CMD (CMD)

The CMD instruction can be used to init the container. In our case, we’ll use it to run our Apache server in the background.

CMD指令可用于初始化容器。 在本例中,我们将使用它在后台运行我们的Apache服务器。

CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

Although our image is now ready for building, we’ll go through some other useful instructions.

尽管我们的图像现在已准备好构建,但我们将通过其他一些有用的说明。

入口点 (ENTRYPOINT)

The ENTRYPOINT instruction lets you specify a command to execute when the user runs the Docker image. We can use it to update our Composer dependencies.

ENTRYPOINT指令可让您指定用户运行Docker映像时要执行的命令。 我们可以使用它来更新我们的Composer依赖项。

// setup-laravel.sh

#!/bin/bash
cd /var/www/laravel
composer update
COPY setup-laravel.sh /setup-laravel.sh # Copy the local file to the image
RUN ["chmod", "+x", "/setup-laravel.sh"] # Make sure it's executable
ENTRYPOINT ["/setup-laravel.sh"]

You can go through all the available instructions in the documentation. In the next section, we’ll see how to use Docker Compose to manage our containers.

您可以阅读文档中所有可用的说明。 在下一节中,我们将看到如何使用Docker Compose来管理我们的容器。

Docker撰写 (Docker Compose)

If you’ve been following along from the first part of this post, we went through the installation process and we already have the environment ready. If not, you can check the documentation for more installation details.

如果您从这篇文章的第一部分开始一直在关注,那么我们已经完成了安装过程,并且已经准备好环境。 如果不是,则可以查看文档以获取更多安装详细信息。

We start by creating a docker-compose.yml file that will hold our configuration. Docker Compose uses YAML for configuration files, you can check the official documentation if you’re not familiar with it. The first node defines the service name; this could be anything. In this case, it’s called web. The build child node specifies the image source, and you may choose an image from the Docker hub or a Dockerfile path to build the image from.

我们首先创建一个将保存我们的配置docker-compose.yml文件。 Docker Compose使用YAML来配置文件,如果您不熟悉它,可以查看官方文档 。 第一个节点定义服务名称; 这可以是任何东西。 在这种情况下,它称为webbuild子节点指定了图像源,您可以从Docker集线器或Dockerfile路径中选择一个图像来构建该图像。

web:
  build: .

The next part is to expose the container ports to make it accessible through the host machine.

下一部分是公开容器端口,以使其可通过主机访问。

web:
  build: .
  ports:
    - "80:80"
    - "443:443"

We talked about mounting volumes in the first part; we can specify that inside our docker-compose file as well.

在第一部分中,我们讨论了安装量。 我们也可以在docker-compose文件中指定它。

web:
  build: .
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - ./laravel:/var/www/laravel

Because most applications need some database interaction, we can use links as mentioned before to help containers communicate with each other.

因为大多数应用程序需要一些数据库交互,所以我们可以使用前面提到的链接来帮助容器彼此通信。

web:
  build: .
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - ./laravel:/var/www/laravel
  links:
    - mysqldb:mysqldb

You specify links in the form of <container name>:<env alias>. The last part is to create the mysqldb container.

您以<container name>:<env alias>的形式指定链接。 最后一部分是创建mysqldb容器。

mysqldb:
  image: mysql
  environment:
    - MYSQL_ROOT_PASSWORD=root

Notice that we used the environment to send the MYSQL_ROOT_PASSWORD to the image. You can use this option to make a generic Laravel image that can install any Laravel version.

注意,我们使用environmentMYSQL_ROOT_PASSWORD发送到图像。 您可以使用此选项制作可安装任何Laravel版本的通用Laravel映像。

If you already have an existing container that you want to link, you can use the external_links configuration.

如果已经具有要链接的现有容器,则可以使用external_links配置。

Now, we are ready to build our image and create the containers to test that everything works as expected. Run the docker-compose up command inside the project folder to build the image and create the containers. This may take a while before everything is installed. You can see the running containers by running docker ps and the build image using docker images from the terminal.

现在,我们准备构建映像并创建容器以测试一切是否按预期进行。 在项目文件夹中运行docker-compose up命令以构建映像并创建容器。 在安装所有组件之前,可能需要一段时间。 您可以通过运行docker ps来查看正在运行的容器,并使用来自终端的docker images来查看构建镜像。

结论 (Conclusion)

This article was a brief introduction to moving from your usual Vagrant development environment to Docker, and how you can benefit from using lightweight containers instead of creating full VMs for small services.

本文是从通常的Vagrant开发环境迁移到Docker的简要介绍,以及如何从使用轻量级容器中受益,而不是为小型服务创建完整的VM而受益。

Docker Compose is a new tool that’s still being developed and improved to remove the pain of managing and porting development environments. You can check the documentation for more details, and the Docker Compose YML file reference to see the list of supported properties. For general Docker docs, see here.

Docker Compose是一个仍在开发和改进中的新工具,以消除管理和移植开发环境的麻烦。 您可以查看文档以获取更多详细信息,以及Docker Compose YML文件参考以查看受支持属性的列表。 有关一般Docker文档的信息,请参见此处

If you’ve already tried Docker and Docker Compose we would love to know what you think about them! If you have any questions or comments, please post them below!

如果您已经尝试过Docker和Docker Compose,我们很想知道您对它们的看法! 如果您有任何疑问或意见,请在下面发布!

翻译自: https://www.sitepoint.com/docker-and-dockerfiles-made-easy/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值