Alpine Linux: Setup

Saudações.

Este é um tutorial de setup tunado do Alpine Linux.

Tutoriais de base:

Pré-requisitos:

  • VM/VPS/Host com instalação do Linux Alpine;
  • Internet no servidor (sua VPS ou host);

1 – Preparando o sistema

Vamos instalar todos os pacotes e configurar todos os serviços básicos para que o Alpine seja um servidor perfeito.

1.1 – Repositórios

Ativando o repositório “main” e “community” para ter suporte ao maior número possível de pacotes estáveis.

Bash
# Populando repositórios principais:
(
    . /etc/os-release;

    AVER=$(echo $VERSION_ID | cut -f1,2 -d.);

    echo;
    echo "http://dl-cdn.alpinelinux.org/alpine/v$AVER/main";
    echo "http://dl-cdn.alpinelinux.org/alpine/v$AVER/community";
    echo;
) > /etc/apk/repositories;

# Sincronizando índice:
apk update;

# Atualizar pacotes
apk upgrade;

1.2 – Data/hora exata

A fonte de relógio oficial via NTP é vital para o funcionamento de todos os sistemas modernos (criptografia, cluster, DNS, etc):

Bash
# Definindo timezone como America/Sao_Paulo (UTC-3):
ln -sf /etc/zoneinfo/America/Sao_Paulo /etc/localtime;

# OpenNTP
apk add openntpd openntpd-openrc;

# Configurando manualmente:
(
    echo;
    echo 'servers pool.ntp.org';
    echo 'server time.cloudflare.com';
    echo 'sensor *';
    echo '';
    echo 'constraint from "9.9.9.9"              # quad9 v4 without DNS';
    echo 'constraint from "2620:fe::fe"          # quad9 v6 without DNS';
    echo 'constraints from "www.google.com"      # intentionally not 8.8.8.8';
    echo;
) >  /etc/systemd/timesyncd.conf;

# Reiniciando o servico de ntp:
service openntpd restart;

# Ativar no boot
rc-update add openntpd default;

1.3 – Ferramentas fundamentais

Etapa opcional, recomendo instalar as ferramentas que ajudam no dia-a-dia das operações.

Bash
# Pacotes basicos
apk   add   bash;
apk   add   sudo;
apk   add   wget;
apk   add   curl;
apk   add   tcpdump;
apk   add   mtr;
apk   add   iproute2;
apk   add   bridge-utils;
apk   add   fping;
apk   add   vlan;
apk   add   htop;
apk   add   strace;
apk   add   iputils-arping;
apk   add   iputils-ping;
apk   add   apache2-utils;
apk   add   rsync;
apk   add   ca-certificates;
apk   add   lsblk;
apk   add   dhcpcd;

# Editores
apk   add   mc;
apk   add   nano;

# Firewall
apk   add   iptables;
apk   add   nftables;
apk   add   nftables-openrc;
apk   add   conntrack-tools;

# Scanner de IPs e portas
apk   add   nmap;

# Zip
apk   add   xz;
apk   add   tar;
apk   add   zstd;
apk   add   gzip;

1.4 – Servidor SSH

O acesso e gestão será feita por servidor SSH usando o OpenSSH.

Bash
# Instalar ferramentas SSH
apk   add   openssh;
apk   add   openssh-server;

# Ativar openssh-server no boot
rc-update add sshd default;

Personalizações do servidor SSH, personalize imperativamente o parâmetro “Port“:

Bash
# Abrir porta padrao 22:
echo "Port                   22" > /etc/ssh/sshd_config.d/inc-port-main.conf;

# Abrir portas em IPv4 e IPv6
echo "AddressFamily         any"  > /etc/ssh/sshd_config.d/inc-addr-family.conf;

# Endereço IPv4 de escuta, 0.0.0.0 = todos os IPv4 do servidor
echo "ListenAddress     0.0.0.0"  > /etc/ssh/sshd_config.d/inc-listen-ipv4.conf;

# Endereço IPv6 de escuta, :: = todos os IPv6 do servidor
echo "ListenAddress          ::"  > /etc/ssh/sshd_config.d/inc-listen-ipv6.conf;

# Desativar exibição do motd do OpenSSH, ainda mantem o /etc/motd do bash
echo "PrintMotd              no"  > /etc/ssh/sshd_config.d/inc-motd.conf;

# Flags de cabeçalho IP para tratamento QoS diferenciado
echo "IPQoS  lowdelay throughput" > /etc/ssh/sshd_config.d/inc-ipv4-qos.conf;

# Ativar keep-alive de TCP (camada 4)
echo "TCPKeepAlive            yes" > /etc/ssh/sshd_config.d/inc-tcp-alive.conf;

# Ativar keep-alive de SSH (camada 5)
echo "ClientAliveInterval       3" >  /etc/ssh/sshd_config.d/inc-ssh-alive.conf;
echo "ClientAliveCountMax      15" >> /etc/ssh/sshd_config.d/inc-ssh-alive.conf;

# Permitir encaminhamento pelo ssh-agent
echo "AllowAgentForwarding   yes" > /etc/ssh/sshd_config.d/inc-agent-forward.conf;

# Permitir encaminhamento de porta remota
echo "AllowTcpForwarding      yes" > /etc/ssh/sshd_config.d/inc-tcp-forward.conf;

# Permitir encaminhamento de servidor X11 por meio de conexao SHS
echo "X11Forwarding           yes" > /etc/ssh/sshd_config.d/inc-x11.conf;

# Permitir que o cliente especifique ips e portas para encaminhamento
echo "GatewayPorts clientspecified" > /etc/ssh/sshd_config.d/inc-gateway-ports.conf;

# Permitir que o cliente especifique IPs a escutar em portas remotas
echo "PermitListen            any" > /etc/ssh/sshd_config.d/inc-permit-listen.conf;

# Permitir abertura de terminal (necessario para usuario conseguir um shell)
echo "PermitTTY               yes" > /etc/ssh/sshd_config.d/inc-tty.conf;

# Permitir usar o SSH para fazer VPN
echo "PermitTunnel            yes" > /etc/ssh/sshd_config.d/inc-tunnel.conf;

# Nao exibir o ultimo login do usuario ao entrar no shell via SSH
echo "PrintLastLog             no" > /etc/ssh/sshd_config.d/inc-lastlog.conf;

# Desativar compressão de dados (shell mais responsivo)
echo "Compression              no" > /etc/ssh/sshd_config.d/inc-compression.conf;

# Nao consultar DNS reverso do ip do usuário no inicio da conexão
echo "UseDNS                   no" > /etc/ssh/sshd_config.d/inc-dns.conf;

# Especificar fingerprint de versão
echo "VersionAddendum    OpenSSH_11" >> /etc/ssh/sshd_config.d/inc-version.conf;

# Permitir que o root faça login usando senha
echo "PermitRootLogin          yes" >  /etc/ssh/sshd_config.d/inc-permit-root.conf;

# Permitir autenticação usando chave publica
echo "PubkeyAuthentication     yes" >  /etc/ssh/sshd_config.d/inc-pubkey.conf;

# Renegociar chaves simetricas a cada 1G transferido ou a cada 1h de sessão
echo "RekeyLimit              1G 1h" >  /etc/ssh/sshd_config.d/inc-rekey.conf;

# Tamanho ma­nimo da chave RSA aceita:
echo "RequiredRSASize          2048" >  /etc/ssh/sshd_config.d/inc-rsa-size.conf;

# Testar configuracao:
sshd -t -f /etc/ssh/sshd_config && { echo; echo CONFIG SSHD OK; echo; };

Opcional: Injetar chaves públicas de SSH para login e acesso remoto sem senha.

Bash
# Arquivo de chaves confiaveis
AKFILE="/root/.ssh/authorized_keys";

# Garantir existencia do arquivo:
mkdir -p /root/.ssh;
touch $AKFILE;

# Funcao para injetar chave de confianca sem duplicar
inject_key(){
    key_name="$1";
    key_type="$2";
    key_content="$3";
    egrep "$key_name" "$AKFILE" || {
        (
            echo;
            echo "$key_type $key_content $key_name";
            echo;
        ) >> "$AKFILE";
    };
};

# Chave de Patrick Brandao
pb_key_name="patrickbrandao@localhost";
pb_key_type="ssh-rsa";
pb_key_content="AAAAB3NzaC1yc2EAAAADAQABAAABAQCn5mH5RDQp3XUDCilcCJOmu41NQa9MddyOdUTbA8OPGexPFGVOSKMoY3Rg7f6jRmnVUNM5NPwRlQ+dgospiPT9zGzYf6MMB5lWiCgakshmUaub8X+tQrpOJhj17OjDZdwKhWhl38MUeXl8yD3MY/DM0WS66OMz3mB0W33PNm1q9pCNBQHNpErD9Au3aOOhDHekVqeUwKXg555VJJUZ/y+9f3oUZYJ8wHsoZYgbscQh89J4ouUkC4mXFLAk/KVO12hLSKnpTj8pIt76Slc6Ic/zvm6RFegcUNOeIoh/cm1j/l6RIL/s6b9i+WsLZPtwTFTZjI/2KnXXBZlqnt1QLXqt";

# - Injetar
inject_key "$pb_key_name" "$pb_key_type" "$pb_key_content";

1.5 – Servidor SNMP

O SNMP é vital para monitorar o servidor e acompanhar o uso de recursos.

Personalize as variáveis ADMIN, COMMUNITY e GPSLOCATION para seu caso.

Bash
# Instalar ferramentas SNMP
apk   add   net-snmp;
apk   add   net-snmp-tools;
apk   add   net-snmp-openrc;
apk   add   net-snmp-agent-libs;

# Ativar snmpd no boot
rc-update add snmpd default;

# Configuracao inicial - personalize as variaveis abaixo antes de colar:
ADMIN="Alpine-Docker";
COMMUNITY="AlpineVPS_2026";
GPSLOCATION="-19.956679287942922,-43.91383052250747"; # Pca Papa POP VBHZ
PORT=48161;
(
    echo;
    echo 'master agentx';
    echo 'agentXPerms 0777 0777';
    echo 'smuxpeer .1.3.6.1.2.1.83';
    echo 'smuxpeer .1.3.6.1.2.1.157';
    echo 'smuxsocket localhost';
    echo;
    echo "rocommunity $COMMUNITY";
    echo "rocommunity6 $COMMUNITY";
    echo;
    echo "syscontact \"$ADMIN\"";
    echo "syslocation $GPSLOCATION";
    echo "sysName $(hostname)";
    echo "SysDescr Debian-$(hostname)";
    echo;
    P=$PORT;
    echo "agentaddress unix:/run/snmpd.socket,udp:$P,udp6:$P,tcp6:$P,tcp:$P";
    echo;
    RS1='linkUpTrap linkUp ifIndex ifDescr ifType ifAdminStatus ifOperStatus';
    RS2='linkDownTrap linkDown ifIndex ifDescr ifType ifAdminStatus ifOperStatus';
    echo "notificationEvent $RS1";
    echo "notificationEvent $RS2";
    echo;
    echo 'monitor -r 10 -e linkUpTrap "Generate linkUp" ifOperStatus != 2';
    echo 'monitor -r 10 -e linkDownTrap "Generate linkDown" ifOperStatus == 2';
    echo;
    echo "com2sec notConfigUser  default       $COMMUNITY";
    echo 'group notConfigGroup v1 notConfigUser';
    echo 'group notConfigGroup v2c notConfigUser';
    echo;
    echo 'view    systemview           included      .1';
    echo;
    echo 'access notConfigGroup "" any noauth exact systemview none none';
    echo 'defaultMonitors yes';
    echo 'linkUpDownNotifications yes';
    echo;
) > /etc/snmp/snmpd.conf;

# Reiniciar:
service snmpd restart;

1.6 – Scripts pos-boot

A pasta /etc/local.d/ poderá ser usada para colocar scripts executáveis que serão automaticamente iniciados após o boot do Alpine.

Bash
# Ativar scripts em /etc/local.d/ durenate o boot
rc-update add local default;

1.7 – Limpeza automática de cache

O Linux tem o costume de utilizar a memória RAM livre para armazenar o máximo de blocos e arquivos para evitar a leitura de disco. Limpar diariamente faz com que o consumo de RAM do servidor fique sob controle.

Bash
# Criar script de limpeza de cache
(
    echo '#!/bin/bash';
    echo;
    echo '# Sincronizar escrita atrasada no disco';
    echo 'sync;';
    echo 'sync;';
    echo;
    echo '# Descarregar cache/buffer por disco';
    echo 'BLIST=$(lsblk -d -n -o NAME | sed "s/^/\/dev\//");';
    echo 'for bdev in $BLIST; do';
    echo '    blockdev --flushbufs $bdev 2>/dev/null;';
    echo 'done';
    echo;
    echo '# Limpar cache/buffer de RAM geral';
    echo 'echo 1 > /proc/sys/vm/drop_caches;';
    echo 'echo 2 > /proc/sys/vm/drop_caches;';
    echo 'echo 3 > /proc/sys/vm/drop_caches;';
    echo;
) > /usr/share/drop-cache.sh;
chmod +x /usr/share/drop-cache.sh;

# Colocar para rodar todo dia:
cp -rav /usr/share/drop-cache.sh /etc/periodic/daily/drop-cache;

# Executar imediatamente:
# - Conferir antes:
free -m;

# - Executar:
/usr/share/drop-cache.sh;

# - Conferir depois:
free -m;

1.8 – Tuning do kernel

Esta é a parte mais importante para a performance. O Linux opera, por padrão, usando configurações modestas para atender os hardwares mais fracos e PC, precisamos optimiza-lo para atuar como servidor:

Bash
# Liberar mais RAM para aceleração de rede
(
    echo  "net.core.rmem_default=31457280";
    echo  "net.core.wmem_default=31457280";
    echo  "net.core.rmem_max=134217728";
    echo  "net.core.wmem_max=134217728";
    echo  "net.core.netdev_max_backlog=250000";
    echo  "net.core.optmem_max=33554432";
    echo  "net.core.default_qdisc=fq";
    echo  "net.core.somaxconn=65535";
) > /etc/sysctl.d/051-net-core.conf;

# Aumentar capacidades de rede do protocolo TCP
(
    echo "net.ipv4.tcp_sack = 1";
    echo "net.ipv4.tcp_timestamps = 1";
    echo "net.ipv4.tcp_low_latency = 1";
    echo "net.ipv4.tcp_max_syn_backlog = 8192";
    echo "net.ipv4.tcp_rmem = 4096 87380 67108864";
    echo "net.ipv4.tcp_wmem = 4096 65536 67108864";
    echo "net.ipv4.tcp_mem = 6672016 6682016 7185248";
    echo "net.ipv4.tcp_congestion_control=htcp";
    echo "net.ipv4.tcp_mtu_probing=1";
    echo "net.ipv4.tcp_moderate_rcvbuf =1";
    echo "net.ipv4.tcp_no_metrics_save = 1";
)  >  /etc/sysctl.d/052-net-tcp-ipv4.conf;

# Ativar TCP-Fast-Open
(
    echo  "net.ipv4.tcp_fastopen=3";
)  >  /etc/sysctl.d/053-tcp-fast-open.conf;

# Ativar TCP-KeepAlive
(
    echo  "net.ipv4.tcp_keepalive_probes=9";
    echo  "net.ipv4.tcp_keepalive_intvl=75";
    echo  "net.ipv4.tcp_keepalive_time=7200";
)  >  /etc/sysctl.d/054-tcp-keepalive.conf;

# Aumentando a faixa de portas de origem (usar toda faixa de portas altas)
(
    echo "net.ipv4.ip_local_port_range=1024 65535";
) >  /etc/sysctl.d/056-port-range-ipv4.conf;

# TTL padrão dos pacotes IPv4
(
    echo "net.ipv4.ip_default_ttl=128";
) >  /etc/sysctl.d/062-default-ttl-ipv4.conf;


# Ajustes de ARP e fragmentacao (maior capacidade) - IPv4
(
    echo "net.ipv4.neigh.default.gc_interval = 30";
    echo "net.ipv4.neigh.default.gc_stale_time = 60";
    echo "net.ipv4.neigh.default.gc_thresh1 = 4096";
    echo "net.ipv4.neigh.default.gc_thresh2 = 8192";
    echo "net.ipv4.neigh.default.gc_thresh3 = 12288";
    echo;
    echo "net.ipv4.ipfrag_high_thresh=4194304";
    echo "net.ipv4.ipfrag_low_thresh=3145728";
    echo "net.ipv4.ipfrag_max_dist=64";
    echo "net.ipv4.ipfrag_secret_interval=0";
    echo "net.ipv4.ipfrag_time=30";
)  >  /etc/sysctl.d/063-neigh-ipv4.conf;

# Ajustes de ARP e fragmentacao (maior capacidade) - IPv6
(
    echo "net.ipv6.neigh.default.gc_interval = 30";
    echo "net.ipv6.neigh.default.gc_stale_time = 60";
    echo "net.ipv6.neigh.default.gc_thresh1 = 4096";
    echo "net.ipv6.neigh.default.gc_thresh2 = 8192";
    echo "net.ipv6.neigh.default.gc_thresh3 = 12288";
    echo;
    echo "net.ipv6.ip6frag_high_thresh=4194304";
    echo "net.ipv6.ip6frag_low_thresh=3145728";
    echo "net.ipv6.ip6frag_secret_interval=0";
    echo "net.ipv6.ip6frag_time=60";
)  >  /etc/sysctl.d/064-neigh-ipv6.conf;

# Ativar roteamento de pacotes IPv4
(
    echo  "net.ipv4.conf.default.forwarding=1"
)  >  /etc/sysctl.d/065-default-foward-ipv4.conf;

# Ativar roteamento de pacotes IPv6
(
    echo  "net.ipv6.conf.default.forwarding=1"
) >  /etc/sysctl.d/066-default-foward-ipv6.conf;

# Ativar roteamento em todas as interfaces de rede
echo  "net.ipv4.conf.all.forwarding=1"   >  /etc/sysctl.d/067-all-foward-ipv4.conf
echo  "net.ipv6.conf.all.forwarding=1"   >  /etc/sysctl.d/068-all-foward-ipv6.conf
echo  "net.ipv4.ip_forward=1"            >  /etc/sysctl.d/069-ipv4-forward.conf

# Aumentar capacidades de arquivos abertos
(
    echo "fs.file-max=2097152";
    echo "fs.aio-max-nr=3263776";
    echo "fs.mount-max=1048576";
    echo "fs.mqueue.msg_max=128";
    echo "fs.mqueue.msgsize_max=131072";
    echo "fs.mqueue.queues_max=4096";
    echo "fs.pipe-max-size=8388608";
)  >  /etc/sysctl.d/072-fs-options.conf;


# Nao usar SWAP enquanto houver memoria RAM livre
echo  "vm.swappiness=0"            >  /etc/sysctl.d/073-swappiness.conf;

# Usar mais RAM para priorizar metadados de sistema de arquivos
echo  "vm.vfs_cache_pressure=50"   >  /etc/sysctl.d/074-vfs-cache-pressure.conf;


# Flush escrita mais rápido
(
    echo "vm.dirty_ratio=5";
    echo "vm.dirty_background_ratio=2";
) > /etc/sysctl.d/075-dirty.conf;


# Flexibilizar a alocacao de RAM para alem dos limites reais
echo  "vm.overcommit_memory=1"     > /etc/sysctl.d/076-ram-overcommit.conf;

# Reiniciar o kernel apos 10 segundos em caso de pane geral
echo  "kernel.panic=10"            >  /etc/sysctl.d/081-kernel-panic.conf;

# Aumentar limite de threads por processo (vital para NODE.js e accel-ppp)
echo  "kernel.threads-max=1031306" >  /etc/sysctl.d/082-kernel-threads.conf;

# Aumentar limite de processos rodando paralelamente
echo  "kernel.pid_max=262144"      >  /etc/sysctl.d/083-kernel-pid.conf;

# Tamanho de buffer de mensagens de sistema (SYSCALL)
echo  "kernel.msgmax=327680"       >  /etc/sysctl.d/084-kernel-msgmax.conf;
echo  "kernel.msgmnb=655360"       >  /etc/sysctl.d/085-kernel-msgmnb.conf;
echo  "kernel.msgmni=32768"        >  /etc/sysctl.d/086-kernel-msgmni.conf;


# Conntrack
# Permitir ate 1 milhao de registros de NAT/Redirecionamento/CGNAT
(
    echo "net.nf_conntrack_max=1000000";  # padrao: 262144 (200k)
) >  /etc/sysctl.d/090-netfilter-max.conf;


# Aumentar tabela de controle da conntrack
(
    echo "net.netfilter.nf_conntrack_buckets=262144";
    echo "net.netfilter.nf_conntrack_checksum=1";
    echo "net.netfilter.nf_conntrack_events = 1";
    echo "net.netfilter.nf_conntrack_expect_max = 1024";
    echo "net.netfilter.nf_conntrack_timestamp = 0";
) >  /etc/sysctl.d/091-netfilter-generic.conf;


# Esquecer registros ICMP apos 30 segundos sem atividade
(
    echo "net.netfilter.nf_conntrack_icmp_timeout=30";
    echo "net.netfilter.nf_conntrack_icmpv6_timeout=30";
) >  /etc/sysctl.d/093-netfilter-icmp.conf;


# Esquecer registros TCP apos um tempo minimamente toleravel sem atividade
(
    echo "net.netfilter.nf_conntrack_tcp_be_liberal=0";
    echo "net.netfilter.nf_conntrack_tcp_loose=1";
    echo "net.netfilter.nf_conntrack_tcp_max_retrans=3";
    echo "net.netfilter.nf_conntrack_tcp_timeout_close=10";
    echo "net.netfilter.nf_conntrack_tcp_timeout_close_wait=10"; #60
    echo "net.netfilter.nf_conntrack_tcp_timeout_established=600"; #432000
    echo "net.netfilter.nf_conntrack_tcp_timeout_fin_wait=10"; #120
    echo "net.netfilter.nf_conntrack_tcp_timeout_last_ack=10"; #30
    echo "net.netfilter.nf_conntrack_tcp_timeout_max_retrans=60"; #300
    echo "net.netfilter.nf_conntrack_tcp_timeout_syn_recv=5"; #60
    echo "net.netfilter.nf_conntrack_tcp_timeout_syn_sent=5"; #60
    echo "net.netfilter.nf_conntrack_tcp_timeout_time_wait=30"; #120
    echo "net.netfilter.nf_conntrack_tcp_timeout_unacknowledged=300";
)  >  /etc/sysctl.d/094-netfilter-tcp.conf;


# Esquecer registros UDP apos 30 segundos sem atividade, 180s para stream
(
    echo "net.netfilter.nf_conntrack_udp_timeout=30";
    echo "net.netfilter.nf_conntrack_udp_timeout_stream=180";
)  >  /etc/sysctl.d/095-netfilter-udp.conf;


# Controle de fragmentacao de pacotes IPv6 (sim, existe!)
(
    echo "net.netfilter.nf_conntrack_frag6_high_thresh=4194304";
    echo "net.netfilter.nf_conntrack_frag6_low_thresh=3145728";
    echo "net.netfilter.nf_conntrack_frag6_timeout=60";
)  >  /etc/sysctl.d/099-netfilter-ipv6.conf;

# Comando (sysctl -p) requer tudo em um unico arquivo:
(
    echo "# NAO EDITAR";
    echo "# Gerado automaticamente via:";
    echo "# cat /etc/sysctl.d/*.conf > /etc/sysctl.conf";
    echo;
    cat /etc/sysctl.d/*.conf;
    echo;
) > /etc/sysctl.conf;

# Aplicar imediatamente:
sysctl -q --system  2>/dev/null;
sysctl -q -p        2>/dev/null;

1.7 – Interação com o hypervisor

O Alpine raramente é utilizado em baremetal (direto no hardware do servidor), logo, é recomendável ter contato com seu hypervisor:

Bash
# Instalar cliente de comunicacao com o hypervisor

# Agent de VMWARE, instalar se for virtualizado no
# VMware ESXi/vShere/Workstation/Fusion/Player
    IS_VMWARE=no;
    egrep -i vmware /sys/devices/virtual/dmi/id/bios_vendor && IS_VMWARE=yes;
    hostnamectl | grep -qi vmware && IS_VMWARE=yes;
    [ "$IS_VMWARE" = "yes" ] && {
        apk add open-vm-tools;
        rc-update add open-vm-tools default;
        service open-vm-tools start;
    };

# Agent de KVM, instalar somente se for virtualizado no
# kvm/q-emu/Proxmox PVE/oVirt
    IS_KVM=no;
    egrep -i kvm   /sys/devices/virtual/dmi/id/bios_vendor     && IS_KVM=yes;
    egrep -i qemu  /sys/devices/virtual/dmi/id/bios_vendor     && IS_KVM=yes;
    egrep -i qemu  /sys/devices/virtual/dmi/id/chassis_vendor  && IS_KVM=yes;
    [ "$IS_KVM" = "yes" ] && {
        apk add qemu-guest-agent;
        rc-update add qemu-guest-agent default;
        service qemu-guest-agent start;
    };

2 – Configuração de rede

O Alpine inicia a rede durante o boot por meio do arquivo /etc/network/interfaces mas cuidado, ele não suporta todos os argumentos como no Debian.

Recomendo sempre testar suas configurações em laboratório antes de aplicá-las remotamente por risco de perder acesso após reboots.

2.1 – Cliente DHCP

Exemplo de configuração para obter IP via DHCP (IPv4 apenas, padrão inicial):

/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

Exemplo de configuração para obter IP via DHCP (IPv4) e IPv6 via Slaac (ND-RD):

/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
    use ipv6-ra

2.2 – IP Fixo

Configuração de IP fixo é recomendada para servidores de todos os tipos.

/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 172.31.0.11
    netmask 255.255.255.0
    gateway 172.31.0.1

iface eth0 inet6 static
    address 2001:db8:f172:aa31::11
    netmask 64
    gateway 2001:db8:f172:aa31::1

2.3 – Configuração via script

Para todos os casos que a simples e limitada configuração do Alpine não atenda, use essa técnica para criar scripts que serão acionados durante o setup da interface.

Ccrie o scripts e tone-os executáveis, exemplo didático:

Bash
# Criar scripts
touch /etc/network/eth0-pre-up.sh;
touch /etc/network/eth0-post-up.sh;

# Tornar executaveis:
chmod +x /etc/network/eth0-pre-up.sh;
chmod +x /etc/network/eth0-post-up.sh;

# Instalar ethtook para ajustes na interface ethernet
which ethtool || apk add ethtool;

# Preenchendo scripts com exemplo de pre-configuracao e pos-configuracao:
# - pre-up, ajustar internamente a interface
(
    echo '#!/bin/sh';
    echo;
    echo '# Habilitar multiqueue na interface';
    echo 'ethtool -L eth0 combined 4;';
    echo;
    echo 'exit 0;';
    echo;
) > /etc/network/eth0-pre-up.sh;

# - post-up, definir configuracoes operacionais
(
    echo '#!/bin/sh';
    echo;
    echo '# Ativar interface';
    echo 'ip link set up dev eth0;';
    echo;
    echo '# Config IPv4';
    echo 'ip -4 address add 172.31.0.11/24 dev eth0;';
    echo 'ip -4 route add 0.0.0.0/0 via 172.31.0.1 proto static;';
    echo;
    echo '# Config IPv6';
    echo 'ip -6 address add 2001:db8:f172:aa31::11/64 dev eth0;';
    echo 'ip -6 route add 0.0.0.0/0 via 2001:db8:f172:aa31::1 proto static;';
    echo;
    echo 'exit 0;';
    echo;
) > /etc/network/eth0-post-up.sh;

Configure a interface como “manual” e especifique o caminho completo dos scripts:

/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual
    pre-up   /etc/network/eth0-pre-up.sh
    post-up  /etc/network/eth0-post-up.sh

3 – FRR

O FRR é um software de roteamento dinâmico que implementa os principais protocolos como RIP, OSPF, BGP e BABEL.

Instale somente se precisar desses protocolos.

Bash
# Instalar FRR
apk add frr;
apk add frr-rpki;
apk add frr-snmp;
apk add frr-pythontools;

# Ativar durante o boot:
rc-update add frr default;

# Ativar servicos de roteamento basicos:
sed -i 's/bgpd=no/bgpd=yes/'       /etc/frr/daemons;
sed -i 's/ospfd=no/ospfd=yes/'     /etc/frr/daemons;
sed -i 's/ospf6d=no/ospf6d=yes/'   /etc/frr/daemons;
sed -i 's/pimd=no/pimd=yes/'       /etc/frr/daemons;
sed -i 's/pim6d=no/pim6d=yes/'     /etc/frr/daemons;
sed -i 's/babeld=no/babeld=yes/'   /etc/frr/daemons;
sed -i 's/pbrd=no/pbrd=yes/'       /etc/frr/daemons;
sed -i 's/bfdd=no/bfdd=yes/'       /etc/frr/daemons;

# Reiniciar para ligar servicos ativados:
service frr restart;

# Criar comando no sistema: show (repassar para FRR VTYSH)
(
    echo '#!/bin/sh';
    echo;
    echo '[ "x$1" = "x" ] && exit 1';
    echo 'cmd="show $@"';
    echo 'vtysh -c "$cmd"';
    echo;
) > /usr/bin/show;
chmod +x /usr/bin/show;

4 – Docker

O Docker permite rodar containers, instale apenas se precisar.

Bash
# Instalar Docker
apk add docker;

# Ativar no boot
rc-update add docker default;

# Reiniciar:
service docker restart;

Criar comandos de atalhos:

Bash
# Comando para parar e destruir um container:
(
    echo '#!/bin/sh';
    echo;
    echo 'for x in $@; do';
    echo '    echo -n "Stop and delete [$1] ";';
    echo '    docker stop $x 2>/dev/null 1>/dev/null;'
    echo '    echo -n ".";';
    echo '    docker stop $x 2>/dev/null 1>/dev/null;'
    echo '    echo -n ".";';
    echo '    docker rm -f $x 2>/dev/null 1>/dev/null;'
    echo '    echo -n ".";';
    echo '    echo "OK";';
    echo 'done';
    echo;
) > /usr/bin/undocker;
chmod +x /usr/bin/undocker;


# Comando para entrar no shell (/bin/sh ou comando informado) de um container:
(
    echo '#!/bin/sh';
    echo;
    echo 'cmd="$2";';
    echo '[ "x$cmd" = "x" ] && cmd="bash"';
    echo 'docker exec --user=root -it $1 $cmd;';
    echo;
) > /usr/bin/dsh;
chmod +x /usr/bin/dsh;


# Comando para inspecionar container
(
    echo '#!/bin/sh';
    echo;
    echo 'which jq 2>/dev/null 1>/dev/null;';
    echo 'jqfound="$?";';
    echo 'if [ "$jqfound" = "0" ]; then';
    echo '    docker inspect $1 | jq;';
    echo 'else';
    echo '    docker inspect $1;';
    echo 'fi;';
    echo;
) > /usr/bin/di;
chmod +x /usr/bin/di;


# Comando para visualizar logs do container
(
    echo '#!/bin/sh';
    echo;
    echo 'docker logs $1;';
    echo;
) > /usr/bin/dlog;
chmod +x /usr/bin/dlog;


# Comando para visualizar logs do container em tempo real
(
    echo '#!/bin/sh';
    echo;
    echo 'docker logs -f $1;';
    echo;
) > /usr/bin/dtail;
chmod +x /usr/bin/dtail;


# Comando para listar containers em execucao (inclusive parados):
(
    echo '#!/bin/sh';
    echo;
    echo 'EXTRA="";';
    echo '[ "x$1" = "x" ] || EXTRA="-f name=$1";';
    echo 'echo;';
    echo 'docker ps -a $EXTRA;';
    echo 'echo;';
    echo;
) > /usr/bin/dps;
chmod +x /usr/bin/dps;


# Parar containers por busca no nome
(
    echo '#!/bin/sh';
    echo;
    echo 'FIND="$1";';
    echo '[ "x$FIND" = "x" ] && FIND="foobar";';
    echo 'echo;';
    echo 'docker ps -a | egrep "$FIND";';
    echo "didlist=\$(docker ps -a | egrep "\$FIND" | awk '{print \$1}');";
    echo 'for did in $didlist; do docker stop $did; done;';
    echo 'echo;';
    echo;
) > /usr/bin/dstop;
chmod +x /usr/bin/dstop;


# Iniciar containers por busca no nome
(
    echo '#!/bin/sh';
    echo;
    echo 'FIND="$1";';
    echo '[ "x$FIND" = "x" ] && FIND="foobar";';
    echo 'echo;';
    echo 'docker ps -a | egrep "$FIND";';
    echo "didlist=\$(docker ps -a | egrep "\$FIND" | awk '{print \$1}');";
    echo 'for did in $didlist; do docker start $did; done;';
    echo 'echo;';
    echo;
) > /usr/bin/dstart;
chmod +x /usr/bin/dstart;


# Deletar containers por busca no nome
(
    echo '#!/bin/sh';
    echo;
    echo 'FIND="$1";';
    echo '[ "x$FIND" = "x" ] && FIND="foobar";';
    echo 'echo;';
    echo 'docker ps -a | egrep "$FIND";';
    echo "didlist=\$(docker ps -a | egrep "\$FIND" | awk '{print \$1}');";
    echo 'for did in $didlist; do';
    echo '    docker stop $did; docker rm $did; docker rm -f $did;';
    echo 'done 2>/dev/null;';
    echo 'echo;';
    echo;
) > /usr/bin/ddelete;
chmod +x /usr/bin/ddelete;


# Lista simples de containers (sem portas estragando a listagem)
(
    echo '#!/bin/sh';
    echo;
    echo 'EXTRA="";';
    echo 'ONLY_RUNNING=yes;';
    echo '[ "x$1" = "x" ] || {';
    echo '    EXTRA="-f name=$1";';
    echo '    ONLY_RUNNING="no";';
    echo '};';
    echo 'CLS1="{{.ID}}\t{{.Names}}\t{{.Networks}}";';
    echo 'CLS2="\t{{.Status}}\t{{.Size}}\t{{.Image}}";';
    echo 'COLS="table $CLS1\t$CLS2";';
    echo 'echo;';
    echo 'if [ "$ONLY_RUNNING" = "yes" ]; then';
    echo '    docker ps --format "$COLS" $EXTRA;';
    echo 'else';
    echo '    docker ps -a --format "$COLS" $EXTRA;';
    echo 'fi;';
    echo 'echo;';
    echo;
) > /usr/bin/dlist;
chmod +x /usr/bin/dlist;

Opcional: Tornar o usuário “suporte” em administrador do Docker:

Bash
# Colocar usuario 'suporte' no grupo 'docker'
addgroup suporte docker;

5 – Finalizando

Vamos conferir e dar os toques finais.

Serviços em uso:

Bash
# Listar scripts e servicos executados no boot:
rc-status --list;
rc-status --manual;
rc-status --crashed;

Criar banner Alpine (Opcional, apenas para efeitos estéticos):

Bash
# Limpar banners
echo -n > /etc/issue;
echo -n > /etc/motd;

# Preencher banner pos-login
(
    echo;
    echo;
    echo '        d8888  888            d8b';
    echo '       d88888  888            Y8P';
    echo '      d88P888  888';
    echo '     d88P 888  888  88888b.   888  88888b.    .d88b.';
    echo '    d88P  888  888  888 "88b  888  888 "88b  d8P  Y8b';
    echo '   d88P   888  8A8  8T8  8R8  8I8  8C8  8K8  88B88888';
    echo '  d8888888888  888  888 d88P  888  888  888  Y8b.';
    echo ' d88P     888  888  88888P"   888  888  888   "Y8888';
    echo '                    888';
    echo '                    888';
    echo '                    888';
    echo
    echo
) > /etc/motd

Volte sempre, o tutorial é um bloco de notas Alpine que incremento a cada novidade ou update.

O orgulhoso prefere perder-se
a perguntar qual é o seu caminho.
Winston Churchill

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com