Programador ajudante e aprendiz da comunidade open source.

Amazon EC2 com Java, MySQL e Tomcat

Amazon EC2

Com a popularização do Cloud Computing foram surgindos mais e mais empresas disponibilizando bons serviços sobre o assunto. Aqui no Brasil já tínhamos a conhecida Locaweb, que alguns diziam ser um Cloud Manual, diga-se de passagem. Outras empresas lá fora como o Heroku ficaram bem conhecidas, assim como a Amazon que já vinha disponibilizando o melhor dos serviços, porém o preço e o ping as vezes deixavam a desejar. Mas para a felicidade de todos a Amazon passou a ter servidores aqui em São Paulo, além de ótimos preço.

Objetivo:

Criar uma instância na Amazon EC2 e instalar o Java, MySQL e o Tomcat, deixando tudo preparado para rodarmos uma aplicação.

Criando a VM:

Primeiramente crie sua conta no EC2 e em seguida acesso o console administrativo EC2 em português da região sul:


Lauch Instance

Escolha o Classic Wizard e dê continuidade:


Classic Wizard

Você poderá escolher instâncias já pré configuradas com alguns aplicativos ou uma do zero. Vá na guia Community AMIs e pesquise pelo termo "amazon/amzn-ami" e terá uma lista dos SOs disponibilizados pela própria Amazon. Iremos escolher a última versão x64 disponível:


Community AMIs

Na próxima tela só iremos escolher uma área entre a A ou B de São Paulo para rodarmos a VM. Preste atenção para não modificar o Instance Type, pois apenas o Micro é gratuito. A não ser que queira algo mais robusto e pague por isto.


Instance Details

Na próxima tela deixe como esta e avance:


Advanced Instance

Agora podemos adicionar tags para identificar melhor a nossa instância. Poderíarmos adicionar até 10, porém vamos apenas dar um nome. Neste caso mockr, o nome da nossa aplicação:


Tag Option

Iremos criar a chave de acesso à instância, ou seja, você só poderá se conectar ao servidor que esta criando se obtiver esta chave. Guarde-a com segurança! Você também tem opção de escolher uma já criada ou não usar nenhuma, bad! Dê um nome para a sua nova chave e clique no link para gerá-la e fazer o download:


Key Pair

Além da chave também devemos criar um grupo de segurança que determina quais portas serão liberadas. Iremos criar um novo grupo em vez de usar o default. Daremos um nome, descrição e escolheremos quais serviços iremos liberar, tendo a opção de se escolher um pré existente no combobox Create a new rule ou entrando com os valores manualmente. Precisaremos da porta do SSH, HTTP, MySQL e a do Tomcat:


Security Group

Aparecerá uma tela para revisão dos dados. Click em Lauch e a instância irá subir:


Review

Uma última tela confirmando que a instância foi configurada com sucesso irá aparecer. Click em close e visualize o seu console EC2 no qual você pode dar um nome para a instância, checar se esta sendo executada e clicando sobre a mesma, visualizar detalhes como o DNS público. Inicialmente o Status Checks estará como initializing, mas rapidamente estará checkado:


Console

O conjunto formado pela Key Pair mais o DNS público liberam o acesso ao servidor, porém digitar ou até mesmo decorar esse DNS é inviável. Para facilitar a nossa vida, podemos vincular um IP a este endereço, sendo que é permitido apenas um IP vinculado para ser free. Qualquer IP a mais não vinculado será cobrado.

Vá no menu Elastic IP click em Allocate New Address, confirmando a alocação do IP:


Elastic IP

Em seguida temos que associar este IP à nossa instância clicando no botão Associate Address e escolhendo a instância. Se você não deu um nome para a sua instância, apenas o nome ilegível irá aparecer no combobox:


Elastic IP Associate

Lembre-se que este IP não é dinâmico, sendo assim toda vez que a VM reiniciar este IP deverá ser novamente associado.

Conectando à VM:

Nessas altura do campeonato o servidor já esta rodando e esperando você se conectar via SSH. Precisaremos mudar a permissão da chave privada, que deixaremos no home, e então usá-la com o IP que criamos:

# ajusta a permissao da key.
chmod 400 ~/mockr.pem
# conecta ao servidor.
ssh -i ~/mockr.pem [email protected]

Iremos confirmar (yes) a conexão e veremos possívelmente que há atualizações disponíveis:

The authenticity of host 'ec2-177-71-181-76.sa-east-1.compute.amazonaws.com (177.71-181-76)' can't be established.
RSA key fingerprint is 23:a1:de:08:42:fd:a1:08:ae:c4:23:f1:ed:0e:8f:42.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'ec2-177-71-181-76.sa-east-1.compute.amazonaws.com,ec2-177-71-181-76' (RSA) to the list of known hosts.

  __|  __|_  )
  _|  (  /  Amazon Linux AMI
  ___|___|___|

See /usr/share/doc/system-release/ for latest release notes.
There are 7 total update(s) available
Run "sudo yum update" to apply all updates.

Atualizando a VM:

Para executar a atualização executaremos o seguinte comando confirmando (y) a ação:

# atualiza o sistema.
sudo yum update
Java 7

Bem, essa imagem que escolhemos vem com a OpenJDK 1.6.0_22 Runtime Environment, porém queremos a JDK full. Para verificar e escolher entre as versões já disponíveis execute o comando:

# mostra as versoes disponiveis do java.
sudo update-alternatives --config java

Subindo o pacote para o servidor:

Acesse a página da JDK7, aceite o termo, localize a versão desejada e faça o download* para a sua máquina. Iremos utilizar aqui a versão no formato .rpm. Ao final do download devemos subir tal arquivo para o servidor com o comando:

# copia o pacote rpm para o servidor no home do nosso usuario (ec2-user)
scp -i ~/mockr.pem jdk-7-linux-i586.rpm [email protected]:/home/ec2-user

Finalizando o upload vamos nos conectar ao servidor e separar um lugar para mantermos as apps:

# conecta ao servidor.
ssh -i ~/mockr.pem [email protected]
# cria uma pasta para manter as apps.
mkdir ~/Development
# move a jdk para tal pasta.
mv ~/jdk-7-linux-i586.rpm ~/Development

Instalando o pacote:

Agora vamos fazer a instalação com os seguintes comandos:

# recebe permissao root.
sudo su
# executa o pacote.
rpm -Uvh ~/Development/jdk-7-linux-i586.rpm
# java.
alternatives --install /usr/bin/java java /usr/java/latest/jre/bin/java 20000
# javaw.
alternatives --install /usr/bin/javaws javaws /usr/java/latest/jre/bin/javaws 20000
# javac.
alternatives --install /usr/bin/javac javac /usr/java/latest/bin/javac 20000
alternatives --install /usr/bin/jar jar /usr/java/latest/bin/jar 20000

Pronto, confirme a versão executando:

# exibe a versao corrente do java.
java -version
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)

Configurando o Classpath

Para outras aplicações utilizarem o Java, se faz necessário a configuração do classpath. Existem arquivos no sistemas para esta finalidade como, por exemplo o .bash_profile que deverá ser editado:

# abre o arquivo para edicao.
vim ~/.bash_profile

Ao abrir o arquivo, apague o conteúdo exemplo contido nele apertando várias vezes a letra 'd' do teclado. Em seguida aperte a letra 'i' para mudar para o modo de inserção e cole o seguinte código:

# exporta a variavel JAVA_HOME com o caminho da JDK.
export JAVA_HOME="/usr/java/latest"

export PATH=$PATH:$JAVA_HOME/bin

Para salvar o arquivo aperte 'esc', digite ':x' e aperte 'enter'.
Este arquivo é lido toda vez que o nosso usuário é iniciado, logo precisamos forçar a leitura das novas configurações:

# faz a leitura do arquivo.
source ~/.bash_profile
Acertando a Key Pair

Caso você já tenha avacalhado a sua chave de tanto trocá-la, receberá algo como:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@  WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!  @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
85:8f:c7:e0:7f:84:f3:62:3d:82:33:7c:a9:92:3e:c7.
Please contact your system administrator.
Add correct host key in /Users/wbotelhos/.ssh/known_hosts to get rid of this message.
Offending key in /Users/wbotelhos/.ssh/known_hosts:8
RSA host key for 177.71.181.76 has changed and you have requested strict checking.
Host key verification failed.
lost connection

Neste caso veja que é indicado o problema na linha 8 do seu ~/.ssh/known_hosts. Abra este arquivo e remova as referências para os IPs da Amazon que não existam mais, deixando apenas o seu atual (ex.: 177.71.181.76). Normalmente terá duas linhas uma iniciando em: "ec2-177-71-xxx-yy.sa-east-1..." e outra como: "177.71.xxx.yy ssh-rsa ...".

E se eu quiser instalar o Java 6?

Para instalar a JDK6 fazemos os mesmo passos, porém com outro pacote de instalação. Se você puxar uma versão "jdk-7-linux-i586-rpm*.bin*", por exemplo, não precisará executar o comando rpm, mas sim o arquivo diretamente: ./jdk-7-linux-i586-rpm.bin.

* Formas de download dos arquivos

De alguma forma a Amazon esta falhando em fazer download do pacote Java diretamente para o servidor, por isso fizemos o download para a nossa máquina e depois o subimos. Porém a forma mais fácil de fazê-lo é utilizando o curl:

curl http://www.java.net/download/jdk6/6u32/promoted/b03/binaries/jdk-6u32-ea-bin-b03-linux-amd64-29_feb_2012-rpm.bin > jdk6-rpm.bin
MySQL

O MySQL é relativamente simples, basta executar os seguintes comandos:

# recebe permissao de root.
sudo su
# instala o pacote do mysql.
yum install mysql mysql-server mysql-libs
# inicia o servico.
service mysqld start
# configura a inicializacao.
chkconfig --levels 235 mysqld on
# inicia as configuracoes.
mysql_secure_installation

Durante o último comando serão pedidas algumas configurações:
+ Senha, apenas aperte enter;
+ Confirmação da ação (Y);
+ Uma nova senha e sua confirmação;
+ Remoção do usuário anônimo (Y);
+ Desabilitação de acesso remoto como root (Y);
+ Remoção da base de test (Y); e
+ Reload dos privilégios (Y).

Trocando a senha de um usuário:
Se você precisar trocar a senha do seu usuário, que digamos ser atualmente 'segredo', faça:

mysqladmin -u root -p'segredo' password 'novo_segredo';

Criando o schema e um novo usuário:

Precisamos de uma base de dados e por segurança um usuário com permissão somente sobre ela:

# acessa o console do mysql, a senha sera pedida.
mysql -u root -p
# cria um novo schema.
create schema mockr;
# cria um novo usuario (mockr) com permissao no schema (mockr) via web.
grant all on mockr.* to 'mockr'@'%' identified by 'segredo';
# da permissao para o usuario acessar via localhost.
grant all on mockr.* to 'mockr'@'localhost' identified by 'segredo';

Para verificar os schemas existentes, execute o comando:

show databases;
Tomcat 7

Primeiramente pegue o link do pacote que você deseja no site do Tomcat e então execute:

# acessa a pasta das nossas apps.
cd ~/Development
# faz o download do tomcat.
curl http://apache.mirror.pop-sc.rnp.br/apache/tomcat/tomcat-7/v7.0.26/bin/apache-tomcat-7.0.26.tar.gz > apache-tomcat-7.0.26.tar.gz
# extrai o pacote do tomcat.
tar zxvf apache-tomcat-7.0.26.tar.gz

Configurando o classpath

Agora vamos adicioná-lo no classpath editando o ~/.bash_profile:

export JAVA_HOME="/usr/java/latest"
export TOMCAT_HOME=/home/ec2-user/Development/apache-tomcat-7.0.26

export PATH=$PATH:$JAVA_HOME/bin:$TOMCAT_HOME/bin

Execute o source ~/.bash_profile para reconhecimento das alterações e inicie o Tomcat. A seguir os comandos para manipulá-lo:

# inicia o tomcat.
$TOMCAT_HOME/bin/startup.sh
# para o tomcat.
$TOMCAT_HOME/bin/shutdown.sh

Removendo arquivos desnecessários

# remove a pasta de documentos.
rm -rf $TOMCAT_HOME/webapps/docs
# remove a pasta com codigos de exemplo.
rm -rf $TOMCAT_HOME/webapps/examples

Agora basta acessar o seu IP na porta 8080 para ver o servidor rodando:

http://177.71.181.76:8080

É, eu também dei um sorrisinho besta na primeira vez que subi meu server na Amazon. (;

Configurando a inicialização do Tomcat

Vamos criar um arquivo de inicialização/manipulação do Tomcat para que o mesmo suba junto com a nossa VM. Execute o seguinte comando:

# prepara um novo arquivo.
sudoedit /etc/init.d/tomcat

E cole o código a seguir no mesmo:

#!/bin/sh
# Tomcat init script for Linux.
#
# chkconfig: 345 80 20
# description: Apache Tomcat

RETVAL="0"

case $1 in
start)
  echo "Starting Tomcat:"
  /home/ec2-user/Development/apache-tomcat-7.0.26/bin/startup.sh
  ;;
stop)
  echo "Stopping Tomcat:"
  /home/ec2-user/Development/apache-tomcat-7.0.26/bin/shutdown.sh
  ;;
restart)
  $0 stop
  $0 start
  ;;
*)
  echo "Usage: $0 {start|stop|restart}"
  RETVAL="1"
esac

exit $RETVAL

Modifique as permissões deste script e o insira nos serviços:

# tira a permissao de escrita do group e do other.
sudo chmod go-w /etc/init.d/tomcat
# adiciona o tomcat nos servicos de auto boot.
sudo chkconfig --add tomcat

Para verificar se o serviço "tomcat" foi incluido execute:

# mostra a lista dos servicos.
chkconfig --list

Agora você pode manipular o Tomcat como um serviço:

# para o servidor.
service tomcat stop
# inicia o servidor.
service tomcat start
# reinicia o servidor.
service tomcat restart

Configurando a porta do Tomcat

Veja que o servidor esta na porta 8080, mas o legal seria tê-lo na porta 80, evitando indicar tal. Para isso iremos executar alguns comandos do iptables que mantém suas configurações em /etc/sysconfig/iptables:

# cria a roda da porta 80 para 8080.
sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# salva a rota.
sudo service iptables save
# reinicia a tabela de rotas.
sudo service iptables restart

Por fim edite o arquivo $TOMCAT_HOME/conf/server.xml e adicione o atributo proxyPort="80" no seguinte ponto:

<Connector port="8080" protocol="HTTP/1.1"
  connectionTimeout="20000"
  redirectPort="8443"
  proxyPort="80" # adicao.
/>

Agora você pode acessar diretamente pelo IP (177.71.181.76), porém o que fazemos é configurar um domínio para o DNS público. Agora suba a sua aplicação e se divirta!

Todo exemplo foi feito durante a configuração do Mockr.me que é um sistema focado em estudos para certificação e que estará disponível para acesso em breve.

  1. Alexandre 30 Out 2015 13:50

    Não sei o que estou fazendo de errado

    mas ja tentei mais de 10 vezes seguindo passo a passo e não funciona

    deletando a instancia refazendo tudo do zero

    quando digito o IP pra acessar o tomcat aparece isso no navegador

    Esta página da web não está disponível
    ERR_CONNECTION_TIMED_OUT

  2. Renato Almeida 14 Jan 2014 15:49

    Mandou bem. Belo post, parabéns!

  3. Denis Santos 18 Mai 2013 04:50

    Rapaz, parabéns! Ótimo POST, me ajudou bastante, está perfeito cada passo.

    Abraço,
    Denis

  4. Donizete 22 Abr 2013 11:08

    Parabéns pelo post!!! Você teria algum material mostrando como publicar no EC2 um projeto com VRaptor, JPA, MySQL e JBoss 7?

  5. Márcio 14 Fev 2013 22:56

    Muito bom o tópico, mas gostaria de ver como seria usando Apache httpd.

    Seria melhor do que:
    sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

    Tem como você ajudar?

    Valeu.

  6. geraldo 12 Fev 2013 19:32

    boa tarde Washington
    nao sei o que estou fazendo de errado mas nao consigo passar dessa parte:
    onde tem que mpver o arquivo, vc sabe o porque?

  7. Guilherme Gotardo 10 Jan 2013 00:33

    Muito legal o post, parabens.

  8. Orlando 4 Set 2012 08:50

    Sensacional o post!

    Ajudou d+!

    Vlw Botelho

  9. Francisco Souza 2 Ago 2012 15:40

    Opa, mandou bem. Bem legal o post, parabéns!

    Legal ver que está usando enterprise linux também :P

    1. Washington Botelho autor 4 Ago 2012 00:50

      Oi Francisco Souza,

      Só para rodar Ruby que fica um pouco ruim, por falta de repositórios atualizados. No mais é de boa.

      1. Almir 'm3nd3s' 7 Ago 2012 19:14

        Você usa RVM no server?

        1. Washington Botelho autor 13 Ago 2012 10:40

          Oi Almir 'm3nd3s',

          Uso não.
          Lá faço só um versionamento via links simbólicos igual ao Mac.

  10. Victor 2 Mai 2012 13:31

    Ótimo post ... ta de parabéns ! Outra coisa ... teu servidor wbotelhos.com está fora do ar ! Não sei se percebeu ... um Abraço e que outros post legais venham !

    1. Washington Botelho autor 5 Mai 2012 12:10

      Muito obrigado Victor,

      Estou migrando o blog .com para o mesmo server do .com.br.
      A DreamHost esta muito ruim.

      Valeu. (:

  11. Edivan 8 Abr 2012 19:24

    Ai wbotelhos cara esse post esta muito bom! Parabéns! A idéia do Mockr.me é muito boa parabéns pela iniciativa. Você poderia fazer outro post ensinando como associar um dominio ao
    ip do amazon ws.

    1. Washington Botelho autor 9 Abr 2012 11:43

      Oi Edivan,

      Na verdade eu até pensei em adicionar isso, porém isso depende de onde você comprou o dominínio.
      No GoDaddy, por exemplo, na seção Zone File Editor e no Host você coloca o IP da Amazon.

      Até semana que vem o Mockr estará no ar. (;

  12. Marco Singer 5 Abr 2012 17:28

    Fala Botelho!

    Na parte de AMI's, se quiser brincar com a instância mais rápido, da pra pegar uma AMI da comunidade, com Tomcat/mySQL instalados. Como é free e da pra matar/subir em minutos, até vale. ;)

    Muito detalhado o post mesmo. Parabéns brother!

    1. Washington Botelho autor 6 Abr 2012 08:59

      Fala Marco,

      Pois é, rola sim.
      Mas a idéia era exatamente mostra como fazer tudo, assim você decidi as versões e tem certeza do que terá.
      Após fazer isso é só gerar um Snapshot, que acabei esquecendo de colocar. (:

      Valeu, abraço.

  13. Daniel Faria 4 Abr 2012 15:43

    Post mais detalhado que já vi sobre o assunto.

    Vou até fazer minha conta lá, aproveitando a promoção do primeiro ano de graça.

    Parabéns ;D.

    1. Washington Botelho autor 4 Abr 2012 16:02

      Fala Daniel,

      É o que esta tendo de melhor, não irá se arrepender. (;

  14. Paulo Silveira 4 Abr 2012 13:18

    Wow! Completo e detalhado Botelho! Parabens

    tem uma hora que voce fala de instalar o Java 6, mas no coméco é o Java 7 que voce está instalando.

    Agora num 2o post só falta colocar as instrucoes via receitas do chef ou via puppet!

    Parabéns novamente

    1. Washington Botelho autor 4 Abr 2012 15:17

      Fala Paulo,

      Na verdade era só um quote para uma alternativa, então passei de título para sub título como pergunta.
      Hehehe... valeu Paulo. (:

Em resposta:
(cancelar)
Formate seu código utilizando Markdown.