Durante um bom tempo, consumi tutoriais de homelab com a vontade de montar o meu. Canais de tech como Diolinux e TechHut vivem mostrando projetos incríveis, e a ideia de ter meu próprio ecossistema sempre me fascinou. O assunto furou tanto a bolha que virou uma verdadeira febre nos últimos anos.
Só que manter um servidor físico em casa, lidando com roteador bloqueado de provedor, sem IP fixo e equipamento ligado 24/7 fugia dos meus planos. Por mais que seja legal demais brincar com um Raspberry Pi ou reciclar um celular (já rodei o AdGuard Home num android antigo), eu queria uma parada limpa, sem puxar cabos e sem mais um equipamento piscando na minha mesa.
A alternativa foi buscar um laboratório “de verdade” na nuvem. O objetivo era ter um ambiente prático para estudar redes, Docker e deploy, mas sem precisar investir em hardware dedicado.
Então descobri que a Oracle Cloud tem um nível gratuito que é bom demais pra ser verdade: uma VM com até 24GB de RAM e 4 núcleos ARM ou 1GB de RAM e 1 núcleo x86 (que é a que estou usando), 200GB de disco e IP público fixo. Tudo 100% gratuito. Parece até post patrocinado, mas é apenas um serviço bom demais mesmo. Resolvi testar. Algumas horas depois, eu tinha um servidor pessoal completo rodando na nuvem, com HTTPS, domínio próprio e vários serviços organizados num painel bem maneiro que virou, de fato, a minha homepage.
Esse post documenta tudo o que fiz, do zero até o ambiente rodando em produção.
O que você vai ter no final
- Um servidor Ubuntu na Oracle Cloud (grátis)
- IP público fixo com domínio via DuckDNS
- Docker gerenciando todos os serviços
- Nginx Proxy Manager com SSL automático (HTTPS em tudo)
Os seguintes serviços rodando:
- Homepage — painel central com links pra tudo - extremamente personalizável, a homepage perfeita e definitiva.
- FileBrowser — interface web intuitiva para gerenciar arquivos diretamente no servidor.
- Jellyfin — servidor de vídeo para cursos, filmes, séries e animes. Ele salva seu histórico e onde você parou; excelente para assistir suas aulas em qualquer lugar. Ele funciona como um Netflix pessoal, você assiste os vídeos direto do navegador! Apenas cuidado com o limite de 200GB e lembre-se de desabilitar o transcoding na VM.Standard.E2.1.Micro.
- Navidrome — streaming de músicas (Spotify pessoal, sem anúncios, sem lag, com apps clients extremamente bons para android e iOS, uso Navisonic)
- Memos — bloco de notas rápido Em vez de se expor ou se estressar no X, guarde seus pensamentos aqui e faça anotações. O app é incrível e permite criar contas para outras pessoas também.
- Actual Budget — controle financeiro pessoal direto, simples e robusto. É um absurdo uma ferramenta dessas ser free.
- Kavita — o melhor leitor de mangás, livros e PDFs que existe. Você terá seu próprio “Kindle” ou “Playbooks” que sincroniza em qualquer lugar.
Actual
Home
Jellyfin
Kavita
Memos
Navidrome
Sinta-se livre para adicionar o serviço que quiser via docker. Esses foram selecionados ao meu gosto para atender minhas necessidades. Como verá a seguir, é bem simples e basta replicar os passos para o serviço desejado. Você pode ter o Adguard Home, PiHole, Wordpress, diversas coisas, só respeitar os limites do servidor.
Parte 1 - Criando a VM na Oracle Cloud
Criando a instância
Crie uma conta Always Free na Oracle Cloud, é bem simples e valide a conta com o seu cartão, nada será cobrado. Entre no painel da Oracle e vá em Compute > Instances > Create Instance.
Nas configurações:
- Name: escolha qualquer nome (
homelab-server, por exemplo) - Image: altere para Ubuntu 22.04 ou 24.04 (Usei 22.04)
- Shape: aqui está a parte interessante. Você tem duas opções gratuitas:
VM.Standard.E2.1.Micro— AMD, 1GB RAM. Funciona, mas é limitada. (Tudo que eu fiz aqui foi nela.)VM.Standard.A1.Flex— ARM, até 24GB RAM e 4 OCPUs. Essa é a escolha certa se você vai querer instalar muitos outros serviços. Muito potente, absurda.
Ambas têm a tag “Always Free”, mas a A1 pode não estar disponível em todas as regiões imediatamente. Se aparecer indisponível, tente criar novamente algumas horas depois, pois costuma liberar. No meu caso, não liberou de imediato, então montei toda essa estrutura na Standard E2.1.Micro mesmo e ela me atendeu super bem. A dica é: não fique bitolado com isso.
- Networking: deixe no padrão. A Oracle cria a rede automaticamente.
- SSH keys: clique em Save private key e guarde esse arquivo
.key. Sem ele, você perde o acesso ao servidor para sempre. Você também pode gerar uma chave SSH e usar ela. - Boot Volume: marque Specify a custom boot volume size e coloque 200 GB. Esse é o limite gratuito — faça isso agora para não precisar expandir pelo terminal depois.
Clique em Create e aguarde o ícone ficar verde.
Fixando o IP público
Por padrão, a Oracle dá um IP “efêmero” que pode mudar se a VM reiniciar. Para usar domínios (DNS), você precisa de um IP fixo (até dá pra configurar um update automático, mas se temos o fixo pra quê se preocupar com isso, não é mesmo? Vamos aproveitar!).
- Vá em Networking > IP Management > Reserved Public IPs
- Clique em Reserve Public IP Address, dê um nome e reserve. Anote esse IP.
- Volte para a sua instância, role para baixo e clique em Attached VNICs
- Clique na VNIC principal > IPv4 Addresses
- Ao lado do IP atual, clique nos três pontos > Edit
- Selecione No public IP e salve (isso remove o IP temporário)
- Abra o edit novamente, selecione Reserved public IP, escolha o que você criou e salve
Pronto. Seu servidor agora tem um IP permanente.
Abrindo as portas no firewall da nuvem
A Oracle bloqueia tudo por padrão, exceto a porta 22 (SSH). Precisamos abrir as portas 80 e 443 para o tráfego web.
Vá novamente em Instances, clique na sua instância, em Instance details clique no link da sua Virtual Cloud Network (VCN), depois em Subnets e no link da sua Subnet pública, depois Security e no link da Default Security List.
Clique Security Rules e em Add Ingress Rules e configure:
| Campo | Valor |
|---|---|
| Source Type | CIDR |
| Source CIDR | 0.0.0.0/0 |
| IP Protocol | TCP |
| Destination Port Range | 80,443,81,8080 |
| Description | Nginx Proxy Manager |
Salve. Por questão de segurança, deixe apenas essas quatro portas abertas na nuvem — os serviços internos (Jellyfin, Navidrome etc.) serão roteados pelo Nginx e não precisam ficar expostos diretamente. Depois de toda a configuração e tudo roteado pelo Nginx, precisamos voltar aqui e excluir a porta 8080 e 81. Sem pontas soltas.
Detalhes dos Recursos Always Free: VM.Standard.A1.Flex ARM: Até 4 instâncias com um total de 4 OCPUs e 24 GB de RAM. VM.Standard.E2.1.Micro x86: 2 instâncias, cada uma com 1 OCPU e 1 GB de RAM. Armazenamento: Máximo total de 200 GB para volumes de blocos (total entre as VMs).
Parte 2 — Preparando o Ubuntu
Primeiro acesso via SSH
Abra o terminal (PowerShell no Windows funciona bem) na pasta onde você salvou o arquivo .key:
ssh -i sua-chave.key ubuntu@SEU_IP_FIXO
Na primeira vez vai perguntar se você confia no servidor. Digite yes e dê Enter. Você está dentro.
Atualizando o sistema
Regra de ouro antes de instalar qualquer coisa:
sudo apt update && sudo apt upgrade -y
Criando o Swap de Emergência
Como o servidor tem RAM limitada, criar uma memória virtual (Swap) no disco evita que o sistema encerre seus containers de surpresa. Se você conseguiu pegar a VM com 24GB de RAM você pode pular isso aqui.
Execute os comandos abaixo para criar 2GB de Swap, aplicar a segurança necessária, ativá-lo e garantir que ele inicie junto com o servidor:
# 1. Cria o arquivo de 2GB e tranca as permissões
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
# 2. Formata e liga o Swap em tempo real
sudo mkswap /swapfile
sudo swapon /swapfile
# 3. Salva a configuração para ser permanente após reboots
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Dica: Digite
free -hpara confirmar se o seu Swap já está ativo.
Instalando o FileBrowser
O FileBrowser é uma interface web para gerenciar arquivos no servidor — você vai usá-lo para criar e editar os arquivos de configuração sem precisar ficar no terminal. Vamos instalá-lo como serviço do sistema para que suba automaticamente com o servidor.
# Instala o FileBrowser
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
# Cria a pasta principal do homelab
mkdir ~/homelab
# Cria o serviço systemd
sudo bash -c 'cat <<EOF > /etc/systemd/system/filebrowser.service
[Unit]
Description=Filebrowser
After=network.target
[Service]
User=ubuntu
ExecStart=/usr/local/bin/filebrowser -r /home/ubuntu -a 0.0.0.0 -p 8080
Restart=always
[Install]
WantedBy=multi-user.target
EOF'
# Ativa e inicia
sudo systemctl daemon-reload
sudo systemctl enable filebrowser
sudo systemctl start filebrowser
O FileBrowser estará rodando em segundo plano na porta 8080.
Instalando o Docker
# Baixa e executa o instalador oficial
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Dá permissão ao usuário ubuntu para usar o Docker sem sudo
sudo usermod -aG docker ubuntu
Importante: para a permissão funcionar, saia do servidor (exit) e entre novamente via SSH.
Liberando portas no firewall interno
O painel da Oracle já está configurado, mas o Ubuntu tem seu próprio firewall (iptables) que também bloqueia portas. Abra as que vamos usar:
sudo iptables -I INPUT 1 -p tcp -m multiport --dports 80,443,81,3000,4533,5000,5006,5230,8080,8096 -j ACCEPT
# Salva a regra para persistir após reinicializações
sudo netfilter-persistent save
Aproveita e já testa o FileBrowser na URL http://SEU_IP_FIXO:8080!
Parte 3 — Domínio, Docker Compose e SSL
Configurando o domínio com DuckDNS
Acesse duckdns.org, faça login e crie um subdomínio (por exemplo: meuservidor.duckdns.org). Aponte esse domínio para o seu IP fixo da Oracle.
O DuckDNS suporta wildcard DNS nativamente, o que significa que qualquer prefixo (arquivos.meuservidor.duckdns.org, videos.meuservidor.duckdns.org) já aponta automaticamente para o mesmo IP, sem configuração adicional.
Criando as pastas de mídia
mkdir ~/musicas ~/videos ~/livros
sudo chown -R ubuntu:ubuntu ~/musicas ~/videos ~/livros
sudo chmod -R 755 ~/musicas ~/videos ~/livros
O arquivo docker-compose.yml
Acesse o FileBrowser pelo navegador em http://SEU_IP:8080, entre na pasta homelab e crie um arquivo chamado docker-compose.yml com o conteúdo abaixo:
version: '3.8'
services:
# Proxy reverso e gerador de SSL
nginx-proxy:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy
restart: unless-stopped
ports:
- "80:80"
- "81:81"
- "443:443"
volumes:
- ./npm-data:/data
- ./npm-letsencrypt:/etc/letsencrypt
# Painel central (dashboard) - ATENÇÃO! VOCÊ PRECISA EDITAR AQUI!!!
# Altere o meuservidor.duckdns.org para o endereço real do seu servidor.
# Pode testar com o IP:3000 primeiro.
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- ./homepage-config:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro
- /:/hostfs:ro
environment:
- HOMEPAGE_ALLOWED_HOSTS=meuservidor.duckdns.org,SEU_IP_FIXO,SEU_IP_FIXO:3000
memos:
image: ghcr.io/usememos/memos:latest
container_name: memos
restart: unless-stopped
ports:
- "5230:5230"
volumes:
- ./memos-data:/var/opt/memos
navidrome:
image: deluan/navidrome:latest
container_name: navidrome
restart: unless-stopped
ports:
- "4533:4533"
environment:
ND_LOGLEVEL: info
volumes:
- ./navidrome-data:/data
- /home/ubuntu/musicas:/music:ro
jellyfin:
image: lscr.io/linuxserver/jellyfin:latest
container_name: jellyfin
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
- TZ=America/Sao_Paulo
ports:
- "8096:8096"
volumes:
- ./jellyfin-config:/config
- /home/ubuntu/videos:/data/videos:ro
actual_server:
image: actualbudget/actual-server:latest
container_name: actual
restart: unless-stopped
ports:
- "5006:5006"
environment:
- ACTUAL_PORT=5006
volumes:
- ./actual-data:/data
kavita:
image: jvmilazz0/kavita:latest
container_name: kavita
restart: unless-stopped
environment:
- TZ=America/Sao_Paulo
ports:
- "5000:5000"
volumes:
- ./kavita-data:/kavita/config
- /home/ubuntu/livros:/kavita/data/livros
Lembre de substituir
meuservidor.duckdns.orgpelo seu domínio real no campoHOMEPAGE_ALLOWED_HOSTS.
Se você tiver algum problema para salvar esse arquivo com o FileBrowser, teste rodar o seguinte comando via SSH:
sudo chown -R ubuntu:ubuntu ~/homelab
chmod -R 755 ~/homelab
Subindo tudo
De volta ao terminal SSH:
cd ~/homelab
docker compose up -d
O Docker vai baixar todas as imagens e iniciar os containers em segundo plano. Na primeira vez pode demorar alguns minutos dependendo da velocidade de download.
Configurando o Nginx Proxy Manager (SSL)
Acesse o painel do NPM em http://SEU_IP:81.
Login padrão: admin@example.com / changeme — troque a senha imediatamente após o primeiro acesso.
Vá em Hosts > Proxy Hosts > Add Proxy Host e crie uma entrada para cada serviço. Em todos eles, vá na aba SSL, selecione “Request a new SSL Certificate” e ative Force SSL.
Conceito importante antes de configurar
Serviços que rodam dentro do Docker (Jellyfin, Memos, Navidrome etc.) devem usar o nome do container como Forward Hostname, pois estão na mesma rede virtual do Nginx.
O FileBrowser é uma exceção — ele foi instalado diretamente no Ubuntu (fora do Docker), então o Nginx precisa usar o IP privado do servidor para encontrá-lo. Atenção: é o privado, não o público aqui. Como vamos bloquear a porta 8080, o Nginx vai usar o próprio IP da máquina para encontrar o FileBrowser e fazer o roteamento. O ip privado na Oracle geralmente se parece com 10.0.0.X. Esse IP não muda nunca enquanto a VM existir.
Tabela de configuração dos hosts
| Serviço | Domain Names | Forward Hostname | Forward Port |
|---|---|---|---|
| Homepage | meuservidor.duckdns.org |
homepage |
3000 |
| FileBrowser | arquivos.meuservidor.duckdns.org |
SEU_IP_PRIVADO |
8080 |
| Jellyfin | videos.meuservidor.duckdns.org |
jellyfin |
8096 |
| Navidrome | musicas.meuservidor.duckdns.org |
navidrome |
4533 |
| Memos | notas.meuservidor.duckdns.org |
memos |
5230 |
| Actual Budget | financas.meuservidor.duckdns.org |
actual |
5006 |
| Kavita | livros.meuservidor.duckdns.org |
kavita |
5000 |
Você deve inserir essas informações dentro de Details em Edit Proxy Host. O Domain Name para cada serviço, o Scheme é http para todos, o forward Hostname conforme na tabela e a Forward Port. Em options ainda em Details marque as 3 caixinhas de Cache Assets, Block Common Exploits e Websockets Support.
Depois de salvar cada host, o NPM vai requisitar o certificado SSL automaticamente via Let’s Encrypt. Em poucos segundos cada serviço estará acessível via HTTPS.
Parte 4 — Finalizando com o painel Homepage e Segurança
Acesse o FileBrowser (agora em https://arquivos.meuservidor.duckdns.org), navegue até homelab/homepage-config e edite o arquivo services.yaml:
- Meu Servidor:
- Arquivos:
icon: filebrowser.png
href: https://arquivos.meuservidor.duckdns.org
description: Gerenciador de Arquivos
- Videos:
icon: jellyfin.png
href: https://videos.meuservidor.duckdns.org
description: Plataforma de Vídeos
- Biblioteca:
icon: kavita.png
href: https://livros.meuservidor.duckdns.org
description: Mangás, Livros e PDFs
- Músicas:
icon: navidrome.png
href: https://musicas.meuservidor.duckdns.org
description: Servidor de Músicas
- Finanças:
icon: actualbudget.png
href: https://financas.meuservidor.duckdns.org
description: Controle Orçamentário
- Anotações:
icon: memos.png
href: https://notas.meuservidor.duckdns.org
description: Notas Rápidas
Agora o arquivo settings.yaml:
title: "Meu Server"
theme: dark
color: zinc
# Configuração do Papel de Parede
background:
image: "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=2564&auto=format&fit=crop" # Link para qualquer papel de parede
blur: "sm" # Desfoque leve
brightness: "50" # Escurece a imagem para destacar os botões
# Força os links a ficarem em linha (lado a lado)
layout:
Meu Servidor:
style: row
columns: 3
# Limpeza visual
hideVersion: true
E pra dar um estilozinho bacana para sua página Home, vamos colocar uns widgets para monitorar cpu, memória e disco no arquivo widgets.yaml:
- resources:
cpu: true
memory: true
disk: /hostfs
- search:
provider: duckduckgo
target: _blank
Salve e atualize a página principal do seu domínio. Tudo organizado, tudo com HTTPS, tudo de graça.
Fechando Portas
Volte para as Ingress Rules (Se não lembra como, verifique novamente essa sessão) e delete as portas extras que abrimos, mantenha apenas a 22, os serviços de ICMP, a 80 e a 443.
Túnel SSH
O painel do Nginx Proxy Manager agora não será mais acessível por ninguém. Se você precisar acessar ele, você pode acessar com um túnel via SSH. É a opção mais recomendada para não deixar o painel aberto para a web.
ssh -i sua-chave.key -L 8081:localhost:81 ubuntu@SEU_IP_FIXO
Note que é quase o mesmo comando para acessar o servidor via SSH, apenas com o comando -L 8081:localhost:81 no meio, que é a criação do túnel. Com essa janela aberta, você consegue acessar o Nginx Proxy Manager direto no seu PC pela URL localhost:8081. Quando fechar a janela, o túnel se fecha.
Considerações finais
O que mais me surpreendeu nesse projeto foi a relação custo-benefício da Oracle Cloud Free Tier. A VM A1 com ARM é absurda de poderosa para uso pessoal, roda todos esses serviços simultâneos easy e você pode facilmente adicionar outros incríveis que existem, só adicionar mais algumas linhas no arquivo do docker, subir no Nginx e atualizar a homepage!
A VM.Standard.E2.1.Micro que é a que eu estou usando também não ficou pra trás! Parece muito pouco (1 núcleo e 1 GB de RAM), mas como não executamos nenhuma GUI e o Ubuntu 22.04 é bem leve, ela entrega tudo. Chego perto do limite, mas nunca tive problema nenhum. Na real, ainda sobram 300 MB de RAM, às vezes mais! Só uma dica importante: se for usar o Jellyfin nessa máquina, desative a transcodificação. E não deixe de criar o swap.
Alguns pontos e coisas que aprendi no processo:
- Segurança: Deixe apenas as portas 80 e 443 abertas no firewall da Oracle. Nunca exponha diretamente as portas dos serviços (8096, 4533 etc.) — o Nginx cuida disso.
- Backups: Os dados dos containers ficam nas subpastas dentro de
~/homelab(npm-data, jellyfin-config, navidrome-data etc.). Para fazer backup, basta comprimir essa pasta inteira e guardar em algum lugar seguro. Odocker compose up -drecria tudo a partir dessas pastas. - Escalabilidade: A arquitetura com Docker Compose é modular. Quer adicionar um novo serviço? Basta incluir um novo bloco no
docker-compose.yml, rodardocker compose up -dnovamente e criar mais uma entrada no Nginx. Sem reinstalações, sem conflitos. - Filebrowser: Deixei o Filebrowser fora do Docker Compose de propósito durante a instalação. Queria testar e ajustar tudo na mão enquanto configurava. Mas ele pode ser facilmente adicionado via Docker também — é só incluir o bloco no docker-compose.yml que roda tranquilamente.
No fim, saí de “queria montar um homelab” para um servidor real, com domínio, SSL e sete serviços rodando, sem gastar nada. Valeu cada minuto!
Tem dúvida ou sugestão? Me manda uma mensagem.