2

When I create new web applications on my up-2-date Ubuntu-LAMP with Apache 2.4.x environment, I create their virtual-host files this way:

s_a="/etc/apache2/sites-available/"
s_e="/etc/apache2/sites-enabled/"

read -p "Have you created db credentials already?" yn
case $yn in
    [Yy]* ) break;;
    [Nn]* ) exit;;
    * ) echo "Please create db credentials in then comeback;";;
esac

read -p "Please enter the domain of your web application:" domain_1 && echo
read -p "Please enter the domain of your web application again:" domain_2 && echo
if [ "$domain_1" != "$domain_2" ]; then echo "Values unmatched. Please try again." && exit 2; fi

read -sp "Please enter the app DB root password:" dbrootp_1 && echo
read -sp "Please enter the app DB root password again:" dbrootp_2 && echo
if [ "$dbrootp_1" != "$dbrootp_2" ]; then echo "Values unmatched. Please try again." && exit 2; fi

read -sp "Please enter the app DB user password:" dbuserp_1 && echo
read -sp "Please enter the app DB user password again:" dbuserp_2 && echo
if [ "$dbuserp_1" != "$dbuserp_2" ]; then echo "Values unmatched. Please try again." && exit 2; fi

cat <<-EOF > "$s_a/$domain_2.conf"
    <VirtualHost *:80>
        ServerAdmin admin@"$domain_2"
        ServerName ${domain_2}
        ServerAlias www.${domain_2}
        DocumentRoot /var/www/html/${domain_2}
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
EOF

ln -sf "$s_a"/"$domain_2".conf "$s_e"

My question

Is there a way to automate that / shorten the amount of lines code (the actual script-file is much bigger in principle), maybe even from some built-in behavior in Apache itself and without involving further software?

If other software might be needed than from what I've read so far it should be Docker and I should look for an Apache-virtual host docker script that will be based on my variable declarations (in dockerhub) which I will then run with a docker command, but maybe Apache itself will have automation functionality for this or there is some third solution the answer's my need?

  • 1
    If you are doing extensive configuration management of the Apache server, it sounds like you need a configuration management tool, like Ansible, Chef or Puppet. The lightest of these is Ansible. You would need to write a small playbook with some variables and template actions to maintain this configuration. – Bruce Becker Nov 20 '18 at 9:01
  • Hi @BruceBecker to be honest this is basically the only change I make in Apache itself... But a tiny playbook is good here, but I still need to be prompted for variables so (while I have to learn more on Ansible) I can't see how it will help me in this particular scenario... :\\ – JohnDoea Nov 20 '18 at 12:57
  • 2
    So: you have 3 problems -- 1. managing variables, 2. managing file content 3. managing file location. You are currently solving it a procedural script, which is not idempotent. Following the 12 factor pattern, you should keep variables in the environment. If you use that pattern, you don't need a templating system and a lot of the read can be skipped. Enabling them should be done with a2ensite – Bruce Becker Nov 20 '18 at 13:55
3
+100

This has already been covered a bit in the comments, but I figured I'd lay out a more extensive answer.

Is there a way to automate that / shorten the amount of lines code (the actual script-file is much bigger in principle), maybe even from some built-in behavior in Apache itself and without involving further software?

You can use a2ensite as a replacement for your very last line, the ln; all it does is set up symlinks into /etc/apache2/sites-enabled, which is where Apache httpd looks by default for configuration. Some details may vary by distribution.

However, this only changes your script a tiny bit. There are much larger problems you have to address.

First, I'll mention that no, Docker is almost certainly not the solution you want. Docker works best when used in a container orchestration layer like Kubernetes, and while I can easily imagine an architecture with a single Docker image that takes in parameters to create different vhosts, it's a much more complicated system than your presumably one-host system and requires substantial changes to how everything works. Docker is a hip new thing, but what many people do not realize is that it solves a set of well-understood problems and creates a set of new, poorly-understood ones, and it's likely that you don't have the problems that such an architecture would solve. So let's set that aside for now.

The first problem you have is that you're writing Apache configuration (primarily) by hand, with templating in bash and limited validation. In reality in your example this isn't a big deal since it's a small and simple config, but it's easy to start this way and end up with a large block of sed and ed commands (this I know from experience).

The larger problem is in how ephemeral your changes are. You configure all these vhosts, great. Then your server dies. What happens? You're probably going to spend a lot of time trying to rebuild it. Hopefully you have a recent backup to help, but the point here is that the last few decades we've settled into this idea of treating configuration the same way as code - rather than setting things up by hand, you write all of your configuration into text files and a program translates that into configuration on the server. This has a multitude of benefits, including backups, code review, and a history of changes that you can look back on. Most configuration management tools also provide convenient abstraction layers. Here is an example that lays out how to translate an Apache vhost file into an Ansible template, and then you only need to add new entries to the variable list and rerun the configuration. When it comes to things like your database passwords, those too can be stored and version-controlled in Ansible Vault or a similar product.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.