Crear y configurar servidor en DigitalOcean
Para empezar hay que crear un droplet
Elegir la distribución como Linux Ubuntu 22.04 LTS (hay más recientes, pero ir a la fija con 22.04 LTS)
Escoger el tamaño del servidor que haga falta. En mi caso, me sirve un procesador regular de un solo núcleo, 512 MB de ram y 10GB de disco:
Elegir la forma de autentificación contra el servidor. Yo quiero usar SSH, así que antes tuve que instalar una llave SSH en DigitalOcean
Especifico el nombre del servidor y lo asocio a un proyecto:
Al final, acepto crear el servidor con la configuración especificada
Esperamos hasta que termine de crear el servidor
Ubicar la IP del servidor
Eventualmente el servidor terminará de crear y podremos ver la IP en el mismo panel:
Adicionalmente, en el panel de la izquierda aparecerán nuestros proyectos. Vamos allá y buscamos el proyecto al que agregamos el droplet:
Configurar el servidor
Conectándonos al servidor
Vamos a conectarnos por SSH al servidor así:
ssh root@your_server_ip
En este ejemplo yo tendría que reemplazar your_server_ip por 146.190.121.34.
Nos va a preguntar si reconocemos la conexión y queremos guardar la firma:
Configuramos firewall
Activamos OpenSSH
ufw allow OpenSSH
ufw enable
Cuando nos pregunte si estamos seguros, le damos y:
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
Abrimos el puerto 8080 para después
sudo ufw allow 8080
Rule added
Crear un usuario en el servidor
Adicional a root vamos a crear un usuario llamado vapor. Al introducir el siguiente comando nos va a pedir introducir una contraseña y confirmación de contraseña (deben coincidir). Luego, nos va a pedir una información adicional que se puede dejar en blanco (Full Name, Room Number, Work Phone, Home Phone y Other). Nos va a pedir que confirmemos y vamos a poner Y.
adduser vapor
Permitir que vapor use sudo:
usermod -aG sudo vapor
Copiar las llaves SSH autorizadas del usuario root a vapor, para poder entrar con SSH a este usuario:
rsync --archive --chown=vapor:vapor ~/.ssh /home/vapor
Cerramos la sesión y entramos como el nuevo usuario:
exit
ssh vapor@your_server_ip
Instalamos Swift en el servidor
Primero hay que instalar Swiftly en Linux para gestionar las versiones de Swift:
curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz && \
tar zxf swiftly-$(uname -m).tar.gz && \
./swiftly init --quiet-shell-followup && \
. "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh" && \
hash -r
Nos va a pedir confirmación, así que le damos Y:
Es probable que después de terminar diga que hacen falta algunas dependencias para continuar:
Las vamos a instalar con apt-get:
sudo apt-get update; sudo apt-get -y install binutils unzip libcurl4-openssl-dev libgcc-13-dev libpython3-dev libstdc++-13-dev libxml2-dev libncurses-dev libz3-dev pkg-config zlib1g-dev
Cuando termine, verificamos la versión de Swift instalada
swift --version
Swift version 6.2.3 (swift-6.2.3-RELEASE)
Target: x86_64-unknown-linux-gnu
Instalar VAPOR
Clonamos el toolbox de vapor
git clone https://github.com/vapor/toolbox.git
Hacemos checkout del último release, que en la fecha es 20.0.0:
cd toolbox
git checkout 20.0.0
Se compila vapor y se mueve el binario al path
swift build -c release --disable-sandbox
sudo mv .build/release/vapor /usr/local/bin
Cuando termine de compilar, se puede borrar el toolbox:
cd ..
rm -rf toolbox
Compilar el repositorio en el servidor
Clonar el repositorio. Para que esto funcione, es necesario instalar una llave SSH del servidor en Github:
git clone git@github.com:<reponame>.git
Luego moverse al directorio del repositorio:
cd StripeIntentService
Compilar (solamente) la aplicación:
swift build -v
Para este paso es posible que haga falta cambiar las dimensiones (RAM) del droplet a 4GB. Después de que termine de compilar, se puede volver a reducir.
Esperar hasta que el servidor acabe. Puede demorarse una eternidad. En un droplet de DigitalOcean con 4GB de RAM y 1 procesador, la compilación de un servicio SUPER SIMPLE que usa Stripe se demoró 17 minutos.
(...) needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "/usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o" "/lib/x86_64-linux-gnu/crtn.o" (end of response file) Build complete! (1018.37s)
Luego se ejecuta el servicio que ya está compilado. NO usar swift run sino directamente:
.build/debug/StripeIntentService serve --hostname 0.0.0.0 --port 8080
Instalar llave SSH del servidor en Github
En el servidor, crear una llave SSH. En el siguiente comando reemplazar "your_email@example.com" con el correo que haga falta. Cuando pregunte por ubicación y contraseña, vamos a ir con las opciones por defecto:
ssh-keygen -t ed25519 -C "your_email@example.com"
Empezar el agente ssh en segundo plano:
eval "$(ssh-agent -s)"
Modificar ~/.ssh/config con nano:
nano ~/.ssh/config
Agregar la configuración para usar la llave en github. Cuidado de no poner la instrucción UseKeychain yes que solo funciona en macos:
Host github.com
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
Agregar la llave SSH al agente. Cuidado de no usar --apple-use-keychain que solo funciona en MacOS:
ssh-add ~/.ssh/id_ed25519
Imprimir en consola el valor de la llave:
cat ~/.ssh/id_ed25519.pub
Se copia la llave y se pega en Github.
Cambiar dimensiones del droplet
La configuación de 512MB de ram puede no ser suficiente para compilar la aplicación. En ese caso, hay que cambiar las dimensiones del droplet.
Buscar en el panel izquierdo de "manage" la opción "Droplets":
E ir directamente al botón "Upsize"
Allí se buscan las dimensiones que hagan falta, como 2GB de RAM
Se hace clic en ella, y luego "Resize"
Troubleshooting
Fatal error: Missing STRIPE_SECRET_KEY
En caso de que se use alguna variable de ambiente, recordar crearlas en un archivo .env. De lo contrario, fallará en la compilación.
Disparo la compilación con swift build, pero se queda congelado
¿El proceso está corriendo?
Primero hay que detectar si el proceso sigue corriendo. Para ello, se crea otra conexión SSH al servidor y se mira si hay algún proceso con el mismo nombre que el servicio compilado.
ps aux | grep StripeIntentService
La respuesta podría ser algo como esto:
vapor 2100 0.3 0.8 74268 17704 ? Sl 13:35 0:00 swift run StripeIntentService serve --hostname 0.0.0.0 --port 8080 vapor 2107 0.7 6.4 726968 129616 ? Sl 13:35 0:01 /home/vapor/.local/share/swiftly/toolchains/6.2.3/usr/bin/swift-run StripeIntentService serve --hostname 0.0.0.0 --port 8080 vapor 2195 0.0 0.1 6680 2340 pts/1 S+ 13:38 0:00 grep --color=auto StripeIntentService
Las siguientes líneas indican que la compilación está en curso:
2100 swift run StripeIntentService ...
2107 swift-run StripeIntentService ...
Si es necesario detener los procesos se hace:
kill 2100 2107
¿El servicio está escuchando en el puerto?
Comprobar si el puerto 8080 está abierto y escuchando:
ss -tulpn | grep 8080
Debería traer algo como
LISTEN 0 128 0.0.0.0:8080
Si no trae nada, es porque el servicio no está escuchando
Ejecutar compilación mostrando todos los logs
Se puede usar el modificador -v para mostrar los logs
swift build -v
Si se queda colgado en "Planning build" es porque hay un problema con SPM:
(...) -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o /lib/x86_64-linux-gnu/crtn.o Planning build
La app no se está ejecutando todavía. La compilación está atascada en la fase de resolución / planificación de Swift Package Manager. SPM está tratando de resolver dependencias, validar el grafo, posiblemente acceder a red (si cree que debe actualizar algo) o está bloqueado por cache corrupta.
Esto puede ocurrir cuando:
- Hay un problema con el cache en
~/.swiftpm - Hay conflicto con
swiftly - Hay un repo de dependencia que quedó corrupto
Para solucionarlo, primero hay que matar los procesos en cursos. Para ello, crear otra conexión ssh, mostrar los procesos que usen StripeIntentService o directamente:
killall -9 swift
killall -9 swift-run
Luego, dentro del directorio del proyecto:
swift package clean
rm -rf .build
rm -rf Package.resolved
También limpiar la caché global:
rm -rf ~/.swiftpm
rm -rf ~/StripeIntentService/.build
Aunque es una solución agresiva (limpiar todo), me funcionó.
Luego, volver a compilar con -v y mirar si el error persiste:
swift build -v















Top comments (0)