如何在私有服务器中使用gitlab-ci自动部署symfony app?

时间:2017-06-17 18:08:22

标签: php symfony gitlab-ci

我最近发现了gitlab-ci,以便为我的开发自动化很多东西。 所以我设法建立了一个"测试"阶段,这允许我运行我的单元测试。 完美,一切运作良好。 现在我被阻止了:当我验证MR时,我希望能够在我的专用服务器上自动部署。 在gitlab文档中,示例在AWS或makefile之上,但没有示例!

如何在私有专用服务器上执行此操作?

有关信息,它是一个PHP项目Symfony 3.在任何情况下,我都希望部署相当普遍:拉动主分支,执行编写器安装并恢复各种文件夹的权限。 我的应用程序在Docker下,所以我不仅要能够访​​问我的远程服务器,还要访问管理我的应用程序的容器。

2 个答案:

答案 0 :(得分:3)

我的部署步骤看起来像这样 - 也许它会给你一些想法:

build:app:
  image: docker:latest
  services:
    - docker:dind
  stage: build
  variables:
    SYMFONY_ENV: "prod"
  before_script:
    - docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
    - export IMAGE_TAG=$(echo -en $CI_COMMIT_REF_NAME | tr -c '[:alnum:]_.-' '-')
  script:
    - docker run --rm --name composerinstall -v "$PWD":/var/www/app -w /var/www/app composer:1.4 install --no-dev --ignore-platform-reqs --no-suggest --no-progress --no-scripts --prefer-dist
    - cp app/config/parameters.yml.dist app/config/parameters.yml
    - docker build --pull -t "$CI_REGISTRY_IMAGE:$IMAGE_TAG" .
    - docker push "$CI_REGISTRY_IMAGE:$IMAGE_TAG"
  only: [develop]
  dependencies:
    - test:php7.0
    - test:php7.1
  tags:
    - autoscale


deploy:staging:
  variables:
    DOCKER_TLS_VERIFY: "1"
    DOCKER_HOST: "tcp://123.123.123.123:2376"
    DOCKER_CERT_PATH: "/home/gitlab-runner/.docker/machine/machines/dockerhost1"
    DOCKER_MACHINE_NAME: "dockerhost1"
    SYMFONY_ENV: prod
    MYSQL_PROD_PASSWORD: "$MYSQL_PROD_PASSWORD"
    SECRET_TOKEN: "$SECRET_TOKEN"
    COMPOSE_PROJECT_NAME: "myproject_staging"
    COMPOSER_CACHE_DIR: "$(pwd -P)/.composer-cache"
    ASSET_VERSION: ${CI_COMMIT_SHA:0:8}
  before_script:
    - export BRANCH=$(echo -en $CI_COMMIT_REF_NAME | tr -c '[:alnum:]_.-' '-')
    - docker-compose -f docker-compose.prod.yml pull --parallel
  script:
    - docker-compose -f docker-compose.prod.yml up -d --force-recreate app
    - docker-compose -f docker-compose.prod.yml restart php
    - docker-compose -f docker-compose.prod.yml exec -T --user www-data php composer install --no-dev --no-suggest --no-progress --prefer-dist --optimize-autoloader
    - docker-compose -f docker-compose.prod.yml exec -T --user www-data php bin/console doctrine:migrations:migrate --no-interaction --allow-no-migration
  stage: deploy
  environment:
    name: staging
    url: http://staging.myproject.com
  only: [develop]
  dependencies:
    - build:app
  tags:
    - deploy

构建步骤的Dockerfile现在只是:

FROM busybox:latest

COPY . /app
RUN mkdir -p /app/vendor && \
    mkdir -p /app/mediastore  && \
    mkdir -p /app/web/imagecache  && \
    mkdir -p /.composer && \
    chown 33:33 -R /.composer && \
    chown 33:33 -R /app/var && \
    chown 33:33 -R /app/mediastore && \
    chown 33:33 -R /app/vendor && \
    chown 33:33 -R /app/web/imagecache && \
    chown 33:33 /app/app/config/parameters.yml

为了env变量的好处,我在我的parameters.yml:

中有这个
parameters:
  database_host:     '%env(DATABASE_HOST)%'
  database_port:     '%env(DATABASE_PORT)%'
  database_name:     '%env(DATABASE_NAME)%'
  database_user:     '%env(DATABASE_USERNAME)%'
  database_password: '%env(DATABASE_PASSWORD)%'    
  secret:            '%env(SECRET_TOKEN)%'    
  asset_version:     '%env(ASSET_VERSION)%'

  # Default fallback if env not set
  env(DATABASE_HOST):     127.0.0.1
  env(DATABASE_PORT):     ~
  env(DATABASE_NAME):     symfony
  env(DATABASE_USERNAME): root
  env(DATABASE_PASSWORD): ~    
  env(ASSET_VERSION): ~
  env(SECRET_TOKEN): ~

Docker-Compose:

version: '2'

volumes:
    database-volume:

services:
    app:
        image: "dockerhub.mydomain.com/mygroup/myproject:${BRANCH}"
        environment:
            BRANCH: develop
        tty: true
        restart: always

    mysql:
        image: mysql:5.7
        volumes:
            - database-volume:/var/lib/mysql
        environment:
            MYSQL_PASSWORD: "${MYSQL_PROD_PASSWORD}"
            MYSQL_USER: myuser
            MYSQL_DATABASE: mydatabase
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
        restart: always

    php:
        image: dockerhub.mydomain.com/docker/php/fpm:7.0
        working_dir: /var/www/app
        environment:
            DATABASE_HOST: "mysql"
            DATABASE_PORT: "3306"
            DATABASE_NAME: "mydatabase"
            DATABASE_USERNAME: "myuser"
            DATABASE_PASSWORD: "${MYSQL_PROD_PASSWORD}"
            SECRET_TOKEN: "${SECRET_TOKEN}"
            SYMFONY_ENV: prod
        volumes_from:
            - app
        restart: always

    apache:
        image: dockerhub.mydomain.com/mygroup/myproject:apache
        volumes_from:
            - app
        environment:
            VIRTUAL_HOST: "staging.myproject.com,staging.myproject.eu"
        restart: always

networks:
  default:
    external:
      name: nginx-proxy

dockerhub.mydomain.com是gitlab中内置的docker注册表的给定URL。

答案 1 :(得分:1)

谢谢!

你的样品真的很棒!我不使用docker hub来托管我的dockerfile:/ 但是我找到了用例的解决方案! 首先,我将我的私有SSH密钥添加到我的gitlab存储库中的变量中(我在这里找到了这个:https://docs.gitlab.com/ee/ci/ssh_keys/README.html)。之后,我可以连接到我的主机并执行远程命令! 所以我的gitlab-ci.yml看起来像:

deploy:app:
  stage: deploy
  environment:
    name: staging
    url: http://example.com
  only:
    - master
  script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - 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'
    - ssh -t user@example.com 'cd ~/docker &&
        git pull origin master &&
        docker exec docker_engine_1 bash -c "
          ./bin/console doctrine:schema:update -f &&
          composer install &&
          chmod -R 777 var/cache/prod/
        "
      '

但是你的例子给了我一些想法:例如使用教义迁移......