Multiple vhosts on one and the same docker container - apache

I'm trying to run two different domains on one and the same Docker container and port.
The Docker container runs CentOS. docker-compose.yml looks like so:
web:
image: fab/centos
ports:
- "80:80"
volumes:
- ./src/httpd.conf:/etc/httpd/conf/httpd.conf
- ./src:/var/www/html
- ./src/hosts:/etc/hosts
environment:
- VIRTUAL_HOST=dummy.dev,tests.dev
I also declared both .dev domain names inside of /etc/hosts on the host computer (OS X.)
It's been a while since I configured virtual hosts. My understanding was that I just needed to declare them and that Apache would automatically serve the proper files depending on the HTTP HOST being requested.
This is what I have, added at the end of httpd.conf:
<VirtualHost *:80> # first host = default host
DocumentRoot /var/www/html/default
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/dummy
ServerName dummy.dev
ServerAdmin webmaster#dummy.dev
ErrorLog logs/dummy.dev-error_log
CustomLog logs/dummy.dev-access_log common
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/tests
ServerName tests.dev
ServerAdmin webmaster#tests.dev
ErrorLog logs/tests.dev-error_log
CustomLog logs/tests.dev-access_log common
</VirtualHost>
However, in practice, visiting either dummy.dev or tests.dev actually serves /var/www/html/default. This is as if Apache didn't realize which host is being called (though a dump of $_SERVER in PHP does show the expected HTTP_HOST value, i.e.: either 127.0.0.1, dummy.dev or tests.dev depending on which URL I visit.)
What did I miss?
It's unclear to me whether this is an Apache issue or a Docker one.
(Please note this is a different question from how to host multiple apps on the same domain with different port. In my case, I do want the virtual hosts to be all inside/on the same app/port/container.)

Turns out this was an Apache configuration issue.
I needed to explicitly enable domain-named virtualhosts, like so:
NameVirtualHost *:80
This answer helped.
Docker had nothing to do with the matter.

The fab/centos does not exist in public docker hub, so not sure why you are experiencing the issue.
My recommendation would be to take a step back and try to make it work with a simple example.
docker search apache yields eboraas/apache as most starred image, so I'll use that one for the example.
In a test directory, use your sample:
File: httpd.conf
<VirtualHost *:80> # first host = default host
DocumentRoot /var/www/html/default
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/dummy
ServerName dummy.dev
ServerAdmin webmaster#dummy.dev
ErrorLog logs/dummy.dev-error_log
CustomLog logs/dummy.dev-access_log common
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/tests
ServerName tests.dev
ServerAdmin webmaster#tests.dev
ErrorLog logs/tests.dev-error_log
CustomLog logs/tests.dev-access_log common
</VirtualHost>
Then create the vhost websites & the logs directory.
mkdir -p logs; for i in default tests dummy; do mkdir -p $i; echo "hello $i" > $i/index.html; done
Finally, run docker.
docker run -it -v $(pwd):/var/www/html -v $(pwd)/httpd.conf:/etc/apache2/sites-available/000-default.conf -v $(pwd)/logs:/etc/apache2/logs -p 9090:80 --rm --name apache_c eboraas/apache
Note that I use basically the same volumes as you did in your docker-compose.yml, except that I use site-available instead of changing the httpd.conf.
To test, make sure you have tests.dev and dummy.dev in your /etc/hosts pointing at the right Docker IP and test:
$> curl dummy.dev:9090
hello dummy
$> curl tests.dev:9090
hello tests
From this point, build up on top of this by first trying the docker apache image that you are using, then try with your custom /etc/hosts file, then put it back in a docker-compose file

Turn on NameVirtualHost in your httpd config:
File : /etc/httpd/conf/httpd.conf
NameVirtualHost *:80
NameVirtualHost *:443

Related

Make local website available to all devices in local network

I have created a LAMP server and in there I host a couple of websites. These websites are currently available only when I access them from my Ubuntu machine. How can I modify the virtual hosts so that all the devices connected in the network can access these websites too ?
Websites' .conf file, located in /etc/apache2/sites-available/ looks like this:
Website1.com
<VirtualHost *:80>
ServerAdmin webmaster#website1.com
ServerName website1.com
ServerAlias www.website1.com
DocumentRoot /var/www/html/website1.com/public
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Website2.com
<VirtualHost *:80>
ServerAdmin webmaster#website2.com
ServerName website2.com
ServerAlias www.website2.com
DocumentRoot /var/www/html/website2.com/public
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
The hosts file looks like this:
127.0.0.1 localhost website1.com website2.com
Both of these websites can be accessed from my Ubuntu machine by simply entering their names in the browser, but any other device in the network has no access to them.
You have to do two things.
1. Setup Apache virtual host
Virtual host must listen to your private IP, not localhost.
Find your private IP using ifconfig command in terminal and look for it in the output.
$ ifconfig
...
wlp4s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.88.11 netmask 255.255.255.0 broadcast 192.168.88.255
...
My private ip is 192.168.88.11
Virtual host must listen to it:
<VirtualHost 192.168.88.11:80>
Note! Maybe *:80 also works!
2. Setup DNS server in your local network.
Other machines in the local network must know where is the website1.com. DNS server must resolve website1.com to 192.168.88.11.
My router is MikroTik. And through the admin panel, using router's terminal, I can configure Static DNS of domains to resolve to internal ip.
/ip dns static add name=website1.com address=192.168.88.11
Also I can use regular expressions to match many domains using one static record.
Regular expression below matches all .lan domains: foo.lan, bar.lan, anysite.lan, etc.. And all of them will be resolved to 192.168.88.11.
/ip dns static add regexp=".+\.lan" address=192.168.88.11
You have to find out capabilities of your router to set it up.

Apache: Serving content from two different locations and ports

I have an Apache server running on Ubuntu 14 on a server on which I have sudo.
When users request the server's IP, Apache serves content from /var/www/html.
I'd like to keep this behavior intact, and make it so that users who request IP/cats get some special content that's hosted by a Docker container on port 7777.
What's the best way to achieve this functionality in Apache?
With thanks to #arkascha I did the following to get this going:
Create a file /etc/apache2/sites-available/wow.conf with the following content:
<VirtualHost *:*>
# enable proxies
ProxyPreserveHost On
ProxyPass /cats http://0.0.0.0:7777/
ProxyPassReverse /cats http://0.0.0.0:7777/
ServerAdmin douglas.duhaime#yale.edu
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
This says when requests come in for IP/cats, serve the users the content from port 7777.
I then symlinked this file to the sites-enabled directory:
sudo ln /etc/apache2/sites-available/wow.conf /etc/apache2/sites-enabled/wow.conf
Finally, I needed to delete the default sites enabled file and restart the server:
sudo rm /etc/apache2/sites-enabled/000-default.conf
sudo service apache2 restart
P.S. Apache is amazing.

Why I see the content of my localhost instead of accessing my created virtual host?

I'm working on Ubuntu-14 and I want to access http://localhost:8086/myproject.net using http://myproject.dev
I created a new folder under "/var/www/" named "myproject.net"
I added this line to "/etc/hosts"
127.0.0.1 myproject.dev
I created "myproject.dev.conf" file under "/etc/apache2/sites-available" which contains:
<VirtualHost *:86>
ServerAdmin i-put-my-email-here
ServerName myproject.dev
ServerAlias www.myproject.dev
DocumentRoot /var/www/myproject.net/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
I enabled my site using
sudo a2ensite myproject.dev.conf
I restarted Apache
sudo service apache2 restart
I verified that Apache is running using
sudo service apache2 status
Now when I tape http://myproject.dev:8086 I see the content of my localhost (like when I do http://localhost:8086) not the content of myproject!
Am I missing a step or Am I doing something wrong?
You have to take care to define your virtual host on the correct address and port so that it can be matched for an incoming request. Otherwise the default host will be selected to respond to the request.
In your specific example you have to change the definition from
<VirtualHost *:86>
to use the port your http server is obviously listening on and that you make the request to:
<VirtualHost *:8086>
Oh, and... don't forget to restart your http server process after such a change ;-)

How do you set the default website to serve when your IP address is entered as URL?

I have a server with multiple websites hosted and distinguishable using name-based virtual hosting of apache.
How do I set it so that a specific website is hosted when the ip of my server is entered in the address bar?
What you want to use is the _default_ VirtualHost.
<VirtualHost _default_:80>
DocumentRoot /www/default80
# ...
</VirtualHost>
It's described here. Basically if nothing else match the request the _default_ host will be used.
EDIT
This could also be written as:
<VirtualHost *>
DocumentRoot /www/default
# ...
</VirtualHost>
Is is important that this is the first VirtualHost in the configuration since Apache will start matching them from top to bottom, selecting the one that fit the best based on ServerName and ServerAlias.
This post might also be of interest:
Apache default VirtualHost
just find the Include sites-enabled/ line in your apache2.conf file and add the path to the conf file you want to be site default above it. from:
Include sites-enabled/
to
Include sites-enabled/mydefault.conf
Include sites-enabled/
When you first install apache2, there is a site configuration file named 000-default.conf. This is going to be the default because it is very likely to appear first in the list of files under /etc/apache2/sites-enabled.
To have your own file as the default, you can either replace the file under /etc/apache2/sites-available/000-default.conf with your own, or replace the link like so:
sudo rm /etc/apache2/sites-enabled/000-default.conf
sudo ln -s ../sites-available/my-site-setup.conf /etc/apache2/sites-enabled/000-default.conf
Then restart apache2 (or just reload).
The _default_ as mentioned by the other answer is for defining a virtual host which can be found with the default IP address. It's not the default virtual host.
<VirtualHost _default_:80>
...
is equivalent to
<VirtualHost *:80>
...
The * is a globing pattern which matches any IP addresses.
Note:
Replacing the 000-default.conf file is okay, but in most cases the installation package is going to view that as a modified file and manage it in some weird way which is why I think it's cleaner to only change the soft link.
Keep it clean, don't delete or edit anything in /etc/apache2/sites-available/.
Create all new site configurations in /etc/apache2/sites-available/. Copy whatever site configuration you want enabled to /etc/apache2/sites-enabled/. Only make sure /etc/apache2/sites-enabled/ has only one configuration file.
Sample format for new apache site configurations in Ubuntu 20.04 LTS is
<VirtualHost *:80>
ServerName http://localhost
ServerAdmin admin#mysite.com
DocumentRoot /var/www/html/mysiteroot/public
<Directory /var/www/html/mysiteroot>
AllowOverride All
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Notice that 000-default.conf is by default in both directories mentioned above and should only be replaced by your new configuration in /etc/apache2/sites-enabled/ so that it can be restored anytime you need it.
Restart Apache2 service after you make any configuration changes.

Apache Virtual Host (Subdomain) access with different computer on LAN

I am currently trying to configure the Virtual Host (Subdomain) of my Apache HTTP Server so it can be accessed with another computer on my LAN. The current setup of Apache with PHP and MySQL works locally on the same physical machine.
So I have two Virtual Host setup (development and cms) running on a non-default port of 50080. The machine of the server have a IP of 10.0.0.10. From the same physical machine, I can access the two Virtual Host using:
development.localhost:50080
cms.localhost:50080
From a different physical machine, I can access the root of the server using:
10.0.0.10:50080
But I cannot or do not know how to access the Virtual Host from the different machine. I tried something like:
development.10.0.0.10:50080
cms.10.0.0.10:50080
But they do not seem to work.
Here's how my httpd-vhosts file looks like:
NameVirtualHost *:50080
<VirtualHost *:50080>
DocumentRoot "C:/www/HTTP"
ServerName localhost
</VirtualHost>
<VirtualHost *:50080>
ServerAdmin administrator#development.localhost
DocumentRoot "C:/www/HTTP/development"
ServerName development.localhost
ErrorLog "logs/development.localhost-error.log"
CustomLog "logs/development.localhost-access.log" common
</VirtualHost>
I read some of the other post here and the Apache forum, but there's not exact case for this.
I was wondering how I can access the Virtual Host (Subdomain) from another machine and keep the same port if possible.
Thanks in advance
Ok, I figured it out, here are the configuration if anyone else is looking for this:
==================================================================================
Machine A (Apache HTTP Server):
httpd-vhost:
NameVirtualHost *:50080
<VirtualHost *:50080>
DocumentRoot "C:/www/HTTP"
ServerName localhost
ServerAlias alias <!-- Added -->
</VirtualHost>
<VirtualHost *:50080>
ServerAdmin administrator#development.localhost
DocumentRoot "C:/www/HTTP/development"
ServerName development.localhost
ServerAlias development.phoenix <!-- Added -->
ErrorLog "logs/development.localhost-error.log"
CustomLog "logs/development.localhost-access.log" common
</VirtualHost>
hosts:
127.0.0.1 development.localhost
127.0.0.1 alias
127.0.0.1 development.alias
==================================================================================
Machine B (Guest Machine):
hosts:
10.0.0.10 alias
10.0.0.10 development.alias
From the second machine, you should be able to access with "alias" and "development.alias"
I suggest making the following change (add the ServerAlias lines):
NameVirtualHost *:50080
<VirtualHost *:50080>
DocumentRoot "C:/www/HTTP"
ServerName localhost
ServerAlias cms.myserver.com
</VirtualHost>
<VirtualHost *:50080>
ServerAdmin administrator#development.localhost
DocumentRoot "C:/www/HTTP/development"
ServerName development.localhost
ServerAlias development.myserver.com
ErrorLog "logs/development.localhost-error.log"
CustomLog "logs/development.localhost-access.log" common
</VirtualHost>
Restart Apache to ensure the changes take effect.
Then on your second computer you need to add a custom dns entry for these new domain names. If it is Windows, edit the file c:\windows\system32\drivers\etc\hosts. If it is Linux, edit /etc/hosts. Either way add:
10.0.0.10 development.myserver.com
10.0.0.10 cms.myserver.com
Now on your second computer you should be able to access the following URLs:
http://development.myserver.com:50080
http://cms.myserver.com:50080
Unless I'm missing something, you'll need to either set up DNS entries, or add entries to the /etc/hosts file of each computer accessing the server.
localhost is an entry that exists in everyone's /etc/hosts file by default, always pointing to 127.0.0.1. Without adding a /etc/hosts entry, developer.localhost doesn't exist, and prefixing an ip address with a subdomain won't work at all.
Using a SSH + Putty tunnel, and thus having a 127.0.0.1 on my server, I managed to access my subdomains by doing the following on my server side:
# nano /etc/hosts
127.0.0.1 localhost.localdomain localhost
127.0.0.1 sub1.domain.com sub2.domain.com sub3.domain.com sub4.domain.com
I did not change the host file of the remote computer, and it works like a charm
For Named Virtual Hosts you need to use a hostname or domainname to connect to you apache server. It does not work with ips.
You could insert an entry in your /etc/hosts on your second system.