Ruby: Usos avançados
Avançar com as suas implementações Ruby
👋 Bem-vindo à documentação do Stackhero!
A Stackhero oferece uma solução Ruby cloud pronta a usar que proporciona uma série de benefícios, incluindo:
- Implemente a sua aplicação em segundos com um simples
git push.- Utilize o seu próprio nome de domínio e beneficie da configuração automática de certificados HTTPS para uma segurança reforçada.
- Desfrute de tranquilidade com backups automáticos, atualizações com um clique, e preços simples, transparentes e previsíveis.
- Obtenha desempenho ótimo e segurança robusta graças a uma VM privada e dedicada.
Poupe tempo e simplifique a sua vida: só leva 5 minutos para experimentar a solução de Ruby cloud hosting da Stackhero!
Implementar uma ramificação diferente de main
Até agora, implementámos a nossa aplicação Ruby ao enviar a ramificação main usando:
git push stackhero main
Se desejar implementar uma ramificação diferente, pode usar este comando. Substitua <BRANCH> pelo nome da ramificação que deseja implementar:
git push stackhero <BRANCH>:main
Por exemplo, para implementar uma ramificação chamada production, execute:
git push stackhero production:main
Implementar tags em vez de ramificações
Em alguns casos, pode querer implementar uma tag em vez de uma ramificação. Para isso, execute o seguinte comando. Substitua <TAG> pela tag que deseja implementar:
git push stackhero '<TAG>^{}:main'
Por exemplo, para implementar a tag v1.0.0, execute:
git push stackhero 'v1.0.0^{}:main'
A sintaxe
^{}é usada para referenciar o commit ao qual a tag aponta.
Implementar um commit específico
Além de ramificações ou tags, pode implementar um commit específico. Substitua <COMMIT_HASH> no comando abaixo pelo hash do commit desejado:
git push -f stackhero <COMMIT_HASH>:main
Por exemplo, para implementar um commit com o hash abcde, execute:
git push -f stackhero abcde:main
Reverter para uma versão anterior
Se a sua implementação em produção não estiver a funcionar como esperado, pode reverter ao implementar um commit mais antigo. Primeiro, use o comando abaixo para ver o histórico de commits:
git log
Este comando exibe a data, o hash do commit e a descrição de cada commit no seu repositório. Por exemplo, pode ver uma saída como:
commit cccc8b3ebdccb9abc1926ef49ee589dae5c5fe06 (HEAD -> main, stackhero/main)
Author: Developer
Date: Fri Apr 28 09:36:18 +0000
Break the code
commit bbbb622301772072c3d82f3cc0d91e29e6e84901
Author: Developer
Date: Wed Apr 26 12:49:28 +0000
Update the code
commit aaaa1d8b06535b413e0df8298ccf52339dfef3ff
Author: Developer
Date: Wed Apr 26 12:44:50 +0000
Improve the code
Se o commit com a mensagem "Break the code" (hash cccc...) estiver em execução em produção, e decidir reverter para o commit anterior "Update the code" (hash bbbb...), execute:
git push -f stackhero bbbb622301772072c3d82f3cc0d91e29e6e84901:main
Para evitar implementar código defeituoso e aumentar a estabilidade da sua produção, é altamente recomendado ter um ambiente "staging".
Situado entre os ambientes "development" e "production", o ambiente "staging" fornece uma réplica quase exata do ambiente de produção. Isso permite testar o seu código e garantir a sua qualidade antes de o implementar em produção.
Ao usar um ambiente de staging, pode estar mais confiante na funcionalidade e desempenho do seu código, garantindo uma implementação em produção mais fiável e robusta.
Este tipo de ambiente será discutido mais tarde na documentação.
Configurar um ambiente de staging
Um ambiente staging é uma boa prática a usar em paralelo com os seus ambientes development e production. Ele replica o seu ambiente de produção para que possa testar atualizações e alterações antes de serem lançadas.
Um ambiente de staging deve refletir de perto o ambiente de produção.
No entanto, certifique-se de que o ambiente de staging usa um clone da base de dados de produção em vez da base de dados de produção real.
Se o seu serviço Ruby estiver ligado a uma base de dados ou outros serviços, recrie-os no novo stack
<Project> - Staging.
Para configurar um ambiente de staging no Stackhero, siga estes passos:
- No painel do Stackhero, renomeie o seu stack existente de
<Project>para<Project> - Production. Por exemplo, se o seu projeto se chamaChat Bot, renomeie o stack paraChat Bot - Production. - Crie um novo stack chamado
<Project> - Staging. Usando o exemplo anterior, seriaChat Bot - Staging. - Inicie um serviço Ruby no stack de staging.
- Recupere o valor do comando
git remotee siga as instruções na seção Implementar no ambiente de staging.
Seguindo estes passos, terá um ambiente de staging devidamente configurado para testar e verificar atualizações antes de chegarem à produção.
Implementar no ambiente de staging
Gerir ambientes separados como staging e production é altamente recomendado. Como explicado em Configurar um ambiente de staging, pode implementar em cada ambiente com diferentes remotes Git.
Comece por renomear o repositório remoto atual. Por exemplo, renomeie o remote "stackhero" para "stackhero-production" com este comando:
git remote rename stackhero stackhero-production
Em seguida, crie um novo serviço Ruby para o ambiente de staging. Use o comando "git remote add" fornecido e modifique-o da seguinte forma (substitua <XXXXXX> pelo domínio do seu serviço):
-
Comando original:
git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git -
Comando modificado:
git remote add stackhero-staging ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git
Agora pode implementar no staging usando:
git push stackhero-staging main
Ou implementar em produção com:
git push stackhero-production main
Para simplificar ainda mais o processo de implementação, considere usar a versão melhorada do Makefile.
Com este
Makefilemelhorado, a implementação em produção ou staging pode ser feita facilmente usandomake deploy-productionoumake deploy-staging.
Versão melhorada do Makefile
Abaixo está um Makefile melhorado que acomoda várias regras para tarefas comuns:
make dev(ou simplesmentemake): Inicia a aplicação em modo de desenvolvimento.make deploy: Implementa a aplicação no remote chamadostackhero(ideal quando tem uma única instância Stackhero).make deploy-production: Implementa a aplicação no remote chamadostackhero-production.make deploy-staging: Implementa a aplicação no remote chamadostackhero-staging.
Este
Makefileé projetado para lidar com casos onde o código já foi implementado, evitando o erro "Everything up-to-date".
Copie e cole o seguinte conteúdo no seu novo Makefile:
# Regra a executar por padrão ao invocar "make" sem argumento
.DEFAULT_GOAL := dev
# Stackhero para Ruby executará a regra "run" na sua instância.
# Este é o comando a executar nas plataformas de produção e staging.
run:
rake assets:precompile
rake db:migrate RAILS_ENV=production
RAILS_ENV=production bundle exec puma -C config/puma.rb
# Comando a executar no ambiente de desenvolvimento
dev:
RAILS_ENV=development rails server -b 0.0.0.0
# A regra "deploy" implementa na instância "stackhero".
# Adequado quando tem apenas uma instância.
deploy:
@$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero DEPLOY_BRANCH=main
# A regra "deploy-*" implementa na instância "stackhero-*".
# Por exemplo, execute "make deploy-production" para implementar em "stackhero-production",
# ou "make deploy-staging" para implementar em "stackhero-staging".
deploy-%:
@$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero-$* DEPLOY_BRANCH=main
# Regra de implementação interna. Não modificar.
deploy-script:
@echo "Implementando a ramificação \"${DEPLOY_BRANCH}\" para \"${DEPLOY_REMOTE}\"..."
@echo
@if [ -n "$$(git status --porcelain)" ]; then \
echo "Não é possível implementar porque há alterações não comprometidas:"; \
echo "\e[0m"; \
git status -s; \
echo ""; \
echo "\e[0;31m"; \
echo "Pode usar este comando para comprometer as alterações:"; \
echo "git add -A . && git commit -m \"Sua mensagem\""; \
echo "\e[0m"; \
exit 1; \
fi
@git push --dry-run ${DEPLOY_REMOTE} ${DEPLOY_BRANCH} 2>&1 | grep -q -F "Everything up-to-date"; \
EXIT_CODE=$$?; \
if [ $$EXIT_CODE -eq 0 ]; then \
echo -n "Nada novo para implementar... Forçar implementação (isto criará um novo commit)? (y/N) "; \
read answer && \
case $$answer in \
y|Y|yes|YES) \
git commit --allow-empty -m "Force update for deploy purpose to \"${DEPLOY_REMOTE}\"" ; \
;; \
*) \
echo "Nada para implementar!"; \
exit 1; \
;; \
esac \
fi
git push ${DEPLOY_REMOTE} ${DEPLOY_BRANCH}
Gestão de segredos (variáveis de ambiente)
Em algum momento, precisará gerir segredos como tokens ou palavras-passe para bases de dados e serviços de terceiros. É essencial armazenar esses segredos de forma segura. Evite incorporar segredos diretamente no seu repositório ou código, pois isso representa um sério risco de segurança.
As variáveis de ambiente oferecem dois benefícios significativos:
- Os seus segredos não serão armazenados no seu repositório Git, reduzindo o risco se alguém ganhar acesso ao seu código-fonte.
- Pode usar credenciais diferentes para diferentes ambientes. Por exemplo, conectar-se à sua base de dados de produção em produção enquanto usa uma base de dados de desenvolvimento durante o desenvolvimento.
Configurar variáveis de ambiente para desenvolvimento
Para desenvolvimento, crie um ficheiro .env na raiz do seu projeto. Este ficheiro será excluído do Git para que nunca seja comprometido. Use a gem dotenv para carregar automaticamente o ficheiro .env.
Primeiro, adicione a gem dotenv-rails ao seu Gemfile:
# Gemfile
gem 'dotenv-rails', groups: [:development, :test]
Depois instale a gem:
bundle install
Em seguida, crie um ficheiro .env na raiz do seu projeto e adicione as suas variáveis:
RAILS_ENV="development"
DATABASE_PASSWORD="secretPassword"
THIRD_API_PRIVATE_KEY="secretKey"
# ...
Finalmente, certifique-se de que o ficheiro .env é ignorado pelo Git:
echo '.env*' >> .gitignore
Configurar variáveis de ambiente para staging e produção
Para staging e produção, o ficheiro .env não é seguro nem prático porque não pode ser armazenado num repositório Git. Em vez disso, o Stackhero fornece uma solução segura para gerir variáveis de ambiente diretamente na configuração do seu serviço Ruby.
Pode definir estas variáveis através do painel do Stackhero ao selecionar o seu serviço Ruby e clicar no botão "Configurar".
Aceder a variáveis de ambiente
Em Ruby, pode aceder facilmente a variáveis de ambiente usando ENV. Por exemplo, para recuperar DATABASE_PASSWORD, use:
ENV['DATABASE_PASSWORD'] # => 'secretPassword'
Aqui está um exemplo de como conectar-se a um servidor RabbitMQ usando variáveis de ambiente:
require 'bunny'
class RabbitMQClient
def initialize
@connection = Bunny.new(hostname: ENV['RABBITMQ_HOST'],
username: ENV['RABBITMQ_USERNAME'],
password: ENV['RABBITMQ_PASSWORD'])
@connection.start
end
def publish(queue_name, message)
channel = @connection.create_channel
queue = channel.queue(queue_name)
channel.default_exchange.publish(message, routing_key: queue.name)
end
def close
@connection.close
end
end
Na plataforma de desenvolvimento, o seu ficheiro .env pode incluir:
RABBITMQ_HOST='127.0.0.1'
RABBITMQ_USERNAME='developmentUser'
RABBITMQ_PASSWORD='developmentPassword'
Para produção e staging, defina as suas variáveis de ambiente no painel do Stackhero sob a configuração do serviço Ruby como mostrado abaixo:
RABBITMQ_HOST='<XXXXXX>.stackhero-network.com'
RABBITMQ_USERNAME='production'
RABBITMQ_PASSWORD='secretProductionPassword'
Abrir portas UDP/TCP
As aplicações Ruby usam frequentemente o protocolo HTTP nas portas 80 (HTTP) e 443 (HTTPS). Se a sua aplicação precisar de portas adicionais ou protocolos diferentes (TCP ou UDP), configure as definições de "Ports Redirections" no seu serviço Ruby através do painel do Stackhero.
Terá de especificar a porta de entrada (aberta publicamente), a porta de destino (aberta dentro do seu serviço Ruby) e o protocolo (TCP ou UDP).
Armazenamento de ficheiros
Para armazenar ficheiros como fotos de utilizadores ou documentos, é altamente recomendado usar uma solução de object storage. O object storage permite partilhar ficheiros entre vários serviços e instâncias e desacopla a camada de armazenamento do seu código. Isto é considerado uma boa prática.
Recomendamos MinIO como uma solução fácil, rápida e poderosa compatível com o protocolo Amazon S3.
Se optar por armazenamento de ficheiros local, pode usar o armazenamento persistente fornecido com a sua instância Ruby. Este armazenamento local está disponível sob o diretório /persistent/storage/.
No entanto, o armazenamento de ficheiros local geralmente não é recomendado, pois pode não ser a melhor prática para escalabilidade e fiabilidade a longo prazo.
AVISO: Nunca armazene dados fora da pasta
/persistent/storage/!Armazenar dados em qualquer local que não seja a pasta de armazenamento persistente pode resultar em perda de dados quando a sua instância é reiniciada, atualizada ou quando envia novo código.
Apple/macOS: guardar a palavra-passe da sua chave privada SSH
Se estiver a usar macOS, pode achar inconveniente digitar a palavra-passe da sua chave privada SSH sempre que envia o seu código. Embora a segurança seja essencial, pode melhorar a conveniência ao armazenar a sua palavra-passe de forma segura no Keychain da Apple.
Pode ser tentador remover a palavra-passe da sua chave privada SSH, mas isso não é aconselhável.
Em vez disso, armazene a palavra-passe da sua chave no Keychain usando o seguinte comando para uma chave chamada id_ed25519:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
Após executar este comando, não deverá ser solicitado a inserir a palavra-passe da sua chave novamente. Se usar uma chave RSA, substitua id_ed25519 por id_rsa como mostrado abaixo:
ssh-add --apple-use-keychain ~/.ssh/id_rsa