diff --git a/.travis.yml b/.travis.yml index 8ae3bb18..6b8a96a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,10 +33,12 @@ install: script: # Build the base image - cd ${TRAVIS_BUILD_DIR}/${VERSION} - - travis_retry make && make test # Retry builds, as pecl.php.net tends to time out often + - travis_retry make # Retry builds, as pecl.php.net tends to time out often + - make test # Build the Cloud9 flavor - cd ${TRAVIS_BUILD_DIR}/cloud9 - - travis_retry make && make test + - travis_retry make + - make test after_success: - docker image ls diff --git a/5.6/Dockerfile b/5.6/Dockerfile index 9a1957d9..2b43d084 100644 --- a/5.6/Dockerfile +++ b/5.6/Dockerfile @@ -32,12 +32,10 @@ RUN set -xe; \ # Cleanup apt-get clean; rm -rf /var/lib/apt/lists/* -# Set timezone and locale +# Set en_US.UTF-8 as the default locale RUN set -xe; \ - dpkg-reconfigure locales; \ - locale-gen C.UTF-8; \ - /usr/sbin/update-locale LANG=C.UTF-8 -ENV LC_ALL C.UTF-8 + localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 +ENV LC_ALL en_US.utf8 # Enable additional repos RUN set -xe; \ @@ -195,6 +193,8 @@ RUN set -xe; \ ;\ pecl update-channels; \ pecl install >/dev/null /dev/null -# Home directory for bundle installs -ENV BUNDLE_PATH .bundler + gem install bundler >/dev/null; \ + # Have bundler install gems locally (./.bundle) by default + echo "\n""export BUNDLE_PATH=.bundle" >> /home/docker/.profile # All further RUN commands will run as the "docker" user USER docker -ARG HOME=/home/docker # PHP tools (installed as user) -ENV PATH=$PATH:$HOME/.composer/vendor/bin \ - MG_CODEGEN_VERSION=1.10 \ +ENV MG_CODEGEN_VERSION=1.10 \ TERMINUS_VERSION=1.8.1 RUN set -xe; \ \ + # Set drush8 as a global fallback for Drush Launcher + echo "\n""export DRUSH_LAUNCHER_FALLBACK=/usr/local/bin/drush8" >> $HOME/.profile; \ # Composer based dependencies # Add composer bin directory to PATH - echo "\n"'PATH="$PATH:$HOME/.composer/vendor/bin"' >> $HOME/.profile; \ + echo "\n"'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> $HOME/.profile; \ + # Reload updated PATH from profile to make composer/drush/etc. visible below + . $HOME/.profile; \ # Install cgr to use it in-place of `composer global require` composer global require consolidation/cgr >/dev/null; \ # Composer parallel install plugin @@ -311,9 +313,8 @@ USER root # Copy mhsendmail binary from stage 1 COPY --from=mhbuild /go/bin/mhsendmail /usr/local/bin/mhsendmail # Copy configs and scripts -COPY --chown=docker:docker config/.acquia $HOME/.acquia -COPY --chown=docker:docker config/.drush $HOME/.drush -COPY --chown=docker:docker config/.ssh $HOME/.ssh +COPY --chown=docker:docker config/.drush /home/docker/.drush +COPY --chown=docker:docker config/.ssh /home/docker/.ssh COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY startup.sh /opt/startup.sh COPY healthcheck.sh /opt/healthcheck.sh diff --git a/5.6/config/.acquia/cloudapi.conf.tmpl b/5.6/config/.acquia/cloudapi.conf.tmpl deleted file mode 100644 index 1cfd222f..00000000 --- a/5.6/config/.acquia/cloudapi.conf.tmpl +++ /dev/null @@ -1 +0,0 @@ -{"email":"{{ getenv "SECRET_ACAPI_EMAIL" }}","key":"{{ getenv "SECRET_ACAPI_KEY" }}"} diff --git a/5.6/config/.ssh/id_rsa.tmpl b/5.6/config/.ssh/id_rsa.tmpl index cc8fa3bb..8c6c22f1 100644 --- a/5.6/config/.ssh/id_rsa.tmpl +++ b/5.6/config/.ssh/id_rsa.tmpl @@ -1 +1 @@ -{{ getenv "SECRET_SSH_PRIVATE_KEY" }} +{{ getenv "SECRET_SSH_PRIVATE_KEY" | base64.Decode }} \ No newline at end of file diff --git a/5.6/config/php/zz-php-fpm.conf b/5.6/config/php/zz-php-fpm.conf index 0624e4de..d4fb5e22 100644 --- a/5.6/config/php/zz-php-fpm.conf +++ b/5.6/config/php/zz-php-fpm.conf @@ -16,3 +16,4 @@ php_value[memory_limit] = 256M php_value[max_execution_time] = 300 php_value[upload_max_filesize] = 500M php_value[post_max_size] = 500M +php_value[max_input_vars] = 2000 diff --git a/5.6/php-modules.txt b/5.6/php-modules.txt index 440b917a..3db6882e 100644 --- a/5.6/php-modules.txt +++ b/5.6/php-modules.txt @@ -1,4 +1,6 @@ [PHP Modules] +apc +apcu bcmath blackfire bz2 diff --git a/5.6/startup.sh b/5.6/startup.sh index 8553fe89..f3308350 100755 --- a/5.6/startup.sh +++ b/5.6/startup.sh @@ -25,7 +25,14 @@ uid_gid_reset () xdebug_enable () { echo-debug "Enabling xdebug..." - sudo ln -s /opt/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/ + ln -s /opt/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/ +} + +add_ssh_key () +{ + echo-debug "Adding a private SSH key from SECRET_SSH_PRIVATE_KEY..." + render_tmpl "$HOME_DIR/.ssh/id_rsa" + chmod 0600 "$HOME_DIR/.ssh/id_rsa" } # Helper function to render configs from go templates using gomplate @@ -62,15 +69,30 @@ convert_secrets () done } -# Pantheon authentication +# Acquia Cloud API login +acquia_login () +{ + echo-debug "Authenticating with Acquia..." + # This has to be done using the docker user via su to load the user environment + # Note: Using 'su -l' to initiate a login session and have .profile sourced for the docker user + local command="drush ac-api-login --email='${ACAPI_EMAIL}' --key='${ACAPI_KEY}' --endpoint='https://cloudapi.acquia.com/v1' && drush ac-site-list" + local output=$(su -l docker -c "${command}" 2>&1) + if [[ $? != 0 ]]; then + echo-debug "ERROR: Acquia authentication failed." + echo + echo "$output" + echo + fi +} + +# Pantheon (terminus) login terminus_login () { echo-debug "Authenticating with Pantheon..." # This has to be done using the docker user via su to load the user environment - # Note: 'su -' = 'su -l' = 'su --login' - local output - output=$(sudo su - docker -c "terminus auth:login --machine-token='${TERMINUS_TOKEN}'" 2>&1) - #>/dev/null 2>&1 + # Note: Using 'su -l' to initiate a login session and have .profile sourced for the docker user + local command="terminus auth:login --machine-token='${TERMINUS_TOKEN}'" + local output=$(su -l docker -c "${command}" 2>&1) if [[ $? != 0 ]]; then echo-debug "ERROR: Pantheon authentication failed." echo @@ -79,12 +101,17 @@ terminus_login () fi } -# Process templates -# Private SSH key -render_tmpl "$HOME_DIR/.ssh/id_rsa" -chmod 0600 "$HOME_DIR/.ssh/id_rsa" -# Acquia Cloud API config -render_tmpl "$HOME_DIR/.acquia/cloudapi.conf" +# Git settings +git_settings () +{ + # These must be run as the docker user + echo-debug "Configuring git..." + gosu docker git config --global user.email "${GIT_USER_EMAIL}" + gosu docker git config --global user.name "${GIT_USER_NAME}" +} + +# Inject a private SSH key if provided +[[ "$SECRET_SSH_PRIVATE_KEY" != "" ]] && add_ssh_key # Convert all Environment Variables Prefixed with SECRET_ convert_secrets @@ -103,9 +130,11 @@ chown "${HOST_UID:-1000}:${HOST_GID:-1000}" -R "$HOME_DIR" # We apply a fix/workaround for this at startup (non-recursive). chown "${HOST_UID:-1000}:${HOST_GID:-1000}" /var/www -# Automatically authenticate with Pantheon in Terminus token is present -# Note: this has to happen after th home directory permissions are reset, -# otherwise the docker user may not have write access to /home/.terminus, where the auth session data is stored. +# These have to happen after the home directory permissions are reset, +# otherwise the docker user may not have write access to /home/docker, where the auth session data is stored. +# Acquia Cloud API config +[[ "$ACAPI_EMAIL" != "" ]] && [[ "$ACAPI_KEY" != "" ]] && acquia_login +# Automatically authenticate with Pantheon if Terminus token is present [[ "$TERMINUS_TOKEN" != "" ]] && terminus_login # If crontab file is found within project add contents to user crontab file. @@ -114,6 +143,9 @@ if [[ -f ${PROJECT_ROOT}/.docksal/services/cli/crontab ]]; then cat ${PROJECT_ROOT}/.docksal/services/cli/crontab | crontab -u docker - fi +# Apply git settings +[[ "$GIT_USER_EMAIL" != "" ]] && [[ "$GIT_USER_NAME" != "" ]] && git_settings + # Initialization steps completed. Create a pid file to mark the container as healthy echo-debug "Preliminary initialization completed." touch /var/run/cli diff --git a/7.0/Dockerfile b/7.0/Dockerfile index b1680888..154cba91 100644 --- a/7.0/Dockerfile +++ b/7.0/Dockerfile @@ -32,12 +32,10 @@ RUN set -xe; \ # Cleanup apt-get clean; rm -rf /var/lib/apt/lists/* -# Set timezone and locale +# Set en_US.UTF-8 as the default locale RUN set -xe; \ - dpkg-reconfigure locales; \ - locale-gen C.UTF-8; \ - /usr/sbin/update-locale LANG=C.UTF-8 -ENV LC_ALL C.UTF-8 + localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 +ENV LC_ALL en_US.utf8 # Enable additional repos RUN set -xe; \ @@ -201,6 +199,7 @@ RUN set -xe; \ ;\ pecl update-channels; \ pecl install >/dev/null /dev/null -# Home directory for bundle installs -ENV BUNDLE_PATH .bundler + gem install bundler >/dev/null; \ + # Have bundler install gems locally (./.bundle) by default + echo "\n""export BUNDLE_PATH=.bundle" >> /home/docker/.profile # All further RUN commands will run as the "docker" user USER docker -ARG HOME=/home/docker # PHP tools (installed as user) -ENV PATH=$PATH:$HOME/.composer/vendor/bin \ - MG_CODEGEN_VERSION=1.10 \ +ENV MG_CODEGEN_VERSION=1.10 \ TERMINUS_VERSION=1.8.1 RUN set -xe; \ \ + # Set drush8 as a global fallback for Drush Launcher + echo "\n""export DRUSH_LAUNCHER_FALLBACK=/usr/local/bin/drush8" >> $HOME/.profile; \ # Composer based dependencies # Add composer bin directory to PATH - echo "\n"'PATH="$PATH:$HOME/.composer/vendor/bin"' >> $HOME/.profile; \ + echo "\n"'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> $HOME/.profile; \ + # Reload updated PATH from profile to make composer/drush/etc. visible below + . $HOME/.profile; \ # Install cgr to use it in-place of `composer global require` composer global require consolidation/cgr >/dev/null; \ # Composer parallel install plugin @@ -319,9 +320,8 @@ USER root # Copy mhsendmail binary from stage 1 COPY --from=mhbuild /go/bin/mhsendmail /usr/local/bin/mhsendmail # Copy configs and scripts -COPY --chown=docker:docker config/.acquia $HOME/.acquia -COPY --chown=docker:docker config/.drush $HOME/.drush -COPY --chown=docker:docker config/.ssh $HOME/.ssh +COPY --chown=docker:docker config/.drush /home/docker/.drush +COPY --chown=docker:docker config/.ssh /home/docker/.ssh COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY startup.sh /opt/startup.sh COPY healthcheck.sh /opt/healthcheck.sh diff --git a/7.0/config/.acquia/cloudapi.conf.tmpl b/7.0/config/.acquia/cloudapi.conf.tmpl deleted file mode 100644 index 1cfd222f..00000000 --- a/7.0/config/.acquia/cloudapi.conf.tmpl +++ /dev/null @@ -1 +0,0 @@ -{"email":"{{ getenv "SECRET_ACAPI_EMAIL" }}","key":"{{ getenv "SECRET_ACAPI_KEY" }}"} diff --git a/7.0/config/.ssh/id_rsa.tmpl b/7.0/config/.ssh/id_rsa.tmpl index cc8fa3bb..8c6c22f1 100644 --- a/7.0/config/.ssh/id_rsa.tmpl +++ b/7.0/config/.ssh/id_rsa.tmpl @@ -1 +1 @@ -{{ getenv "SECRET_SSH_PRIVATE_KEY" }} +{{ getenv "SECRET_SSH_PRIVATE_KEY" | base64.Decode }} \ No newline at end of file diff --git a/7.0/config/php/zz-php-fpm.conf b/7.0/config/php/zz-php-fpm.conf index 0624e4de..d4fb5e22 100644 --- a/7.0/config/php/zz-php-fpm.conf +++ b/7.0/config/php/zz-php-fpm.conf @@ -16,3 +16,4 @@ php_value[memory_limit] = 256M php_value[max_execution_time] = 300 php_value[upload_max_filesize] = 500M php_value[post_max_size] = 500M +php_value[max_input_vars] = 2000 diff --git a/7.0/php-modules.txt b/7.0/php-modules.txt index 2afe1101..ca82761c 100644 --- a/7.0/php-modules.txt +++ b/7.0/php-modules.txt @@ -1,4 +1,5 @@ [PHP Modules] +apcu bcmath blackfire bz2 diff --git a/7.0/startup.sh b/7.0/startup.sh index 8553fe89..f3308350 100755 --- a/7.0/startup.sh +++ b/7.0/startup.sh @@ -25,7 +25,14 @@ uid_gid_reset () xdebug_enable () { echo-debug "Enabling xdebug..." - sudo ln -s /opt/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/ + ln -s /opt/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/ +} + +add_ssh_key () +{ + echo-debug "Adding a private SSH key from SECRET_SSH_PRIVATE_KEY..." + render_tmpl "$HOME_DIR/.ssh/id_rsa" + chmod 0600 "$HOME_DIR/.ssh/id_rsa" } # Helper function to render configs from go templates using gomplate @@ -62,15 +69,30 @@ convert_secrets () done } -# Pantheon authentication +# Acquia Cloud API login +acquia_login () +{ + echo-debug "Authenticating with Acquia..." + # This has to be done using the docker user via su to load the user environment + # Note: Using 'su -l' to initiate a login session and have .profile sourced for the docker user + local command="drush ac-api-login --email='${ACAPI_EMAIL}' --key='${ACAPI_KEY}' --endpoint='https://cloudapi.acquia.com/v1' && drush ac-site-list" + local output=$(su -l docker -c "${command}" 2>&1) + if [[ $? != 0 ]]; then + echo-debug "ERROR: Acquia authentication failed." + echo + echo "$output" + echo + fi +} + +# Pantheon (terminus) login terminus_login () { echo-debug "Authenticating with Pantheon..." # This has to be done using the docker user via su to load the user environment - # Note: 'su -' = 'su -l' = 'su --login' - local output - output=$(sudo su - docker -c "terminus auth:login --machine-token='${TERMINUS_TOKEN}'" 2>&1) - #>/dev/null 2>&1 + # Note: Using 'su -l' to initiate a login session and have .profile sourced for the docker user + local command="terminus auth:login --machine-token='${TERMINUS_TOKEN}'" + local output=$(su -l docker -c "${command}" 2>&1) if [[ $? != 0 ]]; then echo-debug "ERROR: Pantheon authentication failed." echo @@ -79,12 +101,17 @@ terminus_login () fi } -# Process templates -# Private SSH key -render_tmpl "$HOME_DIR/.ssh/id_rsa" -chmod 0600 "$HOME_DIR/.ssh/id_rsa" -# Acquia Cloud API config -render_tmpl "$HOME_DIR/.acquia/cloudapi.conf" +# Git settings +git_settings () +{ + # These must be run as the docker user + echo-debug "Configuring git..." + gosu docker git config --global user.email "${GIT_USER_EMAIL}" + gosu docker git config --global user.name "${GIT_USER_NAME}" +} + +# Inject a private SSH key if provided +[[ "$SECRET_SSH_PRIVATE_KEY" != "" ]] && add_ssh_key # Convert all Environment Variables Prefixed with SECRET_ convert_secrets @@ -103,9 +130,11 @@ chown "${HOST_UID:-1000}:${HOST_GID:-1000}" -R "$HOME_DIR" # We apply a fix/workaround for this at startup (non-recursive). chown "${HOST_UID:-1000}:${HOST_GID:-1000}" /var/www -# Automatically authenticate with Pantheon in Terminus token is present -# Note: this has to happen after th home directory permissions are reset, -# otherwise the docker user may not have write access to /home/.terminus, where the auth session data is stored. +# These have to happen after the home directory permissions are reset, +# otherwise the docker user may not have write access to /home/docker, where the auth session data is stored. +# Acquia Cloud API config +[[ "$ACAPI_EMAIL" != "" ]] && [[ "$ACAPI_KEY" != "" ]] && acquia_login +# Automatically authenticate with Pantheon if Terminus token is present [[ "$TERMINUS_TOKEN" != "" ]] && terminus_login # If crontab file is found within project add contents to user crontab file. @@ -114,6 +143,9 @@ if [[ -f ${PROJECT_ROOT}/.docksal/services/cli/crontab ]]; then cat ${PROJECT_ROOT}/.docksal/services/cli/crontab | crontab -u docker - fi +# Apply git settings +[[ "$GIT_USER_EMAIL" != "" ]] && [[ "$GIT_USER_NAME" != "" ]] && git_settings + # Initialization steps completed. Create a pid file to mark the container as healthy echo-debug "Preliminary initialization completed." touch /var/run/cli diff --git a/7.1/Dockerfile b/7.1/Dockerfile index 14577a28..0e5696be 100644 --- a/7.1/Dockerfile +++ b/7.1/Dockerfile @@ -32,12 +32,10 @@ RUN set -xe; \ # Cleanup apt-get clean; rm -rf /var/lib/apt/lists/* -# Set timezone and locale +# Set en_US.UTF-8 as the default locale RUN set -xe; \ - dpkg-reconfigure locales; \ - locale-gen C.UTF-8; \ - /usr/sbin/update-locale LANG=C.UTF-8 -ENV LC_ALL C.UTF-8 + localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 +ENV LC_ALL en_US.utf8 # Enable additional repos RUN set -xe; \ @@ -201,6 +199,7 @@ RUN set -xe; \ ;\ pecl update-channels; \ pecl install >/dev/null /dev/null -# Home directory for bundle installs -ENV BUNDLE_PATH .bundler + gem install bundler >/dev/null; \ + # Have bundler install gems locally (./.bundle) by default + echo "\n""export BUNDLE_PATH=.bundle" >> /home/docker/.profile # All further RUN commands will run as the "docker" user USER docker -ARG HOME=/home/docker # PHP tools (installed as user) -ENV PATH=$PATH:$HOME/.composer/vendor/bin \ - MG_CODEGEN_VERSION=1.10 \ +ENV MG_CODEGEN_VERSION=1.10 \ TERMINUS_VERSION=1.8.1 RUN set -xe; \ \ + # Set drush8 as a global fallback for Drush Launcher + echo "\n""export DRUSH_LAUNCHER_FALLBACK=/usr/local/bin/drush8" >> $HOME/.profile; \ # Composer based dependencies # Add composer bin directory to PATH - echo "\n"'PATH="$PATH:$HOME/.composer/vendor/bin"' >> $HOME/.profile; \ + echo "\n"'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> $HOME/.profile; \ + # Reload updated PATH from profile to make composer/drush/etc. visible below + . $HOME/.profile; \ # Install cgr to use it in-place of `composer global require` composer global require consolidation/cgr >/dev/null; \ # Composer parallel install plugin @@ -319,9 +320,8 @@ USER root # Copy mhsendmail binary from stage 1 COPY --from=mhbuild /go/bin/mhsendmail /usr/local/bin/mhsendmail # Copy configs and scripts -COPY --chown=docker:docker config/.acquia $HOME/.acquia -COPY --chown=docker:docker config/.drush $HOME/.drush -COPY --chown=docker:docker config/.ssh $HOME/.ssh +COPY --chown=docker:docker config/.drush /home/docker/.drush +COPY --chown=docker:docker config/.ssh /home/docker/.ssh COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY startup.sh /opt/startup.sh COPY healthcheck.sh /opt/healthcheck.sh diff --git a/7.1/config/.acquia/cloudapi.conf.tmpl b/7.1/config/.acquia/cloudapi.conf.tmpl deleted file mode 100644 index 1cfd222f..00000000 --- a/7.1/config/.acquia/cloudapi.conf.tmpl +++ /dev/null @@ -1 +0,0 @@ -{"email":"{{ getenv "SECRET_ACAPI_EMAIL" }}","key":"{{ getenv "SECRET_ACAPI_KEY" }}"} diff --git a/7.1/config/.ssh/id_rsa.tmpl b/7.1/config/.ssh/id_rsa.tmpl index cc8fa3bb..8c6c22f1 100644 --- a/7.1/config/.ssh/id_rsa.tmpl +++ b/7.1/config/.ssh/id_rsa.tmpl @@ -1 +1 @@ -{{ getenv "SECRET_SSH_PRIVATE_KEY" }} +{{ getenv "SECRET_SSH_PRIVATE_KEY" | base64.Decode }} \ No newline at end of file diff --git a/7.1/config/php/zz-php-fpm.conf b/7.1/config/php/zz-php-fpm.conf index 0624e4de..d4fb5e22 100644 --- a/7.1/config/php/zz-php-fpm.conf +++ b/7.1/config/php/zz-php-fpm.conf @@ -16,3 +16,4 @@ php_value[memory_limit] = 256M php_value[max_execution_time] = 300 php_value[upload_max_filesize] = 500M php_value[post_max_size] = 500M +php_value[max_input_vars] = 2000 diff --git a/7.1/php-modules.txt b/7.1/php-modules.txt index 2afe1101..ca82761c 100644 --- a/7.1/php-modules.txt +++ b/7.1/php-modules.txt @@ -1,4 +1,5 @@ [PHP Modules] +apcu bcmath blackfire bz2 diff --git a/7.1/startup.sh b/7.1/startup.sh index 8553fe89..f3308350 100755 --- a/7.1/startup.sh +++ b/7.1/startup.sh @@ -25,7 +25,14 @@ uid_gid_reset () xdebug_enable () { echo-debug "Enabling xdebug..." - sudo ln -s /opt/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/ + ln -s /opt/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/ +} + +add_ssh_key () +{ + echo-debug "Adding a private SSH key from SECRET_SSH_PRIVATE_KEY..." + render_tmpl "$HOME_DIR/.ssh/id_rsa" + chmod 0600 "$HOME_DIR/.ssh/id_rsa" } # Helper function to render configs from go templates using gomplate @@ -62,15 +69,30 @@ convert_secrets () done } -# Pantheon authentication +# Acquia Cloud API login +acquia_login () +{ + echo-debug "Authenticating with Acquia..." + # This has to be done using the docker user via su to load the user environment + # Note: Using 'su -l' to initiate a login session and have .profile sourced for the docker user + local command="drush ac-api-login --email='${ACAPI_EMAIL}' --key='${ACAPI_KEY}' --endpoint='https://cloudapi.acquia.com/v1' && drush ac-site-list" + local output=$(su -l docker -c "${command}" 2>&1) + if [[ $? != 0 ]]; then + echo-debug "ERROR: Acquia authentication failed." + echo + echo "$output" + echo + fi +} + +# Pantheon (terminus) login terminus_login () { echo-debug "Authenticating with Pantheon..." # This has to be done using the docker user via su to load the user environment - # Note: 'su -' = 'su -l' = 'su --login' - local output - output=$(sudo su - docker -c "terminus auth:login --machine-token='${TERMINUS_TOKEN}'" 2>&1) - #>/dev/null 2>&1 + # Note: Using 'su -l' to initiate a login session and have .profile sourced for the docker user + local command="terminus auth:login --machine-token='${TERMINUS_TOKEN}'" + local output=$(su -l docker -c "${command}" 2>&1) if [[ $? != 0 ]]; then echo-debug "ERROR: Pantheon authentication failed." echo @@ -79,12 +101,17 @@ terminus_login () fi } -# Process templates -# Private SSH key -render_tmpl "$HOME_DIR/.ssh/id_rsa" -chmod 0600 "$HOME_DIR/.ssh/id_rsa" -# Acquia Cloud API config -render_tmpl "$HOME_DIR/.acquia/cloudapi.conf" +# Git settings +git_settings () +{ + # These must be run as the docker user + echo-debug "Configuring git..." + gosu docker git config --global user.email "${GIT_USER_EMAIL}" + gosu docker git config --global user.name "${GIT_USER_NAME}" +} + +# Inject a private SSH key if provided +[[ "$SECRET_SSH_PRIVATE_KEY" != "" ]] && add_ssh_key # Convert all Environment Variables Prefixed with SECRET_ convert_secrets @@ -103,9 +130,11 @@ chown "${HOST_UID:-1000}:${HOST_GID:-1000}" -R "$HOME_DIR" # We apply a fix/workaround for this at startup (non-recursive). chown "${HOST_UID:-1000}:${HOST_GID:-1000}" /var/www -# Automatically authenticate with Pantheon in Terminus token is present -# Note: this has to happen after th home directory permissions are reset, -# otherwise the docker user may not have write access to /home/.terminus, where the auth session data is stored. +# These have to happen after the home directory permissions are reset, +# otherwise the docker user may not have write access to /home/docker, where the auth session data is stored. +# Acquia Cloud API config +[[ "$ACAPI_EMAIL" != "" ]] && [[ "$ACAPI_KEY" != "" ]] && acquia_login +# Automatically authenticate with Pantheon if Terminus token is present [[ "$TERMINUS_TOKEN" != "" ]] && terminus_login # If crontab file is found within project add contents to user crontab file. @@ -114,6 +143,9 @@ if [[ -f ${PROJECT_ROOT}/.docksal/services/cli/crontab ]]; then cat ${PROJECT_ROOT}/.docksal/services/cli/crontab | crontab -u docker - fi +# Apply git settings +[[ "$GIT_USER_EMAIL" != "" ]] && [[ "$GIT_USER_NAME" != "" ]] && git_settings + # Initialization steps completed. Create a pid file to mark the container as healthy echo-debug "Preliminary initialization completed." touch /var/run/cli diff --git a/7.2/Dockerfile b/7.2/Dockerfile index 20a2a214..19b87b6e 100644 --- a/7.2/Dockerfile +++ b/7.2/Dockerfile @@ -32,12 +32,10 @@ RUN set -xe; \ # Cleanup apt-get clean; rm -rf /var/lib/apt/lists/* -# Set timezone and locale +# Set en_US.UTF-8 as the default locale RUN set -xe; \ - dpkg-reconfigure locales; \ - locale-gen C.UTF-8; \ - /usr/sbin/update-locale LANG=C.UTF-8 -ENV LC_ALL C.UTF-8 + localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 +ENV LC_ALL en_US.utf8 # Enable additional repos RUN set -xe; \ @@ -204,6 +202,7 @@ RUN set -xe; \ ;\ pecl update-channels; \ pecl install >/dev/null /dev/null -# Home directory for bundle installs -ENV BUNDLE_PATH .bundler + gem install bundler >/dev/null; \ + # Have bundler install gems locally (./.bundle) by default + echo "\n""export BUNDLE_PATH=.bundle" >> /home/docker/.profile # All further RUN commands will run as the "docker" user USER docker -ARG HOME=/home/docker # PHP tools (installed as user) -ENV PATH=$PATH:$HOME/.composer/vendor/bin \ - MG_CODEGEN_VERSION=1.10 \ +ENV MG_CODEGEN_VERSION=1.10 \ TERMINUS_VERSION=1.8.1 RUN set -xe; \ \ + # Set drush8 as a global fallback for Drush Launcher + echo "\n""export DRUSH_LAUNCHER_FALLBACK=/usr/local/bin/drush8" >> $HOME/.profile; \ # Composer based dependencies # Add composer bin directory to PATH - echo "\n"'PATH="$PATH:$HOME/.composer/vendor/bin"' >> $HOME/.profile; \ + echo "\n"'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> $HOME/.profile; \ + # Reload updated PATH from profile to make composer/drush/etc. visible below + . $HOME/.profile; \ # Install cgr to use it in-place of `composer global require` composer global require consolidation/cgr >/dev/null; \ # Composer parallel install plugin @@ -321,9 +322,8 @@ USER root # Copy mhsendmail binary from stage 1 COPY --from=mhbuild /go/bin/mhsendmail /usr/local/bin/mhsendmail # Copy configs and scripts -COPY --chown=docker:docker config/.acquia $HOME/.acquia -COPY --chown=docker:docker config/.drush $HOME/.drush -COPY --chown=docker:docker config/.ssh $HOME/.ssh +COPY --chown=docker:docker config/.drush /home/docker/.drush +COPY --chown=docker:docker config/.ssh /home/docker/.ssh COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY startup.sh /opt/startup.sh COPY healthcheck.sh /opt/healthcheck.sh diff --git a/7.2/config/.acquia/cloudapi.conf.tmpl b/7.2/config/.acquia/cloudapi.conf.tmpl deleted file mode 100644 index 1cfd222f..00000000 --- a/7.2/config/.acquia/cloudapi.conf.tmpl +++ /dev/null @@ -1 +0,0 @@ -{"email":"{{ getenv "SECRET_ACAPI_EMAIL" }}","key":"{{ getenv "SECRET_ACAPI_KEY" }}"} diff --git a/7.2/config/.ssh/id_rsa.tmpl b/7.2/config/.ssh/id_rsa.tmpl index cc8fa3bb..8c6c22f1 100644 --- a/7.2/config/.ssh/id_rsa.tmpl +++ b/7.2/config/.ssh/id_rsa.tmpl @@ -1 +1 @@ -{{ getenv "SECRET_SSH_PRIVATE_KEY" }} +{{ getenv "SECRET_SSH_PRIVATE_KEY" | base64.Decode }} \ No newline at end of file diff --git a/7.2/config/php/zz-php-fpm.conf b/7.2/config/php/zz-php-fpm.conf index 0624e4de..d4fb5e22 100644 --- a/7.2/config/php/zz-php-fpm.conf +++ b/7.2/config/php/zz-php-fpm.conf @@ -16,3 +16,4 @@ php_value[memory_limit] = 256M php_value[max_execution_time] = 300 php_value[upload_max_filesize] = 500M php_value[post_max_size] = 500M +php_value[max_input_vars] = 2000 diff --git a/7.2/php-modules.txt b/7.2/php-modules.txt index 986d28e7..61d7753c 100644 --- a/7.2/php-modules.txt +++ b/7.2/php-modules.txt @@ -1,4 +1,5 @@ [PHP Modules] +apcu bcmath blackfire bz2 diff --git a/7.2/startup.sh b/7.2/startup.sh index 8553fe89..f3308350 100755 --- a/7.2/startup.sh +++ b/7.2/startup.sh @@ -25,7 +25,14 @@ uid_gid_reset () xdebug_enable () { echo-debug "Enabling xdebug..." - sudo ln -s /opt/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/ + ln -s /opt/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/ +} + +add_ssh_key () +{ + echo-debug "Adding a private SSH key from SECRET_SSH_PRIVATE_KEY..." + render_tmpl "$HOME_DIR/.ssh/id_rsa" + chmod 0600 "$HOME_DIR/.ssh/id_rsa" } # Helper function to render configs from go templates using gomplate @@ -62,15 +69,30 @@ convert_secrets () done } -# Pantheon authentication +# Acquia Cloud API login +acquia_login () +{ + echo-debug "Authenticating with Acquia..." + # This has to be done using the docker user via su to load the user environment + # Note: Using 'su -l' to initiate a login session and have .profile sourced for the docker user + local command="drush ac-api-login --email='${ACAPI_EMAIL}' --key='${ACAPI_KEY}' --endpoint='https://cloudapi.acquia.com/v1' && drush ac-site-list" + local output=$(su -l docker -c "${command}" 2>&1) + if [[ $? != 0 ]]; then + echo-debug "ERROR: Acquia authentication failed." + echo + echo "$output" + echo + fi +} + +# Pantheon (terminus) login terminus_login () { echo-debug "Authenticating with Pantheon..." # This has to be done using the docker user via su to load the user environment - # Note: 'su -' = 'su -l' = 'su --login' - local output - output=$(sudo su - docker -c "terminus auth:login --machine-token='${TERMINUS_TOKEN}'" 2>&1) - #>/dev/null 2>&1 + # Note: Using 'su -l' to initiate a login session and have .profile sourced for the docker user + local command="terminus auth:login --machine-token='${TERMINUS_TOKEN}'" + local output=$(su -l docker -c "${command}" 2>&1) if [[ $? != 0 ]]; then echo-debug "ERROR: Pantheon authentication failed." echo @@ -79,12 +101,17 @@ terminus_login () fi } -# Process templates -# Private SSH key -render_tmpl "$HOME_DIR/.ssh/id_rsa" -chmod 0600 "$HOME_DIR/.ssh/id_rsa" -# Acquia Cloud API config -render_tmpl "$HOME_DIR/.acquia/cloudapi.conf" +# Git settings +git_settings () +{ + # These must be run as the docker user + echo-debug "Configuring git..." + gosu docker git config --global user.email "${GIT_USER_EMAIL}" + gosu docker git config --global user.name "${GIT_USER_NAME}" +} + +# Inject a private SSH key if provided +[[ "$SECRET_SSH_PRIVATE_KEY" != "" ]] && add_ssh_key # Convert all Environment Variables Prefixed with SECRET_ convert_secrets @@ -103,9 +130,11 @@ chown "${HOST_UID:-1000}:${HOST_GID:-1000}" -R "$HOME_DIR" # We apply a fix/workaround for this at startup (non-recursive). chown "${HOST_UID:-1000}:${HOST_GID:-1000}" /var/www -# Automatically authenticate with Pantheon in Terminus token is present -# Note: this has to happen after th home directory permissions are reset, -# otherwise the docker user may not have write access to /home/.terminus, where the auth session data is stored. +# These have to happen after the home directory permissions are reset, +# otherwise the docker user may not have write access to /home/docker, where the auth session data is stored. +# Acquia Cloud API config +[[ "$ACAPI_EMAIL" != "" ]] && [[ "$ACAPI_KEY" != "" ]] && acquia_login +# Automatically authenticate with Pantheon if Terminus token is present [[ "$TERMINUS_TOKEN" != "" ]] && terminus_login # If crontab file is found within project add contents to user crontab file. @@ -114,6 +143,9 @@ if [[ -f ${PROJECT_ROOT}/.docksal/services/cli/crontab ]]; then cat ${PROJECT_ROOT}/.docksal/services/cli/crontab | crontab -u docker - fi +# Apply git settings +[[ "$GIT_USER_EMAIL" != "" ]] && [[ "$GIT_USER_NAME" != "" ]] && git_settings + # Initialization steps completed. Create a pid file to mark the container as healthy echo-debug "Preliminary initialization completed." touch /var/run/cli diff --git a/README.md b/README.md index f3752221..fcfaeaef 100644 --- a/README.md +++ b/README.md @@ -147,10 +147,19 @@ Below is the list of secrets currently supported. `SECRET_SSH_PRIVATE_KEY` -Use to pass a private SSH key. The key is stored in `/home/docker/.ssh/id_rsa` inside `cli` and will be considered +Use to pass a private SSH key. The key will be stored in `/home/docker/.ssh/id_rsa` inside `cli` and will be considered by the SSH client **in addition** to the keys loaded in `docksal-ssh-agent` when establishing a SSH connection from within `cli`. +This is useful when you need a project stack to inherit a private SSH key that is not shared with other project stacks +on the same host (e.g. in shared CI environments). + +The value must be base64 encoded, i.e: + +```bash +cat /path/to/some_key_rsa | base64 +``` + `SECRET_ACAPI_EMAIL` and `SECRET_ACAPI_KEY` Credentials used to authenticate with [Acquia Cloud API](https://docs.acquia.com/acquia-cloud/api). @@ -173,6 +182,17 @@ Stored in `/home/docker/.platform` inside `cli`. Platform CLI is installed and available globally in `cli`. +## Git configuration + +When working with git from within the image, it will ask for the `user.email` and `user.name` set before you can commit. +These can be passed as environment variables and will be applied at the container startup. + +``` +GIT_USER_EMAIL="git@example.com" +GIT_USER_NAME="Docksal CLI" +``` + + ## Web based IDE (Cloud9) diff --git a/tests/.docksal/docksal.env b/tests/.docksal/docksal.env index d525d907..db6179f9 100644 --- a/tests/.docksal/docksal.env +++ b/tests/.docksal/docksal.env @@ -1,12 +1,4 @@ DOCKSAL_STACK=node # Project secrets -SECRET_ACAPI_EMAIL="user@example.com" -SECRET_ACAPI_KEY="rSxVZN35bo4jTuncGS+CiKdmhxLPL0BaPuyOvf510sKb6c4ycxZsfFpC/vjJgaMvGvpKi06iHoqX" -SECRET_SSH_PRIVATE_KEY=" ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIMq4x61QtiUirrlN9AqlpniofwSUr674FhZoHGMsm2bDoAoGCCqGSM49 -AwEHoUQDQgAEKLfpo3ln+keZat/HYIG+g0H/Lt/+j0EUENHyGO8q2yqu02l833G8 -l2XRJT5kxNFRa3YGR0Jo1Knzyey8wFOOow== ------END EC PRIVATE KEY----- -" +SECRET_SSH_PRIVATE_KEY="LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU1xNHg2MVF0aVVpcnJsTjlBcWxwbmlvZndTVXI2NzRGaFpvSEdNc20yYkRvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFS0xmcG8zbG4ra2VaYXQvSFlJRytnMEgvTHQvK2owRVVFTkh5R084cTJ5cXUwMmw4MzNHOApsMlhSSlQ1a3hORlJhM1lHUjBKbzFLbnp5ZXk4d0ZPT293PT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=" diff --git a/tests/test.bats b/tests/test.bats index 7a16b79b..7437ee48 100755 --- a/tests/test.bats +++ b/tests/test.bats @@ -310,38 +310,20 @@ _healthcheck_wait () set -a; source $(pwd)/../tests/.docksal/docksal.env; set +a # Config variables were loaded - [[ "${SECRET_ACAPI_EMAIL}" != "" ]] - [[ "${SECRET_ACAPI_KEY}" != "" ]] [[ "${SECRET_SSH_PRIVATE_KEY}" != "" ]] ### Setup ### - make start -e ENV="\ - -e SECRET_ACAPI_EMAIL \ - -e SECRET_ACAPI_KEY \ - -e SECRET_SSH_PRIVATE_KEY \ - " + make start -e ENV="-e SECRET_SSH_PRIVATE_KEY" _healthcheck_wait ### Tests ### - # Check Acquia Cloud API conf - run make exec -e CMD='echo ${SECRET_ACAPI_EMAIL}' - [[ "${output}" != "" ]] - unset output - run make exec -e CMD='echo ${SECRET_ACAPI_KEY}' - [[ "${output}" != "" ]] - unset output - # TODO: figure out how to properly use 'make exec' here (escape quotes) - run docker exec -u docker "${NAME}" bash -lc 'grep "${SECRET_ACAPI_EMAIL}" ${HOME}/.acquia/cloudapi.conf && grep "${SECRET_ACAPI_KEY}" ${HOME}/.acquia/cloudapi.conf' - [[ ${status} == 0 ]] - unset output - # Check private SSH key run make exec -e CMD='echo ${SECRET_SSH_PRIVATE_KEY}' [[ "${output}" != "" ]] unset output # TODO: figure out how to properly use 'make exec' here (escape quotes) - run docker exec -u docker "${NAME}" bash -lc 'echo "${SECRET_SSH_PRIVATE_KEY}" | diff ${HOME}/.ssh/id_rsa -' + run docker exec -u docker "${NAME}" bash -lc 'echo "${SECRET_SSH_PRIVATE_KEY}" | base64 -d | diff ${HOME}/.ssh/id_rsa -' [[ ${status} == 0 ]] unset output @@ -363,6 +345,45 @@ _healthcheck_wait () make clean } +@test "Check Acquia integration" { + [[ $SKIP == 1 ]] && skip + + # Confirm secret is not empty + [[ "${SECRET_ACAPI_EMAIL}" != "" ]] + [[ "${SECRET_ACAPI_KEY}" != "" ]] + + ### Setup ### + make start -e ENV='-e SECRET_ACAPI_EMAIL -e SECRET_ACAPI_KEY' + _healthcheck_wait + + ### Tests ### + + # Confirm secrets were passed to the container + run docker exec -u docker "${NAME}" bash -lc 'echo SECRET_ACAPI_EMAIL: ${SECRET_ACAPI_EMAIL}' + [[ "${output}" == "SECRET_ACAPI_EMAIL: ${SECRET_ACAPI_EMAIL}" ]] + unset output + run docker exec -u docker "${NAME}" bash -lc 'echo SECRET_ACAPI_KEY: ${SECRET_ACAPI_KEY}' + [[ "${output}" == "SECRET_ACAPI_KEY: ${SECRET_ACAPI_KEY}" ]] + unset output + + # Confirm the SECRET_ prefix was stripped + run docker exec -u docker "${NAME}" bash -lc 'echo ACAPI_EMAIL: ${SECRET_ACAPI_EMAIL}' + [[ "${output}" == "ACAPI_EMAIL: ${SECRET_ACAPI_EMAIL}" ]] + unset output + run docker exec -u docker "${NAME}" bash -lc 'echo ACAPI_KEY: ${SECRET_ACAPI_KEY}' + [[ "${output}" == "ACAPI_KEY: ${SECRET_ACAPI_KEY}" ]] + unset output + + # Confirm authentication works + run docker exec -u docker "${NAME}" bash -lc 'drush ac-site-list' + [[ ${status} == 0 ]] + [[ ! "${output}" =~ "Not authorized" ]] + unset output + + ### Cleanup ### + make clean +} + @test "Check Platform.sh integration" { [[ $SKIP == 1 ]] && skip @@ -456,3 +477,25 @@ _healthcheck_wait () ### Cleanup ### make clean } + +@test "Git settings" { + [[ $SKIP == 1 ]] && skip + + ### Setup ### + make start -e ENV='-e GIT_USER_EMAIL=git@example.com -e GIT_USER_NAME="Docksal CLI"' + _healthcheck_wait + + ### Tests ### + + # Check git settings were applied + run docker exec -u docker "$NAME" bash -lc 'git config --get --global user.email' + [[ "${output}" == "git@example.com" ]] + unset output + + run docker exec -u docker "$NAME" bash -lc 'git config --get --global user.name' + [[ "${output}" == "Docksal CLI" ]] + unset output + + ### Cleanup ### + make clean +}