Projekt

Obecné

Profil

Deployment » Historie » Revize 5

Revize 4 (Tomáš Ballák, 2020-04-01 21:15) → Revize 5/19 (Jakub Vašta, 2020-04-03 14:23)

h1. Deployment 

 Pro deployment se bude používat Docker (s vuyžitím Docker-Compose) jeliko6 se bude jednat o webovou aplikaci. 

 h2. Zákazník 

 # Bude mít přístup k testovacímu serveru, který budeme mít (pravděpodobně na ZČU), kde bude naše poslední funkční verze aplikace. 
 # Bude si moci v případě potřeby stáhnout obraz z Docker Hub. 

 h2. Vývojář [Not prepared for deployment to production!] 

 Struktura velmi ovlivněna návodem: https://www.cloudreach.com/en/resources/blog/containerize-this-how-to-use-php-apache-mysql-within-docker-containers/ 

 <pre><code class="text"> 
 /application-root/ 
 ├── build 
 │     ├── nginx 
 │     │       ├── conf.d 
 │     │       │      └── default.conf 
 │     │       ├── sites 
 │     │       │      └── default.conf 
 │     │       ├── Dockerfile 
 │     │       └── nginx.conf 
 │     └── php-fpm [Bad name in repo] 
 │           └── Dockerfile 
 ├── docker-compose.yml 
 ├── build.bat 
 ├── build.sh 
 ├── composer-install.bat 
 └── composer-install.sh 

 </code></pre> 

 Jak je možné vidět, tak každá "služba" je v samostatném kontaineru a navíc je Nginx využíván jako proxy (https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html) , přičemž je využito _php fpm_ 

 h3. Nginx 

 h4. Dockerfile  

 <pre><code class="text"> 
 FROM nginx:alpine 
 COPY nginx.conf /etc/nginx 
 COPY conf.d /etc/nginx/conf.d 
 ADD ./sites /etc/nginx/sites-available 
 WORKDIR /var/www/ 
 CMD ["nginx"] 

 </code></pre> 

 h4. nginx.conf  
 <pre><code class="text"> 
 user    nginx; 
 worker_processes    4; 
 daemon off; 

 error_log    /var/log/nginx/error.log warn; 
 pid          /var/run/nginx.pid; 

 events { 
     worker_connections    1024; 
 } 


 http { 
     include         /etc/nginx/mime.types; 
     default_type    application/octet-stream; 
     access_log    /var/log/nginx/access.log; 
     sendfile          on; 
     keepalive_timeout    65; 

     include /etc/nginx/conf.d/*.conf; 
     include /etc/nginx/sites-available/*.conf; 
 } 


 </code></pre> 

 h4. sites/default.conf 
 <pre><code class="text"> 
 server { 
     listen 80 default_server; 
     listen [::]:80 default_server ipv6only=on; 

     server_name localhost; 
     root /var/www/symfony/public; 
     index index.php index.html index.htm; 

     location / { 
          try_files $uri $uri/ /index.php$is_args$args; 
     } 

     location ~ \.php$ { 
         try_files $uri /index.php =404; 
         fastcgi_pass php-upstream; 
         fastcgi_index index.php; 
         fastcgi_buffers 16 16k; 
         fastcgi_buffer_size 32k; 
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
         fastcgi_read_timeout 600; 
         include fastcgi_params; 
     } 

     location ~ /\.ht { 
         deny all; 
     } 
 } 
 </code></pre> 

 h4. conf.d/default.conf 
 <pre><code class="text"> 
 upstream php-upstream { 
     server php-fpm:9000; 
 } 

 </code></pre> 


 h3. PHP-FPM 

 h4. Dockerfile 
 <pre><code class="text"> 
 FROM php:7.4-fpm-alpine 
 RUN apk update; \ 
     apk upgrade; \ 
     apk add autoconf openssl-dev g++ make && \ 
     pecl install mongodb && \ 
     docker-php-ext-enable mongodb; \ 
     apk del --purge autoconf openssl-dev g++ make; 

 </code></pre> 


 h3. Docker-compose 

 <pre><code class="yaml"> 
 version: "3.2" 
 services: 
        php-fpm: 
                build: './build/php-fpm' 
                depends_on:  
                        - database 
                networks: 
                    - backend 
                ports:  
                        - "9000:9000" 
                volumes: 
                        - ./website/:/var/www/symfony 
                container_name: "heatmap_php_fpm" 
        nginx: 
                build: './build/nginx' 
                depends_on: 
                        - php-fpm 
                        - database 
                networks: 
                        - frontend 
                        - backend 
                ports: 
                        - "80:80" 
                volumes: 
                        - ./logs:/var/nginx/log 
                        - ./website/:/var/www/symfony 
                container_name: "heatmap_nginx" 
        database: 
                image: 'mongo' 
                container_name: "heatmap_mongodb" 
                restart: always 
                networks: 
                        - backend 
                ports: 
                        - '27017-27019:27017-27019' 
                environment: 
                        MONGO_INITDB_DATABASE: open-data-db 
                        MONGO_INITDB_ROOT_USERNAME: root 
                        MONGO_INITDB_ROOT_PASSWORD: root 
 networks: 
        frontend: 
        backend: 

 </code></pre> 

 h3. Database [Currently missing] 

 Zde je možné mít dump databáze, kterou chcete využívat při startu aplikace (možné použít například jako testovací databázi) 

 h2. Spuštění 

 Pokud máte spuštěný Docker, tak stačí pouze ze složky se souborem _docker-composer.yml_ zavolat příkaz _docker-compose up_ z příkazové řádky (power shellu, shellu ...) 

 h2. GitLab CI/CD [In progress] 

 Zajímavá "výuková" videa: 
 # https://www.youtube.com/watch?v=gr76MNXZJfQ - nezabíhá se příliš do detailů, ale ukazuje čeho se dá dosáhnout 
 # https://www.youtube.com/watch?v=34u4wbeEYEo&list=PLaFCDlD-mVOlnL0f9rl3jyOHNdHU--vlJ&index=1 - Indian guy saves the day, víc prakticky zaměřené, celá série 

 Shared runner na GitLabu nemá nainstalovaný docker (nebo sám běží v dockeru), proto se na něm nedá (alespoň ne snadno tzn. nepovedlo se mi to) rozběhnout docker resp. docker-compose pro testování zda jde projekt přeložit. 

 Gitlab-runner nainstalován na heatmap.zcu.cz 
 * https://gitlab.com/gitlab-org/gitlab-runner/issues/4449 
 * potřeba změnit uživateli gitlab-runner práva na root pokud chceme něco instalovat 

 *Zatím běží gitlab-runner na produkčním serveru heatmap.zcu.cz což není úplně dobré řešení*, bylo by vhodné mít oddělený server pro gitlab-runner. 

 Poznámky:   
 # mít na svém serveru dvě věrze, jednu dostupnou všem a jednu jen pro vývoj 
 # prozkoumat integrační zjistit jak vlastně fungují testy v symfony a vytvořit nějaký jednoduchý na otestování 
 # zjistit co všechno bude potřeba v before_script 
 # nasadit nějaké nástroje na metriku kódu 

 <pre><code class="yaml"> 

 # image: php:7.2-cli 

 variables: 
 #       
     IMAGE_NAME: zcu-campus-life-app:$CI_COMMIT_REF_NAME gitlab.kiv.zcu.cz:5000/aswi/aswi-2020/aswi2020sebela:$CI_COMMIT_REF_NAME 

 stages: 
     - test 
     - build 
     - deploy 

 # Now the runner is on the same server as production environment - which is not good - so ssh is not needed     
 # before_script: 
 #       
     - apt-get some update -qq 
 stuff 
     #       - apt-get install -qq git 
 #       # Setup SSH deploy keys 
 #       
     - - 'which ssh-agent || ( apt-get install -qq openssh-client )' 
 #       
     - eval $(ssh-agent -s) 
 #       
     - ssh-add <(echo "$SSH_PRIVATE_KEY") 
 #       
     - mkdir -p ~/.ssh 
 #       
     - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' 
    
 unit_tests: 

 test: 
     image: php:7.2-alpine 
     stage: test 
     script: tags: 
         - apk add composer test-stage 
     script: 
         - cd website 
         - composer require --dev symfony/phpunit-bridge 
         - php bin/phpunit 

 ./phpunit symfony 
    

 build: 
     stage: build 
     tags: 
         - build build-stage 
     script: 
         # Test whether container can be build or not - docker login -u $USER p $PASSWORD gitlab.kiv.zcu.cz:5000 
         - docker-compose build $IMAGE_NAME . 
         # We could also - docker-compose push docker image to some registry or docker hub 
        
 deploy_prod: $IMAGE_NAME 

 deploy_staging: 
     stage: deploy 
     tags: 
         - docker-stage 
 # we could run two application first which is for developers and there will be no access for anyone else and second public 
     script: 
         - ssh root@example.com "docker login -u $USER p $PASSWORD gitlab.kiv.zcu.cz:5000 && docker-compose pull $IMAGE_NAME && docker-compose up" 
     only: 
         - master 

         #    
 deploy_prod: 
     stage: deploy 
     variables: tags: 
         GIT_STRATEGY: none - docker-prod 
     environment: environmnet: 
         name: heatmap deploy 
         url: https://heatmap.zcu.cz http://whatever.zcu.cz 
     script: 
         # - ssh root@example.com "cd ~ "docker login -u $USER p $PASSWORD gitlab.kiv.zcu.cz:5000 && rm -rf aswi2020sebela docker-compose pull $IMAGE_NAME && git clone https://gitlab.kiv.zcu.cz/aswi/aswi-2020/aswi2020sebela.git && cd aswi2020sebela && ./build.sh && exit" 
         - cd ~ 
         - rm -rf aswi2020sebela 
         - git clone https://gitlab.kiv.zcu.cz/aswi/aswi-2020/aswi2020sebela.git 
         - cd aswi2020sebela 
         - ./build.sh docker-compose up" 
     only: 
         - master 
     when: manual 

 </code></pre>