OpenCode es una herramienta de desarrollo asistida por inteligencia artificial que permite trabajar con proyectos de programación, consultar archivos, ejecutar tareas y utilizar diferentes modelos de IA. Aunque puede utilizarse desde la terminal, también dispone de una interfaz web que resulta especialmente práctica cuando queremos mantener la herramienta instalada en un servidor y acceder a ella desde otros ordenadores.
En este artículo vamos a instalar OpenCode 2 en un servidor con Ubuntu Server 26.04.1 LTS, sin entorno gráfico, y configuraremos su interfaz web para que pueda utilizarse desde los equipos de nuestra red local. Para ello aprovecharemos el servidor integrado de OpenCode, sin necesidad de instalar Apache, Nginx o un escritorio remoto.
Al terminar, tendremos un servidor OpenCode gestionado por systemd, disponible a través del navegador y preparado para seguir funcionando aunque cerremos la sesión SSH.
Situación inicial
Partimos de un Ubuntu Server instalado y accesible por SSH. En este ejemplo utilizaremos una máquina virtual en una red privada, con una cuenta de usuario normal que tiene permisos para ejecutar sudo.
Para más información sobre la instalación de Ubuntu Server consultar el siguiente artículo.
- Servidor con Ubuntu Server 26.04.1 LTS y conexión a Internet.
- Acceso mediante SSH desde un ordenador de la misma red.
- Interfaz de red del ejemplo: ens18.
- IP ficticia utilizada para ilustrar los comandos: 192.168.1.100.
- Red permitida: 192.168.1.0/24.
- Puerto web elegido: 4096.
Importante: la dirección 192.168.1.100 es un ejemplo anonimizado. Debe sustituirse en todos los comandos por la IP real del servidor. Igualmente, hay que adaptar el nombre de la interfaz y el rango de red si son distintos. En la conversación original no se registró una salida del comando que comprobara la versión exacta de Ubuntu; por tanto, la guía está orientada a 26.04.1 LTS, pero ese dato no forma parte de las verificaciones capturadas.
Identificar la dirección IP del servidor
Antes de configurar la red conviene conocer la interfaz activa y la dirección IPv4 del servidor.
Ejecutamos:
- ip -4 -br addr show scope global
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
ens18 UP 192.168.1.XXX/24
En la instalación original se obtuvo una interfaz operativa y una dirección de la red 192.168.1.0/24. Aquí hemos ocultado el último octeto de la dirección real. Para continuar utilizaremos como dirección de ejemplo 192.168.1.100.
Instalar OpenCode desde su instalador oficial
Con el acceso SSH disponible, iniciamos la instalación de OpenCode. El instalador se ejecuta desde la cuenta del usuario, sin necesidad de crear otro usuario para el servicio.
Ejecutamos:
- curl -fsSL https://opencode.ai/v2/install | bash
Incorporar OpenCode al PATH y comprobar la versión
Añadimos la carpeta del ejecutable a ~/.bashrc, evitando escribir la misma línea varias veces. Después recargamos la configuración de la terminal y consultamos la versión instalada.
Ejecutamos:
- { grep -Fqx 'export PATH="$HOME/.opencode/bin:$PATH"' "$HOME/.bashrc" || echo 'export PATH="$HOME/.opencode/bin:$PATH"' >> "$HOME/.bashrc"; } && source "$HOME/.bashrc" && opencode --version
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
opencode v2.2.0
El resultado confirma que OpenCode está instalado y ya se puede ejecutar por su nombre. Se utiliza --version; la forma --versión que aparece en la transcripción original es una errata y no debe copiarse.
Configurar la contraseña del servidor web
Antes de ofrecer la interfaz a otros equipos, configuramos una contraseña. El nombre de usuario para la autenticación HTTP de OpenCode 2 es opencode.
Ejecutamos:
- read -r -s -p "Introduce la contraseña de OpenCode: " OC_PASS && printf '\n' && opencode service set password "$OC_PASS" && unset OC_PASS
Este método evita escribir la contraseña literalmente en la línea de comandos que guardamos para el artículo. No publicaremos el valor, ni una captura que lo revele. La opción --service que utilizaremos más adelante permite reutilizar la configuración persistente del servidor.
Comprobar y preparar el cortafuegos UFW
Para limitar el acceso a OpenCode a nuestra red local utilizaremos UFW, el cortafuegos de Ubuntu. Antes de activarlo, es imprescindible garantizar que podremos seguir entrando por SSH.
Ejecutamos:
- sudo ufw status verbose
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
Status: inactive
En la instalación documentada, UFW estaba desactivado. Primero autorizamos SSH y después el puerto 4096 únicamente desde la red local. Son dos reglas; la segunda incluye la interfaz de entrada y la IP del servidor.
Ejecutamos:
- sudo ufw allow 22/tcp && sudo ufw allow in on ens18 from 192.168.1.0/24 to 192.168.1.100 port 4096 proto tcp
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
Rules updated
Rules updated (v6)
Rules updated
Antes de activarlo verificamos que las reglas se han guardado y que la política predeterminada de entrada es de bloqueo.
Ejecutamos:
- sudo ufw show added && grep '^DEFAULT_INPUT_POLICY=' /etc/default/ufw
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
Added user rules (see 'ufw status' for running firewall):
ufw allow 22/tcp
ufw allow in on ens18 from 192.168.1.0/24 to 192.168.1.100 port 4096 proto tcp
DEFAULT_INPUT_POLICY="DROP"
Por último activamos UFW. Como estamos conectados por SSH, comprobamos antes que la regla del puerto 22 existe.
Ejecutamos:
- sudo ufw enable
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
Firewall is active and enabled on system startup
Advertencia: la regla de SSH del ejemplo permite el puerto 22 desde cualquier origen que pueda alcanzar el servidor; la restricción a la red local se aplica específicamente al puerto 4096 de OpenCode. En un servidor con otras aplicaciones o redes adicionales hay que revisar sus reglas antes de activar UFW. No debemos abrir el puerto 4096 en el router.
Crear directamente el servicio permanente de systemd
Durante la puesta en marcha original probamos primero el servidor en segundo plano y después creamos un servicio provisional de tipo oneshot. Esos pasos no son necesarios en una instalación nueva: podemos crear directamente una unidad Type=simple que mantenga OpenCode bajo la supervisión de systemd.
El siguiente comando genera el archivo usando automáticamente el directorio personal de quien lo ejecuta. Así evitamos introducir en el artículo un nombre de usuario o una ruta de cuenta privada.
Ejecutamos:
mkdir -p "$HOME/.config/systemd/user" && cat > "$HOME/.config/systemd/user/opencode.service" <<EOF
[Unit]
Description=OpenCode 2 - Servidor web
After=network.target
[Service]
Type=simple
WorkingDirectory=$HOME
ExecStart=$HOME/.opencode/bin/opencode serve --service --hostname 192.168.1.100 --port 4096
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
EOF
La directiva ExecStart fija la dirección y el puerto; Restart=on-failure indica que el gestor debe intentar reiniciar el proceso si termina con error. Type=simple permite que systemd supervise al proceso principal, a diferencia de la unidad provisional que utilizamos inicialmente.
Registrar y habilitar el arranque automático
Recargamos las unidades del gestor y habilitamos el servicio del usuario. Todavía no es necesario reiniciar Ubuntu.
Ejecutamos:
- systemctl --user daemon-reload && systemctl --user enable opencode.service
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
Created symlink '/home/USUARIO/.config/systemd/user/default.target.wants/opencode.service' → '/home/USUARIO/.config/systemd/user/opencode.service'.
El enlace creado indica que el servicio está habilitado. El nombre del usuario se ha sustituido por USUARIO para no publicar información personal.
Permitir que el servicio funcione sin sesión SSH
Como la unidad pertenece al usuario, activamos linger. De este modo Ubuntu podrá mantener sus servicios en ejecución aunque el usuario cierre SSH y podrá arrancarlos después de iniciar el sistema.
Ejecutamos:
- sudo loginctl enable-linger "$USER" && loginctl show-user "$USER" -p Linger
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
Linger=yes
La respuesta confirma que el usuario dispone de la configuración necesaria para ejecutar servicios sin una sesión interactiva abierta.
Iniciar OpenCode y comprobar systemd
Ahora iniciamos el servicio y consultamos su estado. La salida que mostramos recoge las líneas principales de la comprobación real, ocultando el identificador del proceso y el nombre de la cuenta.
Ejecutamos:
- systemctl --user start opencode.service && systemctl --user --no-pager --full status opencode.service
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
● opencode.service - OpenCode 2 - Servidor web
Loaded: loaded (/home/USUARIO/.config/systemd/user/opencode.service; enabled; preset: enabled)
Active: active (running)
Main PID: [OCULTO] (opencode)
La línea fundamental es Active: active (running). Significa que OpenCode está en ejecución y el propio systemd supervisa el proceso. No debemos confundirlo con active (exited), que era el estado del servicio provisional utilizado durante las pruebas.
Verificar el puerto y la protección de la API
Con el servicio ya iniciado, comprobamos que escucha en la IP que hemos elegido y en el puerto 4096.
Ejecutamos:
- sudo ss -lntp '( sport = :4096 )'
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 512 192.168.1.100:4096 0.0.0.0:* users:(("opencode",pid=[OCULTO],fd=8))
Después realizamos dos peticiones HTTP sin enviar credenciales: la primera a la página principal y la segunda a un recurso de la API que requiere autenticación.
Ejecutamos:
- curl -sS -o /dev/null -w 'Código HTTP: %{http_code}\n' --max-time 5 http://192.168.1.100:4096/ && curl -sS -o /dev/null -w 'Código HTTP sin credenciales: %{http_code}\n' --max-time 5 http://192.168.1.100:4096/api/info
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
Código HTTP: 200
Código HTTP sin credenciales: 401
El código 200 confirma que el servidor responde a la página principal. El 401 de la API indica que la petición sin credenciales ha sido rechazada. Son comprobaciones distintas: un 200 en la raíz no demuestra por sí solo que todas las operaciones estén protegidas.
Acceder desde otro equipo de la red local
Desde un ordenador Windows o Linux de la misma red abrimos Chrome, Firefox, Edge u otro navegador y entramos en la dirección del servidor del ejemplo:
http://192.168.1.100:4096
- Usuario web: opencode.
- Contraseña: la que se estableció anteriormente.
En la prueba realizada, la interfaz web se abrió correctamente desde Windows. No se publicó ni se compartió la contraseña.
Comprobar el arranque automático después de reiniciar
La prueba final consiste en reiniciar Ubuntu y volver a entrar en OpenCode desde el navegador, sin iniciar manualmente el servicio. Este paso interrumpe temporalmente todas las conexiones al servidor, incluido SSH.
Ejecutamos:
- sudo reboot
Una vez que Ubuntu terminó de arrancar, comprobamos que el servicio seguía activo, habilitado y preparado para funcionar sin sesión SSH.
Ejecutamos:
- systemctl --user is-active opencode.service && systemctl --user is-enabled opencode.service && loginctl show-user "$USER" -p Linger
La salida obtenida, abreviada y anonimizada cuando corresponde, fue:
active
enabled
Linger=yes
Los tres valores, junto con el acceso web verificado después del reinicio, confirman que el servidor quedó correctamente configurado para arrancar automáticamente.
Resultado final y consideraciones de seguridad
Hemos instalado OpenCode v2.2.0 en Ubuntu Server y hemos habilitado su interfaz web para los equipos de la red local. El servidor se ejecuta con el usuario habitual, sin escritorio gráfico, y permanece disponible después de cerrar SSH y de reiniciar Ubuntu.
- OpenCode: versión 2.2.0 en el caso documentado.
- Interfaz web: http://192.168.1.100:4096 (IP ficticia).
- Inicio automático: unidad de usuario opencode.service habilitada.
- Supervisión: Restart=on-failure en systemd.
- Autenticación: usuario web opencode y contraseña privada.
- Cortafuegos: acceso al puerto 4096 permitido únicamente desde el segmento local configurado.
- Seguridad: la dirección del ejemplo utiliza http://, sin cifrado TLS. Es adecuada únicamente para una red local de confianza: la contraseña y las peticiones no van cifradas a nivel HTTPS. Si se usa una red compartida o no confiable, conviene incorporar HTTPS o emplear un túnel SSH. El cortafuegos y la contraseña no sustituyen al cifrado de la comunicación.
Tampoco se ha configurado aquí ningún proveedor de modelos de IA. Esta guía se centra en instalar y publicar de forma controlada la interfaz web; la elección del modelo y las credenciales del proveedor pueden realizarse posteriormente desde OpenCode.
En resumen, tenemos una instalación más sencilla que la secuencia de pruebas inicial: se omiten el servicio provisional, las verificaciones repetidas y el arranque manual previo del servidor. Con ello conservamos las garantías importantes —instalación, contraseña, UFW, systemd y prueba tras reinicio— sin añadir pasos innecesarios.



No hay comentarios:
Publicar un comentario
Nota: solo los miembros de este blog pueden publicar comentarios.