Configura tu APP en Google Cloud con Docker y Proxy Inverso

Julio César Ruiz Tejada
4 min readSep 8, 2023

--

Hace unos meses me topé con un dilema al desarrollar una app web y me pregunté ¿Cómo puedo hacer para que mi aplicación en Docker pueda tener un subdominio y con https?, muchas fueron las opciones pero encontré una ruta que puede llegar a interesar si has estado en ese mismo “problema”.

Antes de explicar el paso a paso debemos tener en cuenta que Docker es un sistema de despliegue de aplicaciones en contenedores, lo que hace más fácil y rápido las ejecuciones de las mismas, haciendo que podamos tener ‘X’ cantidad aplicaciones en una sola instancia, ejecutándose a la vez y trabajando de manera independiente una de la otra.

Usando Docker en Google Cloud Platform (GCP)

Image by Google for Developers

Lo primero en hacer es encontrar un servidor para nuestra aplicación, para eso trabajaremos con GCP, que consta con una amplia gama de servicios en la nube que puedes llegar a cubrir cada una de nuestras necesidades tecnológicas al desarrollar. Usando en esta ocasión Compute Engine, crearemos una instancia tipo e2-standard-2 con disco 100GB y Sistema Operativo Debian 11. Esta instancia es donde estaremos configurando Docker para colocar nuestras aplicaciones.

Luego de configurar nuestro server, instalaremos Docker con los siguientes comandos, ejecutando línea por línea:

sudo apt install apt-transport-https lsb-release ca-certificates curl gnupg -y

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update

sudo apt -y install docker-ce docker-ce-cli containerd.io

Para saber si tenemos instalado Docker vamos a ejecutar el comando “sudo docker version”, de esta forma podremos ver la versión instalada en nuestro sistema.

Ya solo nos quedará activar el Docker como un servicio de linux y de esta forma ejecutar el demonio:

sudo systemctl enable docker

sudo systemctl start docker

sudo systemctl status docker

Después de aplicar la última línea de comando, nos debería de salir algo así:

Ya tenemos nuestro sistema de contenedores listo para subir nuestra aplicación. Ahora crearemos un archivo Dockerfile el cual tendrá las instrucciones necesarias para la creación de la imagen de nuestra aplicación para luego convertirla en un app independiente, en pocas palabras, en contenedor🤓. Nuestro Dockerfile lo configuraremos de esta manera:

FROM node:16-alpine 

WORKDIR /app

COPY package.json /app

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "run", "dev"]

Nuestra app la colocaremos en un repositorio en Github para luego descargarla en nuestra instancia en GCP y así ejecutar el Dockerfile que tendremos en la carpeta raíz del aplicativo de la siguiente manera:

sudo docker build -t image-reactapp .

Crearemos el contenedor de la aplicación con la imagen que acabamos de preparar. Ese contenedor le asignaremos el puerto 35486 bajo el nombre de “app-react”. Se preguntarán ¿porqué ese puerto tan ‘random’? … pues porque suena atractivo el número✌️😁.

sudo docker run -d -p 35486:3000 --name app-react image-reactapp

Ya solo nos queda dirigirnos a nuestra consola en Google Cloud Platform, en la sección de Red de VPC -> Firewall y crear una regla de Firewall para habilitar el puerto 35486 y de esta forma permitir la entrada del tráfico a nuestra instancia.

Apache como servidor de Proxy Inverso

Si bien Apache es conocido para usarse como servidor web, en esta ocasión lo utilizaremos como proxy inverso para que nos ayude a configurar nuestra aplicación y de esta forma se vea públicamente usando un subdominio con https de Certbot. Para eso debemos instalar Apache y Certbot y luego le configuramos el subdominio:

sudo apt update

sudo apt install apache2

sudo apt -y install certbot

sudo certbot certonly --apache --domain app.midominiopersonal.com

Seguido, instalaremos los complementos necesarios para realizar la configuración del proxy inverso con apache, al tenerlos listos solo quedaria reiniciar el servicio de apache:

sudo a2enmod proxy

sudo a2enmod proxy_http

sudo a2enmod ssl

sudo a2enmod headers

sudo systemctl restart apache2.service

Crearemos un archivo .conf el cual tendrá todas las configuraciones del proxy, ssl y redireccionamiento:

sudo nano /etc/apache2/sites-available/reactapp.conf

Ejemplo de reactapp.conf:

<VirtualHost *:80>
ServerName app.midominiopersonal.com
ServerAlias www.app.midominiopersonal.com

Redirect permanent / https://app.midominiopersonal.com/
</VirtualHost>
<VirtualHost *:443>
ServerName app.midominiopersonal.com
ServerAlias www.app.midominiopersonal.com

DocumentRoot /var/www/html

ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" https

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/app.midominiopersonal.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/app.midominiopersonal.com/privkey.pem

ProxyPass / http://35.35.250.250:35486/
ProxyPassReverse / http://35.35.250.250:35486/

<Proxy *>
Require all granted
</Proxy>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

De esta manera estaremos configurando que la aplicación de React que actualmente la vemos con la dirección http://35.35.250.250:35486/ se logre ver ahora con https://app.midominiopersonal.com/ . Ya para finalizar solo nos resta activar el reactapp.conf y reiniciar apache:

sudo a2ensite reactapp.conf

sudo systemctl restart apache2

Conclusiones

Ya vimos como usando Google Cloud, Docker y Apache podemos subir a producción nuestras aplicaciones y configurarlas de cierta forma que no sea necesario acceder a ellas desde la ip pública y un puerto específico.

Espero les haya ayudado con esta serie de paso y así darle una forma de como podemos aprovechar el proxy inverso con apache para ejecutar nuestras aplicaciones de una manera más limpia y con mejor seguridad.

--

--

Julio César Ruiz Tejada

Engineer, developer & designer | Technology & life enthusiast 🤓💻