{"id":122,"date":"2026-01-22T09:14:28","date_gmt":"2026-01-22T13:14:28","guid":{"rendered":"https:\/\/juredev.com\/blog\/?p=122"},"modified":"2026-02-16T11:48:58","modified_gmt":"2026-02-16T15:48:58","slug":"como-crear-tu-propio-servidor-git-en-un-vps-usando-solo-ssh","status":"publish","type":"post","link":"https:\/\/juredev.com\/blog\/2026\/01\/como-crear-tu-propio-servidor-git-en-un-vps-usando-solo-ssh\/","title":{"rendered":"C\u00f3mo crear tu propio servidor Git en un VPS usando solo SSH (Gu\u00eda pr\u00e1ctica 2026)"},"content":{"rendered":"\n<p>\u00bfEst\u00e1s buscando una alternativa ligera a <a href=\"https:\/\/github.com\/\" data-type=\"link\" data-id=\"https:\/\/github.com\/\">GitHub<\/a> o <a href=\"https:\/\/about.gitlab.com\/\" data-type=\"link\" data-id=\"https:\/\/about.gitlab.com\/\">GitLab<\/a> para proyectos personales, pruebas internas o simplemente para tener el control total sin depender de terceros?<\/p>\n\n\n\n<p>Montar un servidor <strong><a href=\"https:\/\/juredev.com\/blog\/tag\/git\/\" data-type=\"link\" data-id=\"https:\/\/juredev.com\/blog\/tag\/git\/\">Git<\/a><\/strong> puro por <strong>SSH<\/strong> sigue siendo, en 2026, una de las soluciones m\u00e1s simples, seguras y eficientes que existen. Consigue control absoluto, cero servicios web expuestos innecesariamente y un consumo rid\u00edculamente bajo de recursos.<\/p>\n\n\n\n<p>En esta gu\u00eda vamos a montar un servidor <strong><a href=\"https:\/\/git-scm.com\/\" data-type=\"link\" data-id=\"https:\/\/git-scm.com\/\">Git <\/a><\/strong>minimalista usando solo las herramientas nativas del sistema operativo. Nada de Docker, nada de bases de datos, nada de interfaces web. El resultado: un servidor que normalmente consume entre 5 y 50 MB de RAM y que, una vez configurado, pr\u00e1cticamente no requiere mantenimiento.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfPor qu\u00e9 SSH puro en vez de Gitea, Forgejo, GitLab\u2026?<\/h2>\n\n\n\n<p>Este enfoque no pretende competir con las plataformas completas. Simplemente brilla cuando lo que m\u00e1s valoras es:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Eficiencia brutal:<\/strong> 5\u201350 MB de RAM vs. los cientos de MB o GB que piden las soluciones con interfaz web.<\/li>\n\n\n\n<li><strong>Seguridad minimalista:<\/strong> Solo expones el puerto SSH (idealmente cambiado del 22). No hay que estar parcheando vulnerabilidades de nginx, unicorn, redis, etc.<\/li>\n\n\n\n<li><strong>Mantenimiento casi nulo:<\/strong> Git es extremadamente estable. Configurado una vez, solo te preocupas por hacer backups.<\/li>\n<\/ul>\n\n\n\n<p><strong>Limitaciones claras<\/strong> (para que no haya sorpresas):<\/p>\n\n\n\n<p>No tendr\u00e1s pull requests, issues, wikis ni interfaz bonita. Pero si el proyecto crece y necesitas esas cosas, siempre puedes instalar cgit, Gitea o migrar a Forgejo m\u00e1s adelante sin perder ni un solo <strong>commit<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerrequisitos<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un <strong>VPS<\/strong> con <strong>Linux<\/strong> (funciona perfectamente en Debian 12\/13 y Ubuntu 22.04\/24.04 LTS).<\/li>\n\n\n\n<li>Acceso con privilegios de sudo.<\/li>\n\n\n\n<li><strong>Git<\/strong> instalado tanto en tu m\u00e1quina local como en el servidor.<\/li>\n\n\n\n<li>Una clave <strong>SSH<\/strong> (recomiendo ed25519 por seguridad y rendimiento).<\/li>\n<\/ul>\n\n\n\n<p>Instalar Git en el servidor (si no est\u00e1 ya):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update &amp;&amp; sudo apt install git -y<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 1: Crear un usuario dedicado (seguridad ante todo)<\/h2>\n\n\n\n<p>Nunca uses root ni tu usuario principal para alojar repositorios. Creamos un usuario git con shell restringido que solo permite ejecutar comandos de <strong>Git<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo adduser \\\n  --system \\\n  --shell \/usr\/bin\/git-shell \\\n  --group \\\n  --home \/home\/git \\\n  --disabled-password \\\n  git<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 2: Estructura de carpetas y permisos<\/h2>\n\n\n\n<p>Desde el principio organizamos los repos por tipo para no tener caos cuando tengas 20 o 30 proyectos.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir -p \/home\/git\/repositories\/personal\nsudo mkdir -p \/home\/git\/repositories\/equipo\nsudo chown -R git:git \/home\/git\nsudo chmod 700 \/home\/git<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 3: Configurar el acceso por clave SSH (sin contrase\u00f1as)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir -p \/home\/git\/.ssh\nsudo touch \/home\/git\/.ssh\/authorized_keys\nsudo chmod 700 \/home\/git\/.ssh\nsudo chmod 600 \/home\/git\/.ssh\/authorized_keys\nsudo chown -R git:git \/home\/git\/.ssh<\/code><\/pre>\n\n\n\n<p><strong>Tip de seguridad importante:<\/strong><\/p>\n\n\n\n<p>Cuando a\u00f1adas claves al archivo authorized_keys, utiliza el prefijo de restricciones para que esa clave solo sirva para <strong>Git<\/strong> y nada m\u00e1s:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3...tu_clave_p\u00fablica... aqui@tu-laptop<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 4: Crear un repositorio bare en el servidor<\/h2>\n\n\n\n<p>Como el usuario git tiene el shell restringido, creamos los repositorios desde un usuario con sudo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo -u git git init --bare \/home\/git\/repositories\/personal\/mi-proyecto.git<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 5: Conectar tu proyecto local al servidor<\/h2>\n\n\n\n<p>Si ya tienes un proyecto local, solo a\u00f1ades el remote.<\/p>\n\n\n\n<p><strong>Importante:<\/strong> Si cambiaste el puerto <strong>SSH<\/strong> (muy recomendado por seguridad), usa la sintaxis completa con el puerto.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Entra en tu carpeta de proyecto local\ncd mi-proyecto\n\n# Si es un proyecto nuevo\ngit init\ngit add .\ngit commit -m \"Primer commit\"\n\n# A\u00f1adir el remote (ejemplo con puerto 2222)\ngit remote add origin ssh:\/\/git@TU_IP_O_DOMINIO:2222\/home\/git\/repositories\/personal\/mi-proyecto.git\n\n# Renombrar rama principal (si es necesario) y subir\ngit branch -M main\ngit push -u origin main<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 6: Script para crear repositorios r\u00e1pidamente (automatizaci\u00f3n b\u00e1sica)<\/h2>\n\n\n\n<p>Para no escribir el mismo comando cada vez, puedes tener este peque\u00f1o script en tu m\u00e1quina local (gu\u00e1rdalo como <strong>git-create.sh<\/strong> y dale permisos de ejecuci\u00f3n):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env bash\n\nREPO_NAME=\"$1\"\n# Cambia estos valores seg\u00fan tu setup\nSERVER=\"tu-vps.com\"\nPORT=\"2222\"\nADMIN_USER=\"tu_usuario_con_sudo\"\n\nif &#91; -z \"$REPO_NAME\" ]; then\n    echo \"Uso: .\/git-create.sh nombre-del-repo\"\n    exit 1\nfi\n\nssh -p \"$PORT\" \"$ADMIN_USER@$SERVER\" \"sudo -u git git init --bare \/home\/git\/repositories\/personal\/$REPO_NAME.git\"\n\necho \"\u00a1Repositorio creado!\"\necho \"Con\u00e9ctalo con:\"\necho \"git remote add origin ssh:\/\/git@$SERVER:$PORT\/home\/git\/repositories\/personal\/$REPO_NAME.git\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 7: Backups sencillos (y efectivos)<\/h2>\n\n\n\n<p>Como los repos bare son solo carpetas, hacer backups es trivial con <strong>rsync<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rsync -avz -e 'ssh -p 2222' git@TU_IP:\/home\/git\/repositories\/ \/ruta\/local\/de\/backup\/<\/code><\/pre>\n\n\n\n<p>O hacia otro servidor remoto:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rsync -avz -e 'ssh -p 2222' \/home\/git\/repositories\/ backup@otro-servidor:\/backups\/git\/<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Hasta aqu\u00ed, ya tienes tu propio servidor Git en un VPS usando solo SSH<\/h2>\n\n\n\n<p>Configurar tu propio servidor <strong>Git<\/strong> por <strong>SSH<\/strong> no solo te da privacidad y control total sobre tus proyectos, sino que tambi\u00e9n te ayuda a entender mucho mejor c\u00f3mo funciona <strong>Git<\/strong> por debajo. Es una soluci\u00f3n elegante, ligera y muy profesional que encaja perfectamente en cualquier setup moderno, desde un hobby hasta entornos de pruebas o internos.<\/p>\n\n\n\n<p>En un pr\u00f3ximo art\u00edculo te cuento c\u00f3mo usar <strong>Git Hooks <\/strong>para hacer despliegue autom\u00e1tico: cada <strong>git push<\/strong> actualiza tu sitio web o aplicaci\u00f3n en producci\u00f3n sin intervenci\u00f3n manual.<\/p>\n\n\n\n<p>\u00bfQu\u00e9 te parece esta configuraci\u00f3n? \u00bfLa has probado en Debian 13 o tienes alg\u00fan truco extra para gestionar m\u00faltiples usuarios\/claves? Si tienes dudas (sobre puertos no est\u00e1ndar, hardening de SSH, etc.), puedes dejar tus comentarios. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00bfEst\u00e1s buscando una alternativa ligera a GitHub o GitLab para proyectos personales, pruebas internas o simplemente para tener el control total sin depender de terceros? Montar un servidor Git puro por SSH sigue siendo, en 2026, una de las soluciones m\u00e1s simples, seguras y eficientes que existen. Consigue control absoluto, cero servicios web expuestos innecesariamente [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18],"tags":[16,24,28],"class_list":["post-122","post","type-post","status-publish","format-standard","hentry","category-guia","tag-git","tag-linux","tag-seguridad"],"_links":{"self":[{"href":"https:\/\/juredev.com\/blog\/wp-json\/wp\/v2\/posts\/122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/juredev.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/juredev.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/juredev.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/juredev.com\/blog\/wp-json\/wp\/v2\/comments?post=122"}],"version-history":[{"count":0,"href":"https:\/\/juredev.com\/blog\/wp-json\/wp\/v2\/posts\/122\/revisions"}],"wp:attachment":[{"href":"https:\/\/juredev.com\/blog\/wp-json\/wp\/v2\/media?parent=122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/juredev.com\/blog\/wp-json\/wp\/v2\/categories?post=122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/juredev.com\/blog\/wp-json\/wp\/v2\/tags?post=122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}