<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://lond.com.br/feed.xml" rel="self" type="application/atom+xml" /><link href="https://lond.com.br/" rel="alternate" type="text/html" hreflang="en" /><updated>2025-02-04T12:22:59+01:00</updated><id>https://lond.com.br/feed.xml</id><title type="html">Lond’s Stuff</title><subtitle>Just an aggregator for all my crazy stuff.</subtitle><entry xml:lang="pt"><title type="html">Como é ser parte de um supermercado cooperativo</title><link href="https://lond.com.br/2020/06/27/como-e-ser-parte-de-um-supermercado-cooperativo.html" rel="alternate" type="text/html" title="Como é ser parte de um supermercado cooperativo" /><published>2020-06-27T22:34:00+02:00</published><updated>2020-06-27T22:34:00+02:00</updated><id>https://lond.com.br/2020/06/27/como-e-ser-parte-de-um-supermercado-cooperativo</id><content type="html" xml:base="https://lond.com.br/2020/06/27/como-e-ser-parte-de-um-supermercado-cooperativo.html"><![CDATA[<p>Quem me conhece sabe que tem um tempo que eu falo dessa tal cooperativa. Basta sentar comigo num bar que é bem provável que você vá ouvir, ou já tenha ouvido, da maravilha que é a BEES e talicoisa. Notei que ainda não tinha escrito nada sobre isso e achei que era uma boa ideia pra espalhar mais a ideia por aí.</p>

<p>Cresci em cidade grande e embora tivesse uma vendinha bem perto de casa, que tinha aquelas jarras de vidro cheias de balas pra eu pedir pra mamãe quando eu passava por lá no caminho do colégio, no geral pra mim supermercado sempre foi uma coisa com “super” no nome. Aquela história: um grande espaço, mil corredores e um estoque infindável de todo tipo de coisa.</p>

<p>A maioria dos supermercados cooperativos se baseam na idéia do <a href="https://www.foodcoop.com/" target="_blank" rel="noopener">Park Slope Food Coop (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, em Nova Iorque. O Park Slope Food Coop foi fundado em 1973 e opera em um sistema em que para fazer compras no supermercado, a pessoa precisa ser uma cooperadora. Pra se tornar uma cooperadora, as pessoas pagam um valor uma vez (comprando uma parte na cooperativa) e pra manter seu status ativo, fazem um turno de trabalho de 2h45 uma vez por mês no supermercado, em tarefas que fazem o supermercado funcionar (estoque, manutenção, administração, etc).</p>

<p>Nunca visitei o Park Slope, mas o primeiro supermercado cooperativo que eu visitei foi <a href="https://lacagette-coop.fr/" target="_blank" rel="noopener">La Cagette (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, em Montpellier, no início de 2019 e eu fiquei imediatamente encantado pela ideia. A atmosfera do lugar era bem diferente, mais próxima da vendinha que eu me lembrava quando era criança. Ao invés do ambiente cheio de propaganda, com alguns produtos sendo iluminados como se fossem sagrados, o ambiente era bem mais tranquilo, as pessoas que entravam e saíam se conheciam e conversavam no caixa ou enquanto estavam estocando uma prateleira.</p>

<p>Um supermercado tradicional tem todos os elementos do capitalismo moderno: o marketing agressivo, descontos risíveis se você der informações suas e sempre se identificar quando faz compras de modo que eles possam fazer um perfil seu, funcionários mal pagos executando funções repetitivas por horas a fio (e muitas vezes mais de uma função ao mesmo tempo). Além disso, supermercados tendem a ter uma margem de lucro variável nos produtos, muitas vezes legumes ou macarrão são muito baratos e tem uma margem de lucro bem pequena, e quando você compra algo como uma caneta ou uma pilha, ou um produto orgânico, é nesse tipo de coisa que tem uma margem gigantesca.</p>

<p>Quando voltei pra Bruxelas depois de conhecer La Cagette, fui procurar pra saber se algo do tipo existia por aqui. E encontrei a <a href="http://bees-coop.be/en/" target="_blank" rel="noopener">BEES coop (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>A BEES coop começou como um grupo de compras, as pessoas que participavam do grupo tomavam decisões sobre o que comprar e compravam coletivamente para obter preços reduzidos pro grupo. Mas a ideia foi se transformando até que, também se inspirando no Park Slope, se transformou no atual supermercado cooperativo que funciona desde 2017.</p>

<p>O supermercado lembra um supermercado tradicional: tem cestas e carrinhos e uma gama de produtos que vai de arroz e carnes até produtos de higiene de peças de bicicleta. A grande diferença é na escolha do que entra na loja: essa escolha é também feita de maneira participativa, e prioriza produtos orgânicos, locais ou de cooperativas; e muitas vezes prioridade para o pequeno produtor, mesmo que não tenha o selo “xyz”, ao invés do grande distribuidor. Além disso, também tem um monte de coisa que é disponível a granel: macarrão, arroz, lentilha, sabonete líquido, vinho e mesmo azeite. Dá pra levar seu saco, pote ou garrafa e encher por lá mesmo.</p>

<p>Além dos cooperadores, existem seis pessoas assalariadas que trabalham em tempo parcial. Elas também trabalham na loja, mas uma grande parte do seu trabalho é de fazer os pedidos de produtos, decidir o posicionamento de produtos na loja, recepcionar encomendas e repassar às cooperadoras no início do turno quais são as tarefas pendentes para o turno atual.</p>

<p>Toda pessoa cooperadora tem um cartão, que lhe identifica na entrada da loja e com o qual pode fazer suas compras. Além disso, tem direito a nomear duas outras pessoas de mais de 18 anos que vivem sob o mesmo teto, essas não precisam trabalhar, são “comedoras” e ganham seus próprios cartões para fazer compras.</p>

<p>Eu, como cooperador, trabalho 2h45 na loja por mês. Às vezes fico no caixa, outras vezes reabastecendo prateleiras, na entrada da loja ou arrumando o estoque. Tem também gente que trabalha no escritório, recebendo novos membros, atualizando os status dos membros atuais e outras tarefas do tipo; Tem gente que trabalha no corte de queijos; Tem gente que limpa a loja e guarda os legumes na câmara fria no fim do dia; E tem gente que faz trabalhos em comitês específicos, como o comitê que organiza a assembléia geral ou o comitê que seleciona os produtos.</p>

<p>Um turno normalmente tem uma pessoa “supercooperadora”, que faz um treinamento com as pessoas assalariadas para saber mais sobre o funcionamento da loja, além de ser o ponto de contato das outras cooperadoras para ausências inesperadas. Além disso, é para a supercooperadora que os funcionários explicam quais tarefas tem mais prioridade no turno atual. Além dos trabalhos de sempre, como caixa e entrada da loja, as vezes entregas precisam ser organizadas no estoque, novos produtos precisam ser registrados no sistema da loja, ou as prateleiras de cerveja estão quase vazias e precisam de uma atenção especial ;)</p>

<p>Cada turno de trabalho na loja começa com os membros se reunindo, recebendo da supercooperadora as tarefas para o turno e então se dividindo pra realizar as tarefas. E depois de umas horinhas, todo mundo se despede, com o novo turno acontecendo só dali a 4 semanas.</p>

<p>Trabalhar e fazer as compras na BEES é uma experiência agradável. Não só você conhece os rostos que dividem seus turnos com você, mas você começa a encontrar as mesmas pessoas que fazem compras em horários similares a você, e depois a encontrar essas pessoas nas assembléias gerais. O comitê de vinhos as vezes coloca um aviso caloroso dizendo que eles acharam um novo vinho super gostoso e que você devia experimentar. Quando você está no caixa é normal ver as pessoas conversando dizendo que tal e tal produto são novos e são tão bons por causa disso e daquilo. E nos corredores é comum ver gente se reconhecendo e começando a conversar.</p>

<p>Uma coisa importante, que me perguntam com frequência é: “tá, tudo muito bonito, seu Lond, mas e o preço das coisas?”. E a verdade é que depende. Como eu disse lá no alto, um supermercado tradicional trabalha com uma margem variável de lucro, cada produto tem uma margem diferente. Na BEES a margem é constante. Todo produto tem uma margem de 20%. A loja não tem fins lucrativos, a margem está lá para a manutenção da loja e salários dos funcionários.</p>

<p>A nossa experiência é que o preço médio do carrinho é bem próximo do que é no supermercado tradicional. A gente também começou a comprar mais coisas orgânicas, porque o preço é bem próximo do não-orgânico no supermercado normal. Tem produtos mais caros e algumas marcas tradicionais simplesmente não são vendidos por lá.</p>

<p>E a quantidade plástico que a gente traz pra casa diminuiu de maneira espetacular. Os produtos de supermercado aqui tendem a ter muito mais embalagem plástica do que no Brasil, tenho impressão. E na BEES tem um incentivo ativo a reutilização, então a gente começou a usar sacos laváveis de pano pra legumes e granel, dá preferência pra embalagens de vidro que são retornáveis (ou mesmo quando não são, por aqui tem lixeiras especiais pra vidro, que são reciclados) e pra coisas como óleo e azeite a gente enche os galões a granel, reusando as mesmas garrafas de vidro pra encher de azeite na cozinha no dia-a-dia.</p>

<p>O projeto não é perfeito, claro, mas é uma demonstração agrádavel de que é possível se organizar de maneiras diferentes dentro do capitalismo, enquanto não saímos dele. Que é possível encontrar formas alternativas de fazer coisas essenciais como suas compras de mês que operam de uma forma coletiva, com uma preocupação ambiental e uma preocupação com o aspecto humano, com o trabalhador do outro lado da produção, evitando os grandes conglomerados que infectam a vida do dia-a-dia e tem tanto poder.</p>

<p>Tentei buscar um pouco e não achei projetos similares no Brasil. Sei que existem lojas, como o Armazém do Campo do MST, que tentam aproximar o produtor do consumidor e vendem produtos de assentamentos e de pequenos agricultores. Mas não achei nada com o mesmo modelo participativo, como a BEES ou Park Slope.</p>

<p>Em todo caso, deixo algumas sugestões pra você lendo esse texto: preste atenção o quanto de coisas você compra no supermercado é por causa de propaganda. Pense em comprar mais coisas a granel, no Rio eu sei que existem lojas tradicionais de granel, não são nenhuma BEES, mas você vai sentir o quanto isso diminui o uso de plástico. E por fim, procure projetos que te conectem a pequenos produtores, enquanto a gente não tira do poder do agronegócio por maneiras diretas, a gente pode tirar o poder do agronegócio indo ao pequeno produtor quando possível.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Quem me conhece sabe que tem um tempo que eu falo dessa tal cooperativa. Basta sentar comigo num bar que é bem provável que você vá ouvir, ou já tenha ouvido, da maravilha que é a BEES e talicoisa. Notei que ainda não tinha escrito nada sobre isso e achei que era uma boa ideia pra espalhar mais a ideia por aí.]]></summary></entry><entry xml:lang="pt"><title type="html">2019 - O ano de deixar o instagram</title><link href="https://lond.com.br/2019/01/14/2019-o-ano-de-deixar-o-instagram.html" rel="alternate" type="text/html" title="2019 - O ano de deixar o instagram" /><published>2019-01-14T19:31:00+01:00</published><updated>2019-01-14T19:31:00+01:00</updated><id>https://lond.com.br/2019/01/14/2019-o-ano-de-deixar-o-instagram</id><content type="html" xml:base="https://lond.com.br/2019/01/14/2019-o-ano-de-deixar-o-instagram.html"><![CDATA[<p>No início de 2018 eu finalmente apaguei o meu Facebook.</p>

<iframe src="https://masto.donte.com.br/@renatolond/99411943920135533/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400"></iframe>
<script src="https://masto.donte.com.br/embed.js" async="async"></script>

<p>Eu já tinha reclamado do facebook <a href="https://medium.com/@renatolond/como-e-por-que-estou-tentando-usar-menos-o-facebook-119fb545bbab" target="_blank" rel="noopener">em 2015 (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>; na época a preocupação era mais em termos de como eu consumia informação na internet. Eu procurei alternativas ao Facebook que tinha se tornado meu modo de consumir notícias e de passar as notícias a frente.</p>

<p>As preocupações com privacidade começaram quase ao mesmo tempo, posts como <a href="https://splinternews.com/facebook-recommended-that-this-psychiatrists-patients-f-1793861472" target="_blank" rel="noopener">esse do Splinter, de 2016 (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> ou <a href="https://gizmodo.com/facebook-figured-out-my-family-secrets-and-it-wont-tel-1797696163" target="_blank" rel="noopener">esse do Gizmodo, de 2017 (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> mostravam que os algoritmos de recomendação de amigos do Facebook tinham muito mais informação do que eles deixavam transparecer.</p>

<p>Em seguida todo o escândalo da Cambridge Analytica ganhou força, e logo depois, uma montanha de revelações ainda piores e a campanha #DeleteFacebook começou a ganhar força. <a href="https://www.nytimes.com/2018/11/14/technology/facebook-data-russia-election-racism.html" target="_blank" rel="noopener">Um artigo do New York Times fala de como o Facebook lutou contra os escândalos usando de lobbying e de difamação contra outras empresas. (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>No entanto, uma coisa sempre necessária de lembrar é que o Facebook é dono do Instagram e do Whatsapp. Hoje em dia, já há quem diga que a <a href="https://www.recode.net/2018/6/2/17413786/ben-thompson-facebook-google-aggregator-platform-code-conference-2018" target="_blank" rel="noopener">compra do Instagram pelo Facebook foi a maior falha regulatória da última década. (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a></p>

<p>Sair do Facebook foi um passo importante, mas pra manter contato com outras pessoas, é sempre muito difícil fugir do Whatsapp e do Instagram. A verdade é que o ideal seria que o Facebook (e o Google, já que estamos falando do assunto), sofressem um processo semelhante ao que <a href="https://en.wikipedia.org/wiki/United_States_v._Microsoft_Corp." target="_blank" rel="noopener">a Microsoft passou no fim dos anos 90 (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, quando a empresa teve que ser dividida, e o resultado foi o fôlego dado a outros navegadores como Firefox e Chrome, que puderam finalmente causar uma mudança na internet, que antes era basicamente dedicada ao Internet Explorer.</p>

<p>No entanto, como estamos falando de aplicações sociais por natureza, ações individuais como o #DeleteFacebook podem sim ter efeitos que tiram o poder da rede como um todo, a prova disso é como o Facebook já começou a mover sua atenção para o Instagram de diversas formas, como quando <a href="https://www.bloomberg.com/news/articles/2018-07-13/facebook-is-desperate-for-instagram-s-millennials" target="_blank" rel="noopener">notificações de que pessoas que você seguia tinham postado fotos no Facebook estavam sendo testadas no Instagram (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Ao mesmo tempo, <a href="https://outline.com/r63TUD" target="_blank" rel="noopener">o Whatsapp deve receber anúncios em breve. (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a></p>

<p>Tudo isso mostra como o Facebook pretende continuar extendendo sua influência para os outros apps, em uma tentativa de manter seu controle sobre o dados dos seus usuários.</p>

<p>Por isso, uma das minhas resoluções de 2019 é de tentar abandonar o Instagram. A minha idéia é começar a mover mais e mais para o <a href="https://pt.wikipedia.org/wiki/Fediverso" target="_blank" rel="noopener">Fediverso (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, agora que o <a href="https://pixelfed.org/" target="_blank" rel="noopener">Pixelfed (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, uma alternativa ao instagram, começa a tomar forma.</p>

<p>Resta ver se a mudança vai ser possível. Que tal também vir pro Fediverso comigo? 😉</p>]]></content><author><name></name></author><summary type="html"><![CDATA[No início de 2018 eu finalmente apaguei o meu Facebook.]]></summary></entry><entry xml:lang="pt"><title type="html">O guia paranóico de segurança em tempos digitais</title><link href="https://lond.com.br/2018/10/29/o-guia-paran%C3%B3ico-de-seguran%C3%A7a-em-tempos-digitais.html" rel="alternate" type="text/html" title="O guia paranóico de segurança em tempos digitais" /><published>2018-10-29T00:00:00+01:00</published><updated>2018-10-29T00:00:00+01:00</updated><id>https://lond.com.br/2018/10/29/o-guia-paran%C3%B3ico-de-seguran%C3%A7a-em-tempos-digitais</id><content type="html" xml:base="https://lond.com.br/2018/10/29/o-guia-paran%C3%B3ico-de-seguran%C3%A7a-em-tempos-digitais.html"><![CDATA[<p><em>(atualizado pela última vez em 6 de fevereiro de 2021)</em></p>

<p>Com a escalada do fascismo e o fato de que nossas vidas estão cada vez mais presentes online, é preciso tomar precauções para que nossas identidades digitais não caiam nas mãos erradas. Primeiro porque isso pode revelar informações valiosas nossas e de pessoas queridas à nossa volta. Segundo porque isso pode permitir que atacantes passem informações falsas usando nossas identidades.</p>

<p>Esse post está dividido em duas partes: uma parte de dicas mais gerais e uma parte de recomendações de apps pra substituir.</p>

<p>As recomendações estão num formato em que você pode passar rapidamente o olho e ver os apps recomendados, seguido pelo porque dos outros apps não serem recomendados e por fim uma pequena explicação do porque os apps recomendados estarem na lista.</p>

<p>No geral, ao longo desse guia, uma coisa é recorrente: evite os conglomerados tecnológicos. Google e Facebook sobrevivem de coletar seus dados e seus aplicativos coletam a maior quantidade de dados possíveis. Além disso, evite aplicativos e redes que não encriptam seus dados, porque seus dados podem ser divulgados tanto por causa de vulnerabilidades, quanto por outros meios (por exemplo, podem ser acessados por empregados das empresas e vendidos pra quem paga mais).</p>

<p>Segurança digital é uma luta constante e é preciso se acostumar a ter todos os ítens na cabeça. Mesmo que você resolva adotar todas as sugestões que eu comento por aqui, vai levar um tempo até isso estar naturalizado. Não desista porque uma coisa ou outra ainda não está de acordo com esse guia (ou com outros guias de segurança que você pode encontrar por aí).</p>

<p>Esse guia é mais um dentre outros guias que podem ser encontrados na internet. Posts como <a href="https://medium.com/revista-subjetiva/um-manual-de-seguran%C3%A7a-digital-para-tempos-sombrios-2d414d0a3f24" target="_blank" rel="noopener">Um manual de segurança digital para tempos sombrios (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> e livros como <a href="https://www.goodreads.com/book/show/35105309-queer-privacy" target="_blank" rel="noopener">Queer Privacy: Essays From The Margins Of Society (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> foram usados como referências para esse post.</p>

<p>Se quiser fazer uma correção nesse post ou discutir algum ponto, só entrar em contato por um dos meios disponíveis ali no link <a href="/about">sobre</a>, ou ainda, abrir uma discussão direto no <a href="https://github.com/renatolond/blog/issues">github</a></p>

<p>Tenha em mente: esse post não é revisado com frequência, antes de usar cegamente um dos apps daqui, dê uma pesquisada rápida para ver o status atual do aplicativo. Muita coisa muda o tempo todo :)
Uma outra boa fonte, em inglês, de recomendações que está bem alinhada com as recomendações nesse post é o <a href="https://www.thinkprivacy.ch/" target="_blank" rel="noopener">Think Privacy (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<hr />

<nav>
  <h3 class="toc_title">Nessa página</h3>
<ol id="markdown-toc">
  <li><a href="#dicas-gerais" id="markdown-toc-dicas-gerais">Dicas gerais</a>    <ol>
      <li><a href="#webcam-e-microfone" id="markdown-toc-webcam-e-microfone">Webcam e microfone</a></li>
      <li><a href="#autenticação-em-dois-passos" id="markdown-toc-autenticação-em-dois-passos">Autenticação em dois passos</a></li>
      <li><a href="#gerenciador-de-senhas" id="markdown-toc-gerenciador-de-senhas">Gerenciador de senhas</a></li>
      <li><a href="#redes-sem-fio-sem-senha" id="markdown-toc-redes-sem-fio-sem-senha">Redes sem fio sem senha</a></li>
      <li><a href="#vpns" id="markdown-toc-vpns">VPNs</a></li>
      <li><a href="#extensões-para-navegador" id="markdown-toc-extensões-para-navegador">Extensões para navegador</a></li>
      <li><a href="#ligue-a-criptografia-do-seu-celular-e-computador" id="markdown-toc-ligue-a-criptografia-do-seu-celular-e-computador">Ligue a criptografia do seu celular e computador</a></li>
      <li><a href="#celular-e-protestos" id="markdown-toc-celular-e-protestos">Celular e protestos</a></li>
    </ol>
  </li>
  <li><a href="#o-que-usar-como" id="markdown-toc-o-que-usar-como">O que usar como…</a>    <ol>
      <li><a href="#mecanismo-de-busca" id="markdown-toc-mecanismo-de-busca">Mecanismo de Busca</a></li>
      <li><a href="#aplicativos-de-mensagem-instantânea" id="markdown-toc-aplicativos-de-mensagem-instantânea">Aplicativos de mensagem instantânea</a></li>
      <li><a href="#email" id="markdown-toc-email">Email</a></li>
      <li><a href="#compartilhamento-de-dados--nuvem" id="markdown-toc-compartilhamento-de-dados--nuvem">Compartilhamento de dados / Nuvem</a></li>
      <li><a href="#redes-sociais" id="markdown-toc-redes-sociais">Redes Sociais</a></li>
    </ol>
  </li>
</ol>

</nav>

<hr />

<h2 id="dicas-gerais">Dicas gerais</h2>

<h3 id="webcam-e-microfone">Webcam e microfone</h3>

<p>Podem parecer dicas batidas, mas cubra a sua webcam quando não estiver usando. A solução barata é um post-it na frente da câmera, mas existem alguns adesivos especialmente para esse fim que facilitam caso você usa a sua câmera com frequência para chamadas, que deslizam pra cubrir a câmera, dá pra achar por uns R$10 pela internet.</p>

<p>No caso do microfone, as instruções variam de modelo pra modelo, mas o conselho é o mesmo, desligue quando não estiver usando. Alguns notebooks tem um botão pra dar mute no microfone, outros não são tão fáceis.</p>

<p>Nos dois casos a idéia é evitar capturas indesejadas.</p>

<h3 id="autenticação-em-dois-passos">Autenticação em dois passos</h3>

<p>A autenticação em dois passos (conhecida como 2FA, do inglês <em>2-factor authentication</em>) deve ser ligada para todos os serviços possíveis. Evite usar autenticação em dois passos que dependa de recepção de SMS, prefira aplicativos que gerem a autenticação baseada em tempo, como o FreeOTP (alguns gerenciadores de senha tem essa opção, também).</p>

<p>Com a autenticação em dois passos ativada, para alguém ter acesso à uma das suas contas, além de ter acesso a sua senha, o atacante também deve ter acesso ao seu aplicativo gerador, o que dificulta bastante o acesso.</p>

<p>A autenticação por SMS sofre do problema de estar vulnerável a clonagem de chip, o que é extremamente comum. A vice escreveu <a href="https://motherboard.vice.com/en_us/article/vbqax3/hackers-sim-swapping-steal-phone-numbers-instagram-bitcoin" target="_blank" rel="noopener">um artigo, em inglês, sobre a técnica (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. De maneira curta: os atacantes fazem engenharia social para conseguir clonar os chips de dentro das operadoras. Com isso, conseguem os códigos de confirmação necessários para fazer login. Essa técnica foi usada para derrubar o grupo de facebook “Mulheres contra Bolsonaro”, por exemplo.</p>

<h3 id="gerenciador-de-senhas">Gerenciador de senhas</h3>

<p><strong>Use</strong>: <a href="https://bitwarden.com/" target="_blank" rel="noopener">bitwarden (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://keepassxc.org/" target="_blank" rel="noopener">KeePassXC (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a><br />
Evite: Salvar suas senhas no navegador</p>

<p>Toda semana tem um site sendo invadido e uma lista de senhas é disponibilizada na internet, listas essas que normalmente são uma combinação de emails e senhas. Usar a mesma senha em diversos sites faz com que haja o risco de que quando um site é atacado, todos os outros sites em que usamos a mesma senha possam então ser invadidos sem esforço algum.</p>

<p>Existem diversas aplicações que geram senhas para nós. A idéia dessas aplicações é que nós mantemos somente uma senha, mais complexa, e não sabemos as outras senhas que utilizamos em outros sites, usando senhas geradas por esses aplicativos que são complexas e individuais para cada site.</p>

<p>Usar um gerenciador de senhas requer uma mudança de mentalidade, para que nunca usemos “aquela” senha que a gente usa em todos os sites pra novos cadastros e pra que pouco a pouco possamos mudar as nossas senhas existentes.</p>

<p>Recomendo começar a mudança com passos de formiguinha: escolha um site que você usa bastante e use o gerenciador de senhas para esse site, e somente para ele, por alguns meses. A ideia é acostumar com o fato de ter que desbloquear o gerenciador e se acostumar de que você não vai saber a senha do site de cabeça e que não há problema nisso. E aí, num segundo passo, é começar a ir mudando senhas em outros sites, sempre usando senhas geradas.</p>

<p>Eu recomendo o <a href="https://bitwarden.com/" target="_blank" rel="noopener">bitwarden (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, disponível para a maioria dos sistemas operacionais e browsers, além de sincronizar automaticamente pela internet. Outra boa opção é o <a href="https://keepassxc.org/" target="_blank" rel="noopener">KeePassXC (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, que usa um arquivo local e permite mais controle, necessitando de um pouco mais de trabalho no sentido de ter que sincronizar o arquivo semi-manualmente (usando a nuvem para sincronizar automaticamente, ou pendrive e similares).</p>

<p>Não é diretamente relacionado, mas vale lembrar: evite salvar suas senhas no navegador; em alguns casos como no Chrome/Chromium elas são sincronizadas pela internet e é muito fácil de ter acesso indevido à essas senhas, mesmo usando outros navegadores. Mesmo que você decida usar suas próprias senhas, use algum gerenciador de senha pra digitar as senhas automaticamente pra você ao invés de salvar no navegador.</p>

<h3 id="redes-sem-fio-sem-senha">Redes sem fio sem senha</h3>

<p>Muito comum em aeroportos, hotéis e outros lugares públicos em geral, redes sem fio que não tenham senha devem ser evitadas. Todo o tráfego entre o seu computador (ou telefone) e a internet fica em aberto nessas redes. Qualquer um por perto pode capturar esse tráfego e saber os sites que você está acessando e caso o site não use <em>https</em>, pode inclusive capturar senhas e outros dados sensíveis.</p>

<p>Pra quando não dá pra escolher, o jeito é usar uma VPN.</p>

<h3 id="vpns">VPNs</h3>

<p>VPNs (em português: redes privadas virtuais) são uma camada extra de segurança em cima da sua rede. É como se você estabelecesse um túnel entre o seu dispositivo e o servidor da VPN, e para chegar à internet o tráfego tem de passar por esse túnel.</p>

<p>A vantagem desse tipo de túnel é que todo o tráfego é criptografado entre o seu dispositivo e o servidor, e o servidor pode estar em outros países (passando por bloqueios locais ou censuras a certos serviços). A desvantagem é que todo o seu tráfego vai passar por um servidor de terceiros.</p>

<p>Por esse motivo, VPNs gratuitas devem ser evitadas. Essas VPNs podem ser montadas com o propósito de coletar dados ou de servir malware.</p>

<p>Para uma lista completa, existe a lista do <a href="https://thatoneprivacysite.net/vpn-section/" target="_blank" rel="noopener">That One Privacy Site (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, que tem detalhadas comparações entre VPNs comerciais. Algumas recomendações bem cotadas na comparação: <a href="https://SecureVPN.to" target="_blank" rel="noopener">SecureVPN.to (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://www.mullvad.net/" target="_blank" rel="noopener">Mullvad (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://protonvpn.com/" target="_blank" rel="noopener">ProtonVPN (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://vikingvpn.com/" target="_blank" rel="noopener">VikingVPN (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>As assinaturas são meio caras mesmo, mas normalmente as VPNs permitem um número de conexões simultâneas, então dá pra rachar um pacote com pessoas próximas pra baratear.</p>

<h3 id="extensões-para-navegador">Extensões para navegador</h3>

<p>A internet atual é baseada em anúncios e redes de anunciantes adoram coletar todos os dados possíveis para cruzar o que nos mostrar. Para evitar esse tipo de rastreamento, o ideal é instalar algumas extensões que diminuem essa exposição, ao menos no computador:</p>

<ul>
  <li><a href="https://github.com/ialexsilva/uBlock/blob/master/README.md#instala%C3%A7%C3%A3o" target="_blank" rel="noopener">uBlock origin (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>: Bloqueia anúncios e coletores de informações mais comuns</li>
  <li><a href="https://www.eff.org/privacybadger" target="_blank" rel="noopener">Privacy Badger (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>: Extensão da Eletronic Frontier Foundation, que também bloqueia anúncios e coletores de informações comuns</li>
</ul>

<p>As duas extensões tem trabalhos semelhantes, mas com frequência bloqueiam coisas diferentes. Trabalhando em conjunto reduzem bastante o número de anúncios e informações que são coletadas por anunciantes.</p>

<h3 id="ligue-a-criptografia-do-seu-celular-e-computador">Ligue a criptografia do seu celular e computador</h3>

<p>Ligar a criptografia no seu celular vai ajudar no caso de perda ou furto, protegendo seus dados contra acesso indevido. Quase todo mundo bota uma senha pra desbloquear o celular, mas isso só protege contra um acesso direto. Encriptar o seu celular vai proteger contra acesso usando um computador e ferramentas para acessar o conteúdo do seu celular, sem nunca passar pela tela de desbloqueio.</p>

<p>Algumas notas:</p>
<ol>
  <li>ligar a criptografia pode fazer o seu celular ficar ligeiramente mais lento.</li>
  <li>para desligar a criptografia é necessário retornar o celular às configurações de fábrica</li>
</ol>

<p>É possível ligar a criptografia em quase todo telefone Android e em todos os iPhones. As instruções variam de aparelho para aparelho. No Android normalmente a configuração fica localizada na parte de segurança, enquanto no iPhone você precisar criar um código de acesso.</p>

<p>No computador também é possível ligar a criptografia para seus dados, os passos são bem diferentes dependendo da versão do seu sistema operacional, então é bom dar uma olhada na ajuda do seu sistema.</p>

<h3 id="celular-e-protestos">Celular e protestos</h3>

<p>Se alguem tem acesso físico aos seus dispositivos, fica muito mais difícil de se proteger. Um agente mal intencionado pode forçar você a revelar sua senha e ter acesso ao seu dispotivo. Evitar de levar seu celular pra manifestações pode não ser prático ou desejado (afinal, gravar qualquer coisa que esteja acontecendo pode ser uma parada valiosa depois).</p>

<p>Além da dica da criptografia, evite usar sua digital para destravar seu celular (pelo menos, pela duração do protesto).</p>

<h2 id="o-que-usar-como">O que usar como…</h2>

<h3 id="mecanismo-de-busca">Mecanismo de Busca</h3>
<figure><img alt="Captura de tela da página inicial do DuckDuckGo" src="/assets/2018-10-29_duckduckgo.png" /><figcaption>DuckDuckGo</figcaption></figure>

<p><strong>Use</strong>: <a href="https://duckduckgo.com/privacy" target="_blank" rel="noopener">DuckDuckGo (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://asciimoo.github.io/searx/" target="_blank" rel="noopener">Searx (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a><br />
Evite: Google, Bing</p>

<p>O Google armazena todos seus dados de busca, você pode ver todas as buscas que você realizou no google através de um painel de controle localizado em <a href="https://myactivity.google.com" target="_blank" rel="noopener">My Activity (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. O que isso quer dizer é que mais uma vez, seus dados podem ser acessados em caso de vulnerabilidade ou funcionários mal intencionados.</p>

<p>O Bing não está muito atrás, e embora tenha menos dados em sua posse, faz parte da Microsoft que não está muito melhor no quesito “gigante da tecnologia que guarda mais dados do que poderia”.</p>

<p><a href="https://duckduckgo.com/privacy" target="_blank" rel="noopener">DuckDuckGo (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> e <a href="https://asciimoo.github.io/searx/" target="_blank" rel="noopener">Searx (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> são dois serviços de buscas que tem a privacidade em mente, sem perder a qualidade das buscas.</p>

<h3 id="aplicativos-de-mensagem-instantânea">Aplicativos de mensagem instantânea</h3>

<figure><img alt="Captura de tela de um chat no Signal" src="/assets/2018-10-29_signal.png" height="600" /><figcaption>Signal</figcaption></figure>

<p><strong>Use</strong>: <a href="https://threema.ch/" target="_blank" rel="noopener">Threema (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://signal.org" target="_blank" rel="noopener">Signal (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a><br />
Evite: Whatsapp, Facebook Messenger, Google Hangouts, Google Chats, Telegram, Viber, WeChat, DMs no Twitter</p>

<p>Queremos evitar duas coisas no caso de mensagens instantâneas: armazenamento das mensagens nos servidores do aplicativo, porque podem ser recuperadas através de falhas de segurança ou de funcionários mal intencionados; criptografia ponto-a-ponto, para evitar que alguém possa ler as mensagens sem permissão.</p>

<p>O Whatsapp dispõe de criptografia ponto-a-ponto, mas é de propriedade do Facebook e não dá pra ter certeza de quantos metadados o Facebook armazena de todas as conversas.</p>

<p>O Messenger dispõe de “chats secretos”, mas o resto das conversas não é encriptada e é armazenada nos servidores do Facebook.</p>

<p>Hangouts e chats não dispõe de comunicação segura e toda a comunicação é armazenada nos servidores do Google.</p>

<p>Viber promete criptografia ponto-a-ponto, mas assim como o Whatsapp, não temos como saber o quão segura é a sua implementação.</p>

<p>Outros aplicativos, tais como WeChat não encriptam suas conversas e devem ser evitados.</p>

<p>O Telegram era minha primeira sugestão durante muito tempo. A interface é a melhor dentre os aplicativos de comunicação, mas o seu design faz com que por padrão as conversas não usem criptografia. Só as conversas criadas como “chat secreto” usam criptografia ponto-a-ponto, o que por consequência faz com que as mensagens de conversas normais sejam todas armazenadas nos servidores do Telegram.</p>

<p><a href="https://threema.ch/" target="_blank" rel="noopener">Threema (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> e <a href="https://signal.org" target="_blank" rel="noopener">Signal (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> encriptam suas mensagens e tem código aberto disponível para inspeção.</p>

<p>Numa versão anterior desse post eu recomendava o Wire, que também é encriptado ponta-a-ponta. Porém, em 2019 o Wire mudou de mãos e agora pertence a uma companhia estadunidense. Essa mudança foi <a href="https://www.thinkprivacy.ch/cutting-the-wire/" target="_blank" rel="noopener">bastante criticada (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> pela falta de transparência e por vir junto com <a href="https://en.wikipedia.org/wiki/Wire_(software)#Privacy_policy_changes" target="_blank" rel="noopener">mudanças suspeitas nos termos de uso (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Por isso, eu recomendo evitar o Wire se possível.</p>

<h3 id="email">Email</h3>

<figure><img alt="Captura de tela do app de Android do Tutanota" height="600" src="/assets/2018-10-29_tutanota.png" /><figcaption>Tutanota</figcaption></figure>

<p><strong>Use</strong>: <a href="https://protonmail.com/" target="_blank" rel="noopener">Protonmail (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://tutanota.com" target="_blank" rel="noopener">Tutanota (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a><br />
Evite: Gmail, Yahoo, Outlook</p>

<p>Assim como no caso de mensagens, queremos evitar que as mensagens estejam visíveis para a empresa que fornece o serviço. A única opção para isso são clientes de email que forneçam criptografia ponto-a-ponto, porque esses fazem seus emails serem criptografados no seu computador e somente o destinatário pode ver o email.</p>

<p>O Gmail tem umas funções que dão a impressão de que seus dados são criptografados, mas elas não são seguras.</p>

<p>As alternativas são <a href="https://tutanota.com" target="_blank" rel="noopener">Tutanota (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> ou <a href="https://protonmail.com/" target="_blank" rel="noopener">Protonmail (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Eu recomendo uma conta em cada um. Cada um implementa criptografia de uma maneira diferente e eles (ainda) não são compatíveis entre si. De modo que pra conseguir se comunicar com o máximo de gente possível de modo seguro, o ideal é ter uma conta em cada serviço. Pra quem ainda não usa o serviço, é possível enviar emails protegidos por senha, mas a senha tem que ser comunicada a quem vai receber de alguma forma segura.</p>

<h3 id="compartilhamento-de-dados--nuvem">Compartilhamento de dados / Nuvem</h3>

<p><strong>Use</strong>: <a href="https://nextcloud.com/" target="_blank" rel="noopener">Nextcloud (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a><br />
Evite: Dropbox, iCloud, Google Drive, OneDrive</p>

<p>A grande maioria dos aplicativos de armazenamento de dados na nuvem não tem encriptação dos seus dados. O que quer dizer que os seus arquivos podem ser recuperados por terceiros, por falha de segurança ou funcionários mal intencionados.</p>

<p>Dropbox, iCloud, Google Drive, OneDrive, Box, todas essas soluções de armazenamento na nuvem tem acesso aos seus arquivos.</p>

<p>A recomendação aqui é o <a href="https://nextcloud.com/" target="_blank" rel="noopener">Nextcloud (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Além de ter código aberto, a partir da versão 14 possui uma opção para que os arquivos sejam criptografados localmente e enviados para o servidor criptografados. Ou seja, somente com a sua senha você pode ter acesso aos seus arquivos.</p>

<h3 id="redes-sociais">Redes Sociais</h3>

<p>Evite: usar redes sociais pra fins de organização de movimentos, coletivos e afins</p>

<p>Aqui cabe um grande parenteses: no geral, redes sociais devem ser consideradas como veículos públicos. Grupos de facebook são ótimos pra trocar histórias, mas devem ser evitados como método de organização de movimentos, coletivos e qualquer outro tipo de luta, nenhuma informação nesses grupos é realmente privada. O mesmo é válido pra outras redes sociais como Twitter, mesmo se a sua conta for fechada, isso quer dizer que os seus seguidores, <em>e os funcionários do Twitter</em>, podem ler suas mensagens.</p>

<p>Um outro problema: Twitter, Facebook e afins usam algoritmos desconhecidos para mostrar ou não os posts para outras pessoas. Isso faz com que eles decidam o que é relevante ou não para ser lido e pode fazer informações importantes serem escondidas por não serem detectadas como “importantes” pelos algoritmos.</p>

<p>Uma nota: se for excluir suas redes sociais, mude os seus perfis para algum país da união européia por alguns dias antes, de preferência usando uma VPN. As leis de proteção de dados da união européia mudaram bastante com o <a href="https://pt.wikipedia.org/wiki/Regulamento_Geral_sobre_a_Prote%C3%A7%C3%A3o_de_Dados" target="_blank" rel="noopener">GDPR (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> e é mais garantido que seus dados sejam realmente removidos se o seu perfil for reconhecido como sendo da UE. <a href="https://en.wikipedia.org/wiki/Criticism_of_Facebook#Inability_to_voluntarily_terminate_accounts" target="_blank" rel="noopener">Vale notar que depois de alguns escândalos o Facebook promete que remover sua conta faz com que ela seja permanentemente removida (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>Para substituir grupos de Facebook uma opção pode ser usar <a href="http://matrix.org/" target="_blank" rel="noopener">Matrix (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, que permite a criação de grupos com criptografia inclusive para VoIP.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[(atualizado pela última vez em 6 de fevereiro de 2021)]]></summary></entry><entry><title type="html">Setting up the development environment for Mastodon on Arch Linux</title><link href="https://lond.com.br/2018/07/20/setting-up-the-development-environment-for-mastodon-on-arch-linux.html" rel="alternate" type="text/html" title="Setting up the development environment for Mastodon on Arch Linux" /><published>2018-07-20T00:00:00+02:00</published><updated>2018-07-20T00:00:00+02:00</updated><id>https://lond.com.br/2018/07/20/setting-up-the-development-environment-for-mastodon-on-arch-linux</id><content type="html" xml:base="https://lond.com.br/2018/07/20/setting-up-the-development-environment-for-mastodon-on-arch-linux.html"><![CDATA[<p>Well, on the last post I described <a href="/2018/07/13/running-a-mastodon-instance-using-archlinux">how to run a mastodon instance using Arch Linux</a>. But what if you wanted to contribute to Mastodon also?</p>

<p>I still plan to write maybe a small demo on how to get your hands dirty on Mastodon’s codebase, maybe fixing a small bug, but before that we need to have the development environment up and working!</p>

<p>Now, as it’s the case with the guide on <a href="/2018/07/13/running-a-mastodon-instance-using-archlinux">how to run your instance</a>, this guide is very similar to the <a href="https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Development-guide.md" target="_blank" rel="noopener">official guide (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, and when in doubt, you should double check the official guide because it’s more likely to be up-to-date. This guide is also very similar to how to run an instance, I mean, it’s the same software, right?</p>

<p>There is also an <a href="https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Vagrant-guide.md" target="_blank" rel="noopener">official guide to setting up your environment using vagrant (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> which might be easier if you have enough resources for a VM running side-by-side with your environment and/or does not run Linux.</p>

<p>This guide is focused on Mastodon, but most of the setup done here will work for other ruby on rails projects you might want to contribute to.</p>

<p><em>This was last updated on 31st of January, 2019.</em></p>

<hr />

<h3>Note on the choices made in this guide</h3>

<p>The official guide recommends <a href="http://rbenv.org/" target="_blank" rel="noopener">rbenv (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, but I’m more used to <a href="https://rvm.io/" target="_blank" rel="noopener">rvm (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. <code class="language-plaintext highlighter-rouge">rbenv</code> is likely to be more lightweight. So if you don’t have any preferences, you might want to stick to <a href="https://wiki.archlinux.org/index.php/Rbenv" target="_blank" rel="noopener">rbenv and ruby-build (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> when installing ruby.</p>

<p>Since this is a development setup, I’m not mentioning any security concerns. <br />
⚠️ Do not use this guide for running a production instance. ⚠️ <br />
Refer to <a href="/2018/07/13/running-a-mastodon-instance-using-archlinux">how to run a mastodon instance using Arch Linux</a> instead.</p>

<p>Questions are super welcome, you can contact me using any of the methods listed in the <a href="/about">about page</a>. Also if you notice that something doesn’t seem right, don’t hesitate to hit me up.</p>

<p>As with the other guide, I tested the steps on this guide on a virtual machine and they should work if you copy-paste them. Things might not work well if your computer has less than 2GB of ram.</p>

<hr />

<nav>
  <h3 class="toc_title">On this page</h3>
<ol id="markdown-toc">
  <li><a href="#general-mastodon-development-tips" id="markdown-toc-general-mastodon-development-tips">General Mastodon development tips</a></li>
  <li><a href="#dependencies" id="markdown-toc-dependencies">Dependencies</a></li>
  <li><a href="#postgresql-configuration" id="markdown-toc-postgresql-configuration">PostgreSQL configuration</a></li>
  <li><a href="#redis" id="markdown-toc-redis">Redis</a></li>
  <li><a href="#setting-up-ruby-and-node" id="markdown-toc-setting-up-ruby-and-node">Setting up ruby and node</a></li>
  <li><a href="#cloning-the-repo-and-installing-dependencies" id="markdown-toc-cloning-the-repo-and-installing-dependencies">Cloning the repo and installing dependencies</a>    <ol>
      <li><a href="#run-each-service-separately" id="markdown-toc-run-each-service-separately">Run each service separately</a></li>
      <li><a href="#run-everything-using-foreman" id="markdown-toc-run-everything-using-foreman">Run everything using Foreman</a></li>
    </ol>
  </li>
  <li><a href="#working-on-master" id="markdown-toc-working-on-master">Working on master</a></li>
  <li><a href="#tests" id="markdown-toc-tests">Tests</a></li>
  <li><a href="#other-useful-commands" id="markdown-toc-other-useful-commands">Other useful commands</a></li>
  <li><a href="#troubleshooting" id="markdown-toc-troubleshooting">Troubleshooting</a>    <ol>
      <li><a href="#rvm-says-its-not-a-function" id="markdown-toc-rvm-says-its-not-a-function">RVM says it’s not a function</a></li>
      <li><a href="#mastodon-has-no-css" id="markdown-toc-mastodon-has-no-css">Mastodon has no css</a></li>
    </ol>
  </li>
</ol>

</nav>

<hr />

<h3 id="general-mastodon-development-tips">General Mastodon development tips</h3>

<p>From the official guide:</p>

<blockquote>
  <p>You can use a localhost-&gt;world tunneling service like <a href="https://ngrok.com/" target="_blank" rel="noopener">ngrok (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> if you want to test federation, <strong>however</strong> that should not be your primary mode of operation. If you want to have a permanently federating server, set up a proper instance on a VPS with a domain name, and simply keep it up to date with your own fork of the project while doing development on localhost.</p>

  <p>Ngrok and similar services give you a random domain on each start up. This is good enough to test how the code you’re working on handles real-world situations. But as soon as your domain changes, for everybody else concerned you’re a different instance than before.</p>

  <p>Generally, federation bits are tricky to work on for exactly this reason - it’s hard to test. And when you are testing with a disposable instance you are polluting the databases of the real servers you’re testing against, usually not a big deal but can be annoying. The way I have handled this so far was thus: I have used ngrok for one session, and recorded the exchanges from its web interface to create fixtures and test suites. From then on I’ve been working with those rather than live servers.</p>

  <p>I advise to study the existing code and the RFCs before trying to implement any federation-related changes. It’s not <em>that</em> difficult, but I think “here be dragons” applies because it’s easy to break.</p>

  <p>If your development environment is running remotely (e.g. on a VPS or virtual machine), setting the <code class="language-plaintext highlighter-rouge">REMOTE_DEV</code> environment variable will swap your instance from using “letter opener” (which launches a local browser) to “letter opener web” (which collects emails and displays them at /letter_opener ).</p>
</blockquote>

<p>When trying to fix a bug or implement a new feature, it is a good idea to branch off the <code class="language-plaintext highlighter-rouge">master</code> branch with a new branch and then submit your pull request using that branch.</p>

<p>A good way to see that your environment is working as it should is to check out the latest stable release (for instance, at the time of writing the latest stable release is <code class="language-plaintext highlighter-rouge">v2.7.1</code>) and then run tests as suggested in the <a href="#tests">tests</a> session. They should all pass because the tests in stable releases should always be working.</p>

<hr />

<h3 id="dependencies">Dependencies</h3>

<p>Since we’re trying to run the same software as in the production guide, we’ll need mostly the same dependencies, this is what we’ll need:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">postgresql</code>: The SQL database used by Mastodon</li>
  <li><code class="language-plaintext highlighter-rouge">redis</code>: Used by mastodon for in-memory data store</li>
  <li><code class="language-plaintext highlighter-rouge">ffmpeg</code>: Used by mastodon for conversion of GIFs to MP4s.</li>
  <li><code class="language-plaintext highlighter-rouge">imagemagick</code>: Used by mastodon for image related operations</li>
  <li><code class="language-plaintext highlighter-rouge">protobuf</code>: Used by mastodon for language detection</li>
  <li><code class="language-plaintext highlighter-rouge">git</code>: Used for version control.</li>
  <li><code class="language-plaintext highlighter-rouge">python2</code>: Used by gyp, a node tool that builds native addons modules for node.js</li>
</ul>

<p>Besides those, it’s a good idea to install the <code class="language-plaintext highlighter-rouge">base-devel</code> group, since it comes with <code class="language-plaintext highlighter-rouge">gcc</code> and some ruby modules need to compile native extensions.</p>

<p>Now, you can install those with:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -S postgresql redis ffmpeg imagemagick protobuf git python2 base-devel
</code></pre></div></div>

<hr />

<h3 id="postgresql-configuration">PostgreSQL configuration</h3>

<p>Take a look at <a href="https://wiki.archlinux.org/index.php/PostgreSQL" target="_blank" rel="noopener">Arch Linux’s wiki about PostgreSQL (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.
The first thing to do is to initialize the database cluster. This is done by doing:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u postgres initdb --locale en_US.UTF-8 -E UTF8 -D '/var/lib/postgres/data'
</code></pre></div></div>

<p>If you want to use a different language, there’s no problem.</p>

<p>After this completes, you can then do</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start postgresql # will start postgresql
</code></pre></div></div>

<p>You will need to start postgresql every time you want to use it for development. You could also <code class="language-plaintext highlighter-rouge">enable</code> it so it starts with your system if you prefer, but it will be running and using resources even when you don’t need it.</p>

<p>Now that postgresql is running, we can create your user in postgresql:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Launch psql as the postgres user
sudo -u postgres psql
</code></pre></div></div>

<p>In the prompt that opens, you need to do the command below replacing the username you use on your setup.</p>
<pre><code class="language-SQL">-- Creates user with SUPERUSER permission level
CREATE USER &lt;your username here&gt; SUPERUSER;
</code></pre>

<p>The <code class="language-plaintext highlighter-rouge">SUPERUSER</code> level will let you do anything without having to change users. With great powers…</p>

<hr />

<h3 id="redis">Redis</h3>

<p>We also need to start redis. Same as postgresql:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start redis # will start redis
</code></pre></div></div>

<p>As with postgres, you can <code class="language-plaintext highlighter-rouge">enable</code> it too to make it start with the system, but personally I prefer to start on demand.</p>

<hr />

<h3 id="setting-up-ruby-and-node">Setting up ruby and node</h3>

<p>This part is very similar to the production guide, so I’ll copy and paste a bit:</p>

<p>First step is that we install <code class="language-plaintext highlighter-rouge">rvm</code> that will be used for configuring ruby. For that we’ll follow the instructions at <a href="https://rvm.io/" target="_blank" rel="noopener">rvm.io (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Before doing the following command, visit <a href="https://rvm.io/" target="_blank" rel="noopener">rvm.io (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> and check which keys need to be added with <code class="language-plaintext highlighter-rouge">gpg --keyserver hkp://keys.gnupg.net --recv-keys</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\curl -sSL https://get.rvm.io | bash -s stable
</code></pre></div></div>

<p>After that, we’ll have rvm. You will see that to use rvm in the same session you need to execute additional commands:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source $HOME/.rvm/scripts/rvm
</code></pre></div></div>

<p>With <code class="language-plaintext highlighter-rouge">rvm</code> installed, we can then install the ruby version that Mastodon uses:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rvm install 2.6.1
</code></pre></div></div>

<p>Now, this will take some time, drink some water, stretch and come back.</p>

<p>Similarly, we will install nvm for managing which node version we’ll use.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
</code></pre></div></div>

<p>Refer to <a href="https://github.com/creationix/nvm" target="_blank" rel="noopener">nvm github (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> for the latest version.</p>

<p>You will also need to run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] &amp;&amp; \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] &amp;&amp; \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
</code></pre></div></div>

<p>And add these same lines to <code class="language-plaintext highlighter-rouge">~/.bash_profile</code></p>

<p>And then to install the node version we’re using:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nvm install 8.11.3
</code></pre></div></div>

<p>And to install yarn:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install -g yarn
</code></pre></div></div>

<p>While we’re at it, we also need to install bundler:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem install bundler
</code></pre></div></div>

<p>And with that we have ruby and npm dependencies ready to go.</p>

<hr />

<h3 id="cloning-the-repo-and-installing-dependencies">Cloning the repo and installing dependencies</h3>

<p>You need to clone the repo somewhere on your computer. I usually clone my projects in a <code class="language-plaintext highlighter-rouge">source</code> folder in my home directory, if you do different, change the following instructions accordingly.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~/source
git clone https://github.com/tootsuite/mastodon.git
</code></pre></div></div>

<p>And then, <code class="language-plaintext highlighter-rouge">cd ~/source/mastodon</code> and we will install the dependencies of the project:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle install # install ruby dependencies
yarn install --pure-lockfile # install node dependencies
</code></pre></div></div>

<p>This will also take a while, try to relax a bit, have you listened to your favorite song today? 🎶</p>

<p>Since we created the postgres user before, we can setup the development database using:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle exec rails db:setup
</code></pre></div></div>

<p>This will use the default development configuration to setup the database. Which means: no password, same user as your username, using a database named <code class="language-plaintext highlighter-rouge">mastodon_development</code> in localhost.</p>

<p>In development mode the database is setup with an admin account for you to test with. The email address will be <code class="language-plaintext highlighter-rouge">admin@YOURDOMAIN</code> (e.g. admin@localhost:3000) and the password will be <code class="language-plaintext highlighter-rouge">mastodonadmin</code>.</p>

<p>Now, you have two options.</p>

<hr />

<h4 id="run-each-service-separately">Run each service separately</h4>

<p>If you checked out the guide to run an instance, you probably noticed that mastodon has three parts: A web service, a sidekiq service to run background jobs and a streaming service. In development you need those three components too, plus the webpack development server, which will compile assets (javascript, css) as needed. In production we don’t need webpack running all the time because we compile the assets only once after we update Mastodon.</p>

<p>To run those separately, you will need one window for each, since each of those holds your terminal while it’s running.</p>

<p>To run the web server:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle exec puma -C config/puma.rb
</code></pre></div></div>

<p>To run sidekiq:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle exec sidekiq
</code></pre></div></div>

<p>To run the streaming service:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PORT=4000 yarn run start
</code></pre></div></div>

<p>And to run webpack:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./bin/webpack-dev-server --listen-host 0.0.0.0
</code></pre></div></div>

<p>All of those should start immediately, except for the webpack server, which compiles the assets before starting.</p>

<p>To check that everything is working as expected, if you open your browser window at <code class="language-plaintext highlighter-rouge">http://localhost:3000</code> you should see Mastodon landing page!</p>

<hr />

<h4 id="run-everything-using-foreman">Run everything using Foreman</h4>

<p>Now, most of the time this method is more practical. Running each service by itself is good if one is not starting to see what is the error, but most of the time you’ll want to start everything so that you can start coding away. In which case, first you’ll want to install foreman</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem install foreman
</code></pre></div></div>

<p>And then, when you need to start your dev environment you can do:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>foreman start -f Procfile.dev
</code></pre></div></div>

<hr />

<h3 id="working-on-master">Working on master</h3>

<p>When working on master, the steps are similar to when updating an instance, but they happen much more frequently since master changes much more frequently.</p>

<p>This means, every time you pull changes into your computer (for instance, when you do <code class="language-plaintext highlighter-rouge">git pull origin master</code>), you might need to:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Update any gems that were changed
bundle install
# Update any node packages that were changed
yarn install --pure-lockfile
# Update the database to the latest version
bin/rails db:migrate RAILS_ENV=development
</code></pre></div></div>

<p>Now, you don’t need to run them all the time, you will notice if one of them is not working as it should. How?</p>

<p>Bundler complains like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Could not find proper version of railties (5.2.0) in any of the sources
Run `bundle install` to install missing gems.
</code></pre></div></div>

<p>The name of the gem and version will change, but this means that one of your dependencies is not up to date and you need to run <code class="language-plaintext highlighter-rouge">bundle install</code> again.</p>

<p>If the database is missing a migration, rails will complain with:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ActiveRecord::PendingMigrationError - Migrations are pending. To resolve this issue, run:

        bin/rails db:migrate RAILS_ENV=development
</code></pre></div></div>

<p>This will appear on your console, but also on your browser.</p>

<p>If the ruby being used in the project is updated, you will also see some complaints from rvm (in this example, with a hypothetical ruby 2.6.2):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd .
Required ruby-2.6.2 is not installed.
To install do: 'rvm install "ruby-2.6.2"'
</code></pre></div></div>

<p>In that case we need to do the same as we did to install it the first time, that is:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rvm install 2.6.2
</code></pre></div></div>

<p>And since rvm manages gems by ruby version, you’ll need to install the dependencies again using <code class="language-plaintext highlighter-rouge">bundle install</code>.</p>

<hr />

<h3 id="tests">Tests</h3>

<p>Tests in the mastodon project live in the <code class="language-plaintext highlighter-rouge">spec</code> folder. Tests also use migrations, so if the database was updated since you last ran tests, you will need to run something like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bin/rails db:migrate RAILS_ENV=test
</code></pre></div></div>

<p>But when you try to run tests with a database missing migrations, you’ll get an error from Rails that will explain exactly that.</p>

<p>To run all the tests, you need to do:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rspec
</code></pre></div></div>

<p>To run only one test, you can run it like so:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rspec spec/validators/status_length_validator_spec.rb
</code></pre></div></div>

<hr />

<h3 id="other-useful-commands">Other useful commands</h3>

<p>If you add a new string that needs to be translated, you can run</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yarn manage:translations
</code></pre></div></div>

<p>To update the localization files. This is needed so that <a href="https://weblate.joinmastodon.org" target="_blank" rel="noopener">weblate (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> can inform translators that there are new strings to be translated in other languages.</p>

<p>You can check code quality using</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rubocop
</code></pre></div></div>

<p>Have in mind that it might complain about code violations that you did not introduce, but you should always try not to introduce new violations.</p>

<hr />

<h3 id="troubleshooting">Troubleshooting</h3>

<h4 id="rvm-says-its-not-a-function">RVM says it’s not a function</h4>

<p>Follow recommended instructions at <a href="https://rvm.io/integration/gnome-terminal" target="_blank" rel="noopener">https://rvm.io/integration/gnome-terminal (opens in a new window <i class="fa fa-window-restore" aria-hidden="true"></i>)</a></p>

<h4 id="mastodon-has-no-css">Mastodon has no css</h4>
<p>If mastodon has no css and you see something like <code class="language-plaintext highlighter-rouge">#&lt;Errno::ECONNREFUSED: Failed to open TCP connection to localhost:3035 (Connection refused - connect(2) for "::1" port 3035)&gt;</code> in your console, the issue is where webpacker is trying to connect. You can fix it by changing <code class="language-plaintext highlighter-rouge">config/webpacker.yml</code>.
Instead of</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  dev_server:
    host: localhost
</code></pre></div></div>

<p>Use</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  dev_server:
    host: 127.0.0.1
</code></pre></div></div>]]></content><author><name></name></author><category term="Mastodon" /><category term="Arch Linux" /><category term="Redes sociais" /><category term="Descentralização" /><category term="Código aberto" /><category term="Decentralization" /><category term="Open Source" /><category term="Twitter" /><category term="Social Network" /><category term="Linux" /><summary type="html"><![CDATA[Well, on the last post I described how to run a mastodon instance using Arch Linux. But what if you wanted to contribute to Mastodon also?]]></summary></entry><entry><title type="html">Running a Mastodon instance using Arch Linux</title><link href="https://lond.com.br/2018/07/13/running-a-mastodon-instance-using-archlinux.html" rel="alternate" type="text/html" title="Running a Mastodon instance using Arch Linux" /><published>2018-07-13T00:00:00+02:00</published><updated>2018-07-13T00:00:00+02:00</updated><id>https://lond.com.br/2018/07/13/running-a-mastodon-instance-using-archlinux</id><content type="html" xml:base="https://lond.com.br/2018/07/13/running-a-mastodon-instance-using-archlinux.html"><![CDATA[<p>It’s been a while now that I’ve been running <a href="https://masto.donte.com.br" target="_blank">masto.donte.com.br</a> using Arch Linux and since the <a href="https://docs.joinmastodon.org/administration/installation/" target="_blank">official guide</a> recommends using Ubuntu 18.04, I figured that describing what I did could help someone out there. If in doubt, use the official guide instructions instead, since they’re more likely to be up to date.</p>

<p><em>This was last updated on 31st of January, 2019.</em></p>

<h2>Notes about some choices made in this guide</h2>

<p>The official guide recommends <a href="http://rbenv.org/" target="_blank">rbenv</a>, but I’m more used to <a href="https://rvm.io/" target="_blank">rvm</a>. <code class="language-plaintext highlighter-rouge">rbenv</code> is likely to be more lightweight. So if you don’t have any preferences, you might want to stick to <a href="https://wiki.archlinux.org/index.php/Rbenv" target="_blank">rbenv and ruby-build</a> when installing ruby.</p>

<p>There’s also choices made regarding firewall. You do not need to follow those exact ones if you already have another firewall on your server or if you want to use a different one. However, do use some firewall. :)</p>

<p>Like the official guide, this guide assumes you’re using Let’s Encrypt for the certificates. If it’s not the case, you can ignore let’s encrypt references and configure your own certificate in Nginx.</p>

<p>Also note that the SSL configurations for <code class="language-plaintext highlighter-rouge">nginx</code> are slightly different than the ones in the official guide. They are aimed at being compatible with older android phones and were generated using <a href="https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.14.0&amp;openssl=1.1.0h&amp;hsts=yes&amp;profile=intermediate" target="_blank">Mozilla SSL Configuration Generator</a> with the intermediate configuration and <a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security" target="_blank">HSTS</a> enabled. Have in mind that HSTS disables non-secure traffic and gets cached on the client side, so if you are unsure, generate a new configuration without HSTS.</p>

<p>Questions are super welcome, you can contact me using any of the methods listed in the <a href="/about">about page</a>. Also if you notice that something doesn’t seem right, don’t hesitate to hit me up.</p>

<p>I tested this guide using a digital ocean droplet with 1GB memory and 1vCPU. I had to enable swap to be able to compile the assets. There’s more information about this in the relevant section.</p>

<hr />

<nav>
  <h3 class="toc_title">On this page</h3>
<ol id="markdown-toc">
  <li><a href="#before-starting-the-guide" id="markdown-toc-before-starting-the-guide">Before starting the guide</a></li>
  <li><a href="#what-you-should-have-by-the-end-of-this" id="markdown-toc-what-you-should-have-by-the-end-of-this">What you should have by the end of this</a></li>
  <li><a href="#general-suggestions" id="markdown-toc-general-suggestions">General suggestions</a></li>
  <li><a href="#dns" id="markdown-toc-dns">DNS</a></li>
  <li><a href="#dependencies" id="markdown-toc-dependencies">Dependencies</a></li>
  <li><a href="#configuring-ufw" id="markdown-toc-configuring-ufw">Configuring ufw</a></li>
  <li><a href="#configuring-nginx" id="markdown-toc-configuring-nginx">Configuring Nginx</a></li>
  <li><a href="#intermission-configuring-lets-encrypt" id="markdown-toc-intermission-configuring-lets-encrypt">Intermission: Configuring Let’s Encrypt</a></li>
  <li><a href="#finishing-off-nginx-configuration" id="markdown-toc-finishing-off-nginx-configuration">Finishing off nginx configuration</a></li>
  <li><a href="#mastodon-user-setup" id="markdown-toc-mastodon-user-setup">Mastodon user setup</a></li>
  <li><a href="#cloning-mastodon-repository-and-installing-dependencies" id="markdown-toc-cloning-mastodon-repository-and-installing-dependencies">Cloning mastodon repository and installing dependencies</a></li>
  <li><a href="#postgresql-configuration" id="markdown-toc-postgresql-configuration">PostgreSQL configuration</a></li>
  <li><a href="#redis-configuration" id="markdown-toc-redis-configuration">Redis configuration</a></li>
  <li><a href="#mastodon-application-configuration" id="markdown-toc-mastodon-application-configuration">Mastodon application configuration</a></li>
  <li><a href="#intermission-mastodon-directory-permissions" id="markdown-toc-intermission-mastodon-directory-permissions">Intermission: Mastodon directory permissions</a></li>
  <li><a href="#mastodon-systemd-service-files" id="markdown-toc-mastodon-systemd-service-files">Mastodon systemd service files</a></li>
  <li><a href="#emails" id="markdown-toc-emails">Emails</a></li>
  <li><a href="#monitoring-with-uptime-robot" id="markdown-toc-monitoring-with-uptime-robot">Monitoring with uptime robot</a></li>
  <li><a href="#remote-media-attachment-cache-cleanup" id="markdown-toc-remote-media-attachment-cache-cleanup">Remote media attachment cache cleanup</a></li>
  <li><a href="#renew-lets-encrypt-certificates" id="markdown-toc-renew-lets-encrypt-certificates">Renew Let’s Encrypt certificates</a></li>
  <li><a href="#updating-between-mastodon-versions" id="markdown-toc-updating-between-mastodon-versions">Updating between Mastodon versions</a></li>
  <li><a href="#upgrading-arch-linux" id="markdown-toc-upgrading-arch-linux">Upgrading Arch Linux</a></li>
  <li><a href="#optional-adding-elasticsearch-for-searching-authorized-statuses" id="markdown-toc-optional-adding-elasticsearch-for-searching-authorized-statuses">(Optional) Adding elasticsearch for searching authorized statuses</a></li>
</ol>

</nav>

<hr />

<h3 id="before-starting-the-guide">Before starting the guide</h3>

<p>You need:</p>
<ul>
  <li>A server running at least a base install of <a href="https://wiki.archlinux.org/index.php/installation_guide" target="_blank">Arch Linux</a></li>
  <li>Root access</li>
  <li>A domain or sub-domain to use for the instance.</li>
</ul>

<p>What is assumed:</p>
<ul>
  <li>There’s no service running in the same ports as Mastodon. If that’s the case, adjustments will need to be made throughout the guide.</li>
  <li>You’re not using root as your base user. You do have a user configured with sudo access.</li>
  <li>You already configured <a href="https://wiki.archlinux.org/index.php/Network_Time_Protocol_daemon" target="_blank">NTP</a> or something similar. Some operations, like 2-Factor Authentication need the correct time on your server.</li>
</ul>

<hr />

<h3 id="what-you-should-have-by-the-end-of-this">What you should have by the end of this</h3>

<p>You should have an instance running with a basic firewall, a valid https certificate and prepared to be upgraded when needed. All the services needed will be on the same machine. Basic monitoring to know if your instance is up or not.</p>

<hr />

<h3 id="general-suggestions">General suggestions</h3>

<p>If you have no experience with Linux systems administrations, it’s a good idea to <a href="https://wiki.archlinux.org/index.php/security" target="_blank">read a bit about it</a>. You will need to keep this system up to date since it will be facing the internet.</p>

<p>Do not reuse <a href="https://wiki.archlinux.org/index.php/security#Passwords" target="_blank">passwords</a> and <a href="https://wiki.archlinux.org/index.php/Secure_Shell#Force_public_key_authentication" target="_blank">force public key</a> for your SSH user. Use <a href="https://wiki.archlinux.org/index.php/security#Use_sudo_instead_of_su" target="_blank">sudo instead of running everything as root</a> and <a href="https://wiki.archlinux.org/index.php/Secure_Shell#Deny" target="_blank">disable root login over ssh</a>.</p>

<p>The official guide already recommends this, but I’ll go one step further:
Always use <code class="language-plaintext highlighter-rouge">tmux</code> or <code class="language-plaintext highlighter-rouge">screen</code> when doing operations on your server. You will need to learn the <a href="https://tmuxcheatsheet.com/" target="_blank">basic commands</a> but it’s well worth it to avoid losing things if your connection go down and also for long operations in which you can disconnect and leave it running.</p>

<p>If you have 1GB it’s quite likely that asset compilation will fail. Remember to setup a swap partition or use <a href="https://wiki.archlinux.org/index.php/swap#systemd-swap">systemd-swap</a></p>

<hr />

<h3 id="dns">DNS</h3>

<p>The domain you’re planning to use should have DNS records pointing to your server. If your server has a IPv6 address, you should also configure an AAAA record, otherwise, only the A record should be enough.</p>

<p>Now, this guide will not get into <a href="https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md" target="_blank">serving a different domain</a>. Just have in mind that:</p>
<ul>
  <li>The domain will be part of the identifier of your instance users. Once it’s defined, you cannot change it anymore or you’ll get all kinds of federation weirdness.</li>
  <li>Because of that, avoid using “temporary” domains, like the ones coming from ngrok or similar.</li>
</ul>

<hr />

<h3 id="dependencies">Dependencies</h3>
<ul>
  <li><code class="language-plaintext highlighter-rouge">ufw</code>: An easy-to-use firewall</li>
  <li><code class="language-plaintext highlighter-rouge">certbot</code> and <code class="language-plaintext highlighter-rouge">certbox-nginx</code>: used for generating the certificates from Let’s Encrypt.</li>
  <li><code class="language-plaintext highlighter-rouge">nginx</code>: Frontend web server that will be used in this setup</li>
  <li><code class="language-plaintext highlighter-rouge">jemalloc</code>: Different memory management library that improves memory usage for this setup.</li>
  <li><code class="language-plaintext highlighter-rouge">postgresql</code>: The SQL database used by Mastodon</li>
  <li><code class="language-plaintext highlighter-rouge">redis</code>: Used by mastodon for in-memory data store</li>
  <li><code class="language-plaintext highlighter-rouge">ffmpeg</code>: Used by mastodon for conversion of GIFs to MP4s.</li>
  <li><code class="language-plaintext highlighter-rouge">imagemagick</code>: Used by mastodon for image related operations</li>
  <li><code class="language-plaintext highlighter-rouge">protobuf</code>: Used by mastodon for language detection</li>
  <li><code class="language-plaintext highlighter-rouge">git</code>: Used for version control.</li>
  <li><code class="language-plaintext highlighter-rouge">python2</code>: Used by gyp, a node tool that builds native addons modules for node.js</li>
  <li><code class="language-plaintext highlighter-rouge">libxslt</code>, <code class="language-plaintext highlighter-rouge">libyaml</code>: I don’t know. They were in the official guide so I’m installing them, but I have to say: I do not have they installed in other instances and never noticed an issue 🤷🏽‍♂️</li>
</ul>

<p>Besides those, it’s a good idea to install the <code class="language-plaintext highlighter-rouge">base-devel</code> group. It comes with <code class="language-plaintext highlighter-rouge">sudo</code> and other tools which might come in handy.</p>

<p>Now, you can install those with:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -S ufw certbot nginx jemalloc postgresql redis ffmpeg imagemagick protobuf git base-devel python2 libxslt libyaml
sudo pacman -S --asdeps certbot-nginx
</code></pre></div></div>

<hr />

<h3 id="configuring-ufw">Configuring ufw</h3>

<p>🛑<strong>WARNING</strong>: Configuring a firewall is quite important, but if something goes wrong you might lose connectivity to your server. Make sure you have other ways of reaching your server if something goes wrong. 🛑</p>

<p>Now, Mastodon runs a couple of different services and to support it we will be running different services too, but since we will have everything in the same server, the only ports that should be available for the outside world are the HTTP/HTTPS ports that will be used to connect to the instance. Also, we want the SSH port open so that we can connect remotely to the server.</p>

<p>You should read into <a href="https://wiki.archlinux.org/index.php/Uncomplicated_Firewall" target="_blank">Arch Linux’s wiki about ufw</a>. For this guide what you want is to do:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo ufw allow SSH # this allows SSH traffic to your server
sudo ufw allow WWW # this allows traffic on port 80 to your server
sudo ufw allow "WWW Secure" # this allows traffic on port 443 to your server
</code></pre></div></div>

<p>And then you can do:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo ufw enable
sudo systemctl enable ufw # Enables ufw to be started at startup
sudo systemctl start ufw # starts ufw
</code></pre></div></div>

<p>And with this the firewall should be up :)</p>

<hr />

<h3 id="configuring-nginx">Configuring Nginx</h3>

<p>You should read into <a href="https://wiki.archlinux.org/index.php/Nginx" target="_blank">Arch Linux’s wiki about nginx</a>, but again, what you want to do is something along these lines:</p>

<p>First, you want to edit <code class="language-plaintext highlighter-rouge">nginx.conf</code>.
To remove the “welcome to nginx” page, you want to change the beginning of your <code class="language-plaintext highlighter-rouge">server</code> block to something like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    server {
        listen       80 default_server;
        server_name  '';

        return 444;
</code></pre></div></div>

<p>And at the very end of the <code class="language-plaintext highlighter-rouge">http</code> block, add:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    types_hash_max_size 4096; # sets the maximum size of the types hash tables
    include sites-enabled/*; # Includes any configuration located in /etc/nginx/sites-enabled
</code></pre></div></div>

<p>And then create these two directories:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mkdir /etc/nginx/sites-available # All domain configurations will live here
sudo mkdir /etc/nginx/sites-enabled # The enabled ones will be linked here
</code></pre></div></div>

<p>Now, let’s say we’re using <code class="language-plaintext highlighter-rouge">my.instance.com</code> as the instance domain/sub-domain. You will need to replace this accordingly throughout this next steps.</p>

<p>Create a new file <code class="language-plaintext highlighter-rouge">/etc/nginx/sites-available/my.instance.com.conf</code>, replacing <code class="language-plaintext highlighter-rouge">my.instance.com</code> by your domain, and then add to it the following content:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

server {
  listen 80;
  listen [::]:80;
  server_name my.instance.com;
  root /home/mastodon/live/public;
  # Useful for Let's Encrypt
  location /.well-known/acme-challenge/ { allow all; }
  location / { return 301 https://$host$request_uri; }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name my.instance.com;

  ssl_certificate     /etc/letsencrypt/live/my.instance.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/my.instance.com/privkey.pem;
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:10m;
  ssl_session_tickets off;

  ssl_dhparam /etc/ssl/certs/dhparam.pem;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
  ssl_prefer_server_ciphers on;

  add_header Strict-Transport-Security max-age=15768000;

  ssl_stapling on;
  ssl_stapling_verify on;

  ssl_trusted_certificate /etc/letsencrypt/live/my.instance.com/chain.pem;

  resolver 8.8.8.8 8.8.4.4 valid=300s;
  resolver_timeout 5s;

  keepalive_timeout    70;
  sendfile             on;
  client_max_body_size 8m;

  root /home/mastodon/live/public;

  gzip on;
  gzip_disable "msie6";
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

  add_header Strict-Transport-Security "max-age=31536000";

  location / {
    try_files $uri @proxy;
  }

  location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
    add_header Cache-Control "public, max-age=31536000, immutable";
    try_files $uri @proxy;
  }

  location /sw.js {
    add_header Cache-Control "public, max-age=0";
    try_files $uri @proxy;
  }

  location @proxy {
    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 https;
    proxy_set_header Proxy "";
    proxy_pass_header Server;

    proxy_pass http://127.0.0.1:3000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  location /api/v1/streaming {
    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 https;
    proxy_set_header Proxy "";

    proxy_pass http://127.0.0.1:4000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  error_page 500 501 502 503 504 /500.html;
}
</code></pre></div></div>

<p>⚠️ It’s a good idea to take a look if something changed in relation to the <a href="https://docs.joinmastodon.org/administration/installation/#setting-up-nginx" target="_blank">official guide</a> ⚠️</p>

<p>At this point <code class="language-plaintext highlighter-rouge">nginx</code> still doesn’t know about our instance (because we’re including files from <code class="language-plaintext highlighter-rouge">/etc/nginx/sites-enabled</code> and we created the file in <code class="language-plaintext highlighter-rouge">/etc/nginx/sites-available</code>), however, we should be able to start <code class="language-plaintext highlighter-rouge">nginx</code> already.</p>

<p>For that, we need to do:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start nginx # Starts the nginx service
sudo systemctl enable nginx # Makes the service start automatically at boot
</code></pre></div></div>

<p>If you do <code class="language-plaintext highlighter-rouge">curl -v &lt;your server ip&gt;</code> now, you should see something like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ curl -v &lt;your server's ip&gt;
* Rebuilt URL to: &lt;your server's ip&gt;/
*   Trying &lt;your server's ip&gt;...
* TCP_NODELAY set
* Connected to &lt;your server's ip&gt; (&lt;your server's ip&gt;) port 80 (#0)
&gt; GET / HTTP/1.1
&gt; Host: &lt;your server's ip&gt;
&gt; User-Agent: curl/7.60.0
&gt; Accept: */*
&gt;
* Empty reply from server
* Connection #0 to host &lt;your server's ip&gt; left intact
curl: (52) Empty reply from server
</code></pre></div></div>

<p>And that means <code class="language-plaintext highlighter-rouge">nginx</code> was correctly started and that <code class="language-plaintext highlighter-rouge">ufw</code> is allowing connections as expected. We will now get our certificates from Let’s Encrypt before jumping back to nginx configuration</p>

<hr />

<h3 id="intermission-configuring-lets-encrypt">Intermission: Configuring Let’s Encrypt</h3>

<p>Now, for Let’s Encrypt we will use <code class="language-plaintext highlighter-rouge">certbot</code>, that we installed previously. For more information about it you can take a look at <a href="https://wiki.archlinux.org/index.php/Certbot" target="_blank">Arch Linux’s wiki about Certbot</a>. For this guide, you need to run the following command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo certbot --nginx certonly -d my.instance.com
</code></pre></div></div>

<p>As usual, remind to change the url to the url for your actual instance. You will need to follow the instructions on screen.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel:

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
-------------------------------------------------------------------------------
(Y)es/(N)o:
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for my.instance.com
Using default address 80 for authentication.
2018/07/13 18:28:47 [notice] 4617#4617: signal process started
Waiting for verification...
Cleaning up challenges
2018/07/13 18:28:53 [notice] 4619#4619: signal process started
</code></pre></div></div>

<p>If everything goes as expected, you should see something like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/my.instance.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/my.instance.com/privkey.pem
   Your cert will expire on 2018-10-11. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
</code></pre></div></div>

<p>This means that now we have a valid certificate and that we can go back to nginx. Double check that the path informed by certbot (in this example <code class="language-plaintext highlighter-rouge">/etc/letsencrypt/live/my.instance.com/fullchain.pem</code>) matches the one in your nginx file.</p>

<p>Let’s Encrypt certificates only last for 90 days, so we will still come back to this. But for now, let’s go back to nginx.</p>

<p>If you have an error like</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Saving debug log to /var/log/letsencrypt/letsencrypt.log
An unexpected error occurred:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 10453: ordinal not in range(128)
Please see the logfiles in /var/log/letsencrypt for more details.
</code></pre></div></div>
<p>Check that you have set up correctly your locale! If your locale is set to <code class="language-plaintext highlighter-rouge">C</code>, certbot will fail.</p>

<hr />

<h3 id="finishing-off-nginx-configuration">Finishing off nginx configuration</h3>

<p>At this point the certificate should be working. Since this configuration is using HSTS, we also need to generate a <a href="https://security.stackexchange.com/questions/38206/can-someone-explain-what-exactly-is-accomplished-by-generation-of-dh-parameters" target="_blank">dhparam</a>. You can do that by doing (might take a little while!)</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>openssl dhparam -out dhparam.pem 2048
sudo mv dhparam.pem /etc/ssl/certs/dhparam.pem
</code></pre></div></div>

<p>What is left for us to do is to enable the instance configuration and reload nginx. We should do this (remember to replace with your instance config!):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo ln -s /etc/nginx/sites-available/my.instance.com.conf /etc/nginx/sites-enabled/ # creates a softlink of the configuration we created previously to the enabled sites directory
sudo systemctl reload nginx
</code></pre></div></div>

<p>Now, if everything went fine, your nginx should reload. Otherwise, it will throw some error like this:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>systemctl reload nginx
Job <span class="k">for </span>nginx.service failed because the control process exited with error code.
See <span class="s2">"systemctl status nginx.service"</span> and <span class="s2">"journalctl -xe"</span> <span class="k">for </span>details.
</code></pre></div></div>

<p>In that case, you need to execute one of the commands and try to see what went wrong.</p>

<p>However, if everything went right until now, if you do <code class="language-plaintext highlighter-rouge">curl -v my.instance.com</code> replacing for your domain, you should see something like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ curl -v my.instance.com
* Rebuilt URL to: my.instance.com/
*   Trying &lt;your server's ip&gt;...
* TCP_NODELAY set
* Connected to my.instance.com (&lt;your server's ip&gt;) port 80 (#0)
&gt; GET / HTTP/1.1
&gt; Host: my.instance.com
&gt; User-Agent: curl/7.60.0
&gt; Accept: */*
&gt;
&lt; HTTP/1.1 301 Moved Permanently
&lt; Server: nginx/1.14.0
&lt; Date: Fri, 13 Jul 2018 18:41:17 GMT
&lt; Content-Type: text/html
&lt; Content-Length: 185
&lt; Connection: keep-alive
&lt; Location: https://my.instance.com/
&lt;
&lt;html&gt;
&lt;head&gt;&lt;title&gt;301 Moved Permanently&lt;/title&gt;&lt;/head&gt;
&lt;body bgcolor="white"&gt;
&lt;center&gt;&lt;h1&gt;301 Moved Permanently&lt;/h1&gt;&lt;/center&gt;
&lt;hr&gt;&lt;center&gt;nginx/1.14.0&lt;/center&gt;
&lt;/body&gt;
&lt;/html&gt;
* Connection #0 to host my.instance.com left intact
</code></pre></div></div>

<p>And if you curl or visit the https address you should get a <code class="language-plaintext highlighter-rouge">502 Bad Gateway</code>.</p>

<hr />

<h3 id="mastodon-user-setup">Mastodon user setup</h3>

<p>We need to create the Mastodon user:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo useradd -m mastodon # create the user
</code></pre></div></div>

<p>Then, we will start using this user for the following commands:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo su - mastodon
</code></pre></div></div>

<p>First step is that we install <code class="language-plaintext highlighter-rouge">rvm</code> that will be used for configuring ruby. For that we’ll follow the instructions at <a href="https://rvm.io/" target="_blank">rvm.io</a>. Before doing the following command, visit <a href="https://rvm.io/" target="_blank">rvm.io</a> and check which keys need to be added with <code class="language-plaintext highlighter-rouge">gpg --keyserver hkp://keys.gnupg.net --recv-keys</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\curl -sSL https://get.rvm.io | bash -s stable
</code></pre></div></div>

<p>After that, we’ll have rvm. You will see that to use rvm in the same session you need to execute additional commands:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source /home/mastodon/.rvm/scripts/rvm
</code></pre></div></div>

<p>With <code class="language-plaintext highlighter-rouge">rvm</code> installed, we can then install the ruby version that Mastodon uses:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rvm install 2.6.1 -C --with-jemalloc
</code></pre></div></div>

<p>Note that the <code class="language-plaintext highlighter-rouge">-C --with-jemalloc</code> parameter is there so that we use jemalloc instead the standard memory allocation library, since it’s more efficient in Mastodon’s case. Now, this will take some time, drink some water, stretch and come back.</p>

<p>Similarly, we will install nvm for managing which node version we’ll use.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
</code></pre></div></div>

<p>Refer to <a href="https://github.com/creationix/nvm" target="_blank">nvm github</a> for the latest version.</p>

<p>You will also need to run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] &amp;&amp; \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] &amp;&amp; \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
</code></pre></div></div>

<p>And add these same lines to <code class="language-plaintext highlighter-rouge">~/.bash_profile</code></p>

<p>And then to install the node version we’re using:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nvm install 8.11.4
</code></pre></div></div>

<p>And to install yarn:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install -g yarn
</code></pre></div></div>

<p>And with that we have our mastodon user ready.</p>

<hr />

<h3 id="cloning-mastodon-repository-and-installing-dependencies">Cloning mastodon repository and installing dependencies</h3>

<p>For these next instructions we still need to be logged in Mastodon’s user. First, we will clone the repo:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Return to mastodon user's home directory
cd ~
# Clone the mastodon git repository into ~/live
git clone https://github.com/tootsuite/mastodon.git live
</code></pre></div></div>

<p>Now, it’s highly recommended to run a stable release. Why? Stable releases are bundles of finished features, if you’re running an instance for day-to-day use, they are the most recommended for being the less likely to have breaking bugs.</p>

<p>The stable release is the latest on <a href="https://github.com/tootsuite/mastodon/releases/" target="_blank">tootsuite’s releases</a> without any “rc”. At the time of writing the latest one is <code class="language-plaintext highlighter-rouge">v2.7.1</code>.
With that in mind, we will do:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Change directory to ~/live
cd ~/live
# Checkout to the latest stable branch
git checkout v2.7.1
</code></pre></div></div>

<p>And then, we will install the dependencies of the project:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Install bundler
gem install bundler
# Use bundler to install the rest of the Ruby dependencies
bundle install -j$(getconf _NPROCESSORS_ONLN) --without development test
# Use yarn to install node.js dependencies
yarn install --pure-lockfile
</code></pre></div></div>

<p>After this finishes you can go back to the user you were using before. This will also take a while, try to relax a bit, have you listened to your favorite song today? 🎶</p>

<hr />

<h3 id="postgresql-configuration">PostgreSQL configuration</h3>

<p>Now, once more, check out <a href="https://wiki.archlinux.org/index.php/PostgreSQL" target="_blank">Arch Linux’s wiki about PostgreSQL</a>.
The first thing to do is to initialize the database cluster. This is done by doing:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u postgres initdb --locale en_US.UTF-8 -E UTF8 -D '/var/lib/postgres/data'
</code></pre></div></div>

<p>If you want to use a different language, there’s no problem.</p>

<p>After this completes, you can then do</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable postgresql # will enable postgresql to start together with the system
sudo systemctl start postgresql # will start postgresql
</code></pre></div></div>

<p>Now that postgresql is running, we can create mastodon’s user in postgresql:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Launch psql as the postgres user
sudo -u postgres psql
</code></pre></div></div>

<p>In the prompt that opens, create the mastodon user with:</p>
<pre><code class="language-SQL">-- Creates mastodon user with CREATEDB permission level
CREATE USER mastodon CREATEDB;
</code></pre>

<p>Okay, after this we’re done with postgresql. Let’s move on!</p>

<hr />

<h3 id="redis-configuration">Redis configuration</h3>

<p>The last service we need to start is <code class="language-plaintext highlighter-rouge">redis</code>. Check out <a href="https://wiki.archlinux.org/index.php/redis" target="_blank">Arch Linux’s wiki about Redis</a>.</p>

<p>We need to start redis and enable it on initialization:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable redis
sudo systemctl start redis
</code></pre></div></div>

<hr />

<h3 id="mastodon-application-configuration">Mastodon application configuration</h3>

<p>We’re approaching the end, I promise!</p>

<p>We need to go back to Mastodon user:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo su - mastodon
</code></pre></div></div>

<p>Then we change to the live directory and run the setup wizard:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~/live
RAILS_ENV=production bundle exec rake mastodon:setup
</code></pre></div></div>

<p>This will do the instance setup: ask you about some options, generate needed secrets, setup the database and precompile the assets.</p>

<p>For PostgreSQL host, port and etc, you can just press enter and it will use default values. The same goes for redis. For email options, refer to the <a href="#email">email section</a>. You will want to allow the setup to prepare the database and compile the assets.</p>

<p>Precompiling the assets will take a little while! Also, pay attention to the output. It might output:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>That failed! Maybe you need swap space?

All done! You can now power on the Mastodon server 🐘
</code></pre></div></div>

<p>Which means the asset compilation failed and you will need to try again with more memory. You can try again using <code class="language-plaintext highlighter-rouge">RAILS_ENV=production bundle exec rails assets:precompile</code></p>

<hr />

<h3 id="intermission-mastodon-directory-permissions">Intermission: Mastodon directory permissions</h3>

<p>The mastodon user folder cannot be accessed by nginx. The path <code class="language-plaintext highlighter-rouge">/home/mastodon/live/public</code> needs to be accessed by nginx because it’s where images and css are served from.</p>

<p>You have some options, the one I chose for this guide is:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo chmod 751 /home/mastodon/ # Makes mastodon home folder executable by all users in the server and readable and executable by the user group
sudo chmod 755 /home/mastodon/live/public # Makes mastodon public folder readable and executable by all users in the server
sudo chmod 640 /home/mastodon/live/.env.production # Gives read access only to the user/group for the file with production secrets
</code></pre></div></div>

<p>Other subfolders will also be readable by other users if they know what to search for.</p>

<hr />

<h3 id="mastodon-systemd-service-files">Mastodon systemd service files</h3>

<p>Now, you can go back to your user and we’ll create service files for Mastodon. You again should compare with the <a href="https://docs.joinmastodon.org/administration/installation/#setting-up-systemd-services" target="_blank">official guide</a> to see if something changed, but have in mind that since we’re using <code class="language-plaintext highlighter-rouge">rvm</code> and <code class="language-plaintext highlighter-rouge">nvm</code> in this guide the final result will be a bit different.</p>

<p>This is what our services will look like, first the one in <code class="language-plaintext highlighter-rouge">/etc/systemd/system/mastodon-web.service</code>, responsible for Mastodon’s frontend and API:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
Description=mastodon-web
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="PORT=3000"
Environment="WEB_CONCURRENCY=3"
ExecStart=/bin/bash -lc "bundle exec puma -C config/puma.rb"
ExecReload=/bin/kill -SIGUSR1 $MAINPID
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target
</code></pre></div></div>

<p>Then, the one in <code class="language-plaintext highlighter-rouge">/etc/systemd/system/mastodon-sidekiq.service</code>, responsible for running background jobs:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
Description=mastodon-sidekiq
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="DB_POOL=5"
ExecStart=/bin/bash -lc "bundle exec sidekiq -c 5 -q default -q push -q mailers -q pull"
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target
</code></pre></div></div>

<p>Lastly, the one in <code class="language-plaintext highlighter-rouge">/etc/systemd/system/mastodon-streaming.service</code>, responsible for sending new content to users in real time:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
Description=mastodon-streaming
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="NODE_ENV=production"
Environment="PORT=4000"
ExecStart=/bin/bash -lc "npm run start"
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target
</code></pre></div></div>

<p>Now, you can enable these services using:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable /etc/systemd/system/mastodon-*.service
</code></pre></div></div>

<p>And then run them using</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start mastodon-*.service
</code></pre></div></div>

<p>Check that they are running as they should using:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl status mastodon-*.service
</code></pre></div></div>

<p>At this point, if everything is as it should, going to <code class="language-plaintext highlighter-rouge">https://my.instance.com</code> should give you the Mastodon landing page! 🐘</p>

<hr />
<p><a name="email"></a></p>

<h3 id="emails">Emails</h3>
<p>Now, you’ll probably want to send emails, since new users get an email to confirm their emails.</p>

<p>You should really follow the <a href="https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md#email-service" target="_blank">official guide</a> on this one, because there’s no difference in this case.</p>

<hr />

<h3 id="monitoring-with-uptime-robot">Monitoring with uptime robot</h3>

<p>I’m giving an example with Uptime Robot because they have a free tier, but you can use other services if you prefer. The idea is just to be pinged if your instance goes down and also to have an independent page where your users can be sure if everything is working as expected.</p>

<p>After creating an UptimeRobot account, you can create a HTTP(s) type monitor pointing to your instance full url: <code class="language-plaintext highlighter-rouge">https://my.instance.com</code>, don’t forget to change accordingly.</p>

<p>If you have IPv6, you should also create another monitor with the Ping type, in which you should use your server’s IPv6 as the IP.</p>

<p>Now, in the settings page, you can click on “add public status page”, then you select “for selected monitors” and select the ones you just created. You can create a CNAME DNS entry, so that for instance <code class="language-plaintext highlighter-rouge">status.my.instance.com</code> would show the this new status page. There’s more instructions in Uptime Robot’s page.</p>

<p>Now if your instance goes down or your IPv6 stops working, you should get an email.</p>

<hr />

<h3 id="remote-media-attachment-cache-cleanup">Remote media attachment cache cleanup</h3>

<p>Mastodon downloads media from other instances and caches them locally. If you don’t clean this from time to time, this will only keep growing. Using mastodon user, you can add a cron job that cleans it up daily using <code class="language-plaintext highlighter-rouge">crontab -e</code> and adding:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0 2 * * * /bin/bash -lc "cd live; RAILS_ENV=production bundle exec bin/tootctl media remove" 2&gt;&amp;1 /home/mastodon/remove_media.output
</code></pre></div></div>

<p>If you don’t have any cron installed in your server, you need to take a look in <a href="https://wiki.archlinux.org/index.php/cron" target="_blank">Arch Linux’s wiki page about cron</a>.</p>

<hr />

<h3 id="renew-lets-encrypt-certificates">Renew Let’s Encrypt certificates</h3>

<p>The best way for this is to follow <a href="https://wiki.archlinux.org/index.php/certbot#Automatic_renewal" target="_blank">Arch Linux’s wiki about Certbot automatic renewal</a>, which is:</p>

<p>Create a file <code class="language-plaintext highlighter-rouge">/etc/systemd/system/certbot.service</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --agree-tos
</code></pre></div></div>

<p>The nginx plugin should take care of making sure the server is reloaded automatically after renewal.</p>

<p>Then, create a second file <code class="language-plaintext highlighter-rouge">/etc/systemd/system/certbot.timer</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
Description=Daily renewal of Let's Encrypt's certificates

[Timer]
OnCalendar=03:00:00
RandomizedDelaySec=1h
Persistent=true

[Install]
WantedBy=timers.target
</code></pre></div></div>

<p>Now, enable and start the timer service:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start certbot.timer
sudo systemctl enable certbot.timer
</code></pre></div></div>

<hr />

<h3 id="updating-between-mastodon-versions">Updating between Mastodon versions</h3>

<p>Okay, you set it all up, everything is running and then Mastodon <code class="language-plaintext highlighter-rouge">v2.8.0</code> comes out. What do you do?</p>

<p>Do not despair, dear reader, all is well.</p>

<p>Remember our tip about <code class="language-plaintext highlighter-rouge">tmux</code>? When updating is always a good idea to be running <code class="language-plaintext highlighter-rouge">tmux</code>. Database migrations can take some time and <code class="language-plaintext highlighter-rouge">tmux</code> will help to avoid losing data if your connection fails in the meantime.</p>

<p>First, we will go to the Mastodon user once again:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo su - mastodon
</code></pre></div></div>

<p>Okay, first things first, let’s go into the live directory and get the new version:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~/live
git fetch origin --tags
git checkout v2.8.0
cd . # This is to force rvm to check if we're in the right ruby version
</code></pre></div></div>

<p>Now, suppose the ruby version changed, since the last time you were here and instead of <code class="language-plaintext highlighter-rouge">2.6.1</code> is now <code class="language-plaintext highlighter-rouge">2.6.2</code>. After you do <code class="language-plaintext highlighter-rouge">cd .</code>, rvm will complain:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd .
Required ruby-2.6.2 is not installed.
To install do: 'rvm install "ruby-2.6.2"'
</code></pre></div></div>

<p>In this case, we will need to use rvm to install the new version. The command is the same as last time:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rvm install 2.6.2 -C --with-jemalloc
</code></pre></div></div>

<p>Everything will take some time and at the end you will be ready to follow through. Notice that this won’t happen very often. Also, after you make sure everything is running as expected, you can remove the old ruby version with <code class="language-plaintext highlighter-rouge">rvm remove &lt;version&gt;</code>. Wait for you to be sure that the new version is running, though!</p>

<p>Now, you’ll always want to make sure that you look at the releases notes for the release you’re going to. Sometimes there’s special tasks that need to be done before following.</p>

<p>If there was dependencies updated, you need to do:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle install --without development test # if you need to update ruby dependencies or if you installed a new ruby
yarn install --pure-lockfile # if you need to update node dependencies
</code></pre></div></div>

<p>In most of the updates you will need to update the assets:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>RAILS_ENV=production bundle exec rails assets:precompile
</code></pre></div></div>

<p>For comparison: in the digital ocean droplet I tested this guide on, compiling assets on v2.4.3 took around 5 minutes.</p>

<p>If the update includes database migrations that you’ll need to do:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>RAILS_ENV=production bundle exec rails db:migrate
</code></pre></div></div>

<p>Sometimes database migrations will change the database in a way that the instance will stop working for a little bit until you restart the services, that’s why I usually leave them for last to reduce downtime.</p>

<p>⚠️ Backup your database regularly ⚠️</p>

<p>After the migration is finished running, you can leave the mastodon user and then restart the services:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart mastodon-sidekiq
sudo systemctl restart mastodon-streaming
sudo systemctl reload mastodon-web
</code></pre></div></div>

<p>Now, if there was some database changes you need to <code class="language-plaintext highlighter-rouge">restart mastodon-web</code> instead of <code class="language-plaintext highlighter-rouge">reload</code>.</p>

<p>Alrite, you should be in the last version of Mastodon now!</p>

<hr />

<h3 id="upgrading-arch-linux">Upgrading Arch Linux</h3>

<p>Some special notes about upgrading Arch Linux itself. If you haven’t yet, read through the <a href="https://wiki.archlinux.org/index.php/System_maintenance#Upgrading_the_system" target="_blank">Arch Linux’s wiki on Upgrading the system</a>. Since Arch Linux is rolling, there’s some differences if you’re coming from other distros.</p>

<p>Ruby uses native modules in some of the gems, that is, modules compiled against local libraries. This means that if your system changes radically from one version to the other, you might have issues starting services.</p>

<p>However, to make your life a bit easier, you can re-compile native modules by doing (using mastodon user):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~/live
bundle pristine
</code></pre></div></div>

<p>This will take a little while but will recompile needed gems. When in doubt, do that after a system upgrade.</p>

<p>I had issues in the past with gems that Mastodon uses which have native extensions and are being installed straight from git, namely <code class="language-plaintext highlighter-rouge">posix-spawn</code> and <code class="language-plaintext highlighter-rouge">http_parser.rb</code>. They were not reinstalled with <code class="language-plaintext highlighter-rouge">bundle pristine</code> and I had to manually rebuild them. This seems to fixed in the most recent rvm, but in case you need to do that, find where they are installed doing:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle show posix-spawn
</code></pre></div></div>

<p>With the output of that (which will be something like <code class="language-plaintext highlighter-rouge">/home/mastodon/.rvm/gems/ruby-2.5.1/bundler/gems/posix-spawn-58465d2e2139</code>, do:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rm -rf /home/mastodon/.rvm/gems/ruby-2.5.1/bundler/gems/posix-spawn-58465d2e2139 /home/mastodon/.rvm/gems/ruby-2.5.1/bundler/gems/extensions/x86_64-linux/2.5.0/posix-spawn-58465d2e2139
</code></pre></div></div>

<p>This is just an example and you will have to replace this with the output of your bundle show command, and then find the equivalent path in the <code class="language-plaintext highlighter-rouge">gems/extensions</code> folder. Do it for both <code class="language-plaintext highlighter-rouge">posix-spawn</code> and <code class="language-plaintext highlighter-rouge">http_parser.rb</code> (and any other gem that comes from git if it gives you trouble).</p>

<p>And after that you can do <code class="language-plaintext highlighter-rouge">bundle install --without development test</code> to install them again.</p>

<p>Now, second thing to take note: <a href="https://www.postgresql.org/support/versioning/" target="_blank">Postgresql minor version</a> are compatible between themselves. This means that 9.6.8 is compatible with 9.6.9 and after version 10 they adopted a two number versioning, which means that 10.3 is compatible with 10.4. However, 9.6 is not compatible with 10. And 10 will not be compatible with 11. This means that: when upgrading from 10 to 11 you need to follow the <a href="https://www.postgresql.org/docs/current/static/upgrading.html" target="_blank">official documentation</a> and <a href="https://wiki.archlinux.org/index.php/PostgreSQL#Upgrading_PostgreSQL" target="_blank">Arch Linux’s wiki orientation</a>. With that in mind, be careful when upgrading.</p>

<p>🛑 Upgrading wrongly may cause data loss. 🛑</p>

<hr />

<h3 id="optional-adding-elasticsearch-for-searching-authorized-statuses">(Optional) Adding elasticsearch for searching authorized statuses</h3>

<p>Since Mastodon v2.3.0, you can enable full text search for authorized statuses. That means toots you have written, boosted, favourited or were mentioned in. For this functionality, Mastodon uses Elasticsearch. As usual, you should take a look in <a href="https://wiki.archlinux.org/index.php/Elasticsearch" target="_blank">Arch Linux’s wiki about Elasticsearch</a>.</p>

<p>Note: I was able to run elasticsearch on my test instance using the 1GB/1vCPU droplet from Digital Ocean with 1GB of Swap by using the memory configurations suggested at the <a href="https://wiki.archlinux.org/index.php/Elasticsearch#Configuration" target="_blank">Arch Linux’s wiki about Elasticsearch</a>, that is, <code class="language-plaintext highlighter-rouge">-Xms128m -Xmx512m</code>. However, I don’t have any load and I don’t know how the system would behave with more real loads.</p>

<p>To install elasticsearch do:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -S elasticsearch
</code></pre></div></div>

<p>Pacman then will ask which version of jdk you want to use. After installed, you can start Elasticsearch by doing:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable elasticsearch # Enables elasticsearch to be started at startup
sudo systemctl start elasticsearch # starts elasticsearch
</code></pre></div></div>

<p>Then you need to switch to Mastodon user, <code class="language-plaintext highlighter-rouge">cd ~/live</code> and edit <code class="language-plaintext highlighter-rouge">.env.production</code>, to add configuration related to Elasticsearch, look for the commented configs and change them:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ES_ENABLED=true
ES_HOST=localhost
ES_PORT=9200
</code></pre></div></div>

<p>Then, you need to build the index. This might take a while if your database is big!</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>RAILS_ENV=production bundle exec rails chewy:deploy
</code></pre></div></div>

<p>When this is finished, you need to restart all mastodon services.</p>

<p>The <a href="https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Elasticsearch-guide.md#advanced-elasticsearch-configuration-optional" target="_blank">official docs</a> have some tips on how to tune Elasticsearch.</p>]]></content><author><name></name></author><category term="Mastodon" /><category term="Arch Linux" /><category term="Redes sociais" /><category term="Descentralização" /><category term="Código aberto" /><category term="Decentralization" /><category term="Open Source" /><category term="Twitter" /><category term="Social Network" /><category term="Linux" /><summary type="html"><![CDATA[It’s been a while now that I’ve been running masto.donte.com.br using Arch Linux and since the official guide recommends using Ubuntu 18.04, I figured that describing what I did could help someone out there. If in doubt, use the official guide instructions instead, since they’re more likely to be up to date.]]></summary></entry><entry xml:lang="pt"><title type="html">Mastodon&amp;amp;colon; como navegar nessa nova rede social</title><link href="https://lond.com.br/2017/10/19/mastodon-como-navegar-nessa-nova-rede-social/" rel="alternate" type="text/html" title="Mastodon&amp;amp;colon; como navegar nessa nova rede social" /><published>2017-10-19T22:31:48+02:00</published><updated>2017-10-19T22:31:48+02:00</updated><id>https://lond.com.br/2017/10/19/mastodon-como-navegar-nessa-nova-rede-social</id><content type="html" xml:base="https://lond.com.br/2017/10/19/mastodon-como-navegar-nessa-nova-rede-social/"><![CDATA[<figure><img alt="" src="/assets/2017-10-19-mastodon-main.png" /><figcaption>Sobre toots, servidores e emojis customizados</figcaption></figure>

<p><em>(atualizado pela última vez em 4 de dezembro de 2018)</em></p>

<p>Talvez você tenha ouvido falar do Mastodon, há alguns meses atrás a rede social bombou na mídia internacional como a rede que veio pra sacudir o Twitter. Mas talvez não, porque a cobertura na mídia nacional foi bem pequena. Ainda assim, a rede está chegando na versão 2.7 e está chegando aos 1.7 milhão de usuários, além de mais de 2400 servidores ativos.</p>

<p>O Mastodon é uma rede social de <em>microblogging</em>, semelhante ao Twitter. A sua proposta é ser local onde os seus usuários podem postar status de até 500 caracteres. Até aí, tudo bem igual ao Twitter.</p>

<p>A diferença começa no modelo da rede, que é mais semelhante ao serviço de email, com vários servidores que se comunicam, do que ao modelo do twitter de um grande servidor com todo mundo dentro.</p>

<hr />

<h3 id="começando-pela-parte-difícil-como-funcionam-os-servidores">Começando pela parte difícil: como funcionam os servidores?</h3>

<figure><img alt="" src="/assets/2017-10-19-mastodon-elephants.png" /><figcaption>Vamos pegar a imagem bonitinha do joinmastodon.org</figcaption></figure>

<p>O Mastodon é composto por vários servidores. Tem o <a href="https://mastodon.social" target="_blank" rel="noopener">mastodon.social (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, que é mantido pelo líder do projeto, o <a href="https://mastodon.social/@gargron" target="_blank" rel="noopener">Eugen Rochko (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Ou mesmo o <a href="https://masto.donte.com.br" target="_blank" rel="noopener">Mastodon(te) (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, mantido por mim mesmo. Os dois estão em lugares diferentes, controlados por pessoas diferentes, mas ainda assim, eles falam entre si. Se eu quero mandar uma mensagem pro Eugen, basta eu mandar uma mensagem pra <code class="language-plaintext highlighter-rouge">@gargron@mastodon.social</code> e ele vai receber ela por lá e se ele quiser me responder ele vai responder pra <code class="language-plaintext highlighter-rouge">@renatolond@masto.donte.com.br</code> e eu vou receber ela de cá. Ou seja, em vez de ser só uma arroba, você é uma arroba em um endereço, que nem email.</p>

<p>Assim como no Twitter no início dos tempos, é possível acompanhar uma timeline especial, a timeline local, que tem todos os toots…</p>

<hr />

<p>Peraí. Eu num disse isso, né? Quando alguém posta uma coisa no Mastodon isso se chama um toot, se pronuncia “Tut”.</p>

<figure><img alt="" src="/assets/2017-10-19-mastodon-toot.jpeg" /><figcaption>Toot é a onomatopeia de uma corneta em inglês. fonte: <a href="https://www.toastmonster.com/2015/01/new-year-toot-toot/">toastmonster</a></figcaption></figure>

<hr />

<p>Então, como eu ia dizendo, é possível acompanhar uma timeline especial onde tem todos os toots públicos dos usuários do seu servidor. É uma maneira bem legal de descobrir gente e conteúdo novo.</p>

<p>E aí, tem a timeline global (também chamada de federada) que é onde estão os toots de todos os usuários que são vistos pela servidor onde você está. Pode ser meio confuso, porque tem gente do mundo todo postando. Tem umas ferramentas pra filtrar línguas nas timelines local e global pra ajudar um pouco nesse sentido.</p>

<h4 id="pô-mas-aí-só-me-complicou-qual-a-vantagem">Pô, mas aí só me complicou. Qual a vantagem?</h4>

<p>A vantagem é que cada servidor é administrado por gente diferente. Você com certeza pode achar um servidor onde você vai estar livre de conteúdo que você não quer ver e ver mais do que você quer. Tá querendo um servidor feito para brasileiros? <a href="https://masto.donte.com.br" target="_blank" rel="noopener">Tem lá (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Quer um servidor mais voltado pro público LGBTQ? <a href="https://lgbt.io" target="_blank" rel="noopener">Tem lá (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Ou de repente cê tá procurando um servidor mais voltado pro público interessado em livros e <a href="https://booktoot.club" target="_blank" rel="noopener">também tem lá (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. E se quiser derrubar o capitalismo e falar de gatinhos, <a href="https://anticapitalist.party" target="_blank" rel="noopener">também tem um cantinho (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>O que você vê na timeline local vai variar bastante de servidor pra servidor. O que você vê na global vai variar porque servidores podem bloquear conteúdo de outros servidores. Então se você está num servidor que não permite nazismo, fascismo e afins, você provavelmente não vai ver conteúdo desse tipo na sua timeline (e se aparecer, você pode reportar aos administradores e eles provavelmente vão bloquear).</p>

<p>E no final das contas, todo mundo com conhecimento técnico ou um pouco de dinheiro pode botar um servidor novo no ar. Então se você quer fazer um servidor pra fãs do campeonato brasileiro, você também pode. (Tô jogando no ar. Acho que ainda não tem, hein. Corre lá :)</p>

<h4 id="ah-mas-é-tipo-reddit-então">Ah, mas é tipo reddit então?</h4>

<p>Não muito, o reddit tem vários fóruns, mas todos são desconectados. No Mastodon você pode seguir gente de todos os servidores, a diferença é só que gente que está no mesmo servidor que você é mais fácil de acompanhar.
Alguns servidores até são temáticos (pra agregar gente falando de desenvolvimento de jogos ou de tecnologia), mas não é necessariamente o caso em todos os servidores. Na maioria das vezes o tema do servidor vai ajudar só a juntar gente que pensa do mesmo jeito, mas muitas vezes o servidor existe porque tem um nome de domínio maneiro.</p>

<h4 id="tá-e-como-eu-escolho-meu-servidor-então">Tá, e como eu escolho meu servidor, então?</h4>

<p>Tem um site que tem um pequeno questionário pra te ajudar justamente nessa questão, o <a href="https://instances.social/" target="_blank" rel="noopener">Mastodon Instances (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>Uma coisa importante do servidor é que a administração e moderação é por servidor. Então o quão rígida ou não vai ser a moderação vai depender do servidor que você escolher. É importante dar uma lida nas regras do servidor pra não ser pego de surpresa ao violar uma delas!</p>

<p>Outra coisa importante é que por não ter uma grande empresa por trás de cada instância, é bom dar uma conferida em quanto tempo o servidor está no ar e se ele não costuma sair do ar com frequência, dá pra ter uma idéia usando o <a href="https://fediverse.network/masto.donte.com.br/" target="_blank" rel="noopener">fediverse network (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, que mostra um gráfico de disponibilidade dos últimos 30 dias. O site também mostra quando a instância foi descoberta, mas o serviço começou a funcionar no fim de abril/2018, então tem instância que tá listada por volta dessa data mas já existia antes.</p>

<p>Não se preocupe de escolher o melhor servidor logo de cara. Você pode exportar seus dados e ir pra um outro servidor se você não curtir alguma coisa do servidor em que você está.</p>

<hr />

<h4 id="toots-e-tweets">Toots e tweets</h4>

<p>No Twitter ou o seu perfil é fechado e aí ninguém vê seus tweets, ou ele é aberto e todo mundo vê seus tweets. No mastodon tem um controle mais fino disso. Você pode ter uma conta fechada e ainda postar toots pra todo mundo ver, quando quiser.</p>

<p>Além disso, no Mastodon tudo vem sempre em ordem cronológica, e nenhum like dos amiguinhos aparece no meio da sua timeline. Você escolhe o que você quer ver, e ninguém vê os posts que você curte, seus favoritos são sempre privados.</p>

<p>Olha as diferenças entre os toots, no mastodon, e os tweets:</p>

<ul>
  <li>Os toots podem ter até 500 caracteres<a href="#500-chars">⁽¹⁾</a>;</li>
  <li>Os toots têm configurações de privacidade:
    <ul>
      <li>Você pode postar publicamente (ou seja, todo mundo vê seu toot e ele aparece nas timelines local e global)</li>
      <li>Você pode postar não listado (ou seja, todo mundo pode ver seu toot, mas ele não aparece nas timelines local e global)</li>
      <li>Você pode postar privado (e nesse caso seu toot só aparece pra quem te segue)</li>
      <li>Você pode postar um toot diretamente pra alguns usuários, e nesse caso é parecido com uma mensagem, só os usuários que você citar vão ver.</li>
    </ul>
  </li>
  <li>Spoiler / alerta de conteúdo: Isso é mara. Você pode marcar enquanto for postar um aviso de conteúdo pra um toot. Aí aparece assim:
    <figure><img alt="" src="/assets/2017-10-19-mastodon-spoiler.png" /><figcaption>Cuidado. Contém spoilers!</figcaption></figure>
  </li>
</ul>

<hr />

<h3 id="emojis">Emojis</h3>

<p>Desde a versão 2.0 tem uma parada que eu acho particularmente bem legal: emojis customizados!</p>

<iframe src="https://masto.donte.com.br/@renatolond/100627452094203608/embed?autoplay=1" class="mastodon-embed" style="max-width: 100%; border: 0" width="400"></iframe>
<script src="https://masto.donte.com.br/embed.js" async="async"></script>

<p>Além dos emojis normais que você acha no seu telefone, os administradores das instâncias podem adicionar outros emojis.</p>

<hr />

<h3 id="apagar--usar-como-rascunho">Apagar &amp; usar como rascunho</h3>

<p>Imagina que você acabou de fazer aquele toot maneiro e assim que ele foi postado, você notou um erro. Não dá pra editar toots, mas dá pra clicar em “apagar &amp; usar como rascunho”. Isso apaga o toot e manda ele de volta pra caixa de edição junto com as mídas que estavam nele pra você poder corrigir e postar outra vez.</p>

<figure><img alt="Uma imagem de um toot, com uma foto de um mastodonte segurando a bandeira brasileira e o texto diz 'Olha que bonito esse elefante!'" src="/assets/2017-10-19-mastodon-erro.png" /><figcaption>Epa. Isso não é um elefante.</figcaption></figure>
<figure><img alt="A mesma imagem, mas com um menu de opções abertos onde a opção 'Apagar &amp; usar como rascunho' está selecionada'" src="/assets/2017-10-19-mastodon-erro-2.png" /><figcaption>Vou corrigir!</figcaption></figure>
<figure><img alt="A caixa de edição do Mastodon com o texto 'Olha que bonito esse elefante!' e a imagem do mastodonte segurando a bandeira brasileira" src="/assets/2017-10-19-mastodon-erro-3.png" /><figcaption>Ah, agora dá pra corrigir e botar mastodonte :)</figcaption></figure>

<p>Eu uso isso um monte pra adicionar descrição de texto nas imagens, por exemplo. É super prático!</p>

<p>Isso existe em alguns clientes do Twitter também, mas no Mastodon tem direto pela interface padrão.</p>

<hr />

<h3 id="aplicativos">Aplicativos</h3>

<p>Sim, tem aplicativos pra Android, pra IOS, pra desktop e até mesmo pra uns certos editores de texto 😉</p>

<p>Por exemplo, pra Android os mais comuns são o <a href="https://tuskyapp.github.io/" target="_blank" rel="noopener">Tusky (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://github.com/TwidereProject/Twidere-Android" target="_blank" rel="noopener">Twidere (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> (que funciona tanto pro Mastodon quanto pro Twitter), <a href="https://github.com/stom79/mastalab" target="_blank" rel="noopener">Mastalab (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://play.google.com/store/apps/details?id=jp.juggler.subwaytooter" target="_blank" rel="noopener">Subway Tooter (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> e <a href="https://github.com/jeroensmeets/mastodon-app" target="_blank" rel="noopener">11t (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>Pra iOS o <a href="https://itunes.apple.com/app/toot/id1229021451?ls=1&amp;mt=8" target="_blank" rel="noopener">Toot! (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, <a href="https://itunes.apple.com/us/app/amaroq-for-mastodon/id1214116200" target="_blank" rel="noopener">Amaroq (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> e <a href="https://itunes.apple.com/jp/app/imast/id1229461703" target="_blank" rel="noopener">iMast (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>Além disso, ambos Android e iOS recentemente suportam <a href="https://pt.wikipedia.org/wiki/Progressive_Web_App" target="_blank" rel="noopener">PWAs (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> e por isso você pode usar o próprio site da sua instância como um app no seu celular.</p>

<p>Pra outros sistemas e uma lista mais atualizada, dá pra dar uma olhada nessa lista aqui que é mantida pelo projeto: <a href="https://github.com/masto-donte-com-br/documentation/blob/master/Using-Mastodon/Apps.md" target="_blank" rel="noopener">aplicativos (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>Como o Mastodon é open-source, a maioria dos seus aplicativos também é. Então você pode dar uma procurada até encontrar um app que te faça se sentir mais em casa.</p>

<h3>Ferramentas</h3>

<p>Mudar de rede social é um negócio complicado e é por isso que tem ferramentas pra tentar ajudar um pouco na transição.</p>

<p><a href="http://bridge.mastodon.social" target="_blank" rel="noopener">Mastodon Bridge (a ponte) (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>: Criado pelo próprio <a href="https://mastodon.social/@gargron" target="_blank" rel="noopener">Eugen Rochko (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, a ponte serve pra descobrir amigos do Twitter no Mastodon e vice-versa. Depois de criar sua conta em um dos servidores, basta ir lá e conectar a sua conta do Twitter e do Mastodon. Aí ele vai mostrar onde você pode seguir seus amigos do Twitter.</p>

<p><a href="http://crossposter.masto.donte.com.br" target="_blank" rel="noopener">Mastodon Twitter Crossposter (postando entre as redes) (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>: Essa aí é minha. Você conecta suas contas do Twitter e do Mastodon e aí você pode decidir como você quer postar entre as redes. Do Twitter pro Mastodon, ou do Mastodon pro Twitter, que tipo de posts vão ser postados. É open-source e tem coisa pra fazer, se quiser contribuir.</p>

<h3 id="segurança-de-dados">Segurança de dados</h3>

<p>Quando você se inscreve em um servidor do Mastodon (vamos dizer, no <a href="https://masto.donte.com.br" target="_blank" rel="noopener">masto.donte.com.br (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>), seus dados ficam registrados no masto.donte.com.br. O administrador do servidor pode ver suas mensagens, assim como o Gmail também pode ver suas mensagens. O Mastodon por padrão não permite que administradores vejam messagens marcadas como privadas, mas através de denúncias ou olhando o conteúdo do banco de dados, mesmo as mensagens privadas podem ser visualizadas.</p>

<p>Quando alguém de outro servidor (digamos, do <a href="https://mastodon.social" target="_blank" rel="noopener">mastodon.social (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>) te segue ou se você enviar uma mensagem pra um usuário que esteja por lá, os seus posts são enviados também para esse outro servidor e uma cópia desses posts vai ser guardada lá.</p>

<p>Isso quer dizer que administradores de servidores em que você tenha seguidores ou pra quem você envia mensagens podem espiar as mensagens. É exatamente o mesmo caso de servidores de email, se você enviar uma mensagem pra alguém no servidor do trabalho dessa pessoa, a empresa poderia ver as mensagens.</p>

<p>Na prática é tão (in)seguro quanto outras redes sociais.</p>

<h3 id="mais-informações">Mais informações</h3>

<p>A página do projeto é um bom ponto pra começar: <a href="http://joinmastodon.org" target="_blank" rel="noopener">The Mastodon Project (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Tem tradução em português por lá. Aliás, falando em tradução: tanto a página do projeto quanto a interface do Mastodon em si foram traduzidas pro português Brasileiro pela <a href="https://anna.flourishing.stream" target="_blank" rel="noopener">Anna (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a> 🎉</p>

<p>Tem muito mais informação, muito mais detalhada, no <a href="https://github.com/tootsuite/documentation" target="_blank" rel="noopener">repositório de dosumentação do projeto (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, mas a maioria das coisas ainda não está traduzida pra português ou português do Brasil. (Tá aí uma oportunidade, ó.)</p>

<p>Um pouco mais velho mas igualmente útil é o texto da Qina Liu: <a href="https://hackernoon.com/what-i-wish-i-knew-before-joining-mastodon-7a17e7f12a2b" target="_blank" rel="noopener">What I wish I knew before joining Mastodon (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>. Embora esteja desatualizado em alguns pontos, ainda é bem divertido e foi o que me inspirou a escrever esse aqui :)</p>

<p>Um outro também que explica bem vários pontos que eu tento explicar por aqui é o texto da Ginny McQueen: <a href="https://medium.com/@GinnyMcQueen/toot-how-to-intro-to-mastodon-e5655bfa87d2" target="_blank" rel="noopener">Toot How-To : Intro to Mastodon (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<p>Sabe tudo que eu falei sobre instâncias diferentes do Mastodon? O Mastodon na verdade está no Fediverso, e ele não é o único software por lá. Dá uma olhada em mais informações sobre o Fediverso <a href="https://en.wikipedia.org/wiki/Fediverse" target="_blank" rel="noopener">por aqui (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>.</p>

<hr />

<p><a name="500-chars"></a>[1]: Vale notar que por padrão os toots têm 500 caracteres. Na prática alguns servidores permitem mais, no finado <a href="https://web.archive.org/web/20180417044653/https://witches.town/about" target="_blank" rel="noopener">witches.town (abre em uma nova janela <i class="fa fa-window-restore" aria-hidden="true"></i>)</a>, por exemplo, o limite era de 666 caracteres. 😜</p>]]></content><author><name>Lond</name></author><category term="Mastodon" /><category term="Redes sociais" /><category term="Descentralização" /><category term="Código aberto" /><category term="Decentralization" /><category term="Open Source" /><category term="Twitter" /><category term="Social Network" /><summary type="html"><![CDATA[Sobre toots, servidores e emojis customizados]]></summary></entry><entry><title type="html">E se ao invés de Uber tivesse uma alternativa aberta, tipo um OpenTaxi?</title><link href="https://lond.com.br/2015/08/11/e-se-ao-inves-de-uber-tivesse-uma-alternativa-aberta-tipo-um-opentaxi/" rel="alternate" type="text/html" title="E se ao invés de Uber tivesse uma alternativa aberta, tipo um OpenTaxi?" /><published>2015-08-11T12:06:04+02:00</published><updated>2015-08-11T12:06:04+02:00</updated><id>https://lond.com.br/2015/08/11/e-se-ao-inves-de-uber-tivesse-uma-alternativa-aberta-tipo-um-opentaxi</id><content type="html" xml:base="https://lond.com.br/2015/08/11/e-se-ao-inves-de-uber-tivesse-uma-alternativa-aberta-tipo-um-opentaxi/"><![CDATA[<p>Curto a idéia do Uber: pagamentos pelo aplicativo, motoristas avaliados e essas coisas que meio que permeam a internet hoje em dia. Mas não curto a empresa, suas técnicas estão longe de ser “legais”: [<a href="http://www.vox.com/2014/11/19/7248819/uber-scandal-explained" target="_blank">The latest Uber scandal, explained</a>] [<a href="http://techcrunch.com/2015/06/17/uber-drivers-deemed-employees-by-california-labor-commission" target="_blank">Uber Driver Deemed Employee By California Labor Commission</a>] [<a href="http://citypaper.net/uberdriver/" target="_blank">I was an undercover Uber driver</a>]</p>

<p>E tem mais um ponto: eu sou a favor dos taxis serem agenciados pelo estado. Acho que taxi, como um transporte público que integra a malha de transportes do estado, também tem que ter suas concessões como parte do planejamento do estado de alguma maneira.</p>

<p>E aí eu andei pensando, e se a gente tivesse a união entre as duas coisas? Senta que lá vem viagem.</p>

<p>Imagina uma mistura entre Uber e EasyTaxi de código aberto. Esse software, que teria seu código disponível pra ser auditado por qualquer um, faria esse papel de controlar a frota e também teria aplicativos para as plataformas de modo que fosse possível chamar taxis por dentro dele, além de efetuar pagamentos também por dentro do aplicativo.</p>

<p>O ideal seria o software ser gerenciado (em termos de custos de manutenção pra manter tudo funcionando) em um esquema de cooperativa entre os taxistas participantes (ou ainda, aproveitando o que já existe, seria coordenado pelo sindicato dos taxistas de cada lugar).</p>

<p>Os custos do sistema seriam um custo fixo para o taxista (que seria pelo custo da infraestrutura) e um custo que viria do gateway de pagamento sendo escolhido pelo sindicato que estivesse mantendo aquela “versão” do aplicativo. Todo o dinheiro da corrida, tirando o custo do pagamento, iria para o bolso do taxista.</p>

<p>Para melhorar, o ideal seria que tivesse alguma maneira (boletos, cartões pré-pagos?) para que quem não tivesse cartão de crédito também pudesse pagar pelo aplicativo.</p>

<p>Todos os dados do sistema estariam disponíveis para serem auditados publicamente, tanto pelo estado, quanto pelos usuários. O estado fica mais eficiente sabendo quanto os taxistas estão ficando ociosos e a duração das suas corridas, e o usuário pode ficar mais em cima de problemas acontecendo nos taxis.</p>

<p>Ao fim de cada corrida, o usuário avaliaria o taxista e no caso de uma nota abaixo da média, informaria os problemas que seriam acumulados no perfil do taxista para uma auditoria posterior.</p>

<p>Claro que tem alguns problemas a serem resolvidos nessa idéia: será que ser gerenciado por cada cooperativa é uma coisa eficiente? Ou será que era melhor fazer uma fundação (tipo a Free Software Foundation) que ficasse responsável pela implementação e manutenção do sistema?</p>

<p>Acho que seria um caminho melhor e mais próximo do que eu acho ideal, mais próximo da socialização do uber. [<a href="http://www.thenation.com/article/socialize-uber/" target="_blank">Socialize Uber</a>]</p>]]></content><author><name>Lond</name></author><category term="Random Thoughts" /><category term="99 Taxis" /><category term="Código Aberto" /><category term="EasyTaxi" /><category term="Nerdish" /><category term="Open Source" /><category term="Random Thoughts" /><category term="Taxi" /><category term="Táxis" /><category term="Uber" /><summary type="html"><![CDATA[Curto a idéia do Uber: pagamentos pelo aplicativo, motoristas avaliados e essas coisas que meio que permeam a internet hoje em dia. Mas não curto a empresa, suas técnicas estão longe de ser “legais”: [The latest Uber scandal, explained] [Uber Driver Deemed Employee By California Labor Commission] [I was an undercover Uber driver]]]></summary></entry><entry><title type="html">Internet Video Game Library: a experiência de lançar um projeto</title><link href="https://lond.com.br/2015/03/04/internet-video-game-library-a-experiencia-de-lancar-um-projeto/" rel="alternate" type="text/html" title="Internet Video Game Library: a experiência de lançar um projeto" /><published>2015-03-04T21:37:59+01:00</published><updated>2015-03-04T21:37:59+01:00</updated><id>https://lond.com.br/2015/03/04/internet-video-game-library-a-experiencia-de-lancar-um-projeto</id><content type="html" xml:base="https://lond.com.br/2015/03/04/internet-video-game-library-a-experiencia-de-lancar-um-projeto/"><![CDATA[<p>Um dos meus projetos mais velhos finalmente está no ar e eu acho que vale a pena falar um pouco sobre a experiência.</p>

<h1 id="uma-introdução">Uma introdução</h1>

<p>No ensino médio conheci um amigo que guardava planilhas com os jogos que ele tinha, os que ele já tinha terminado e os que tinha emprestado.</p>

<p>Nessa época comecei a guardar os meus em uma também, mas em 2003 planilhas eram coisas muito etéreas, quando formatar seu SO (win.. cof.. dows.. cof.. cof..) eram coisas rotineiras, era fácil perder uma por descuido. E várias vezes perdi o conteúdo delas.</p>

<p>Comecei a ler mais portais de jogos e acabei desenvolvendo alguns métodos, ainda que primitivos, de guardar que jogos eu tinha jogado, quais eu queria em alguns desses, principalmente o gamespot.</p>

<p>A internet evoluiu desde então, e com isso, alguns novos serviços apareceram. Conheci sites e tracking de outras coisas: livros, filmes, seriados, cerveja, vinho, lugares. Usei todos os sistemas de tracking de jogos que eu conheci pelo caminho: Raptr, PlayFire, Backloggery, HowLongToBeat, Alvanista, EstouJogando. Nenhum deles me deixou muito feliz, até que recentemente eu voltei a usar planilhas (dessa vez, do Google Drive) pra manter meus jogos e quando eu os terminei.</p>

<h1 id="conhecendo-o-goodreads">Conhecendo o Goodreads</h1>

<p>Em 2012 conheci o Goodreads. Na época, usava o skoob pra guardar os livros que eu lia. Achei o sistema incrível, diversas edições, suporte a várias línguas, ratings unificados. Era tudo que eu queria pra um site de jogos.</p>

<h1 id="a-difícil-criação-dointernet-video-game-library">A difícil criação do Internet Video Game Library</h1>

<p>O IVGLib ficou em gestação algumas vezes. A primeira vez tentei usar o Google App Engine para fazer, mas java nunca foi minha praia e eu entrei no barco durante os meses que seguiram uma atualização <em>major</em> na plataforma. Na época, o projeto tinha o codinome SEMAG. E com isso ele ficou de lado.</p>

<p>Um tempo depois, resolvi tentar retomar o projeto, dessa vez usando algum framework de PHP. Li sobre alguns, tentei usar o FuelPHP, e mais uma vez a falta de documentação, algumas frustrações pra fazer coisas que eu achava que eram básicas acabaram me fazendo mais uma vez largar o projeto de lado.</p>

<p>Do meio do ano passado pra cá eu vinha tentando aprender Ruby on Rails, fazendo homeopaticamente o tutorial do ruby.railstutorial.org e a parada foi fluindo. Em janeiro, durante as minhas férias, finalmente recomecei o projeto, dessa vez em Rails.</p>

<h1 id="desenvolvimento-e-tecnologias">Desenvolvimento e tecnologias</h1>

<p>Rails é um negócio incrível, você pensa em fazer uma parada e tem uma Gem pra fazer isso. (o que também é verdade pra muitas linguagens mais novas, antes que me joguem pedras).</p>

<p>Assim que comecei a fazer o sistema e me animei, registrei o domínio (um monte deles, na verdade), defini um <em>MVP</em> e saí fazendo a parada. Passei parte das minhas férias de janeiro debruçado sobre o PC fazendo o início do sistema.</p>

<p>Atualmente, o sistema tá uma sopa de nomes de serviços e aplicações: Tô hospedando o código no <em>Heroku</em>, com a busca usando o <em>ElasticSearch</em> através do <em>SearchBox</em>, usando coisas do <em>Amazon AWS</em> pra armazenamento de imagens e etc.</p>

<p>É muito doido ficar nessa de <em>DevOps</em>, nunca tinha ficado nessa posição antes e tá sendo uma experiência bem curiosa.</p>

<figure>
<img src="http://i.imgur.com/JPnYWL3.gif" alt="Go Live Day, by DevOps Reactions" width="275" height="189" />
<figcaption>Go Live Day, by DevOps Reactions</figcaption>
</figure>

<p>Apesar disso, meu MVP tá lá. Mil e umas funcionalidades legais pra implementar nos próximos dias. Diversos jogos pra cadastrar. Enfim, muito trabalho.</p>

<p>Nos próximos dias vai ser tempo de esmagar bugs antes de voltar pro roadmap e implementar os próximos passos. Parece que vai ser um longo e interessante caminho :)</p>]]></content><author><name>Lond</name></author><category term="Random Thoughts" /><category term="Developments" /><category term="Nerdish" /><category term="Random Thoughts" /><summary type="html"><![CDATA[Um dos meus projetos mais velhos finalmente está no ar e eu acho que vale a pena falar um pouco sobre a experiência.]]></summary></entry><entry><title type="html">Facebook, aplicativos e a privacidade</title><link href="https://lond.com.br/2013/12/07/facebook-aplicativos-e-a-privacidade/" rel="alternate" type="text/html" title="Facebook, aplicativos e a privacidade" /><published>2013-12-07T19:17:39+01:00</published><updated>2013-12-07T19:17:39+01:00</updated><id>https://lond.com.br/2013/12/07/facebook-aplicativos-e-a-privacidade</id><content type="html" xml:base="https://lond.com.br/2013/12/07/facebook-aplicativos-e-a-privacidade/"><![CDATA[<p>Começo esse post com uma afirmação sem medo de estar errado: privacidade e facebook não andam juntos. Não se pode ter um com o outro. E a cada dia que passa, isso é mais verdade.</p>

<p>Recentemente o Lulu foi o assunto mais falado de toda a internet. Vários textos foram escritos sobre o app e eu não vou aqui falar sobre o aplicativo em si, mas se você quer ler mais sobre ele, aqui vão ótimos textos pra você:</p>

<p><a title="“Lulu”, machismo invertido?" href="http://outraspalavras.net/destaques/machismo-invertido/" target="_blank">“Lulu”, machismo invertido?</a> por Marília Moschklovich</p>

<p><a title="Clube da Lulu e a objetificação masculina" href="http://thinkolga.com/2013/11/22/clube-da-lulu-e-a-objetificacao-masculina/" target="_blank">Clube da Lulu e a objetificação masculina</a> por Olga</p>

<p>Mas o meu ponto mesmo é sobre privacidade, e aí a gente entra em outro <em>rabbit hole</em>.</p>

<p>Toda vez que converso com pessoas que não tem um <em>background</em> de computação, elas parecem não fazer idéia quanto privacidade é cada vez menos o conceito que se imagina. A privacidade, como as pessoas entendiam há alguns anos atrás, existe menos a cada dia. Cada vez que você escreve um novo post no seu facebook, ou faz uma nova pesquisa no google, mesmo que não esteja realmente associado a você, esses dados criam uma identidade virtual que já tem todas as informações relevantes. Por isso “anúncios relevantes”, por isso quando você busca por um produto que te interessa o facebook mostra sobre aquilo na sua timeline, o google mostra aquilo nos ads que aparecem pra você nas páginas.</p>

<p>A Target, loja americana de varejo, tem um cartão fidelidade que dá diversos descontos. A partir dos dados desse cartão de fidelidade, ela consegue prever quando as suas clientes estão grávidas e quanto tempo aproximadamente falta para elas terem o bebê e com essas informações oferecem cupons de desconto direcionados. [1]</p>

<p>Em outro artigo, entrevistaram especialistas em segurança sobre o que deveria ser feito para ficar anônimo no mundo moderno e as respostas são assustadoras[2]. Dentre elas, um cara descobriu que o dispositivo que ele usa pra passar em pedágios sem pagar (como aqueles usados por aqui na Linha Amarela e em shoppings) também era usado pra rastrear por onde o carro dele passava. Supostamente essa informação é usada para obter informações sobre como está o trânsito na cidade, a partir da massa de dados dos diversos carros que usam o dispositivo. Mas qualquer um que tenha acesso a essa banco de dados também pode saber por onde você anda e quando.</p>

<p>Quando entramos na discussão sobre Facebook, Google Plus, Twitter e diversas outras redes sociais, batemos em vários problemas. Dentre eles, a “censura” de conteúdo. Embora o conteúdo na maioria das redes sociais não seja de fato censurado, o Facebook muda o modo como você se relaciona com as coisas compartilhadas pelos seus amigos escondendo os posts que seus algoritmos julgam apropriados. É fácil de notar isso: escolha um amigo da sua timeline com quem você tenha pouco contato (aquele seu amigo de colégio que você adicionou mas nunca trocou uma mensagem) e você vai ver que nem todos os posts dele apareceram pra você. E mesmo os que aparecem, aparecem numa ordem escolhida pelos algoritmos do Facebook, baseado no que ele acha que é o mais relevante para você. Isso é especialmente notável no caso das páginas que podem ser criados para negócios, pessoas públicas, bandas e etc. Nesse caso, os algoritmos dão ainda mais prioridades para posts pagos, e os que não são pagos muitas vezes não são entregues pra boa parte da audiência. Há diversos posts apontando sobre como possívelmente posts não pagos perdem audiência para posts pagos. [4]</p>

<p>O Google Reader, extinto pelo Google recentemente, usava o protocolo de RSS e Atom, que são dois protocolos abertos de divulgação de conteúdo. Nesse tipo de serviço (hoje em dia disponível através do The Old Reader, Feedly, Digg Reader, etc) TODO o conteúdo compartilhado por um feed que o usuário siga é entregue para o usuário e essa seleção é feita pelo receptor, não pelo serviço que entrega os feeds. Assim, um blog, como este, pode entregar todo o seu conteúdo e o filtro é o próprio usuário e não algoritmos especializados.</p>

<p>Ainda sobre as redes sociais, temos os seus termos de uso e privacidade sempre complicados e com vários poréns. No caso do Lulu (e qualquer outro aplicativo do facebook, na verdade), o <em>catch</em> é que segundo o facebook, sua foto de perfil e seu nome são informações públicas [3], ou seja, quando um amigo seu se inscreve um aplicativo e entrega as informações sobre a rede de amigos que ele possui, a sua foto e o seu nome vão para esse aplicativo, sem a sua permissão, porque você já deu permissão para que isso acontecesse quando criou a sua conta.</p>

<p>O problema é enorme, e há ramificações para todo lado. Um bom ponto de partida sobre o assunto é ler sobre Neutralidade da Rede [5]. Outro ponto de partida é ler sobre como o facebook trata os seus dados, mesmo quando deletados [6]. Por fim, há um artigo sobre vigilância e controle de conteúdo no Capitalismo em Desencanto que fala sobre esses e outros pontos, com ótimos links[7].</p>

<p>Da próxima vez que for compartilhar um dado no facebook, pense duas vezes se aquele dado realmente é público. Porque mesmo quando você não compartilhar ele com o mundo, alguém que você não conhece pode estar vendo ele do outro lado.</p>

<p>[1] – <a title="How Target Figured Out A Teen Girl Was Pregnant Before Her Father Did" href="http://www.forbes.com/sites/kashmirhill/2012/02/16/how-target-figured-out-a-teen-girl-was-pregnant-before-her-father-did/" target="_blank">How Target Figured Out A Teen Girl Was Pregnant Before Her Father Did</a> (artigo em inglês)</p>

<p>[2] – <a title="Think You Can Live Offline Without Being Tracked? Here's What It Takes" href="http://www.fastcompany.com/3019847/think-you-can-live-offline-without-being-tracked-heres-what-it-takes" target="_blank">Think You Can Live Offline Without Being Tracked? Here’s What It Takes</a> (artigo em inglês)</p>

<p>[3] – <a title="Política de uso de dados do Facebook" href="https://www.facebook.com/full_data_use_policy#publicinfo" target="_blank">Política de uso de dados do Facebook<br /> </a>[4] – <a title="Disruptions: As User Interaction on Facebook Drops, Sharing Comes at a Cost" href="http://bits.blogs.nytimes.com/2013/03/03/disruptions-when-sharing-on-facebook-comes-at-a-cost/" target="_blank">Disruptions: As User Interaction on Facebook Drops, Sharing Comes at a Cost</a> (artigo em inglês)</p>

<p>[5] – <a title="Neutralidade da Rede" href="http://pt.wikipedia.org/wiki/Neutralidade_da_rede" target="_blank">Neutralidade da Rede<br /> [</a>6] – <a title="Think Your Deleted Facebook Posts Are Really Deleted? Guess Again" href="http://hothardware.com/News/Think-Your-Deleted-Facebook-Posts-Are-Really-Deleted-Guess-Again/" target="_blank">Think Your Deleted Facebook Posts Are Really Deleted? Guess Again</a> (artigo em inglês)</p>

<p>[7] – <a title="Vigilância e controle de conteúdo na internet" href="http://capitalismoemdesencanto.wordpress.com/2013/06/10/vigilancia-e-controle-de-conteudo-na-internet/" target="_blank">Vigilância e controle de conteúdo na internet</a></p>]]></content><author><name>Lond</name></author><category term="Random Thoughts" /><category term="Data Mining" /><category term="Facebook" /><category term="Google" /><category term="Google Plus" /><category term="Google Reader" /><category term="Lulu" /><category term="Nerdish" /><category term="Net Neutrality" /><category term="Neutralidade da Rede" /><category term="Paid Posts" /><category term="Política de Privacidade" /><category term="Posts pagos" /><category term="Privacidade" /><category term="Privacy Policy" /><category term="Random Thoughts" /><category term="Tubby" /><category term="twitter" /><summary type="html"><![CDATA[Começo esse post com uma afirmação sem medo de estar errado: privacidade e facebook não andam juntos. Não se pode ter um com o outro. E a cada dia que passa, isso é mais verdade.]]></summary></entry><entry><title type="html">Pebble, o smartwatch</title><link href="https://lond.com.br/2013/04/18/pebble-o-smartwatch/" rel="alternate" type="text/html" title="Pebble, o smartwatch" /><published>2013-04-18T16:22:11+02:00</published><updated>2013-04-18T16:22:11+02:00</updated><id>https://lond.com.br/2013/04/18/pebble-o-smartwatch</id><content type="html" xml:base="https://lond.com.br/2013/04/18/pebble-o-smartwatch/"><![CDATA[<p>Pra quem não é chegado em tecnologia, talvez não tenha ouvido falar do Pebble, o relógio com tecnologia de tela e-paper, que foi até a última vez que conferi o projeto com mais funding no kickstarter, chegando a mais de 10 milhões de dólares, quando o objetivo do funding era de meros 100 mil dólares.</p>

<figure style="width: 512px">
<a href="http://www.kickstarter.com/projects/597507018/pebble-e-paper-watch-for-iphone-and-android" target="_blank"><img class=" " alt="Dá uma olhada no protótipo 3d da criança." src="https://s3.amazonaws.com/ksr/projects/111694/photo-main.jpg" width="512" height="384" /></a>
<figcaption class="wp-caption-text">Dá uma olhada no protótipo 3d da criança.</figcaption>
</figure>

<p>A idéia é bem simples, um relógio com uma bateria recarregável que dura até sete dias, que é programável (ou seja, você pode mostrar a hora de diversas formas, na foto aí de cima já tem duas), se liga por bluetooth com seu celular e pode receber notificações de qualquer aplicativo, além de ter acelerômetro e tudo mais que um geek pode querer.</p>

<p>O relógio me ganhou na parte em que ele poderia fazer uma ponte com o RunKeeper e virar uma espécie de Garmin mais versátil.</p>

<figure style="width: 504px">
<img class=" " alt="Enquanto se corre a idéia é que o gadget se comporte assim." src="http://d2brbg16830x6.cloudfront.net/running1.jpg" width="504" height="284" /><figcaption class="wp-caption-text">Enquanto se corre a idéia é que o gadget se comporte assim.</figcaption></figure>

<p>E aí fica a pergunta, ele entrega o que promete? Ele é mesmo tudo isso? Vamos por partes</p>

<h2 id="o-tempo-de-entrega">O tempo de entrega</h2>

<p>A internet não é paciente. A internet não é razoável. O tempo estimado de entrega dos relógios era setembro de 2012. Mas claro, sendo um produto completamente novo, sendo feito em larga escala, por uma equipe que não parece ser enorme e tendo que trabalhar entre estados unidos e china não é uma tarefa fácil. Os caras tentaram ser transparentes: 33 updates no kickstarter desde abril de 2012 até agora, em março de 2013. Mas é complicado, problemas acontecem em qualquer entrega de produto, especialmente em um físico.</p>

<p>No geral, eu achei que eles se esforçaram pra cumprir o prazo, e não fiquei decepcionado com o tempo. Especialmente levando em consideração o produto final. O problema é as pessoas não estarem acostumadas com um modelo tipo Kickstarter, na minha opinião. Onde as coisas podem dar errado e podem atrasar.</p>

<h2 id="o-relógio">O relógio</h2>

<p>Peguei meu pebble hoje pela manhã. Provavelmente esse post não vai ser lançado no dia que eu peguei, até pra ter uma impressão maior sobre o tempo de bateria e tudo o mais. Mas desde então, já mudei uma coisa na minha vida: não tem mais vibração ou som no meu celular. É muito mais prático a vibração do relógio, e ver as notificações é bem tranquilo. A coisa não é bem out-of-the-box, mas instalando um appzinho auxiliar, o Pebble Notifier, fica bem tranquilo e as coisas funcionam bem, dando pra ver inclusive várias mensagens de whatsapp de uma vez só. (mas não dá pra ver aquele longo tópico de 23 messagens do grupo da <em>galere</em>, isso não dá.)</p>

<figure style="width: 421px">
<a href="https://lh4.googleusercontent.com/-fmttYyAfziw/UUOKvP2ysuI/AAAAAAAAOPM/iS9WRdRP7G0/s802/IMG_20130315_175418.jpg" target="_blank"><img class=" " alt="O exemplo de uma notificação de SMS, que vem no app do pebble" src="https://lh4.googleusercontent.com/-fmttYyAfziw/UUOKvP2ysuI/AAAAAAAAOPM/iS9WRdRP7G0/s802/IMG_20130315_175418.jpg" width="421" height="561" /></a>
<figcaption class="wp-caption-text">O exemplo de uma notificação de SMS, que vem no app do pebble</figcaption></figure>

<p>Uma parte meio ruim é que a tela é um imã de digital, mas como ela não é touch, não era pra você tocar nela anyway. Mas é inevitável, e em poucas horas, dava pra ver a tela meio sujinha. Nada que passar ele na camisa não resolva.</p>

<figure style="width: 421px">
<a href="https://lh4.googleusercontent.com/-iw_R3U-6J-g/UUOF53Lp88I/AAAAAAAAOOw/8DFt0c0R9EY/s1078/IMG_20130315_173344.jpg" target="_blank"><img class=" " alt="Mas que bela digital, hein." src="https://lh4.googleusercontent.com/-iw_R3U-6J-g/UUOF53Lp88I/AAAAAAAAOOw/8DFt0c0R9EY/s802/IMG_20130315_173344.jpg" width="421" height="561" /></a>
<figcaption class="wp-caption-text">Mas que bela digital, hein.</figcaption></figure>

<h2 id="a-caixa">A caixa</h2>

<p>Peraí, a caixa? É, a caixa merece ser mostrada, porque ela é tão bonitinha :)<figure style="width: 528px"></figure></p>

<p><a href="http://i.imgur.com/X67ODkI.jpg" target="_blank"><img class="   " alt="O pebble bonitinho na caixinha, foto roubada do amigo Luiz" src="http://i.imgur.com/X67ODkI.jpg" width="528" height="396" /></a></p>
<figcaption class="wp-caption-text">O pebble bonitinho na caixinha, foto roubada do amigo Luiz</figcaption>
<p>&lt;/figure&gt;</p>

<h2 id="a-bateria">A bateria</h2>

<p>A bateria agrada no sentido de que tem durado basicamente o que foi prometido, entre cinco e sete dias. Tive que carregar ele algumas vezes desde que chegou, mas a duração é bem agradável e a notificação de bateria baixa aparece em tempo suficiente pra você ainda aguentar um dia inteiro com ele (da última vez assim que cheguei no trabalho a notificação de bateria baixa apareceu e só fui carregá-lo ao chegar em casa, de noite).</p>

<p>A única vez que ele durou pouco tempo foi durante o Lollapalooza, pois embora estivesse com o bluetooth desligado, estava com a função de acender a tela ao sacudir o braço, e vocês podem imaginar o quanto se sacode o braço durante um fim de semana de shows, né? :)<figure style="width: 460px"></figure></p>

<p><a href="http://i.imgur.com/QOzdsYb.jpg" target="_blank"><img alt="Nota para mim, sacudir o braço um fim de semana inteiro pode descarregar o pebble." src="http://i.imgur.com/QOzdsYb.jpg" width="460" height="276" /></a></p>
<figcaption class="wp-caption-text">Nota para mim, sacudir o braço um fim de semana inteiro pode descarregar o pebble.</figcaption>
<p>&lt;/figure&gt;</p>

<h2 id="watchfaces">Watchfaces</h2>

<p>Ao contrário de um relógio digital tradicional, você pode mudar a cara do seu relógio. E existe um site com muitas watchfaces e mais ainda aparecendo todo o dia, pra agradar a todos os gostos. E em breve, com a SDK mais completa, com certeza aparecerão watchfaces que estão mais pra aplicativos.</p>

<figure style="width: 496px">
<a href="http://i.imgur.com/kurlfPI.png?1" target="_blank"><img class="   " alt="http://www.mypebblefaces.com/" src="http://i.imgur.com/kurlfPI.png?1" width="496" height="360" /></a>
<figcaption class="wp-caption-text">http://www.mypebblefaces.com/</figcaption></figure>

<h2 id="considerações-finais">Considerações finais</h2>

<p>Acho que o pebble foi um investimento muito válido. Não invasivo, ele parece um relógio normal e engana tranquilamente como se você não estivesse permanentemente conectado. Ao mesmo tempo, diminuiu o número de vezes em que pego o celular durante ocasiões sociais porque todas as notificações importantes vão até o relógio. Há ainda algumas arestas a aparar, como o fato de que o Whatsapp, mesmo em mute, ainda notifica no relógio.</p>

<p>De resto, que venham os dispositivos de convergência. Mal posso esperar a época em que estarei com meu pebble fazendo um review do meu mais novo Google Glass :)</p>]]></content><author><name>Lond</name></author><category term="Android" /><category term="Apple" /><category term="Bluetooth" /><category term="Gadgets" /><category term="Iphone" /><category term="Kickstarter" /><category term="Nerdish" /><category term="Notifications" /><category term="Pebble" /><category term="Runkeeper" /><category term="Smart Watch" /><category term="Smartwatch" /><category term="Watchfaces" /><summary type="html"><![CDATA[Pra quem não é chegado em tecnologia, talvez não tenha ouvido falar do Pebble, o relógio com tecnologia de tela e-paper, que foi até a última vez que conferi o projeto com mais funding no kickstarter, chegando a mais de 10 milhões de dólares, quando o objetivo do funding era de meros 100 mil dólares.]]></summary></entry></feed>