直到最近,我还使用 Cpanel 或 Webmin 等工具来管理 Apache2 虚拟主机。我最近发现了如何在sites-available
目录下手动创建这些。
我可以一次又一次地手动执行此过程,但手动完成时,它包括大量的复制和粘贴、重复的字符串更改(一次用于文件名和其中的域+tld,以及进一步的执行,如a2ensite
(见下文)。
我现在寻求自动化该过程,但我不确定在内部(在虚拟主机中)和外部(在文件名和进一步执行中)更改域+tld 的最佳方法是什么
这是我手动创建每个虚拟主机的方法:
1. Copy a ready Vhost template file (I have such a file which I name `d.t` and I clone it whenever I need to create a new Vhost):
<VirtualHost *:80>
DocumentRoot "/var/www/html/d.t"
ServerName www.d.t
<Directory "/var/www/html/d.t">
Options +SymLinksIfOwnerMatch
Require all granted
</Directory>
ServerAlias www.d.t
</VirtualHost>
3. Search and replace "d.t", with domain+tld:
Do in nano.
4. Replace filename (d.t) with domain+tld:
mv /etc/apache2/sites-available/d.t /etc/apache2/sites-available/domain.tld
5. Enable domain.tld.conf & restart the Apache service:
a2ensite domain.tld.conf && systemctl restart apache2.service
这可能看起来很简单,但是当我从手动文件中手动执行此算法时,可能需要更多时间将每个示例(例如 dt)重写到相关域+tld 中。
我的问题:
我正在寻找一种通过以下操作运行脚本的方法:该脚本实际上看起来非常相似,但在此脚本中,d.t
将替换为脚本的文件名。例如,如果脚本的文件名是MyNewVhost.com
,则d.t
其中的每个出现位置都将变为MyNewVhost.com
.
我想一些可变的工作可以达到这个目的,但我可能是错的;如果是这样,我需要一种告诉程序“将文件名放入每个 dt 中”的方法。
笔记:
- 我相信答案也可以为在 Nginx 服务器块(Nginx Sblocks)中遇到类似问题的人提供一个很好的指导。
答案1
GNUmake
运行良好
您可以使用 GNU make
1,其中创建新的虚拟主机就像执行一样简单make example.com
简短而简单:一个静态模板
首先,创建/etc/apache2/sites-available/Makefile
包含:
% :
printf '%s\n' \
'<VirtualHost *:80>' \
' DocumentRoot "/var/www/html/$@"' \
' ServerName www.$@' \
' <Directory "/var/www/html/$@">' \
' Options +SymLinksIfOwnerMatch' \
' Require all granted' \
' </Directory>' \
' ServerAlias www.$@' \
'</VirtualHost>' \
> "$@"
a2ensite "$@"
systemctl restart apache2.service
请注意,后面的每一行都% :
以制表符开头,而不是空格。另请注意,其中大部分实际上是您的模板文件,但d.t
替换为$@
.
之后,您可以创建一个名为的新虚拟主机domain.tld
:
cd /etc/apache2/sites-available
make domain.tld
添加选项:多个模板
这是最简单的使用方法之一make
。对于稍微复杂的配置,假设您有两个(或更多)模板。我将在这里展示一个我称之为basic.template
的模式:
<VirtualHost *:80>
DocumentRoot "/var/www/html/$domain$"
ServerName www.$domain$
<Directory "/var/www/html/$domain$">
Options +SymLinksIfOwnerMatch
Require all granted
</Directory>
ServerAlias www.$domain$
</VirtualHost>
然后您将修改(简化!)您的Makefile
:
% :
sed 's/\$$domain\$$/$@/g' < "$<" > "$@"
a2ensite "$@"
systemctl restart apache2.service
.PHONY : all
all :
@true
这里的秘诀涉及使用预期的域名sed
替换形式的变量。$domain$
此外,我还添加了一个PHONY
名为 的目标all
,它的用途很快就会变得显而易见。
要立即创建虚拟主机,您必须指定哪个要使用的模板。对我来说,最好将其包装在脚本中。
#!/bin/sh
# File update-makefile
# Call as:
# ./update-makefile domain.tld basic.template
sed '/^all :/s/$/ '"$1"'/' < Makefile > Makefile.new
printf '%s\n' "$1 : $2" >> Makefile.new
mv Makefile.new Makefile
请注意,这还有一个额外的步骤添加2.新建虚拟主机到Makefile中。这让我们make
看看哪个模板domain.tld
依靠在。然后你可以这样做:
cd /etc/apache2/sites-available
./update-makefile domain.tld basic.template && make
有了这个设置,每一个如果相应的模板发生更改,站点将会更新。
重要的是要all
成为第一的命名目标。这使得它成为make
不带参数调用时的默认值。该update-makefile
脚本将新域添加为 的依赖项all
,因此make
如果它相对于其自身的依赖项(模板文件)变得过时,则会重新创建它。
1 make
是一个用于创建的工具目标文件从一组食谱和依赖关系记录在Makefile
.在 GNU 语法中,
% :
# do stuff
是一个模式规则。它声明可以创建具有任何名称 ( ) 的文件%
作为目标,并且它没有依赖项。这# do stuff
是配方(任何 shell 脚本),按一个制表符缩进。您可以使用一些变量来引用目标名称 ( $@
)、第一个依赖项 ( $<
) 或所有依赖项 ( $^
) 等。有关更多信息,请参阅维基百科。
您的系统可能尚未make
安装,在这种情况下您必须自行安装。此外,某些系统使用make
.概念是相同的,但规则的语法与 GNU 版本略有不同。
2绝对确定您使用>>
追加而不是>
覆盖!
答案2
恭喜,您正在向配置管理迈出第一步!
这里有很多可能的结果,但从根本上讲,您正在制作配置片段的模板,并创建该模板的实例。
您是正确的,模板中的一些变量可以满足您的需要;只需选择某种编程语言(甚至是简单的 shell)来驱动用所需的值填充模板即可。 Fox 使用 Make 的回答是一个很好的简短示例;当您想要更新模板时,您可以通过在 Makefile 中声明所有站点来修改它,以重建所有站点。
这是配置管理的简单结束(保留用变量填充模板的脚本,以防您以后想要更新大量配置)。
配置管理工具变得更加复杂,例如 Puppet、Chef、Cfengine、Salt 等。
这是一个使用 Puppet 和 PuppetLabs Apache 模块并使用 Hiera 中的数据填充它的现成示例(变量值的结构化集合)。