Esta postagem foi originalmente de www.jaredwolff.com.
Depois de hospedar com o Netlify por alguns anos, decidi voltar para a hospedagem automática. Existem algumas razões para isso, mas o principal raciocínio foi que eu tinha mais controle sobre como as coisas funcionavam.
Nesta postagem, mostrarei meu fluxo de trabalho para implantar meu Hugo site gerado (www.jaredwolff.com) Em vez de usar o que a maioria das pessoas usaria, eu farei tudo isso usando um servidor baseado no FreeBSD Jails. Ademais, mostrarei alguns truques que aprendi ao longo dos anos no redimensionamento de imagens em massa e muito mais.
Vamos lá.
Onde hospedar?
Se você deseja hospedar seu próprio serviço, precisará de um servidor. É aí que entra um fornecedor de VPS como o Digital Ocean ou o Vultr. Sou fã e utilizo o Digital Ocean há algum tempo. Depois de descobrir o Vultr, experimentei a plataforma deles. Nesta publicação, as instruções serão aplicadas apenas ao Vultr.
Para configurar um novo servidor, aqui estão algumas etapas:
Faça o login com uma conta @ Vultr. (Se você não tiver uma, poderá obter um crédito de conta de US $ 100 por 30 dias se usar meu Link de referência. Eu agradeço seu apoio!)
Crie um novo servidor
Escolha o FreeBSD 12.1. Ao contrário do Digital Ocean, o Vultr suporta apenas o sistema de arquivos UFS. Muitas vezes, essa é a escolha certa. (O ZFS consome muita memória, o que não funcionaria no nosso caso!)
Certifique-se de importar sua chave pública. Caso contrário, você não poderá usar imediatamente o login sem senha.
Você também pode escolher um rótulo e nome de host do servidor.
Hit that blue Implantar agora e vamos colocar esse programa na estrada.
Configurando seu servidor FreeBSD com Bastille
Até recentemente, tudo estava funcionando em uma plataforma baseada no Docker usando Exoframe. Foi fácil e quase sem cérebro. A parte infeliz disso é o fato de o Docker dedicar muito a muitos recursos. Ademais, o gerenciamento de arquivos em um contêiner do Docker é tão ou mais trabalhoso do que hospedá-lo nativamente. Ah, e você verificou quanto espaço o Docker tem usado na sua máquina ultimamente? Na minha máquina de desenvolvimento, havia cerca de 19 GB de espaço. 😬
Então, qual é a alternativa?
Cadeias do FreeBSD usando Bastille.
Eu jogo com Bastille há alguns meses. Quanto mais eu o uso, mais faz 100% de sentido.
O Bastille permite que você crie um (agora) cárter portátil, leve e baseado em FreeBSD. Essas cadeias são “contêineres” que praticamente não têm sobrecarga. Não há daemon (o sistema operacional é o “daemon”!). Ademais, as cadeias são seguras em comparação com a lata de worms que o Docker é. Sim, pode ser necessário compilar e portar alguns utilitários. Muitos já são suportados no gerenciador de pacotes do FreeBSD pkg
.
Nesta seção, você aprenderá como executar uma cadeia com caddy
para que você possa hospedar seu site com segurança.
Vamos manter o ritmo!
Depois de obter o endereço IP do seu servidor, faça o login:
ssh [email protected]
Você deve receber uma mensagem MOTD e um sh
pronto. Woo!
FreeBSD 12.1-RELEASE-p2 GENERICWelcome to FreeBSD!...#
Vamos instalar alguns bits importantes usando pkg
(Gerenciador de pacotes do FreeBSD)
pkg install restic rsync bastille
Nós estaremos usando restic
para backups, rsync
para transferir arquivos e bastille
para instalação na cadeia.
Você também precisa configurar algumas rotas estáticas no seu pf.conf
. Aqui está um exemplo meu:
ext_if="vtnet0"# Caddy relatedcaddy_addr=10.10.2.20set block-policy returnscrub in on $ext_if all fragment reassembleset skip on lotable persistnat on $ext_if from to any -> $ext_if# container routesrdr pass inet proto tcp from any to port 80 -> $caddy_addr port 8880rdr pass inet proto tcp from any to port 443 -> $caddy_addr port 4443# Enable dynamic rdr (see below)rdr-anchor "rdr/*"block in allpass out quick modulate stateantispoof for $ext_if inetpass in inet proto tcp from any to any port ssh flags S/SA keep state
Este é um padrão pf.conf
arquivo para bastille
. Certifique-se de editar caddy_addr
para o IP que você escolheu.
Agora vamos iniciar o firewall. Você será expulso do seu ssh
sessão:
sysrc pf_enable="YES"service pf start
Então vamos pegar um pouco bastille
configuração fora do caminho:
# set up bastille networkingsysrc cloned_interfaces+=lo1sysrc ifconfig_lo1_name="bastille0"service netif cloneup# bootstrap the base jail and start bastillebastille bootstrap 12.1-RELEASE updatesysrc bastille_enable="YES"service bastille start
Isso configurará sua rede e buscará a cadeia base padrão mais recente que você usará mais tarde.
Em seguida, vamos configurar a prisão:
bastille create caddy 12.1-STABLE 10.10.2.20bastille start caddy
Depois instale caddy
#install the binaryfetch https://github.com/caddyserver/caddy/releases/download/v1.0.4/caddy_v1.0.4_freebsd_amd64.tar.gztar xvf caddy_v1.0.4_freebsd_amd64.tar.gz caddybastille cp caddy caddy /usr/local/bin/rm caddy#create the caddy userbastille cmd caddy pw useradd caddy -m -s /usr/sbin/nologin#install ca root filebastille pkg caddy install ca_root_nss
Ao instalar ca_root_nss
, pkg
terá que inicializar. Aceite os prompts. Quando terminar aqui, vamos para o próximo passo!
Depois que a instalação estiver concluída, também devemos configurar caddy
para iniciar na inicialização. A maneira mais fácil de fazer isso é usar este rc.d
roteiro.
#!/bin/sh# $FreeBSD: head/net/caddy/files/caddy.in 452063 2017-10-14 12:58:24Z riggs $## PROVIDE: caddy# REQUIRE: LOGIN# KEYWORD: shutdown## Add the following lines to /etc/rc.conf.local or /etc/rc.conf# to enable this service:## caddy_enable (bool): Set to NO by default.# Set it to YES to enable caddy.# caddy_user (user): Set user to run caddy.# Default is "caddy".# caddy_group (group): Set group to run caddy.# Default is "caddy".# caddy_conf (path): Path to caddy configuration file.# Default is /usr/local/etc/caddyfile.conf. /etc/rc.subrname=caddyrcvar=caddy_enableload_rc_config $name: ${caddy_enable:="NO"}: ${caddy_user:="caddy"}: ${caddy_group:="caddy"}: ${caddy_conf:="/usr/local/etc/caddyfile.conf"}: ${caddy_log:="/home/caddy/caddy.log"}: ${caddy_env:="CADDYPATH=/home/caddy/"}: ${caddy_https_port:="4443"}: ${caddy_http_port:="8880"}pidfile="/var/run/caddy.pid"procname="/usr/local/bin/caddy"command="/usr/sbin/daemon"command_args="-f -p ${pidfile} /usr/bin/env ${caddy_env} ${procname} -agree -http-port ${caddy_http_port} -https-port ${caddy_https_port} -conf=${caddy_conf} -log=${caddy_log} ${caddy_args}"extra_commands="reload"start_precmd=caddy_startprecmdreload_cmd=caddy_reloadcmdcaddy_startprecmd(){ if [ ! -e ${pidfile} ]; then install -o ${caddy_user} -g ${caddy_group} /dev/null ${pidfile}; fi}caddy_reloadcmd(){ kill -s USR1 $(cat ${pidfile})}run_rc_command "$1"
Remova o caddy
executável se você ainda não o fez. Em seguida, crie um novo arquivo com vi
. Este será o seu rc.d
roteiro!
vi caddy
Em seguida, cole o conteúdo do script acima, salve e saia.
Em seguida, verifique se o arquivo é executável usando chmod
e copie para o contêiner Caddy.
chmod +x caddybastille cp caddy caddy /usr/local/etc/rc.d/
Finalmente, precisaremos de um Caddyfile. Aqui está um exemplo de um:
stage.jaredwolff.com { tls [email protected] log /home/caddy/stage.jaredwolff.com.log root /var/www/stage.jaredwolff.com/ gzip log stderr}
log
refere-se a este log de acesso específico do site.
root
refere-se a onde a raiz public
pasta está na sua máquina. No meu caso, é comum /var/www/
. Defina seus caminhos e lembre-se deles. Nós precisaremos deles mais tarde!
Para que o Caddy gere certificados para este subdomínio, você precisará definir o tls opção. Um e-mail é tudo o que é necessário.
Para saber mais sobre a estrutura Caddyfile confira a documentação.
Crie um arquivo chamado caddyfile.conf
e copie-o para /usr/local/etc/
no seu contêiner Caddy:
vi caddyfile.conf# Paste your caddyfile contents and savebastille cp caddy caddyfile.conf /usr/local/etc/
Agora você deve redirecionar seu DNS para o IP do servidor. Dessa forma, o Caddy pode gerar / buscar os certificados corretos. Então você pode iniciar o Caddy com:
bastille service caddy caddy start
Você pode verificar o log em /usr/home/caddy/caddy.log
para garantir que seu domínio seja provisionado corretamente.
Nota: A configuração com certificados SSL é difícil no começo. (Especialmente se você estiver migrando de outro servidor.) Seu site precisará ser desativado um pouco enquanto você altera as configurações de DNS e inicia caddy
. (Isso se você estiver usando o padrão caddy
1.0 Você também pode usar o provedor DNS plugins aqui que tornam as coisas um pouco mais fáceis.)
Agora que temos caddy
instalado e funcionando, é hora de copiar nossa hugo
ativos gerados usando rsync
. Vamos para o próximo passo!
Faço construindo e implantando fácil
Passo muito tempo programando o código C e isso significa que gasto muito tempo usando Makefiles. Para muitos make
(ou gmake
para GNU make) é a desgraça de nossas existências. Para construir e implantar, make
facilita a criação de receitas reutilizáveis. Dessa forma, você sabe que pode implantar com confiança sempre.
Meu Makefile pede emprestado aquele que Victoria Drake postou não muito tempo atrás. Mudei um pouco para atender às minhas necessidades. Vamos fazer um tour e ver o que há dentro:
.POSIX:HUGO_VERSION := 0.66.0OPTIMIZED_DIR := optimizedCONTENT_DIR := contentDEST_DIR := publicSERVER := 123.456.789.10USER := user
A primeira seção contém todas as variáveis que eu uso para informar as funções posteriormente sobre o que fazer. Também tem uma referência ao .POSIX
alvo. Isso significa que o Makefile será tão portátil entre diferentes versões do make
.
Em seguida, criei uma lógica para determinar se estou implantando no palco ou Produção:
# Set the place where it's deployed to.ifdef PRODUCTION$(info Building for production. 🚀)TARGET := wwwelse$(info Building for development. 🚀)BASEURL := --baseURL "https://stage.jaredwolff.com"TARGET := stageendif
Por padrão, as receitas abaixo usarão o fluxo de trabalho de desenvolvimento. Para usar o fluxo de trabalho de produção, você pode chamar make
como isso:
PRODUCTION=1 make build
Isso adiciona algum atrito extra ao processo de implantação. É um bom passo, no entanto. Dessa forma, você tem certeza de que a implantação está indo para o lugar certo!
# Full pathDEPLOY_DIR := /usr/local/bastille/jails/caddy/root/path/to/$(TARGET).jaredwolff.com
Usando o TARGET
variável acima, defino o caminho para os ativos do meu servidor. Estou usando o Bastille para organizar minhas cadeias, para que o caminho seja mais longo. (sim, longamente) Isso nos permite usar rsync
implantar os arquivos com facilidade.
Agora, aqui estão as partes divertidas. Para fazer um redimensionamento em massa completo, estou usando o wildcard
funcionalidade do Makefile.
IMAGES := $(wildcard $(CONTENT_DIR)/*/images/*.jpg) $(wildcard $(CONTENT_DIR)/*/images/*.JPG) $(wildcard $(CONTENT_DIR)/*/images/*.jpeg) $(wildcard $(CONTENT_DIR)/*/images/*.png) $(wildcard $(CONTENT_DIR)/*/*/images/*.jpg) $(wildcard $(CONTENT_DIR)/*/*/images/*.jpeg) $(wildcard $(CONTENT_DIR)/*/*/images/*.png) $(wildcard $(CONTENT_DIR)/*/*/images/*.JPG)
Nesse caso, ele criará uma enorme lista delimitada por espaço de todas as imagens que estão dentro do meu diretório de conteúdo. A maior desvantagem desse método é que ele não é tolerante ao espaço. Uma solução fácil é garantir que todas as minhas fotos não tenham espaços.
Aqui está um comando bash rápido e sujo. Você pode usar o nome para renomear arquivos que possuem espaços e substituí-los por caracteres ‘_’:
for f in * *; do mv "$f" "${f// /_}"; done
Em seguida, renomeamos essas entradas para que o prefixo agora seja o diretório de destino. Isso será útil quando quisermos redimensionar:
OPTIMIZED_IMAGES := $(subst $(CONTENT_DIR)/,$(OPTIMIZED_DIR)/,$(IMAGES))
Agora confira o optimize
receita:
.PHONY: optimizeoptimize: build $(OPTIMIZED_IMAGES)@echo "🧂 Optimizing images"rsync -r $(OPTIMIZED_DIR)/ $(DEST_DIR)/du -sh $(CONTENT_DIR)/du -sh $(DEST_DIR)/$(OPTIMIZED_IMAGES):convert -strip -compress JPEG -resize '730>' $(subst $(OPTIMIZED_DIR)/,$(CONTENT_DIR)/,$@) $@
Primeiro chama o build
receita e depois também o $(OPTIMIZED_IMAGES)
receita. O posterior otimizará a imagem usando o convert
comando de Imagemagick. Nesse caso, estou apenas redimensionando arquivos com mais de 730 px de largura. Mude de acordo para poder colher os benefícios de um site otimizado.
Após o redimensionamento, a receita usa rsync
para copiar os arquivos do OPTIMIZED_DIR
para DEST_DIR.
Se dermos uma olhada no build
receita, eu primeiro construindo os ativos. Em seguida, copio as fotos do content
dir para optimized
dir. O bom é que rsync
apenas moverá arquivos que foram alterados. Portanto, não é necessário copiar os arquivos repetidamente e sempre que você criar.
finalmente, o deploy
receita.
.PHONY: deploydeploy:@echo rsync to $(DEPLOY_DIR)@rsync -r --del public/ $(USER)@$(SERVER):$(DEPLOY_DIR)/@echo making restic snapshot@scp scripts/backup.sh $(USER)@$(SERVER):/root/backup.sh@ssh $(USER)@$(SERVER) sh /root/backup.sh $(DEPLOY_DIR)@echo "🚀 Site is deployed!"
Você pode ver novamente que estou usando o rsync para sincronizar o conteúdo de public/
para o servidor. Certifique-se de definir o USER
, SERVER
e DEPLOY_DIR
. No meu caso DEPLOY_DIR
sai para /usr/local/bastille/jails/caddy/root/var/www/www.jaredwolff.com
Quando você finalmente obtém uma implantação bem-sucedida, pode verificar novamente se tudo está no lugar correto. Então, quando tudo estiver bem, você poderá iniciar seu servidor de caddy usando
bastille service caddy caddy start
deploy
também fará algo mais útil aqui. Ele irá implantar meu restic
script de backup e execute-o. Vou falar sobre isso mais na seção de backup.
Em suma, aqui está o Makefile completo
.POSIX:HUGO_VERSION := 0.66.0OPTIMIZED_DIR := optimizedCONTENT_DIR := contentDEST_DIR := publicSERVER := 155.138.230.8USER := root# Set the place where it's deployed to.ifdef PRODUCTION$(info Building for production. 🚀)TARGET := wwwelse$(info Building for development. 🚀)BASEURL := --baseURL "https://stage.jaredwolff.com"TARGET := stageendif# Full pathDEPLOY_DIR := /usr/local/bastille/jails/caddy/root/var/www/$(TARGET).jaredwolff.comIMAGES := $(wildcard $(CONTENT_DIR)/*/images/*.jpg) $(wildcard $(CONTENT_DIR)/*/images/*.JPG) $(wildcard $(CONTENT_DIR)/*/images/*.jpeg) $(wildcard $(CONTENT_DIR)/*/images/*.png) $(wildcard $(CONTENT_DIR)/*/*/images/*.jpg) $(wildcard $(CONTENT_DIR)/*/*/images/*.jpeg) $(wildcard $(CONTENT_DIR)/*/*/images/*.png) $(wildcard $(CONTENT_DIR)/*/*/images/*.JPG) OPTIMIZED_IMAGES := $(subst $(CONTENT_DIR)/,$(OPTIMIZED_DIR)/,$(IMAGES)).PHONY: allall: build optimize.PHONY: cleanclean:rm -rf public/rm -rf optimized/.PHONY: serveserve:@hugo serve -D.PHONY: sshssh:@ssh $(USER)@$(SERVER).PHONY: buildbuild:@echo "🍳 Generating site"hugo --gc --minify -d $(DEST_DIR) $(BASEURL)rsync -av --del -f"+ */" -f"- *" $(CONTENT_DIR)/ $(OPTIMIZED_DIR)/.PHONY: optimizeoptimize: build $(OPTIMIZED_IMAGES)@echo "🧂 Optimizing images"rsync -r $(OPTIMIZED_DIR)/ $(DEST_DIR)/du -sh $(CONTENT_DIR)/du -sh $(DEST_DIR)/$(OPTIMIZED_IMAGES):convert -strip -compress JPEG -resize '730>' $(subst $(OPTIMIZED_DIR)/,$(CONTENT_DIR)/,$@) [email protected]: deploydeploy:@echo rsync to $(DEPLOY_DIR)@rsync -r --del public/ $(USER)@$(SERVER):$(DEPLOY_DIR)/@echo making restic snapshot@scp scripts/backup.sh $(USER)@$(SERVER):/root/backup.sh@ssh $(USER)@$(SERVER) sh /root/backup.sh $(DEPLOY_DIR)@echo "🚀 Site is deployed!"
Existem algumas outras pepitas úteis que você pode querer usar. clean
, serve
e ssh
foram muito úteis ao testar e conectar.
No final, você terá um processo de implantação em duas etapas. O primeiro gera seu site com imagens otimizadas. A segunda é a implantação em um servidor para hospedagem estática.
Backup incremental
Depois de descobrir Restic Fui informado de como foi útil para todas as minhas necessidades de backup incremental. No caso do meu servidor, estou usando para fazer backup da pasta raiz do meu site. Dessa forma, se eu precisar reverter, posso fazê-lo com alguns passos curtos.
Veja como você pode configurar um local restic
repo.
Configurando
A inicialização do repositório é simples. A parte mais importante é garantir que você não perca / esqueça sua senha!
# restic init -r /root/backups enter password for new repository: enter password again: created restic repository 32e14c7052 at /root/backups Please note that knowledge of your password is required to access the repository. Losing your password means that your data is irrecoverably lost.
Colocou o RESTIC_PASSWORD
variável de ambiente para evitar digitar sua senha. Para torná-lo permanente, você terá que colocar export RESTIC_PASSWORD="Your password here!"
dentro do .profile
arquivo em /root/
.
Fazendo backup
Invocando restic
sobre SSH é difícil. Então, nossa próxima melhor aposta?
Transfira um script de shell (muito breve) para o servidor e execute-o após uma implantação. Aqui está o conteúdo do que estou usando hoje:
#!/bin/shexport RESTIC_PASSWORD="Your password here!"restic backup $1 -r /root/backups/
Nota: Enquanto eu sento aqui e olho para este script, por motivos de segurança, você pode substituir “Sua senha aqui!” com $ 2, que é o segundo argumento para o script. Dessa forma, você não precisa confirmar / enviar a senha armazenada em um arquivo estático!
Isso primeiro define sua senha de backup. Então corre restic
usando o primeiro argumento da linha de comandos como o caminho. Portanto, para executar um backup com este script, seria algo como isto:
./backup.sh /path/to/your/public/folder/
Nota: você precisa inicializar seu restic
cópia de segurança antes você começa a fazer backup. Vai vomitar para você de outra forma!
No meu caso, estou colocando os backups incrementais em uma pasta diferente da minha máquina. Dessa forma, eles são facilmente acessíveis e velozes.
Visualizando seus backups
Para visualizar seus backups, você pode executar o seguinte comando:
# restic snapshots -r /root/backups -g paths -center password for repository:repository e140b5e4 opened successfully, password is correctsnapshots for (paths [/usr/local/bastille/jails/caddy/root/var/www/www.jaredwolff.com]):ID Time Host Tags--------------------------------------------------d3328066 2020-03-10 00:30:58 vultr.guestf3360819 2020-03-10 04:03:03 vultr.guest231dd134 2020-03-10 04:44:00 vultr.guest3c1be26a 2020-03-10 04:56:19 vultr.gueste96c947c 2020-03-10 05:03:00 vultr.guest34c3682a 2020-03-10 14:01:37 vultr.guestfbccdb8c 2020-03-10 14:04:26 vultr.guest9ce11146 2020-03-10 15:38:49 vultr.guest046b3da3 2020-03-10 15:47:06 vultr.guest9c28d4bc 2020-03-10 15:48:25 vultr.guest469dc228 2020-03-10 15:48:54 vultr.guest6f78af72 2020-03-10 17:00:21 vultr.guest29ad17b2 2020-03-10 20:18:23 vultr.guested22ce1f 2020-03-10 20:20:24 vultr.guest9c8c1b03 2020-03-11 13:56:40 vultr.guestb6cfcfec 2020-03-11 14:08:14 vultr.gueste8546005 2020-03-11 14:27:22 vultr.guest49a134fe 2020-03-17 00:47:58 vultr.guestc0beb283 2020-03-18 20:44:52 vultr.guest--------------------------------------------------
Você pode usar esta lista para determinar se você precisa reverter uma implantação.
Restaurando
A restauração de um backup, especialmente em um ambiente ativo, precisa ser rápida. Após visualizar seus backups, você pode restaurar um backup específico usando seu EU IRIA.
restic restore d3328066
Isso restaurará os arquivos de volta ao backup feito em 2020-03-10 00:30:58. Impressionante. Ademais, ele não substituirá todos. Somente aplicará as diferenças entre o estado atual e o estado armazenado.
Conclusão
Cobrimos uma tonelada de terreno neste post. Você aprendeu como:
- Implante seu próprio servidor usando o Vultr
- Use Bastille para criar prisões semelhantes a contêineres
- Configure o Caddy para servir ativos de arquivos estáticos com TLS
- Implante os arquivos usando um Makefile bastante simples e
rsync
- Faça backup após cada implantação usando
restic
No final, temos uma plataforma robusta, segura e simples para hospedar arquivos e serviços estáticos. Fique ligado, pois há mais postagens como essa em breve! Enquanto isso, confira meu outras postagens. Obrigado pela leitura e até a próxima! 👍