Usar Docker en reComputer
Introducción

Este wiki explica cómo usar docker en la caja reComputer. Docker es una plataforma de código abierto utilizada para automatizar el despliegue, el escalado y la gestión de aplicaciones dentro de contenedores ligeros y portátiles. Los contenedores permiten a los desarrolladores empaquetar aplicaciones y sus dependencias en un entorno consistente, asegurando que se ejecuten sin problemas en diferentes entornos de computación.
Preparar el hardware
reComputer R1125 | reComputer AI R2130 | reComputer AI Industrial R2145 |
---|---|---|
![]() | ![]() | ![]() |
Preparar software
actualizar el sistema
sudo date -s "$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z"
sudo apt update
sudo apt full-upgrade
Instalar docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
Añadir el usuario actual al grupo docker
sudo usermod -aG docker $USER
reboot
Comprobar la versión de docker
docker --version
El resultado es el siguiente:

Usar docker
Crear tu proyecto
Aquí usamos my_app
como ejemplo para demostrar el uso de docker
.
mkdir my_app
cd my_app
Crear la carpeta src
y crear main.py
mkdir src && cd src
nano main.py
main.py
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import os
app = FastAPI()
# Create directories if they don't exist
os.makedirs("static", exist_ok=True)
os.makedirs("templates", exist_ok=True)
# Mount static files directory
app.mount("/static", StaticFiles(directory="static"), name="static")
# Set up Jinja2 templates
templates = Jinja2Templates(directory="templates")
@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
Crear carpeta static
cd .. && mkdir static
cd static
mkdir css && mkdir js
Crear el archivo css
:
cd css
nano style.css
style.css
body {
font-family: 'Roboto', sans-serif;
margin: 0;
padding: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: #333;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
header {
text-align: center;
padding: 40px 0;
color: white;
}
header h1 {
font-size: 2.5rem;
margin-bottom: 10px;
}
header p {
font-size: 1.2rem;
font-weight: 300;
}
main {
display: flex;
flex-direction: column;
gap: 20px;
}
.card {
background: white;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
padding: 25px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 6px 25px rgba(0, 0, 0, 0.15);
}
.card h2 {
margin-top: 0;
color: #667eea;
display: flex;
align-items: center;
gap: 10px;
}
.card ul {
padding-left: 20px;
}
.card li {
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 10px;
}
.endpoint {
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
padding: 15px;
border-radius: 5px;
margin-top: 10px;
}
.endpoint code {
background: #e9ecef;
padding: 5px 10px;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
.button {
background: #667eea;
color: white;
padding: 10px 20px;
border-radius: 5px;
text-decoration: none;
font-weight: bold;
transition: background 0.3s ease;
}
.button:hover {
background: #5a6fd8;
}
footer {
text-align: center;
padding: 30px 0;
color: white;
font-weight: 300;
}
footer p {
margin: 0;
}
footer i {
color: #ff6b6b;
}
Luego crear el archivo js
:
cd .. && mkdir js
cd js
nano main.js
main.js
// Simple JavaScript to add interactivity to the UI
document.addEventListener('DOMContentLoaded', function() {
// Add a click event listener to the "Try it" button
const tryButton = document.querySelector('.button');
if (tryButton) {
tryButton.addEventListener('click', function(e) {
// Add a simple animation effect
this.style.transform = 'scale(0.95)';
setTimeout(() => {
this.style.transform = '';
}, 100);
});
}
// Add a hover effect to the cards
const cards = document.querySelectorAll('.card');
cards.forEach(card => {
card.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-5px)';
});
card.addEventListener('mouseleave', function() {
this.style.transform = '';
});
});
});
Crear archivo html
cd ../../
mkdir templates
nano index.html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FastAPI App</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: #333;
}
.container {
background: white;
border-radius: 10px;
padding: 30px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
text-align: center;
}
h1 {
color: #667eea;
}
.card {
background: #f8f9fa;
border-radius: 8px;
padding: 20px;
margin: 20px 0;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
transition: transform 0.3s ease;
}
.endpoint {
display: flex;
justify-content: space-between;
align-items: center;
background: #e9ecef;
padding: 15px;
border-radius: 5px;
margin-top: 10px;
}
code {
background: #dee2e6;
padding: 5px 10px;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
.button {
background: #667eea;
color: white;
padding: 10px 20px;
border-radius: 5px;
text-decoration: none;
font-weight: bold;
transition: all 0.2s ease;
}
.button:hover {
background: #5a6fd8;
transform: scale(1.05);
}
</style>
</head>
<body>
<div class="container">
<h1>FastAPI Application</h1>
<p>A modern, high-performance web application</p>
<div class="card">
<h2>About This App</h2>
<p>This is a simple yet elegant web application built with FastAPI. It demonstrates how to create a beautiful UI with minimal code.</p>
</div>
<div class="card">
<h2>Features</h2>
<ul>
<li>Fast and lightweight</li>
<li>Responsive design</li>
<li>Modern UI components</li>
<li>RESTful API endpoints</li>
</ul>
</div>
<div class="card">
<h2>Try the API</h2>
<p>You can access the API endpoints directly:</p>
<div class="endpoint">
<code>GET /items/{item_id}</code>
<a href="/items/42" class="button">Try it</a>
</div>
</div>
</div>
<script src="/static/js/main.js"></script>
</body>
</html>
Crear Dockerfile
cd ..
nano Dockerfile
Dockerfile
# Use the official Python image as the base image
FROM python:3.9-slim
# Set the working directory in the container
WORKDIR /app
# Copy the requirements file into the container
COPY requirements.txt .
# Install the required packages
RUN pip install --no-cache-dir -r requirements.txt
# Create directories for templates and static files
RUN mkdir -p templates static
# Copy the source code into the container
COPY src/ ./src
# Copy the templates and static files into the container
COPY templates/ ./templates
COPY static/ ./static
# Expose the port that the application will run on
EXPOSE 8000
# Define the command to run the application
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
Crear requirements.txt
nano requirements.txt
requirements.txt
fastapi
uvicorn[standard]
jinja2
El directorio del proyecto es el siguiente
tree

Compilar y publicar la imagen
Compilar imagen
Nota: Si no tienes una cuenta para dockerhub, por favor registra una.
xxx
es el nombre de usuario de tu Docker Hub.
docker build -t xxx/fastapi_app_ui:latest .

Probar la imagen
docker image ls -a

docker run -d -p 8000:8000 jiahaoxyz/fastapi_app_ui
El resultado se muestra a continuación:

Publicar la imagen
y crea tu propio token.
Nota:
xxx
es tu propio nombre de usuario de dockerhub
docker login -u xxx

Nota:
xxx
es tu propio nombre de usuario de dockerhub
docker push xxx/fastapi_app_ui:latest

Resultado
Puedes ver que la imagen empaquetada usando Docker se ha subido a Docker Hub, y está disponible para que cualquiera la use.

Puedes usar mis imágenes como se muestra a continuación, y aquí está la página de GitHub del proyecto:
docker pull jiahaoxyz/fastapi_app_ui
Soporte Técnico y Discusión de Producto
¡Gracias por elegir nuestros productos! Estamos aquí para proporcionarte diferentes formas de soporte para garantizar que tu experiencia con nuestros productos sea lo más fluida posible. Ofrecemos varios canales de comunicación para adaptarnos a diferentes preferencias y necesidades.