- Go 67.3%
- Shell 32.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
On a desktop (or with --remote IP[:PORT]) setup asks for the server IP and the SSH password (hidden, never logged), uploads this binary and runs setup --yes remotely, streaming the output; --local forces local mode. Flags: --ssh-user, --ssh-port, --ssh-password-file, --caprover (forwarded). Claude-Session: https://claude.ai/code/session_01RnxFu4YRd8qX88Hp3YCLwP |
||
| .claude/skills | ||
| .github/workflows | ||
| .specify | ||
| cmd | ||
| internal | ||
| specs | ||
| .air.toml | ||
| .gitignore | ||
| caprover.sh | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| main_test.go | ||
| README.md | ||
| setup.sh | ||
server-configurator
Herramienta DevOps (Go + cobra) que configura un servidor Contabo / Ubuntu 24.04–26.04
para usarlo desde Coolify. Sustituye a setup.sh (v0.3.3), que se conserva en el repo
como referencia hasta validar el binario en un servidor real.
Uso
# En el servidor, como root
./server-configurator setup --yes # sin preguntas, reinicia al terminar
./server-configurator setup # pregunta antes de tocar UFW y antes de reiniciar
./server-configurator setup --dry-run # muestra comandos y ficheros, no ejecuta nada (no requiere root)
./server-configurator version
# Desde un escritorio, configurando un servidor por SSH
./server-configurator setup --remote 1.2.3.4 # pregunta la contraseña y confirma
./server-configurator setup --remote 1.2.3.4:2222 -y # sin preguntas (puerto explícito)
# Instalación legacy de CapRover (no reinicia)
./server-configurator setup --caprover --yes
Flags de setup:
| Flag | Por defecto | Descripción |
|---|---|---|
-y, --yes |
false |
No pregunta: confirma el firewall y reinicia automáticamente |
--dry-run |
false |
Muestra comandos y ficheros sin ejecutar nada (no requiere root) |
--caprover |
false |
Instalación legacy de CapRover en lugar de la configuración para Coolify |
--remote IP[:PUERTO] |
— | Configura por SSH el servidor indicado |
--local |
false |
Fuerza la configuración de esta máquina (excluyente con --remote) |
--ssh-user |
root |
Usuario SSH del modo remoto |
--ssh-port |
22 |
Puerto SSH del modo remoto (IP:PUERTO tiene prioridad) |
--ssh-password-file |
— | Fichero con la contraseña SSH (evita la pregunta) |
Pasos aplicados, en orden: zona horaria Europe/Madrid → alias update → actualización del
sistema → UFW (22/80/443) → hardening sshd_config (con backup) → fail2ban (whitelist Coolify,
baneos progresivos) → swap 8 GB + swappiness → paquetes de seguridad sin MTA → auditd →
unattended-upgrades (01:30 / 02:00) → sysctl → limits → clave SSH de Coolify → logwatch →
desactivación de servicios innecesarios → resumen → reinicio.
Es idempotente: puede ejecutarse varias veces.
Toda la salida de la terminal se guarda además en out.log, en la misma carpeta que el
binario (se añade al final en cada ejecución, con una cabecera con fecha y argumentos).
Modo remoto (desde un escritorio)
El programa detecta si se está ejecutando en un Ubuntu de escritorio (variable
XDG_CURRENT_DESKTOP, /usr/bin/gnome-shell, o los paquetes ubuntu-desktop /
ubuntu-desktop-minimal instalados). Si es así, no configura tu equipo: pide la IP del
servidor y la contraseña y hace todo el trabajo en remoto por SSH. En un Ubuntu Server se
comporta exactamente como antes (todo en local, sin preguntas nuevas).
./server-configurator setup # escritorio → pregunta IP y contraseña
./server-configurator setup --remote 1.2.3.4 # fuerza remoto en cualquier máquina
./server-configurator setup --local # fuerza local aunque sea un escritorio
./server-configurator setup --remote 1.2.3.4 --ssh-password-file pw.txt --yes # sin preguntas
Cómo funciona:
- Se conecta por SSH (
--ssh-user, por defectoroot; puerto deIP:PUERTOo--ssh-port). La contraseña se lee de--ssh-password-fileo se pregunta sin eco (x/term); nunca se imprime ni se guarda enout.log. - Como es una herramienta de aprovisionamiento de servidores nuevos, acepta la clave de host
desconocida e imprime su huella (
Huella del servidor: SHA256:…) para poder verificarla por otro canal. - Comprueba la arquitectura del servidor (
uname -m): si no coincide con la del binario local aborta indicando ambas (no hay compilación cruzada: descarga el binarioserver-configurator-linux-{amd64,arm64}que corresponda). - Sube este mismo binario a
/tmp/server-configurator(0755) y ejecuta allísetup --yescon los flags reenviados (--dry-run,--caprover), mostrando la salida remota en tu terminal (y enout.log).
Sin --yes avisa de que el servidor se configurará entero y se reiniciará al terminar, y
pide confirmación antes de conectar. El reinicio final corta la sesión SSH: es lo esperado (el
binario remoto sale antes de reiniciar).
Ver specs/003-remote-ssh/.
CapRover (legacy)
Algunos servidores (por ejemplo los que están tras VPN) siguen usando CapRover en vez de
Coolify. --caprover reproduce caprover.sh, que se conserva en el repo como referencia:
./server-configurator setup --caprover --yes
./server-configurator setup --remote 1.2.3.4 --caprover # también en remoto
Pasos, en orden: zona horaria → alias update → actualización del sistema → UFW con los
puertos de CapRover/Swarm (22, 80, 443, 3000, 996, 7946, 4789 y 2377 tcp; 7946, 4789 y 2377
udp) → fail2ban → swap 8 GB → Docker Engine desde el repositorio oficial (clave en
/etc/apt/keyrings/docker.gpg y docker.list con el codename de la release) → contenedor de
CapRover. Ningún paso exclusivo de Coolify (hardening sshd, auditd, unattended-upgrades,
sysctl, límites, clave SSH de Coolify, logwatch, servicios) y sin reinicio al terminar.
Es idempotente: si docker-ce ya está instalado no se toca el repositorio, y si existe
/captain o ya hay un contenedor caprover/caprover el arranque se omite con ⚠.
Dos diferencias documentadas respecto del script original:
- fail2ban: el script abría
vim /etc/fail2ban/jail.conf(interactivo). Aquí se usa el pasoFail2banStepde siempre, que escribejail.local(baneos progresivos, whitelist) y verifica que el servicio queda activo. - contenedor: se arranca con
-d(en segundo plano). El script lo dejaba en primer plano y bloqueaba la terminal.
Al terminar recuerda: completa la instalación web en http://<IP>:3000 y BLOQUEA el puerto
3000 (ufw delete allow 3000/tcp).
Ver specs/004-caprover-legacy/.
Ubuntu 26.04 y la instalación no interactiva
En 26.04 el truco apt-mark hold postfix exim4 dma dejaba de funcionar: el resolutor de apt
escogía otro proveedor de mail-transport-agent (courier-mta), cuyo debconf del certificado
X.509 volvía interactiva la ejecución. La herramienta lee /etc/os-release y:
- Ubuntu < 26.04 (24.04): mantiene la estrategia original de
setup.sh(debconf-set-selections+apt-mark hold→ instalar →apt-mark unhold), que ahí funciona. - Ubuntu ≥ 26.04 (o SO no detectado):
logwatchtiene una dependencia dura demail-transport-agent, así que un MTA es inevitable. Se instala explícitamente el mínimo,dma(sin demonio, sin puerto abierto, debconf preseedeado), junto conapt-listchangesylogwatchcon--no-install-recommends. Así apt no elige postfix ni courier-mta. - En todos los casos, cada subproceso se ejecuta con
DEBIAN_FRONTEND=noninteractive,NEEDRESTART_MODE=ayNEEDRESTART_SUSPEND=1(internal/sys.NonInteractiveEnv).
Ver specs/002-noninteractive-apt/.
Desarrollo
go build -o server-configurator .
go test ./... # todo el código tiene tests (FS en memoria + runner falso)
air # live reload: recompila y ejecuta `setup --dry-run --yes`
Estructura:
main.go entrada
cmd/ comandos cobra (setup, version)
internal/sys/ Context, Runner (real / dry-run / fake), Summary, helpers de ficheros
internal/steps/ un fichero por paso + tests
internal/setup/ orden de pasos, comprobación de root, informe, reinicio
internal/remote/ cliente SSH (x/crypto/ssh), subida del binario y ejecución remota
specs/ especificaciones Spec Kit (001 migración, 002 apt no interactivo,
003 modo remoto SSH, 004 CapRover legacy)
.specify/ constitución y plantillas de Spec Kit
CI (Forgejo Actions)
.github/workflows/build.yml ejecuta gofmt/go vet/go test y construye binarios estáticos
server-configurator-linux-{amd64,arm64} como artefactos (un zip por binario; la API de
artefactos siempre comprime) en cada push a main/dev, en PRs y manualmente.
En los tags v* además crea una Release en Forgejo con los binarios (y sus .sha256)
como assets descargables directamente, y el binario reporta la versión del tag:
wget https://git.devbeebit.com/beebit/server-configurator/releases/download/v0.1.0/server-configurator-linux-amd64 -O server-configurator
chmod +x server-configurator && ./server-configurator setup -y
Para publicar: git tag -a vX.Y.Z -m "vX.Y.Z" && git push origin vX.Y.Z. Corre en el runner con etiqueta go (imagen
con el toolchain de Go ya instalado, sin setup-go) y solo usa actions/checkout,
actions/cache (módulos y caché de build) y actions/upload-artifact, que Forgejo (≥ 7) resuelve desde github.com.
Este proyecto sigue Spec Kit: spec.md → plan.md →
tasks.md → implementación. Commits con Conventional Commits.
Licencia
Copyright 2025–2026 Beebit Solutions SLU.