{"id":3347,"date":"2026-02-08T00:26:45","date_gmt":"2026-02-07T22:26:45","guid":{"rendered":"https:\/\/www.sinetiqueta.com\/?p=3347"},"modified":"2026-02-08T03:06:47","modified_gmt":"2026-02-08T01:06:47","slug":"%f0%9f%9f%a2-mini-cpanel-mejora-profesional-de-ux-diseno-y-funcionalidades","status":"publish","type":"post","link":"https:\/\/www.sinetiqueta.com\/?p=3347","title":{"rendered":"&#x1f7e2; Mini cPanel \u2013 Mejora Profesional de UX, Dise\u00f1o y Funcionalidades"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">Continuaci\u00f3n del Mini cPanel para Raspberry Pi 3B<\/h3>\n\n\n\n<p>En la entrada anterior dejamos operativo un <strong>mini cPanel funcional<\/strong>, con gesti\u00f3n de archivos, backups y control b\u00e1sico de PHP-FPM.<br>En esta segunda parte vamos a <strong>dar el salto a un entorno m\u00e1s profesional<\/strong>, mejorando:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Experiencia de usuario (UX)<\/li>\n\n\n\n<li>Dise\u00f1o visual<\/li>\n\n\n\n<li>Organizaci\u00f3n del panel<\/li>\n\n\n\n<li>Escalabilidad futura<\/li>\n\n\n\n<li>Preparaci\u00f3n para nuevas herramientas<\/li>\n<\/ul>\n\n\n\n<p>Todo ello <strong>sin romper lo ya configurado<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">&#x1f3af; Objetivo de esta mejora<\/h2>\n\n\n\n<p>Transformar el panel b\u00e1sico en un <strong>dashboard limpio, moderno y usable<\/strong>, similar a un cPanel ligero o Portainer, manteniendo:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ligereza (Raspberry Pi 3B)<\/li>\n\n\n\n<li>Seguridad (solo LAN, sin root en PHP)<\/li>\n\n\n\n<li>Simplicidad de mantenimiento<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">&#x1f9f1; Nueva estructura del panel (frontend)<\/h2>\n\n\n\n<p>A partir de ahora, el frontend del panel quedar\u00e1 as\u00ed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/var\/www\/html\/<br>\n\u251c\u2500\u2500 admin.php<br>\n\u251c\u2500\u2500 assets\/<br>\n\u2502   \u251c\u2500\u2500 css\/<br>\n\u2502   \u2502   \u2514\u2500\u2500 panel.css<br>\n\u2502   \u2514\u2500\u2500 img\/<br>\n\u2502       \u2514\u2500\u2500 logo.png<br>\n<\/code><\/pre>\n\n\n\n<p>&#x1f4cc; <strong>Recordatorio importante<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>\/var\/www\/html<\/code> \u2192 solo frontend<\/li>\n\n\n\n<li><code>\/var\/www\/apps<\/code> \u2192 apps, datos y scripts<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1&#xfe0f;&#x20e3; Crear estructura de directorios del panel<\/h2>\n\n\n\n<p>Este paso es <strong>obligatorio<\/strong> y evita errores como <em>\u201cNo such file or directory\u201d<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir -p \/var\/www\/html\/assets\/css\n<br>\nsudo mkdir -p \/var\/www\/html\/assets\/img<\/code><\/pre>\n\n\n\n<p>Asignamos permisos correctos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo chown -R www-data:www-data \/var\/www\/html\/assets<br>\nsudo chmod -R 755 \/var\/www\/html\/assets<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2&#xfe0f;&#x20e3; A\u00f1adir el logo del panel (adaptativo)<\/h2>\n\n\n\n<p>Para hacerlo c\u00f3modo, tendremos que dar permisos a FileBrowser para que acceda a la carpeta, he estado tocando varias cosas&#8230; pero al final ser\u00eda<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl stop filebrowser #Paramos el servicio<br>\nsudo nano \/etc\/systemd\/system\/filebrowser.service<br>\n<br>\n#Editamos y el \"Service queda tal que as\u00ed:<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Service]<br>\nType=simple<br>\nUser=www-data<br>\nGroup=www-data<br>\nExecStart=\/usr\/local\/bin\/filebrowser \\<br>\n  -d \/etc\/filebrowser.db \\<br>\n  <strong>-r \/var\/www\/<\/strong> \\<br>\n  -a 0.0.0.0 \\<br>\n  -p 8080<br>\nRestart=on-failure<br>\nRestartSec=5<br>\nNoNewPrivileges=true<br>\nPrivateTmp=true<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Creamos rutas y damos permisos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir -p \/var\/www\/html\/assets\/img<br>\nsudo chown -R www-data:www-data \/var\/www\/html\/assets<br>\nsudo chmod -R 755 \/var\/www\/html\/asset<\/code><\/pre>\n\n\n\n<p>Recargamos&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl daemon-reload<br>\nsudo systemctl start filebrowser<br>\nsudo systemctl status filebrowser<\/code><\/pre>\n\n\n\n<p>Copiamos el logo (por ejemplo de 460\u00d7460px) a:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/var\/www\/html\/assets\/img\/logo.png<\/code><\/pre>\n\n\n\n<p>&#x1f539; El tama\u00f1o <strong>se adapta autom\u00e1ticamente<\/strong> por CSS<br>&#x1f539; No ser\u00e1 intrusivo<br>&#x1f539; Mantiene proporci\u00f3n<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3&#xfe0f;&#x20e3; Estilo profesional del Mini cPanel (UX + tipograf\u00eda)<\/h2>\n\n\n\n<p>Creamos el archivo CSS:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nano \/var\/www\/html\/assets\/css\/panel.css<\/code><\/pre>\n\n\n\n<p>Contenido:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>body {<br>\n    background: #0f172a;<br>\n    color: #e5e7eb;<br>\n    font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;<br>\n    margin: 0;<br>\n}<br>\n<br>\n.logo {<br>\n    max-width: 120px;   \/* El logo 460x460 se adapta aqu\u00ed *\/<br>\n    height: auto;<br>\n    margin-bottom: 20px;<br>\n    opacity: 0.9;<br>\n}<br>\n<br>\n.login, .panel {<br>\n    max-width: 420px;<br>\n    margin: 120px auto;<br>\n    text-align: center;<br>\n}<br>\n<br>\ninput, button {<br>\n    width: 100%;<br>\n    padding: 12px;<br>\n    margin-top: 10px;<br>\n    border-radius: 8px;<br>\n    border: none;<br>\n    font-size: 14px;<br>\n}<br>\n<br>\nbutton {<br>\n    background: #3b82f6;<br>\n    color: white;<br>\n    cursor: pointer;<br>\n}<br>\n<br>\nbutton:hover {<br>\n    background: #2563eb;<br>\n}<br>\n<br>\n.panel a {<br>\n    display: block;<br>\n    margin: 10px 0;<br>\n    padding: 12px;<br>\n    background: #1e293b;<br>\n    color: #e5e7eb;<br>\n    text-decoration: none;<br>\n    border-radius: 8px;<br>\n}<br>\n<br>\n.panel a:hover {<br>\n    background: #334155;<br>\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4&#xfe0f;&#x20e3; Actualizar admin.php con dise\u00f1o moderno<\/h2>\n\n\n\n<p>Editamos el archivo existente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nano \/var\/www\/html\/admin.php<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Versi\u00f3n mejorada (login + panel)<\/h3>\n\n\n\n<p>&lt;?php<br>session_start();<br>$secret_pass = \u00abCAMBIA_ESTA_PASSWORD\u00bb;<br><br>if (isset($_POST[&#8216;password&#8217;])) {<br>    if (hash_equals($secret_pass, $_POST[&#8216;password&#8217;])) {<br>        $_SESSION[&#8216;auth&#8217;] = true;&lt;<br>    } else {<br>        $error = \u00abContrase\u00f1a incorrecta\u00bb;<br>    }<br>}<br><br>if (!isset($_SESSION[&#8216;auth&#8217;])) {<br>?><br>&lt;!DOCTYPE html><br>&lt;html><br>&lt;head><br>&lt;title>Mini cPanel&lt;\/title><br>&lt;link rel=\u00bbstylesheet\u00bb href=\u00bbassets\/css\/panel.css\u00bb><br>&lt;\/head><br>&lt;body><br>&lt;div class=\u00bblogin\u00bb><br>&lt;img src=\u00bbassets\/img\/logo.png\u00bb class=\u00bblogo\u00bb><br>&lt;form method=\u00bbpost\u00bb><br>&lt;input type=\u00bbpassword\u00bb name=\u00bbpassword\u00bb placeholder=\u00bbContrase\u00f1a\u00bb><br>&lt;button>Entrar&lt;\/button><br>&lt;?php if(isset($error)) echo \u00ab&lt;p>$error&lt;\/p>\u00bb; ?><br>&lt;\/form><br>&lt;\/div><br>&lt;\/body><br>&lt;\/html><br>&lt;?php exit; }<br><br>function run($script){<br>    echo \u00ab&lt;pre>\u00bb;<br>    echo shell_exec(\u00absudo \/var\/www\/apps\/admin-scripts\/$script 2>&amp;1\u00bb);<br>    echo \u00ab&lt;\/pre>\u00bb;<br>}<br>?><br>&lt;!DOCTYPE html><\/p>\n\n\n\n<p>&lt;html><br>&lt;head><br>&lt;title>Mini cPanel&lt;\/title><br>&lt;link rel=\u00bbstylesheet\u00bb href=\u00bbassets\/css\/panel.css\u00bb><br>&lt;\/head><br>&lt;body><br>&lt;div class=\u00bbpanel\u00bb><br>&lt;img src=\u00bbassets\/img\/logo.png\u00bb class=\u00bblogo\u00bb><br>&lt;h2>Panel de Control&lt;\/h2><br><br>&lt;a href=\u00bb?do=php\u00bb>&#x1f501; Reiniciar PHP-FPM&lt;\/a><br>&lt;a href=\u00bb?do=perms\u00bb>&#x1f510; Ajustar permisos&lt;\/a><br>&lt;a href=\u00bb?do=backup\u00bb>&#x1f4e6; Backup de apps&lt;\/a><br><br>&lt;?php&lt;<br>if(isset($_GET[&#8216;do&#8217;])){<br>    if($_GET[&#8216;do&#8217;]==&#8217;php&#8217;) run(&#8216;reiniciar-php.sh&#8217;);<br>    if($_GET[&#8216;do&#8217;]==&#8217;perms&#8217;) run(&#8216;ajustar-permisos.sh&#8217;);<br>    if($_GET[&#8216;do&#8217;]==&#8217;backup&#8217;) run(&#8216;backup.sh&#8217;);<br>}<br>?><br>&lt;\/div><br>&lt;\/body><br>&lt;\/html><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5&#xfe0f;&#x20e3; Resultado visual<\/h2>\n\n\n\n<p>Ahora el mini cPanel tiene:<\/p>\n\n\n\n<p>&#x2705; Tipograf\u00eda moderna<br>&#x2705; Botones claros<br>&#x2705; Logo adaptativo<br>&#x2705; Mejor jerarqu\u00eda visual<br>&#x2705; UX tipo dashboard<br>&#x2705; Preparado para crecer<\/p>\n\n\n\n<p>Acceso:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:&#47;&#47;IP_DE_LA_RASPI\/admin.php<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">&#x1f510; Buenas pr\u00e1cticas mantenidas<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>&#x274c; No root en PHP<\/li>\n\n\n\n<li>&#x274c; No MariaDB expuesta<\/li>\n\n\n\n<li>&#x2705; Scripts controlados con sudo<\/li>\n\n\n\n<li>&#x2705; Acceso solo LAN<\/li>\n\n\n\n<li>&#x2705; Separaci\u00f3n frontend \/ backend<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-large-font-size\"><strong>&#x1f601;Resultado<\/strong><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"453\" height=\"416\" src=\"https:\/\/www.sinetiqueta.com\/wp-content\/uploads\/2026\/02\/image-4.png\" alt=\"\" class=\"wp-image-3350\" srcset=\"https:\/\/www.sinetiqueta.com\/wp-content\/uploads\/2026\/02\/image-4.png 453w, https:\/\/www.sinetiqueta.com\/wp-content\/uploads\/2026\/02\/image-4-300x275.png 300w\" sizes=\"auto, (max-width: 453px) 100vw, 453px\" \/><\/figure>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Continuaci\u00f3n del Mini cPanel para Raspberry Pi 3B En la entrada anterior dejamos operativo un mini cPanel funcional, con gesti\u00f3n de archivos, backups y control b\u00e1sico de PHP-FPM.En esta segunda parte vamos a dar el salto a un entorno m\u00e1s&#8230; <a href=\"https:\/\/www.sinetiqueta.com\/?p=3347\" class=\"readmore\">Leer m\u00e1s<span class=\"screen-reader-text\">&#x1f7e2; Mini cPanel \u2013 Mejora Profesional de UX, Dise\u00f1o y Funcionalidades<\/span><span class=\"fa fa-angle-double-right\" aria-hidden=\"true\"><\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3349,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[274,236,498],"tags":[],"class_list":["post-3347","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cpanel","category-raspberry-pi","category-servidor","content-layout-excerpt-thumb"],"jetpack_featured_media_url":"https:\/\/www.sinetiqueta.com\/wp-content\/uploads\/2026\/02\/logo.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=\/wp\/v2\/posts\/3347","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3347"}],"version-history":[{"count":17,"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=\/wp\/v2\/posts\/3347\/revisions"}],"predecessor-version":[{"id":3371,"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=\/wp\/v2\/posts\/3347\/revisions\/3371"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=\/wp\/v2\/media\/3349"}],"wp:attachment":[{"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sinetiqueta.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}