Es momento de preparar tu aplicación para un entorno productivo. Subiremos la web a un servidor para que esté disponible el acceso desde cualquier parte del mundo.
Rust y Docker
Comencemos "dockerizando" la aplicación que hemos creado en Rust. Para esto, luego de instalar Docker en tu ordenador, generaremos algunos archivos necesarios en la raíz del proyecto.
Paso 1. Dockerización
Archivo .dockerignore para que Docker ignore algunos archivos o directorios.
target/
Archivo Dockerfile para construir la imagen de Docker.
# STAGE 1: Creamos contenedor para compilar la aplicaciónFROM ubuntu:20.04# Variable para evitar bloqueos en la terminal al construir el contenedorENV DEBIAN_FRONTEND=noninteractive
## Dependencias necesarios del Sistema OperativoRUN apt-get update && apt-get install curl pkg-config libssl-dev build-essential libpq-dev -y
## Instalamos RustRUN curl https://sh.rustup.rs -sSf | sh -s ---y
ENV PATH="/root/.cargo/bin:${PATH}"
## Preparamos directorio principal del proyectoWORKDIR /app
COPY ./ /app
## Compilamos la aplicaciónRUN cargo clean
RUN cargo build --release
# STAGE 2: Como el primer contenedor es muy pesado y no lo necesitamos, creamos otro solo para exponer la aplicaciónFROM ubuntu:20.04# Variable para evitar bloqueos en la terminal al construir el contenedorENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install curl pkg-config libssl-dev build-essential libpq-dev -y
WORKDIR /app
## Copiamos desde el otro contenedor, los archivos de la aplicaciónCOPY --from=0 /app/target/release/rust-backend /app
COPY /templates/ /app/templates
COPY /statics/ /app/statics
## Corremos la aplicaciónCMD ./rust-backend
Archivo docker-compose.yml para configurar y levantar el contenedor con más facilidad.
version:'3'services:rust-backend:# Nombre de la imagenbuild: . # Seleccionamos el Dockerfile en la raíz del proyectoimage: rust-backend
env_file:# Leemos variables de entorno- .env
ports:-"8080:8080"# El primer puerto es para ingresar desde el navegador, el segundo el puerto configurado en el .env
NOTA:Docker Compose es una herramienta que viene junto a Docker. Nos servirá para correr múltiples contenedores juntos y de forma más fácil.
Paso 2. Preparar servidor HTTP
Antes de probar el contenedor, prepara tu aplicación con una nueva variable de entorno para configurar dinámicamente el puerto en el que escuchará el servidor HTTP.
// main.rs// Traemos la variable de entorno y la convertimos a enterolet port =env::var("PORT").expect("La variable de entorno PORT no existe.");let port:u16= port.parse().unwrap();// Configuramos el puerto dinamicamenteHttpServer::new(move||{/* ... */}).bind(("0.0.0.0", port)).unwrap().run().await
TIP: Para evitar otros inconvenientes, configura el host de tu aplicación como 0.0.0.0 para que funcione tanto en local, como con Docker y posteriormente en Heroku.
Paso 3. Lanzar la aplicación
Teniendo Docker listo, vamos a probar el contenedor de forma local con el comando sudo docker-compose up -d. Este proceso tardará varios minutos la primera vez que lo ejecutes.
Una vez finalizado, si todo ha ido bien, podrás ingresar a tu aplicación corriendo en Docker desde localhost:8080 (o con el puerto que hayas definido en el docker-compose.yml).
¡Felicidades! Tu aplicación está lista para ser desplegada en Heroku.
Contribución creada por Kevin Fiorentinocon aportes deSebastián Franco Gomez.
Despliegue de Aplicaciones Rust en Heroku con Docker
Si en algún momento de la creación del Docker te aparece este menú
Y no importa que input le des, simplemente no sigue y tienes que reiniciar el proceso, puede que alguna de estas opciones te sirva.
Antes de todo, este problema se da porque la interfaz de WSL choca con el "menú" de tzdata, así que tenemos 2 opciones: Configurar el timezone desde el archivo Dockerfile o directamente ignorar los menús interactivos. Personalmente apliqué la segunda por facilidad pero entiendo que esto puede generar problemas a largo plazo.
La primer opción es añadir la configuración del timezone antes de hacer los apt-get, dado que en dicho momento es que se genera la interfaz que nos bloquea.
Después de definir la versión de Ubuntu (en ambos casos, recuerda que ese proceso se hace 2 veces) coloca inmediatamente las instrucciones
ENVTZ=America/Bogota #O la timezone que quieras
RUN ln -snf /usr/share/zoneinfo/$TZ/etc/localtime && echo $TZ>/etc/timezone
Repito, debe ponerse las 2 veces debajo de la definición de la versión de Ubuntu, sino te vas a chocar con el mismo menú muchos minutos despues de haber empezado la build.
La segunda opción es desactivar los menús interactivos, esto se hace con la instrucción
DEBIAN_FRONTEND=noninteractive
De esta manera se ignoran todos los menús interactivos e internamente se resuelven las elecciones.
Dejo de respuesta todos los comandos.
FROMubuntu:20.04ENVDEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install curl pkg-config libssl-dev build-essential libpq-dev -y
RUN curl https://sh.rustup.rs-sSf | sh -s ---y
ENVPATH="/root/.cargo/bin:${PATH}"WORKDIR/app
COPY.//app
RUN cargo build --release
FROMubuntu:20.04ENVDEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install curl pkg-config libssl-dev build-essential libpq-dev -y
WORKDIR/app
COPY--from=0/app/.env/app
COPY--from=0/app/target/release/backend_project /app
COPY/templates//app/templates
CMD./backend_project
Ohhh muchas gracias <3 no me ha pasado, pero definitivamente os puede pasar
"No deberia tardar nada" Ese debe ser el equivalente de los doctores de "No te dolera" XD
La segunda vez ya tenia las imagenes, pero la compilación tenia que hacerla toda de nuevo.
heroku ya no es gratis, recomiendo rail, que es gratis y te da una base de datos
Falto aclara que NO se necesita instalar Docker en WSL. Solo en Windows y automáticamente lo puede usar desde la consola WSL Ubuntu.
Para el build, ¿por qué no usas la imagen de rust?
¡Hola! :D
¿Cuál es el problema que tienes?, ¿en qué te puedo ayudar?
Nunca pares de aprender 💚
Pues que no veo necesario usar ubuntu, se puede usar para compilar la imagen de rust y para ejecutar algúna distro slim o en una de esas un alpine.
Por otro lado, ¿por qué vuelve a instalar dependencias de desarrollo o incluso curl para la imagen final?
En el caso de Windows 10 Pro, versión 22H2 es posible que necesites asegurarte de tener la versión más reciente de WSL (WSL 2) para el mejor rendimiento y compatibilidad con Docker. Aquí están los pasos para actualizar a WSL 2:
Habilitar el subsistema Windows para Linux (WSL) y la plataforma de máquina virtual
Abre una ventana de PowerShell como administrador y ejecuta los siguientes comandos:
bash
Actualizar WSL a la versión 2
En la misma ventana de PowerShell, ejecuta el siguiente comando:
wsl --set-default-version 2
Instalar una distribución de Linux
Ve a la Microsoft Store, busca la distribución de Linux que prefieres (por ejemplo, Ubuntu) y haz clic en "Instalar".
Instalar Docker Desktop
• Descarga e instala Docker Desktop desde el sitio oficial de Docker.
• Una vez instalado, abre Docker Desktop y ve a Settings > General.
• Asegúrate de que la opción "Enable WSL 2 Features" está seleccionada.
• Luego ve a la sección Resources > WSL Integration en Docker Desktop Settings y selecciona la distribución de Linux que deseas usar con Docker.
Comprobar la instalación
Puedes verificar que Docker esté funcionando correctamente ejecutando el siguiente comando en tu terminal de Linux:
sudo docker run hello-world
Este comando descargará y ejecutará la imagen de Docker hello-world. Si todo está configurado correctamente, deberías ver un mensaje que indica que tu instalación de Docker funciona correctamente.
Ten en cuenta que el rendimiento y la compatibilidad pueden variar en función de la versión exacta de Windows y del hardware de tu sistema.
![](
Recomiendo quitar el Cargo.lock del .dockerignore. Este archivo NO debe ser ignorado, ya que puede provocar que se instalen otras versiones de las dependencias en el contenedor y que algo no funcione.
Los archivos *.lock, en cualquier gestor de dependencias, no debe ignorarse ni por Git ni por Docker.
Si usas Ubuntu en WSL y no sabes cómo instalar Docker, seguir los pasos del siguiente enlace: