# Cómo alojar un sitio web estático en Back4app Containers con Docker y nginx

Tienes un sitio y ningún lugar donde ponerlo. Envuélvelo en un container, apunta un host al repositorio y ya está en línea: sin servidor que alquilar, parchear ni mantener en marcha.

URL: https://www.back4app.com/blog/es/como-alojar-un-sitio-estatico-en-un-contenedor-con-docker-y-nginx
Publicado: 2026-11-10 · Probado: 2026-09-23
Probado en: Local: Docker 29.4.3, macOS, arm64 · Imágenes: ubuntu:latest (26.04.1), nginx:1.27-alpine · Plataforma: Back4app Containers, plan Free
Publisher: Back4app Engineering

Tienes un sitio web. Algo de HTML, una hoja de estilos, quizá un poco de JavaScript. Funciona cuando lo abres en tu laptop, y ahora necesita una dirección que otras personas puedan escribir, sin alquilar un servidor, mantenerlo parcheado ni aprender qué es un proxy inverso.

Meterlo en un container resuelve eso. Describes el servidor web una vez en un archivo pequeño, lo subes a un repositorio y un host lo construye y lo ejecuta por ti. Después no hay nada que mantener, porque no hay ninguna máquina tuya en la ecuación.

Esta guía lo hace de principio a fin: el sitio, el archivo del container, el deploy y una dirección en vivo. Tardó **9 segundos** desde el push hasta estar en línea, y la última sección explica por qué la mayoría de los ejemplos que encontrarás en internet tardan bastante más.

## Míralo en acción

El recorrido original lleva una página desde un repositorio de GitHub hasta un container en ejecución, de principio a fin.

## ¿Qué necesitas realmente?

Tus archivos, y un archivo más junto a ellos. Esa es la lista completa: sin servidor, sin cuenta de hosting que configurar, sin servidor web que instalar en nada tuyo.

El archivo extra es un `Dockerfile`. Nombra un servidor web, dice dónde van tus páginas, y eso es todo lo que tiene que hacer. Un host lo lee, construye el resultado una vez y lo ejecuta.

El ejemplo de aquí es un sitio de cuatro archivos: una página HTML, una hoja de estilos, unas líneas de JavaScript y el `Dockerfile`. El tuyo puede tener mil páginas; nada de lo que sigue cambia.

## ¿Cómo se escribe el archivo del container?

Tres líneas. Parte de la imagen oficial de nginx, copia tu sitio en la carpeta que sirve y declara el puerto.

```dockerfile
FROM nginx:1.27-alpine
COPY site/ /usr/share/nginx/html
EXPOSE 80
```

Ese es el archivo completo. No hay paso de instalación, porque la imagen ya contiene nginx, ni comando de arranque, porque la imagen ya sabe cómo arrancarlo.

El único valor que conviene conocer es `/usr/share/nginx/html`, el directorio desde el que sirve esta imagen. Pon tu `index.html` ahí y el sitio funciona; ponlo en cualquier otro lugar y recibes un 404.

Fija la versión en el tag, como hace aquí `1.27-alpine`. Significa que la imagen que construyas el mes que viene es la que construiste hoy, y no la que resulte estar vigente en ese momento.

## ¿Cómo lo pones en línea?

Sube el repositorio y después apunta una app de container a él. En la dashboard, **Web Deployment** → elige el repositorio de GitHub → rama y directorio raíz → **Create app**.

No hay nada que rellenar por el camino. La plataforma encuentra el `Dockerfile` y marca el build como detectado: sin comando de build, sin comando de arranque, sin puerto, porque las tres cosas ya las responde el archivo que escribiste.

![El panel de deployments de Containers mostrando el deploy marcado como Ready en 9 segundos, la app Available y un aviso de que la URL del plan Free es temporal y estará activa durante 60 minutos](/blog/blog-assets/host-a-static-website-in-a-container/02-deployment.jpg)

El deploy volvió marcado como *Ready in 9 seconds*: listo en **9 segundos**. Esa es la cifra de la propia plataforma, desde el push hasta una dirección HTTPS en vivo, y es el número que explica la última sección de este post.

## ¿Funcionó de verdad?

Sí: la dirección sirve el sitio real, no un marcador de posición. Cada archivo volvió con el tamaño exacto en bytes que guarda el repositorio, y el header del servidor indica la versión fijada en el tag.

```text
/            HTTP 200   text/html                2083 B
/style.css   HTTP 200   text/css                 2218 B
/app.js      HTTP 200   application/javascript    204 B

Server: nginx/1.27.5
```

El JavaScript se ejecuta, la hoja de estilos se aplica y la página se ve como se ve en una laptop. El container no está haciendo nada ingenioso aquí; esa es justamente la gracia de usar uno.

## ¿Por qué la mayoría de los ejemplos construyen algo mucho más grande?

Porque instalan el servidor web en lugar de partir de uno. Casi todos los tutoriales que encontrarás, incluida la grabación de arriba, empiezan desde una imagen de Linux de propósito general y usan el gestor de paquetes.

```dockerfile
FROM ubuntu:latest
RUN apt-get update
RUN apt-get -y install nginx
COPY index.html /var/www/html/index.html
EXPOSE 80
CMD nginx -g "daemon off;"
```

Funciona, y la página que sirve es idéntica. Lo que cambia es lo que se construye, se sube y se descarga cada vez que despliegas, y el desglose por capas muestra de dónde sale ese peso.

| Capa, tal como la reporta `docker history` | Tamaño |
| --- | --- |
| Base Ubuntu 26.04 | 135 MB |
| `apt-get update` | **43,1 MB** |
| `apt-get -y install nginx` | 3,62 MB |
| `COPY index.html` | 20,5 kB |

Lo que querías, un servidor web y tu página, son 3,64 MB, dentro de una imagen que `docker images` reporta como 254 MB. El paso `apt-get update`, que existe solo para que la línea *siguiente* pueda ejecutarse, es más de diez veces mayor que el software que descargó.

## ¿Puedes quedarte con la distribución y seguir siendo pequeño?

En gran parte, sí, y conviene saberlo si necesitas una distribución para otra cosa. El peso extra de arriba no es realmente de Ubuntu; es que `apt-get update` escribe su catálogo en una capa, y las capas son inmutables, así que borrarlo después no recupera nada.

Haz la instalación y la limpieza en una sola instrucción y nunca llega a quedar confirmado en una capa.

```dockerfile
FROM ubuntu:26.04
RUN apt-get update \
 && apt-get install -y --no-install-recommends nginx \
 && rm -rf /var/lib/apt/lists/*
COPY site/ /var/www/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```

Eso mide **181 MB**: 73 MB menos, misma distribución, mismo nginx. Además fija la base en lugar de seguir `latest`, omite los paquetes recomendados y escribe `CMD` en forma exec para que nginx reciba las señales directamente.

| | Tamaño de imagen | Build en frío | Versión de nginx |
| --- | --- | --- | --- |
| Distribución, como se suele escribir | 254 MB | 12 s | 1.28.3, la que tenga apt |
| Distribución, con limpieza | 181 MB | 9 s | 1.28.3, la que tenga apt |
| nginx Alpine oficial | **75,9 MB** | **1 s** | 1.27.5, fijada por tag |

![Las tres imágenes dibujadas a escala: 254 MB para la base de distribución tal como se suele escribir, con 43,1 MB marcados como el índice de paquetes de apt; 181 MB para la misma base con limpieza; 75,9 MB para la imagen oficial de nginx Alpine](/blog/blog-assets/host-a-static-website-in-a-container/01-sizes.svg)

De aquí salen los nueve segundos. Un archivo de tres líneas no tiene paso de instalación que ejecutar, así que desplegar es un pull y una copia; un archivo que instala paquetes repite ese trabajo en cada release.

## ¿Qué te da el plan Free?

Lo suficiente para poner algo delante de alguien, y no lo suficiente para dejarlo en marcha. El container recibe 0,25 vCPU, 256 MB de memoria y 100 GB de transferencia, que es de sobra para un sitio estático.

El límite que importa es la dirección: en el plan Free es temporal y caduca **60 minutos** después del deploy. Eso lo convierte en una ventana para compartir más que en un alojamiento: vale para enseñárselo a un cliente, no para un sitio que la gente guarde en favoritos. Un subdominio permanente o tu propio dominio necesitan un plan de pago.

## ¿Qué deberías hacer ahora?

Pon tus propios archivos en `site/`, no cambies nada más y despliega. Al archivo del container le da igual si lleva una página o un sitio de documentación generado, así que las mismas tres líneas cubren casi cualquier cosa estática que construyas.

Quédate con la imagen oficial del servidor que necesites y fija su tag. Recurre a una distribución solo cuando algo lo requiera de verdad (un módulo poco habitual, un paso de build) y, cuando lo hagas, mantén la instalación y su limpieza en una sola instrucción.
