">
 

Automatically Deploy Your App to a VPS with GitHub Actions

Iniciado por joomlamz, Hoje at 02:25

Respostas: 1   |   Visualizações: 1

Tópico anterior - Tópico seguinte

0 Membros e 1 Visitante estão a ver este tópico.

Olá comunidade do **webmastersmz.com**!

Como especialista em tecnologia, analisei o tópico sobre a implementação de *pipelines* de CI/CD para automação de *deploy* em VPS utilizando o **GitHub Actions**. Esta é uma prática fundamental para qualquer desenvolvedor ou administrador de sistemas que queira elevar o nível da sua produtividade e garantir a consistência nos ambientes de produção.

Aqui estão os pontos principais desta técnica:

1.  **Eliminação do Erro Humano:** Ao automatizar o processo através de ficheiros `.github/workflows/deploy.yml`, removemos a necessidade de fazer *uploads* manuais via FTP ou execuções repetitivas de comandos via SSH. O sistema encarrega-se de mover o código directamente para o servidor após o *push* no repositório.
2.  **Segurança com GitHub Secrets:** Um dos pontos mais críticos abordados é o uso das *Secrets* para armazenar chaves privadas SSH e endereços IP. Isto assegura que dados sensíveis não ficam expostos no código-fonte, uma prática de segurança essencial no nosso ecossistema.
3.  **Ambiente de Pré-produção vs. Produção:** O uso do GitHub Actions permite criar *workflows* distintos para diferentes ramos (*branches*), permitindo testar as alterações num ambiente de *staging* antes de submeter ao servidor de produção, minimizando o tempo de indisponibilidade (*downtime*).
4.  **Agilidade no Ciclo de Vida de Software:** Com esta configuração, o *Time-to-Market* reduz drasticamente, pois qualquer correção ou nova funcionalidade é aplicada em segundos, mantendo o servidor sempre sincronizado com o repositório principal.

**Convite ao Debate:**
Gostaria de saber qual é a vossa experiência com ferramentas de automação. Vocês já utilizam GitHub Actions nos vossos projectos hospedados aqui em Moçambique, ou ainda preferem métodos tradicionais? Alguém aqui já enfrentou desafios específicos ao configurar o SSH nos *runners* do GitHub? Vamos partilhar conhecimento nos comentários abaixo!

---

Para garantir que os vossos projectos e fóruns rodam sem falhas, com a estabilidade e a velocidade que os utilizadores moçambicanos merecem, convido-vos a conhecer as soluções de alojamento de alta performance da **AplicHost** em https://aplichost.com. Estamos prontos para apoiar o crescimento da infraestrutura web nacional.

Automatically Deploy Your App to a VPS with GitHub Actions



Tópico: Automatically Deploy Your App to a VPS with GitHub Actions
Categoria: Tutoriais | Programação & Tecnologia
Idioma Principal: Português (Conteúdo de Tecnologia)

Descrição do Conteúdo / Informações:
-------------------------------------------------------------------------
If your deploy process is "SSH into the server, cd to the app, git pull, restart something, hope" — this post replaces it with git push.

What you'll have by the end: every push to your main branch updates the app on your server automatically. You can also trigger a deploy by hand from the GitHub UI.

This is the simple version — it has a few seconds of downtime during the restart and it builds on the server. Post 6 in this series upgrades it to a zero-downtime setup. Start here; the simple version is enough for a long time.



What is "deploying with GitHub Actions"?


GitHub Actions is a task runner built into every GitHub repo. You describe a job in a YAML file, and GitHub runs it on a fresh virtual machine when something happens — in our case, "when code lands on main."

The job we want is tiny: connect to our server over SSH and run the same commands we'd run by hand. The value isn't magic — it's that the steps are written down, always run in the same order, and don't depend on you being awake.



Prerequisites


• An app in a GitHub repo.

• A VPS (any provider) you can SSH into, with your app already cloned and running once — e.g. in /srv/snip, served by nginx, run by a process manager. If you don't have that yet, set it up manually first; this post automates the update, not the first install.

• A dedicated Linux user for deploys (don't use root). We'll call it deploy.



Step 1: Make an SSH key just for deploys


On your local machine, generate a key pair that only GitHub Actions will use:

ssh-keygen -t ed25519 -f ~/.ssh/snip_deploy -N "" -C "github-actions-deploy"

This creates ~/.ssh/snip_deploy (private) and ~/.ssh/snip_deploy.pub (public).

Add the public key to your server so the deploy user accepts it:

ssh-copy-id -i ~/.ssh/snip_deploy.pub deploy@YOUR_SERVER_IP
# or manually: append the .pub line to /home/deploy/.ssh/authorized_keys on the server

Test it:

ssh -i ~/.ssh/snip_deploy deploy@YOUR_SERVER_IP "echo connected"



Step 2: Give the deploy user permission to restart the app


The deploy needs to restart your app process without a password prompt. If you run the app as a systemd service (snip.service), allow exactly that one command:

# On the server, as root:
echo 'deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart snip, /usr/bin/systemctl reload nginx' \
| sudo tee /etc/sudoers.d/snip-deploy

Adjust for your stack: if you use PM2, supervisor, Docker Compose, etc., substitute the restart command you actually run.



Step 3: Store the secrets in GitHub


In your repo: Settings → Secrets and variables → Actions → New repository secret. Add three:

Name
Value

VPS_HOST
your server's IP or hostname

VPS_USER
deploy

VPS_SSH_KEY
the entire contents of ~/.ssh/snip_deploy (the private key, including the BEGIN/END lines)

Secrets are encrypted and never printed in logs.



Step 4: The workflow file


Create .github/workflows/deploy.yml:

name: Deploy

on:
push:
branches: [main]
workflow_dispatch:        # adds a "Run workflow" button in the Actions tab

# Never run two deploys at once.
concurrency:
group: deploy-main
cancel-in-progress: false

jobs:
deploy:
name: Deploy to VPS
runs-on: ubuntu-latest
steps:
- name: Deploy over SSH
uses: appleboy/[email protected]
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: |
set -euo pipefail
cd /srv/snip

# Get the exact code that's on origin/main.
git fetch origin main
git reset --hard origin/main

# Install dependencies and build.
# Adjust for your stack:
npm ci
npm run build

# Apply database migrations.
# Adjust for your stack:
npm run migrate

# Restart the app.
sudo systemctl restart snip

Commit and push it to main.



What each part does



on.push.branches: [main] — run only when commits land on main. Pull requests don't trigger it. (Post 2 adds a test job that does run on pull requests.)


concurrency — if you push twice quickly, the second deploy waits for the first to finish instead of racing it.


git reset --hard origin/main — not git pull. This guarantees the server's code is exactly origin/main, even if something on the server got modified. Nothing should ever be edited directly on the server.


set -euo pipefail — stop on the first error instead of charging ahead. If npm run build fails, the deploy stops before the restart, and your old version keeps running.



Step 5: Watch it run


Push any commit to main, then open the repo's Actions tab. You'll see the workflow run live. Click it to see the SSH output.

To deploy without a new commit (e.g. to retry): Actions → Deploy → Run workflow.



Common gotchas



Permission denied (publickey) — the private key in VPS_SSH_KEY doesn't match the public key in authorized_keys, or you pasted only part of it. Re-copy the whole file.


could not read Username for 'https://github.com' — your server's clone uses an HTTPS remote, which can't authenticate non-interactively. Switch it to SSH with a deploy key, or make the repo public, or add a step that sets a token.


npm: command not found — the non-interactive SSH session has a minimal PATH. Use full paths, or add source ~/.profile / source ~/.nvm/nvm.sh at the top of the script.


Build gets killed on a small server — npm run build can run out of memory on a 1 GB VPS. Add swap, or build in GitHub Actions and copy the result over — that's covered in post 2 and post 6.


The site is broken for a few seconds on every deploy — expected with this approach. Post 6 fixes it.



What's next


Right now a commit that breaks the app will still deploy — the workflow doesn't know the difference between working code and broken code. Next: run your test suite in CI and only deploy if it passes.


Joomlamz
Consultoria em Informática
-------------------------------------------------------
Especialista em Sistemas Web & Manutenção de Servidores.
A desenvolver o novo AplPortal com suporte a PHP 8.
Precisa de ajuda profissional? Contacte-me.

Tags: