Como ya comenté en el pasado, para este sitio (y otros en el mismo server) estoy utilizando Apache para servir el PHP en el puerto 8080 y al frente un nginx como reverse proxy, que redirecciona las peticiones PHP al Apache y sirve los archivos estáticos, utilizando el prótocolo http2.
Entonces vamos a ver como configurar los vhosts en ambos servers para poder servir más de un sitio desde la misma VM.
Para agregar vhosts a Apache vamos a ir a /etc/apache2/sites-available y agregar ahi las configuraciones. En este ejemplo vamos a suponer que agregamos sitio1.com y sitio2.com, cuyos dominios ya deberían estar apuntando a los nameservers de nuestro hosting.
Entonces vamos a crear el archivo sitio1.conf:
<VirtualHost *:8080>
ServerAdmin [email protected]
ServerName sitio1.com
#esta linea NO HACE FALTA, ya que nginx se encargará de redireccionar www, la dejamos a modo de ejemplo
ServerAlias www.sitio1.com
DocumentRoot /var/www/vhosts/sitio1/htdocs
<Directory /var/www/vhosts/sitio1/htdocs>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
AccessFileName .htaccess
LogLevel warn
ErrorLog /var/www/vhosts/sitio1/logs/error.log
CustomLog /var/www/vhosts/sitio1/logs/access.log combined
</VirtualHost>
Y sitio2.conf:
<VirtualHost *:8080>
ServerAdmin [email protected]
ServerName sitio2.com
DocumentRoot /var/www/vhosts/sitio2/htdocs
<Directory /var/www/vhosts/sitio2/htdocs>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
AccessFileName .htaccess
LogLevel warn
ErrorLog /var/www/vhosts/sitio2/logs/error.log
CustomLog /var/www/vhosts/sitio2/logs/access.log combined
</VirtualHost>
Observando el archivo se ve que sitio1 se sirve desde /var/www/vhosts/sitio1/htdocs y sitio2 desde /var/www/vhosts/sitio2/htdocs. También tengo la costumbre de separar los logs por vhost, de esta forma es más simple encontrar errores o tomar métricas específicas para cada sitio. Por esto vamos a crear los directorios que necesitamos:
mkdir -p /var/www/vhosts/sitio1/htdocs
mkdir /var/www/vhosts/sitio1/logs
mkdir -p /var/www/vhosts/sitio2/htdocs
mkdir /var/www/vhosts/sitio2/logs
Como último paso, nos queda habilitar las configs, para esto hacemos:
a2ensite sitio1
a2ensite sitio2
service apache2 restart
Con esto terminamos la configuración de apache, pero todavía no podemos acceder a nuestros sitios porque, recordemos, el que sirve desde el puerto 443 es nginx, asi que vamos al siguiente paso.
La configuración de nginx es muy similar a la de Apache, de hecho usan la misma estructura de directorios (solo que los archivos de configuración de nginx, al igual que los de apache anteriores a la versión 2.4, no tienen extensión). Asi que nos vamos al directorio /etc/nginx/sites-available y creamos nuestros dos archivos, sitio1 y sitio2:
#archivo /etc/nginx/sites-available/sitio1
server {
listen 443 deferred ssl http2 default_server;
listen [::]:443 deferred ssl http2 default_server;
# gzip should not be used with ssl
gzip off;
ssl_certificate /etc/letsencrypt/live/sitio1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sitio1.com/privkey.pem;
root /var/www/vhosts/sitio1/htdocs;
index index.php;
server_name sitio1.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
location ~* \.(gif|jpg|jpeg|js|css)$ {
try_files $uri =404;
}
location ~ /\.ht {
deny all;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/sitio1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sitio1.com/privkey.pem;
server_name www.sitio1.com;
return 301 https://sitio1.com$request_uri;
}
server {
listen 80;
listen [::]:80;
server_name sitio1.com www.sitio1.com;
return 301 https://$server_name$request_uri;
}
#archivo /etc/nginx/sites-available/sitio2
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# gzip should not be used with ssl
gzip off;
ssl_certificate /etc/letsencrypt/live/sitio2.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sitio2.com/privkey.pem;
root /var/www/vhosts/sitio2/htdocs;
index index.php;
server_name sitio2.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
location ~* \.(gif|jpg|jpeg|js|css)$ {
try_files $uri =404;
}
location ~ /\.ht {
deny all;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/sitio2.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sitio2.com/privkey.pem;
server_name www.sitio2.com;
return 301 https://sitio1.com$request_uri;
}
server {
listen 80;
listen [::]:80;
server_name sitio2.com www.sitio2.com;
return 301 https://$server_name$request_uri;
}
Básicamente acá lo que hacemos es: escuchar en el puerto 443 y servir contenido de sitio1.com y sitio2.com, en el mismo puerto redireccionar www.sitio1.com y www.sitio2.com a sus correspondientes URLs sin el www y escuchar el puerto 80 para redireccionar a https. Recordemos que esta configuración se complementa con la configuración de SSL de nginx.
Para que nginx efectivamente lea las configuraciones tenemos que crear los links simbólicos desde sites-enabled:
cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/sitio1 sitio1
ln -s /etc/nginx/sites-available/sitio2 sitio2
Esto es exactamente lo mismo que hace apache automáticamente si usamos a2ensite.
Validamos que la config esté OK y reiniciamos Nginx:
nginx -t
service nginx restart
Y con esto estamos listos para servir nuestros dos sitios desde el mismo server.
Ya se pueden agregar los archivos a las carpetas /var/www/vhosts/sitio1/htdocs y /var/www/vhosts/sitio2/htdocs y ver el contenido de ambos sitios. Igual más que subir via ftp o scp yo prefiero utilizar git para hacer los despliegues.
Espero les sea útil.