O Alpine Linux é a menor imagem que oferecemos. Nos nossos servidores, um Alpine 3.21 recém-instalado usava em repouso 55 MB de RAM e 153 MB de disco, contra 313 MB e 2,7 GB do Ubuntu 24.04. Em troca, você abre mão das ferramentas de sempre. O Alpine usa apk em vez de apt, doas em vez de sudo, OpenRC em vez de systemd e musl em vez de glibc.
Os passos abaixo são os mesmos primeiros dez minutos do Debian ou do Ubuntu, traduzidos para o Alpine. Rodamos cada comando na nossa imagem do Alpine 3.21 antes de publicar, e dois deles nos pegaram na primeira vez. Entre como root com a senha do seu painel.
1. Atualize e reinicie uma vez
apk update && apk upgrade
uname -r
ls /lib/modules
Seu servidor já instalou as atualizações disponíveis no primeiro boot, então o apk upgrade costuma ter pouco a fazer. Olhe para as duas últimas linhas. Se essa primeira atualização trouxe um kernel novo, o kernel em execução (uname -r) não tem mais seus módulos no disco. Tudo o que carrega um módulo falha até você reiniciar. No nosso servidor de teste, a instalação do firewall mostrou ERROR: Couldn't determine iptables version. Se as duas versões forem diferentes, reinicie agora:
reboot
Nosso servidor de teste voltou em menos de um minuto.
2. Crie um usuário que consiga entrar
adduser -D deploy
passwd deploy
adduser deploy wheel
Não pule o passwd. O adduser -D cria a conta sem senha, o Alpine a marca como bloqueada e o sshd recusa uma conta bloqueada mesmo com a chave correta. No nosso teste, a única pista foi esta linha em /var/log/messages:
User deploy not allowed because account is locked
A senha também importa depois: é ela que o doas vai pedir.
Se você adicionou uma chave SSH ao pedir o servidor, ela está no authorized_keys do root. Copie-a para o novo usuário:
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
Ainda não tem chave? Crie uma no seu computador e cole a parte pública em /home/deploy/.ssh/authorized_keys.
3. Faça o doas pedir a senha
O Alpine usa doas em vez de sudo, e a nossa imagem já o libera para o grupo wheel. A regra em /etc/doas.d/wheel.conf é permit nopass :wheel, ou seja, qualquer membro de wheel vira root sem digitar nada. Faça-o pedir a senha e lembrá-la por alguns minutos:
echo 'permit persist :wheel' > /etc/doas.d/wheel.conf
A partir de agora, doas apk add nano funciona como sudo apt install nano no Ubuntu.
4. SSH: só chaves, sem root
O sshd lê os arquivos de /etc/ssh/sshd_config.d/ em ordem de nome e fica com o primeiro valor que encontra para cada configuração. Na nossa imagem, o primeiro arquivo é 00-eqvps.conf, que libera root e senha para você conseguir entrar no primeiro dia. Substitua o conteúdo dele:
cat > /etc/ssh/sshd_config.d/00-eqvps.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
EOF
sshd -t && rc-service sshd restart
sshd -T | grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication) '
A terceira linha faz diferença no Alpine. A imagem usa a versão do OpenSSH com PAM, e só com as duas primeiras linhas nosso servidor de teste ainda oferecia login keyboard-interactive. Com as três, uma tentativa de login sem chave recebe:
Permission denied (publickey).
Mantenha a sessão de root aberta. Num segundo terminal, confira se ssh deploy@YOUR.SERVER.IP funciona (num plano NAT, acrescente -p e a porta pessoal do painel) e se doas id aceita a senha.
5. Firewall: ufw
O ufw está no repositório community, que já vem ativado na nossa imagem:
apk add ufw
ufw limit 22/tcp
ufw --force enable
rc-update add ufw default
ufw status
O limit deixa o SSH passar, mas freia quem abre muitas conexões seguidas. O rc-update importa aqui, porque o OpenRC não inicia o firewall após um reboot se você não o colocar no runlevel. Depois de reiniciar, nosso servidor voltou com Status: active. Num plano NAT, deixe o SSH na porta 22: sua porta externa pessoal é redirecionada para a 22 dentro do servidor. Num plano com IPv4 próprio, abra as portas web quando precisar (ufw allow 80/tcp, ufw allow 443/tcp). O guia do ufw cobre o resto.
6. Ative o cron e as atualizações diárias
Um Alpine recém-instalado não roda cron nenhum. Ative-o:
rc-update add crond default
rc-service crond start
O crontab do root no Alpine já roda tudo o que está em /etc/periodic/daily às 02:00. Coloque ali um script de atualização:
cat > /etc/periodic/daily/apk-upgrade <<'EOF'
#!/bin/sh
apk upgrade --update-cache --no-progress >> /var/log/apk-auto.log 2>&1
EOF
chmod +x /etc/periodic/daily/apk-upgrade
run-parts --test /etc/periodic/daily
O último comando lista os scripts que o cron vai rodar, e o seu deve aparecer. Assim você recebe as correções da 3.21. Passar para a próxima versão do Alpine é um passo separado e manual. Atualizações de kernel ainda exigem reboot: repita de vez em quando a verificação uname -r / ls /lib/modules do passo 1.
7. OpenRC numa tabela
Se você conhece o systemd, é isto que muda, em resumo:
| Tarefa | systemd | Alpine (OpenRC) |
|---|---|---|
| Iniciar um serviço | systemctl start nginx | rc-service nginx start |
| Iniciar no boot | systemctl enable nginx | rc-update add nginx default |
| Status | systemctl status nginx | rc-service nginx status |
| O que está rodando | systemctl list-units | rc-status |
| Log do sistema | journalctl | /var/log/messages |
8. Docker, e a porta que o ufw não bloqueia
O Alpine é um bom host de Docker, porque o próprio sistema quase não atrapalha:
apk add docker docker-cli-compose
rc-update add docker default
rc-service docker start
docker run --rm hello-world
No nosso servidor isso levou 12 segundos, já com o download. Com o daemon do Docker rodando, a memória usada foi de 57 MB para 124 MB.
Uma armadilha que não é só do Alpine: o Docker escreve as próprias regras de firewall. Com o ufw liberando só o SSH, iniciamos o nginx com -p 8080:80 e o acessamos de fora do servidor na porta 8080. O ufw não bloqueou. Se um contêiner só deve ser acessado por um proxy reverso no mesmo servidor, publique-o em localhost:
docker run -d -p 127.0.0.1:8080:80 nginx:alpine
Qual plano
O Alpine deixa quase toda a RAM para o seu próprio software. O plano Nano (2 vCPU, 1 GB, 15 GB, $3/mês) basta para um serviço pequeno ou alguns contêineres. É um plano NAT, então o SSH entra por uma porta pessoal. Se precisar das portas 80 e 443 abertas para a internet, o Nano-IP tem IPv4 próprio por $8/mês. Para pilhas Docker mais pesadas, o Micro dá 2 GB por $5/mês.
O Alpine 3.21 está na página do Alpine VPS e disponível em todos os planos Linux em VPS. O pagamento é em USDT, USDC ou ETH nas redes Base, Ethereum ou Polygon, sem documento nem cartão.
Comentários
Nenhum comentário ainda. Seja o primeiro.