# Deploy de Projetos com GitHub Actions > [name=Vinicius Roberto Martins] [time=Thu, Apr 9, 2020 11:05 AM] Este documento explica como é realizar o deploy em um serviço Amazon ECS utilizando Continuous Integration com Workflows do GitHub Actions. O conteúdo deste docimento poderá ser alterado a qualquer momento de acordo com a necessidade de melhorias e otimizações no processo. Estamos sempre abertos a novas ideias e soluções! --- [TOC] ## Get Started O ponto de partida é ter um repositório do projeto no GitHub, o qual será atualizado e cada modificação atribuida a *branch master* acionará o workflow. Então, vamos ao repositório! Inicialmente você terá uma estrutura de arquivos como esta: ![](https://i.imgur.com/zUirRr9.png) Então incluiremos alguns arquivos que serão fundamentais para o processo de deploy. Para isto, primeiro sincronize o repositório local com o remotoj, utilizando o comando abaixo em seu terminal. ```shell $ git pull https://github.com/user/repositorio.git ``` ### Arquivos #### dockerfile O dockerfile é um arquivo que contém instruções para gerar a imagem que será utilizada para criar o container. Na raiz do projeto crie um arquivo com o nome `dockerfile`, e insira o código abaixo. > Este dockerfile irá criar uma imagem com o PHP7.3 + Laravel. ```dockerfile= FROM ubuntu:18.04 RUN apt update RUN apt -y install software-properties-common RUN add-apt-repository ppa:ondrej/php RUN apt update WORKDIR /var/www COPY . . RUN apt install nginx -y RUN service nginx start RUN chown www-data:www-data /var/www/public -R RUN chmod 777 /var/www/database -R RUN chmod 777 /var/www/storage -R ENV DEBIAN_FRONTEND=noninteractive RUN apt -y install php7.3-fpm php7.3-mysql php-common \ php7.3-cli php7.3-common php7.3-json php7.3-opcache \ php7.3-readline php7.3-mbstring php7.3-xml php7.3-gd php7.3-curl RUN service php7.3-fpm start RUN apt -y install git && apt -y install curl && apt -y install zip RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer RUN rm /etc/nginx/sites-enabled/default ADD vhost.conf /etc/nginx/conf.d/default.conf RUN apt install python-setuptools -y \ && apt -y install python-pip \ && pip install supervisor COPY supervisord.conf /etc/ RUN chmod +x /etc/supervisord.conf COPY run.sh / RUN chmod +x /run.sh ENTRYPOINT ["sh", "/run.sh"] RUN composer install ``` #### vhost.conf Configuração do arquivo Virtual Host do Nginx para para determinar qual site será solicitado. ```conf= server { listen 80; root /var/www/public/; index index.php index.html index.htm index.nginx-debian.html; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { fastcgi_pass unix:/run/php/php7.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; include snippets/fastcgi-php.conf; } # A long browser cache lifetime can speed up repeat visits to your page location ~* \.(jpg|jpeg|gif|png|webp|svg|woff|woff2|ttf|css|js|ico|xml)$ { access_log off; log_not_found off; expires 360d; } # disable access to hidden files location ~ /\.ht { access_log off; log_not_found off; deny all; } } ``` #### supervisor.conf O supervisor.conf é o arquivo de configuração do "Supervisor", aplicação que controla a inicialização de processos em um sistema UNIX. Neste caso definimos o PHP7.3 e o Nginx para serem inicilializados junto com o SO. ```conf= [supervisord] nodaemon=false [program:php-fpm7.3] command=/usr/sbin/php-fpm7.3 [program:nginx] command=/usr/sbin/nginx ``` #### run.sh Este scrip é para inicializar o Supervisor. ```sh= #!/bin/bash /usr/local/bin/supervisord -c /etc/supervisord.conf /bin/bash ``` #### task-definition.json Agora incluiremos o arquivo de `task-definition.json` o qual contém informações que definarão o container e como ele será construído, de acordo com o projeto em questão. > Os valores que estão como "projeto" e somente eles, deverão ser anterados para o nome do projeto em questão. ```json= { "family": "ecos-projeto", "containerDefinitions": [ { "name": "ecos-projeto", "memory": 150, "image": "779863683866.dkr.ecr.us-west-2.amazonaws.com/php7.3-laravel", "portMappings": [ { "containerPort": 80, "hostPort": 0, "protocol": "tcp" } ], "interactive": true, "essential": true, "command": [], "dockerLabels": { "traefik.frontend.rule": "Host:projeto.com.br,www.projeto.com.br", "traefik.enable": "true", "traefik.backend": "projeto-backend", "traefik.port": "" } } ], "requiresCompatibilities": [ "EC2" ] } ``` #### .dockerignore Adicione o arquivo `.dockerignore`. Há arquivos e diretórios que não precisamos que sejam incluídos no contexto de build da imagem. ```dockerfile= dockerfile .git .github task-definition.json *.md !README*.md README-secret.md .cache ``` Após inserir todos os arquivos, seu diretório do projeto terá uma estrutura como esta. ![](https://i.imgur.com/OvMbcPU.png) ## Criando o Workflow > É necessário criar previamente o repositório para imagem do projeto no AWS ECR, pois será o qual, durante o processo do workflow, receberá a imagem "buildada" Agora, este é procedimento que faz a "mágica" acontecer, iremos configurar o workflow. No repositório do projeto no GitHub, clique na opção "Action", e procure por "Deploy to Amazon ECS". ![](https://i.imgur.com/xgebrVG.png) Em seguida clique em "Set up this workflow". Será gerado um arquivo `aws.yml`, o qual contêm os procedimentos que serão realizados para o processo de deploy. Substitua pelo conteúdo abaixo. ```yml on: push: branches: - master name: Deploy to Amazon ECS jobs: deploy: name: Deploy runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-west-2 - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Build, tag, and push image to Amazon ECR id: build-image env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: projeto IMAGE_TAG: ${{ github.sha }} run: | # Build a docker container and # push it to ECR so that it can # be deployed to ECS. docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" - name: Fill in the new image ID in the Amazon ECS task definition id: task-def uses: aws-actions/amazon-ecs-render-task-definition@v1 with: task-definition: task-definition.json container-name: ecos-projeto image: ${{ steps.build-image.outputs.image }} - name: Deploy Amazon ECS task definition uses: aws-actions/amazon-ecs-deploy-task-definition@v1 with: task-definition: ${{ steps.task-def.outputs.task-definition }} service: ecos-projeto cluster: ecos wait-for-service-stability: true ``` Será necessário a modificação de valores pelo nome do projeto, em: * ECR_REPOSITORY * container-name * service Como pode ser observado em aws-access-key-id e aws-secret-access-key são tratados com variáveis de ambiente, então é necessário solicitar ao Admin da conta do GitHub do Grupo, para que insira os valores e respectivas chaves como variáveis, na aba "Settings" do repositório. Após realizar todas as modificações clique em "Start commit" para confirmar a configuração do workflow. ## Push to GitHub Agora com todos os arquivos já incluídos no projeto, realize o commit e enviei para o repositório. ```shell $ git push -u origin branch ``` Com isso, caso o push tenha sido realizado na master já irá acionar o workflow da action, que realizará o deploy. Caso tenha feito o push em uma branch dev, por exemplo, é só gerar o pull request para mergear a branch dev na master, assim acionará automaticamente o workflow. Com isso concluímos nossa configuração de CI! > O procedimento de gerar o Certificado e inceri-lo no Load Balancer, e configuração do AWS Route53 devem ser realizados normalmente.