Matheus Bratfisch Cogito ergo sum

Loopback migrando seus models com o postgresql

Eu estou brincando com o Loopback, um framework javascript. Inicialmente eu só estava criando modelos e utilizando o explorer para verificar os resultados do mesmo, porém agora eu atingi um ponto que preciso persistir os dados.

Eu não consegui encontrar como manter meu banco de dados e meus modelos sincronizados facilmente, não tenho certeza se eu que não estou tão familiar com o Loopback ainda, ou se a documentação esta realmente um pouco confusa.

Então para criar um script que mantenha seus modelos sincronizados você pode criar um arquivo na pasta bin e nomea-lo autoupdate.js e adicionar o seguinte:

var path = require('path');

var app = require(path.resolve(__dirname, '../server/server'));
var ds = app.datasources.db;
ds.autoupdate(function(err) {
  if (err) throw err;
  ds.disconnect();
});

O código é bem simples, ele vai importar seu app do server.js, adicionar o datasource e rodar o comando autoupdate. Você poderia usar automigrate mas este limpa o seu database todas as vezes, então se você quer manter seus dados, essa não é a maneira apropriada.

Eu acredito que isso vai funcionar para outros bancos de dados, como MySQL. Se não funcionar, me avise, eu posso tentar ajudar.

Matheus

PS: Ele não vai fazer uma gerencia como o Django faz pra você, então as vezes você pode cair em estados indesejáveis, acredito que o ideal seria utilizar loopback com NoSQL

Comment

Django Storages com Boto3 e Metadados adicionais somente para as Medias

Eu tenho um projeto pessoal o qual estou usando Django com django-storages para enviar meus arquivos estáticos e medias para a Amazon S3, já que as minhas medias possuem UUID e não são editáveis eu gostaria de ter um tempo de expiração maior para elas, assim eu poderia salvar transferência porém eu não gostaria de ter essa cache maior para os arquivos estáticos que são atualizados com mais frequência.

Maioria dos conteúdos que encontrei na internet se referiam a AWS_HEADERS porém o mesmo não funcionou para mim. Parece que o mesmo só funciona para o boto (não para o boto3) e depois de olhar o código do boto3 eu descobri o AWS_S3_OBJECT_PARAMETERS o qual funciona para o boto3, mas esta é uma configuração global então eu precisei extender a classe S3Boto3Storage.

Então o código que resolveu meu problema foi:

class MediaRootS3Boto3Storage(S3Boto3Storage):
    location = 'media'
    object_parameters = {
        'CacheControl': 'max-age=604800'
    }

Se você está usando o boto (não o boto3) e gostaria de ter meta dados especiais somente para a sua classe Media, você pode usar:

class MediaRootS3Boto3Storage(S3BotoStorage):
    location = 'media'
    headers = {
        'CacheControl': 'max-age=604800'
    }

Você também vai precisar atualizar a sua configuração do django-storages, preste atenção ao nome da classe, no boto 3 é S3Boto3Storage porém no boto, o mesmo não possui o 3 depois da palavra Boto

DEFAULT_FILE_STORAGE = 'package.module.MediaRootS3Boto3Storage'

Uma dica simples, porém pode salvar um pouco do seu tempo.

Matheus

Comment

Redirecionar acessos para um servidor Wordpress secundário usando Nginx

Alguns de vocês provavelmente acompanhou, mas recentemente eu decidi atualizar meu antigo wordpress blog do PHP4~5 para um mais recente. Deixando meu host compartilhado e indo para o heroku e posteriormente para Amazon EC2.

Eu precisava decidir se eu manteria o Wordpress ou se eu mudaria para uma tecnologia diferente, como Jekyll? Ou o que? Eu pensei bastante sobre isso e no fim eu decidi utilizar Jekyll, por que? Para ser sincero, usando algo mais novo/recente me motiva a estudar e fuçar mais a fundo para conseguir as coisas rodando.

Depois que decidi que usaria o Jekyll, eu precisava pensar sobre meu dominio, eu queria manter meu blog antigo rodando como histórico mas também gostaria de fazer redirecionamento correto para não perder meus pontos de SEO por exemplo, então como manter 2 blogs funcionando de uma maneira inteligente sem quebrar os links antigos?

Eu pensei que o ideal seria algo que tentasse acessar o novo site e caso não encontrasse, deveria redirecionar para o blog antigo rodando Wordpress, mas como atingir isso somente quando a página não fosse encontrada e de uma maneira boa para SEO (utilizando 301 para os redirects)?

Depois de algum tempo brincando e lendo a documentação do nginx eu achei uma maneira de rodar um servidor com um proxy e caso o acesso falhe, interceptar o mesmo e redirecionar para outro servidor do nginx.

Então para fazer isso eu tenho um arquivo de configuração do nginx com multiplas configurações, a primeira delas possui a configuração do Wordpress, esse servidor é bem simples e somente trata acessos de páginas PHP com o PHP FPM basicamente usando um subdomínio.

server {
   listen 80;
   server_name wordpress.matbra.com;

    location / {
        root   /var/www/wordpress/live;
        index  index.php index.html index.htm;
        try_files $uri $uri/ /index.php?$uri$args;
    }

    location ~ \.php$ {
        root /var/www/wordpress/live;
        fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

Read more

Compilando seu site em Jekyll depois do git push

Se você quer compilar (buildar) o seu blog no seu próprio servidor depois de um git push, você pode usar os git hooks. Para fazer isso, você pode simplesmente extender a minha dica Deploy depois de push para também compilar o seu Jekyll como ambiente de produção. Para fazer isso basta adicionar o código abaixo depois do rm -rf

	cd $LIVE_PATH
	bundle install
	JEKYLL_ENV=production jekyll build

Matheus

Comment

Forçar www no endereço do seu Jekyll usando Javascript

Eu queria fazer meu site ter sempre a mesma url, com o prefixo www como meu Jekyll não possui um back-end eu não podia fazer no servidor, portanto eu precisava utilizar Javascript ou meta tags. Algumas pessoas comentam que o buscador do Google considera tags meta refresh como redirects (301/302) então essa solução seria a mais adequada.

Teimoso do jeito que sou, decidi utilizar Javascript. Se você desejar fazer com que o seu blog tenha esse mesmo comportamento, utilize o seguinte código:

<script>
if (window.location.hostname.indexOf("www") != 0) {
	window.location = window.location.protocol + "//www." + window.location.hostname + window.location.pathname;
}
</script>

Eu criei um arquivo _include/force_www.html e estou usando a variável jekyll.environment para incluir essa paret do template e ter esse comportamento somente no ambiente de produção.

Matheus

Comment

Definindo variáveis de ambiente para o PHP-FPM

Após instalar o nginx e o PHP, eu queria passar variáveis de ambiente para o PHP 7 para que eu não tivesse que salvar as configurações para o meu repositório.

Quando você utiliza variáveis de ambiente o ideal é defini-las sem deixa-las salvas, porém nesse caso eu salvei as mesmas.

Se você deseja adicionar variáveis de ambiente para o seu PHP-FPM, você pode editar /etc/php-fpm.d/www.conf (Estou fazendo isso no Amazon Linux e PHP 7.0)

Existe uma configuração no PHP-FPM, clear_env = no esta variável define se o PHP vai receber um ambiente limpo ou não. Eu deixei a mesma habilitada (o valor padrão é habilitado) mas adicionei as minhas variáveis de ambiente:

env[WP_SECURE_AUTH_KEY] = "valor1"
env[WP_NONCE_KEY] = "valor2"

Depois disso eu reiniciei o nginx e o PHP-FPM:

sudo service nginx restart
sudo service php-fpm restart

Matheus

Comment

Deploy depois de dar push com o seu git

Eu expliquei como enviar seu código para o seu próprio servidor e depois disso você talvez queira executar algumas ações específicas, no meu caso eu gostaria que meu blog fosse atualizado quando eu enviasse uma nova versão para o git então eu usei um `post-receive hook.

Este script vai manter as 3 últimas versões do seu código, então se algo der errado, você pode fazer rollback mudando o link. Para fazer isso o script utiliza a variável DEPLOY_PATH e cria uma nova pasta sources nela, a qual vai ter as versões do seu site. A versão ativa é basicamente um link simbolico (symlink) da pasta live para a pasta sources

Variáveis:

  • REPO_PATH = Caminho para o seu repositório local
  • DEPLOY_PATH = Caminho para a pasta de release
  • DEPLOY_BRANCH = Branch que você quer lançar
#!/bin/bash
REPO_PATH=/home/someuser/test.git
DEPLOY_PATH=/var/www/
DEPLOY_BRANCH="master"

echo "REPO_PATH=$REPO_PATH"
echo "DEPLOY_PATH=$DEPLOY_PATH"

while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ $DEPLOY_BRANCH == "$branch" ]; then
        TIMESTAMP=$(date +%Y%m%d%H%M%S)
        VERSION_PATH=$DEPLOY_PATH/sources/$TIMESTAMP
        LIVE_PATH=$DEPLOY_PATH/live
        echo "TIMESTAMP=$TIMESTAMP"
        echo "VERSION_PATH=$VERSION_PATH"
        echo "LIVE_PATH=$LIVE_PATH"

        mkdir -p $VERSION_PATH
        mkdir -p $VERSION_PATH/sources

        git --work-tree=$VERSION_PATH --git-dir=$REPO_PATH checkout -f $DEPLOY_BRANCH
        # Remove git files
        rm -rf $VERSION_PATH.git
        rm -rf $LIVE_PATH
        ln -s $VERSION_PATH $LIVE_PATH


        # Delete old folder keeping the 3 most recent ones, which aren't the current live one, / (root, security measure, different from your source folder)
        rm -rf $(ls -1dt $(find -L $DEPLOY_PATH/sources/ -maxdepth 1 -type d ! -samefile / ! -samefile $DEPLOY_PATH/sources/ ! -samefile $LIVE_PATH -print) | tail -n+3)
    fi
done

Se você ainda tiver alguma questão me avise, Matheus

Comment

Enviando seus códigos para o seu próprio git

Eu estou mudando a minha infraestrutura como vocês devem ter percebido, neste momento eu gostaria de enviar meus códigos para o meu próprio servidor para poder fazer deploy com um simples git push my_server branch.

Então se você quer o mesmo tipo de comportamento você precisa conectar a sua máquina que vai hostear seu git com ssh e executar:

  1. $ mkdir test.git
  2. $ cd git
  3. $ git --bare init

Você vai precisar saber o caminho completo para a pasta recém criada. Para verificar o diretório que você se encontra utilize pwd. Voltando a sua máquina local, adicione o seu servidor como uma origin no seu git.

git remote add my_server ssh:[email protected]:/replace/with/pwd/test.git

Após isso você pode enviar os códigos do seu repositório utilizando git push my_server branch.

Matheus

Comment

Instalar Nginx, PHP no Amazon Linux

Estou migrando meu blog e alguns outros serviços para a infraestrutura da Amazon. Eu precisava de uma instância EC2 com suporte a PHP e a conectar no MySQL.

Passos:

  1. yum update
  2. yum install nginx
  3. yum install php70 php70-fpm php70-mysqlnd
  4. Edite /etc/nginx/conf.d/virtual.conf
server {
    listen       3000;

    location / {
        root   /var/www/;
        index  index.php index.html index.htm;
    }

    location ~ \.php$ {
        root /var/www/;
        fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
  1. Edite as seguintes propriedades do: /etc/php-fpm-7.0.d/www.conf
user = nginx
group = nginx

listen = /var/run/php-fpm/php-fpm.sock

listen.owner = nginx
listen.group = nginx
listen.mode = 0660
  1. Crie um arquivo php em /var/www/
<?php
phpinfo();
?>
  1. Acesse http://SERVER_IP:3000

Você vai precisar da porta 3000 aberta nos security group da sua instância ec2.

Se você deseja iniciar os serviços automaticamente:

sudo chkconfig nginx on
sudo chkconfig php-fpm on

Se você quer reiniciar os seriviços:

sudo service nginx restart
sudo service php-fpm restart

Matheus

Comment

Migrando um antigo Wordpress para o Heroku, Amazon RDS e S3

Depois de alguns bons longos anos com o blog parado, decidi voltar a escrever e mudar o mesmo para o Heroku. Decidi utilizar o Heroku como servidor, o serviço de banco de dados da Amazon, o RDS e o S3 como servidor de arquivos.

Passos:

  1. Desabilite todas as extensões do Wordpress
  2. Faça um backup completo (Wordpress, banco de dados, uploads, etc)
  3. Sério faça o backup!
  4. Crie um repositório git
  5. Adicione o código do Wordpress ao seu git
    1. Se você quer atualizar seu Wordpress, adicione a ultima versão do Wordpress
      1. Não adicione as suas configurações privadas!
      2. Não adicione o conteúdo da pasta uploads
      3. Adicione seus plugins
      4. Adicione seu tema
    2. Se você quer manter a sua versão, adicione o código do seu blog atual
      1. Não adicione as suas configurações privadas!
      2. Não adicione a pasta uploads ao seu repositório
  6. Atenção com os arquivos que contém dados privados!!
  7. Altere seu wp-config.php
    1. Todas as configurações privadas devem usar getenv, essa função é responsável por pegar as informações das variaveis de ambiente no PHP
    <?php
    define('AUTH_KEY',         getenv('WP_AUTH_KEY'));
    define('SECURE_AUTH_KEY',  getenv('WP_SECURE_AUTH_KEY'));
    define('LOGGED_IN_KEY',    getenv('WP_LOGGED_IN_KEY'));
    define('NONCE_KEY',        getenv('WP_NONCE_KEY'));
    
    define('AUTH_SALT',        getenv('WP_AUTH_SALT'));
    define('SECURE_AUTH_SALT', getenv('WP_SECURE_AUTH_SALT'));
    define('LOGGED_IN_SALT',   getenv('WP_LOGGED_IN_SALT'));
    define('NONCE_SALT',       getenv('WP_NONCE_SALT'));
    
    define('S3_UPLOADS_BUCKET', getenv('AWS_S3_BUCKET'));
    define('S3_UPLOADS_KEY', getenv('AWS_S3_KEY'));
    define('S3_UPLOADS_SECRET', getenv('AWS_S3_SECRET'));
    define('S3_UPLOADS_REGION', getenv('AWS_S3_REGION')); 
    
  1. Crie um arquivo composer.json para definir pacotes e versão do PHP
    1. Exemplo composer.json
    {
      "require" : {
          "php": ">=7.0.0"
      },
      "require-dev": {
      }
    }
    
  1. Execute composer update para gerar o composer.lock
  2. Altere o seu .htaccess para fazer redirect dos uploads para o S3
    1. Atualize o BUCKET para o nome do seu bucket
    2. A regra da 5 linha é a responsável por fazer o redirect
    <IfModule mod_rewrite.c>
     RewriteEngine On
     RewriteBase /
     RewriteRule ^index\.php$ - [L]
     RewriteRule ^wp-content/uploads/(.*)$ https://s3-us-west-2.amazonaws.com/BUCKET/uploads/$1 [R=301,L]
     RewriteCond %{REQUEST_FILENAME} !-f
     RewriteCond %{REQUEST_FILENAME} !-d
     RewriteRule . /index.php [L]
     </IfModule>    
    
  3. Faça um commit no seu git com os arquivos do seu wordpress
  4. Setup da Amazon
    1. Crie um banco de dados no RDS
    2. Importe o backup do seu banco de dados no RDS
    3. Envie seus arquivos para o S3
      1. Lembre-se de criar os arquivos com permissão publíca para que usuários não autenticados consigam acessar
  5. Setup do Heroku
    1. Adicione as variáveis de ambiente no Heroku com os nomes e valores que você utilizou no seu wp-config.php, lembre de usar as configurações para o RDS.
    2. Atualize seu DNS no Heroku
    3. Envie seu código para o Heroku usando o repositório git que você criou
  6. Acesse o seu site

Se você está atualizando seu Wordpress, existem chances dos plugins que você usava não funcionarem na nova versão, então verifique se os plugins funcionam ;)

Se vocês tiverem dúvidas em algum passo específico eu posso criar um novo post com mais detalhes sobre ele, esse foi uma visão geral de como eu fiz.

Matheus

Comment