为了方便微服务的开发及部署,最近开发任务中需要用到Docker。
于是尝试把之前的应用构建为Docker镜像并运行。
以下是这次的经验总结,特此记录以留后用。
单容器应用
下面将以创建一个简单的php应用为例。
其它的应用无非就是Dockerfile的配置不同,其它步骤都是一样的。
1、
创建一个 Dockerfile(无文件后缀)
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
您可以使用文本编辑器或 IDE 为 PHP 应用程序创建 Dockerfile。
下面是一个 PHP 应用程序的简单 Dockerfile 示例:
# Use the official PHP 8.0 image with Apache as the base image
FROM php:8.0-apache
# Copy the application files to the default web root directory in the container
COPY . /var/www/html/
# Enable the Apache rewrite module
RUN a2enmod rewrite
# Install any necessary PHP extensions (e.g. mysqli, pdo_mysql)
RUN docker-php-ext-install pdo_mysql
# Set the default working directory for the container
WORKDIR /var/www/html
# Expose port 80 to the outside world
EXPOSE 80
# Start the Apache server
CMD ["apache2-foreground"]
这个 Dockerfile 使用带有 Apache 的官方 PHP 7.4 镜像,并将当前目录的内容复制到容器中的 /var/www/html/
目录。
FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
RUN <命令行命令>
RUN ["可执行文件", "参数1", "参数2"]
COPY:复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
COPY [--chown=
: ] <源路径1>... <目标路径> WORKDIR:指定工作目录。可以省略。
还有很多知识,这块很重要,有兴趣的可以继续学习。
2、
构建 Docker 镜像
有了 Dockerfile 后,就可以使用 docker build
命令构建 Docker 镜像。 打开终端并导航到 Dockerfile 所在的目录,然后运行以下命令:
docker build -t my-php-app .
此命令将构建一个带有标签my-php-app
的 Docker 镜像。 末尾的.
指上下文路径,即当前目录下所有内容。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
3、
运行 Docker 容器
构建 Docker 镜像后,您可以使用 docker run
命令启动 Docker 容器。 这是一个例子:
docker run -p 80:80 -v $(pwd):/var/www/html my-php-app
此命令将从 my-php-app
图像启动一个 Docker 容器,将容器中的端口 80 映射到主机上的端口 80,并将当前目录 ($(pwd)
) 挂载到 /var/ 容器中的 www/html
目录。 这允许您在主机上更改 PHP 代码并立即在容器中查看更改。
4、
访问您的 PHP 应用程序
容器运行后,您可以在 Web 浏览器中通过http://localhost:80
访问您的 PHP 应用程序。
如果一切正常,您应该会看到 PHP 应用程序的输出。
多容器应用 Docker Compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
Compose 使用的三个步骤:
- 使用 Dockerfile 定义应用程序的环境。
- 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
- 最后,执行 docker-compose up 命令来启动并运行整个应用程序。
下面我还是创建一个简单的php应用为例:
1.
创建基础配置yml文件
首先创建一个文件:docker-compose.yml
内容为:
version: "3"
services:
web:
image: nginx:latest
ports:
- "8010:80"
volumes:
- ./code:/var/www/html
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- php
php:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./code:/var/www/html
db:
image: mariadb:latest
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
MYSQL_USER: root
MYSQL_PASSWORD: 123456
ports:
- "3310:3306"
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
2.
创建Dockerfile
这是为了自定义php程序的配置,内容可以为:
这里我们给php程序安装了GD扩展
FROM php:8.0-fpm
RUN apt-get update \
&& apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
&& docker-php-ext-configure gd \
--with-freetype \
--with-jpeg \
&& docker-php-ext-install -j$(nproc) gd
3.
创建nginx配置文件
根据第1步的nginx的配置,在对应位置配置nginx文件。
比如我的是在./nginx/conf.d
目录下,创建myapp.conf
,内容为:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
4.
准备好php应用的代码
同样根据第1步的php中的volumes来放php应用代码。
比如我的php应用代码是放在./code
目录下。
5.
启动docker-compose
现在的目录结构应该为:
接下来执行docker-compose up即可在容器中启动这个服务了。
6.
访问php应用
可以通过http://localhost:8010
来访问应用(code目录下的php代码)。
常见问题
- Error response from daemon: Mounts denied:
Error response from daemon: Mounts denied:
The path /Applications/MAMP/htdocs/docker/myphpapp/code is not shared from the host and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing.
See https://docs.docker.com/desktop/mac for more info.
挂载磁盘是被拒绝,错误原因是:文件目录不在docker允许的文件分享目录中。
解决方法是在 资源 --> 文件分享 中,加入这个文件目录。
- 访问应用提示无权限访问资源或者服务未响应等
这种一般都是因为nginx的配置文件未成功加载有关,请确认文件目录及配置文件是否正确
(参考 多容器应用 Docker Compose 中的 第3步和第5步)。