☰
02.11.2026

Como executar o Jupyter Notebook em um VPS para projetos acadêmicos

Introdução

O Jupyter Notebook é uma das ferramentas mais usadas em disciplinas de programação, ciência de dados, estatística e aprendizado de máquina. Ele permite misturar código, texto explicativo, fórmulas e gráficos em um único documento, o que facilita entregar trabalhos, montar relatórios de laboratório e apresentar resultados para o orientador.

O problema aparece quando o projeto cresce. O notebook do laptop trava ao carregar um dataset de alguns gigabytes, o treino de um modelo ocupa a máquina a noite inteira e o grupo do TCC precisa acessar o mesmo ambiente de lugares diferentes. Além disso, cada integrante costuma ter versões diferentes de Python e bibliotecas, e o código que roda em um computador quebra no outro.

Uma solução simples é instalar o Jupyter em um servidor virtual (VPS). O ambiente fica disponível 24 horas por dia, pode ser acessado de qualquer computador pelo navegador e não depende do estado do seu laptop. Neste artigo, vamos explicar como o Jupyter funciona, quais configurações de servidor fazem sentido para projetos acadêmicos e, passo a passo, como instalar o Jupyter Notebook em um VPS com Ubuntu, protegê-lo com senha e acessá-lo com segurança.

Termos principais

Como o Jupyter funciona

Quando você executa jupyter notebook, o processo do Jupyter Server começa a escutar em uma porta HTTP, por padrão a 8888. O navegador carrega a interface web, e cada notebook aberto inicia um kernel separado no servidor. O código que você digita na célula é enviado ao kernel por WebSocket, executado lá, e o resultado (texto, tabela ou gráfico) volta para o navegador.

Isso significa que todo o processamento acontece no servidor. O navegador apenas exibe a interface. Por isso, o mesmo notebook pode ser aberto de um laptop simples, de um computador da biblioteca da universidade ou de um tablet, e o cálculo continua usando a CPU e a memória do VPS.

Por que o Jupyter não deve ficar exposto sem proteção

Um notebook dá acesso a execução de código arbitrário com os privilégios do usuário que iniciou o Jupyter. Se o servidor ficar aberto na internet sem senha, qualquer pessoa que encontrar o endereço consegue rodar comandos no seu VPS. Por isso, nesta instrução seguimos três regras:

Cenários de uso em projetos acadêmicos

Trabalho individual com datasets grandes

Um VPS com 4 a 8 GB de RAM carrega tabelas de milhões de linhas com pandas sem travar o computador pessoal. Você inicia o processamento, fecha o navegador e volta mais tarde: o kernel continua rodando no servidor.

TCC ou projeto em grupo

O grupo usa um único ambiente com as mesmas versões de bibliotecas. Os notebooks ficam em uma pasta no servidor, de preferência versionada com Git. Isso elimina o clássico “na minha máquina funciona”.

Monitoria e aulas práticas

Monitores e professores podem preparar um ambiente pronto com os pacotes da disciplina e compartilhar o acesso com a turma para exercícios curtos, sem pedir que cada aluno instale Python localmente.

Qual configuração escolher

Tipo de projeto vCPU RAM Disco
Exercícios, listas de disciplina, gráficos simples 1 2 GB 20–30 GB
Análise de dados com pandas, datasets de até alguns GB 2 4 GB 40–60 GB
Machine learning clássico (scikit-learn), projeto em grupo 4 8 GB 80 GB ou mais

Esses números são um ponto de partida. A vantagem da nuvem é que dá para começar com uma configuração menor e aumentar os recursos quando o projeto exigir. Para testar, você pode criar um VPS na nuvem Serverspace com Ubuntu em poucos minutos.

Instalação passo a passo

A seguir, usamos Ubuntu 24.04 LTS. Os comandos também funcionam no Ubuntu 22.04 e no Debian 12 com pequenas diferenças nas versões dos pacotes. Supomos que você tem o IP do servidor e acesso SSH como root ou como usuário com sudo.

Passo 1. Conecte-se ao servidor e atualize o sistema

No terminal do seu computador (no Windows 10 e 11 o PowerShell já tem cliente SSH), conecte-se ao VPS:

ssh root@IP_DO_SERVIDOR

Atualize a lista de pacotes e os pacotes instalados:

apt update && apt upgrade -y

Passo 2. Crie um usuário para o Jupyter

Rodar o Jupyter como root é arriscado: qualquer código em uma célula teria controle total do sistema. Crie um usuário separado e dê a ele permissão de usar sudo:

adduser student
usermod -aG sudo student

O comando adduser pede uma senha e alguns dados opcionais, que podem ser deixados em branco. Depois, entre como o novo usuário:

su - student

Passo 3. Configure o firewall

Vamos permitir apenas SSH. A porta 8888 não será aberta, porque o Jupyter vai escutar só no endereço local:

sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

Exemplo de saída:

Status: active

To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)

Passo 4. Instale Python e o módulo venv

O Ubuntu 24.04 já vem com Python 3.12, mas faltam o pip e o suporte a ambientes virtuais:

sudo apt install -y python3-pip python3-venv
python3 --version

Por que não instalar com pip direto no sistema

Nas versões recentes do Ubuntu e do Debian, o comando pip install fora de um ambiente virtual termina com o erro externally-managed-environment. Isso é proposital (PEP 668): o sistema protege os pacotes Python que ele mesmo usa. O caminho correto é criar um venv.

Passo 5. Crie um ambiente virtual e instale o Jupyter

Crie o ambiente na pasta do usuário e ative-o:

python3 -m venv ~/jupyter-env
source ~/jupyter-env/bin/activate

Depois da ativação, o prompt do terminal ganha o prefixo (jupyter-env). Atualize o pip e instale o Jupyter Notebook junto com as bibliotecas mais comuns em trabalhos acadêmicos:

pip install --upgrade pip
pip install notebook pandas numpy matplotlib scikit-learn

Se preferir a interface do JupyterLab, instale também o pacote jupyterlab. Os dois podem conviver no mesmo ambiente.

Crie uma pasta para os notebooks do projeto:

mkdir -p ~/notebooks

Passo 6. Defina uma senha

Por padrão, o Jupyter usa um token aleatório que aparece no log a cada inicialização. Para o uso diário, é mais prático definir uma senha fixa:

jupyter server password

O comando pede a senha duas vezes e grava o hash dela no arquivo ~/.jupyter/jupyter_server_config.json. A senha em texto puro não é salva.

Enter password:
Verify password:
[JupyterPasswordApp] Wrote hashed password to /home/student/.jupyter/jupyter_server_config.json

Passo 7. Faça um teste de inicialização

Inicie o Jupyter manualmente, escutando apenas no endereço local:

cd ~/notebooks
jupyter notebook --no-browser --ip=127.0.0.1 --port=8888

O parâmetro --no-browser impede que o Jupyter tente abrir um navegador no servidor, que não tem interface gráfica. No log deve aparecer uma linha parecida com esta:

[I ServerApp] Jupyter Server is running at:
[I ServerApp] http://127.0.0.1:8888/tree

Deixe essa janela aberta e passe para o próximo passo.

Passo 8. Acesse o Jupyter por túnel SSH

Abra um segundo terminal no seu computador e crie o túnel:

ssh -N -L 8888:127.0.0.1:8888 student@IP_DO_SERVIDOR

O que acontece aqui:

Agora abra no navegador o endereço http://localhost:8888 e digite a senha do passo 6. Se a porta 8888 já estiver ocupada no seu computador (por exemplo, por um Jupyter local), use outra porta local: -L 9999:127.0.0.1:8888 e o endereço http://localhost:9999.

Crie um notebook novo e rode uma célula de teste:

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(5, 3), columns=["a", "b", "c"])
df.describe()

Se a tabela com estatísticas apareceu, o ambiente está funcionando. Volte ao primeiro terminal e pare o Jupyter com Ctrl+C.

Passo 9. Rode o Jupyter como serviço do systemd

Para que o Jupyter continue rodando depois que você fechar o SSH e volte sozinho após uma reinicialização, crie um serviço do systemd:

sudo nano /etc/systemd/system/jupyter.service

Cole o conteúdo abaixo, trocando student pelo seu usuário, se ele for diferente:

[Unit]
Description=Jupyter Notebook
After=network.target
[Service]
Type=simple
User=student
WorkingDirectory=/home/student/notebooks
ExecStart=/home/student/jupyter-env/bin/jupyter notebook --no-browser --ip=127.0.0.1 --port=8888
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

Repare que o caminho em ExecStart aponta para o executável dentro do venv. Assim não é preciso ativar o ambiente: o systemd já usa o Python e as bibliotecas corretos. Recarregue a configuração do systemd, habilite e inicie o serviço:

sudo systemctl daemon-reload
sudo systemctl enable --now jupyter
sudo systemctl status jupyter

Na saída do último comando deve aparecer active (running). Os logs ficam disponíveis com journalctl -u jupyter -f. A partir de agora, basta abrir o túnel SSH do passo 8 para trabalhar.

Passo 10 (opcional). Acesso por domínio com Nginx e HTTPS

O túnel SSH é a opção mais segura, mas exige terminal. Se o grupo prefere abrir o Jupyter direto no navegador, configure um proxy reverso com certificado gratuito do Let’s Encrypt. Você vai precisar de um domínio ou subdomínio, por exemplo jupyter.seudominio.com.br, com um registro A apontando para o IP do VPS.

Instale o Nginx e o Certbot e libere as portas 80 e 443 no firewall:

sudo apt install -y nginx certbot python3-certbot-nginx
sudo ufw allow 'Nginx Full'

Crie o arquivo /etc/nginx/sites-available/jupyter:

server {
listen 80;
server_name jupyter.seudominio.com.br;
location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}

As linhas Upgrade e Connection são obrigatórias: sem elas o WebSocket não passa pelo proxy, e o kernel fica eternamente no estado de conexão. O proxy_read_timeout alto evita que células longas percam a conexão.

Ative o site, verifique a sintaxe e recarregue o Nginx:

sudo ln -s /etc/nginx/sites-available/jupyter /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Emita o certificado. O Certbot ajusta a configuração do Nginx para HTTPS automaticamente e configura a renovação:

sudo certbot --nginx -d jupyter.seudominio.com.br

Ajuste no Jupyter para funcionar atrás do proxy

Quando o Jupyter escuta em 127.0.0.1, ele verifica se o cabeçalho Host da requisição também é local. Como o Nginx repassa o nome do domínio, as requisições seriam bloqueadas. Para resolver, adicione o parâmetro --ServerApp.allow_remote_access=True ao final da linha ExecStart no arquivo do serviço e reinicie:

sudo systemctl daemon-reload
sudo systemctl restart jupyter

A porta 8888 continua fechada no firewall, e o Jupyter continua escutando só no endereço local. Quem acessa de fora passa obrigatoriamente pelo Nginx com HTTPS e pela senha. Use uma senha longa e única: com o domínio público, ela é a principal barreira de proteção.

Dicas para o dia a dia

Instalar novas bibliotecas

Instale pacotes sempre dentro do venv. Pelo terminal do servidor:

source ~/jupyter-env/bin/activate
pip install seaborn

Ou direto em uma célula do notebook, com o comando mágico %pip install seaborn. Ele instala no mesmo ambiente em que o kernel está rodando.

Fixar as versões do projeto

Para que o ambiente possa ser recriado em outro servidor ou na máquina de um colega, salve a lista de pacotes:

pip freeze > requirements.txt

Para restaurar: pip install -r requirements.txt em um venv novo.

Adicionar swap em servidores pequenos

Em um VPS com 1 ou 2 GB de RAM, um dataset maior pode derrubar o kernel por falta de memória. Um arquivo de swap não substitui RAM, mas evita travamentos em picos curtos:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

A última linha registra o swap no /etc/fstab para que ele seja ativado após reinicializações.

Copiar arquivos entre o computador e o servidor

Datasets grandes chegam mais rápido por scp do que pelo botão de upload do navegador:

scp dados.csv student@IP_DO_SERVIDOR:~/notebooks/

Encerrar kernels esquecidos

Cada notebook aberto mantém um kernel com os dados na memória. Feche os que não estão em uso pelo menu File → Close and Shut Down Notebook ou pela aba Running. Em grupo, essa simples disciplina libera mais memória do que qualquer otimização de código.

Solução de problemas

Sintoma Causa provável O que fazer
bind: Address already in use ao criar o túnel A porta local 8888 está ocupada Use outra porta local, por exemplo -L 9999:127.0.0.1:8888
O serviço não sobe Caminho errado em ExecStart ou na pasta de trabalho Veja journalctl -u jupyter -n 50
Kernel fica em “Connecting” WebSocket bloqueado pelo proxy Confira as linhas Upgrade e Connection na configuração do Nginx
Kernel reinicia sozinho Falta de memória Feche outros kernels, adicione swap ou aumente a RAM do VPS
Erro externally-managed-environment pip rodou fora do venv Ative o ambiente com source ~/jupyter-env/bin/activate

Conclusão

Instalar o Jupyter Notebook em um VPS resolve os problemas mais comuns de projetos acadêmicos: falta de memória no laptop, ambientes diferentes entre os integrantes do grupo e a necessidade de deixar processamentos longos rodando. Neste artigo, criamos um usuário dedicado, instalamos o Jupyter em um ambiente virtual, protegemos o acesso com senha, configuramos o serviço do systemd e mostramos duas formas seguras de acesso: túnel SSH e Nginx com HTTPS.

Para a maioria dos trabalhos individuais, o túnel SSH é suficiente e não exige domínio. Para grupos que preferem abrir o Jupyter direto no navegador, o proxy reverso com certificado é a opção mais prática. Em ambos os casos, o servidor pode crescer junto com o projeto: se o dataset aumentar, basta ampliar os recursos do VPS Serverspace sem reinstalar nada.