Docker 有三个特性能够帮助我们构建与主机环境无关的系统:
- Read-only filesystems (只读文件系统)
- Environment variable injection (环境变量注入)
- Volumes(卷)
只读文件系统
只读文件系统有两个显而易见的好处,其一是容器本身不会因为文件的改变(因为改变不了)而变得特殊,其他是攻击者无法修改上面的文件,能够保证安全。
其中一个例子就是 WordPress, 对于 WP 自身来说,应该让其只读,所有的数据写到数据库中,这样至少对于 WP 来说,他是稳定的、安全的。
要启用文件只读功能,应该使用 --read-only
参数
docker run -d --name wp --read-only wordpress:5.0.0-php7.2-apache
运行上面命令,使用 docker ps
,会发现 wp 并不会运行。如果使用 docker log
查看命令,可以看到下面一段文字,原因就是因为整个系统都是只读的。
但是可以添加额外的 -v
参数,去挂载主机下面的某个目录,运行在里面进行读写。
docker run -d --name wp2 --read-only -v /run/apache2/ --tmpfs /tmp wordpress:5.0.0-php7.2-apache
现在可以来试着运行下面这几行命令了,如果运行正确,最后将会如下图所示。
DB_CID=$(docker create -e MYSQL_ROOT_PASSWORD=ch2demo mysql:5.7)
docker start $DB_CID
MAILER_CID=$(docker create dockerinaction/ch2_mailer)
docker start $MAILER_CID
WP_CID=$(docker create --link $DB_CID:mysql -p 80 --read-only -v /run/apache2/ --tmpfs /tmp wordpress:5.0.0-php7.2-apache)
docker start $WP_CID
AGENT_CID=$(docker create --link $WP_CID:insideweb --link $MAILER_CID:insidemailer dockerinaction/ch2_agent)
docker start $AGENT_CID
但这样会出现一些问题,比如所有的服务都部署在一台服务器上,另外这些服务都是使用默认的配置,比如默认的帐号、密码。
环境变量注入
莫环境变量注入能够较好的解决默认配置项的问题(当然不止这一种),通过 -env
参数,后面接上 key=values
的形式,将所需要的配置文件传入进去,如果之前存在同名的键值对,那么就覆盖它。
试着运行这样一行命令,就能够发现在容器里面可以找到这样一条信息,那么我们提前写好一些配置属性,之后容器内运行的服务,就能够读取这些配置信息啦。
docker run --env MY_ENVIRONMENT_VAR="this is a test" busybox:1.29 env
那么或许 我们启动 MySQL 的时候,可以这样去写,提前写入一些配置信息。
docker create --env WORDPRESS_DB_HOST="my-host-name" \
--env WORDPRESS_DB_USER="site_admin" \
--env WORDPRESS_DB_PASSWORD=MeowMix42 \
wordpress:5.0.0-php7.2-apache
卷
这是一个很重要的概念,但目前还没学到,故不先记录。