From 4c3c18551bcab102a74fe99bda7666337aa6d467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Alfonsi?= Date: Tue, 17 Oct 2017 18:20:56 +0200 Subject: [PATCH 01/32] PHP7 Dev --- Dockerfile | 66 ++++++++++++++++++++++------------------ bin/docker-entrypoint.sh | 56 ++++++++++++++++++---------------- conf/passbolt.conf | 4 +-- 3 files changed, 69 insertions(+), 57 deletions(-) diff --git a/Dockerfile b/Dockerfile index e459854..3a0d25c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,29 +2,37 @@ FROM alpine:3.6 MAINTAINER diego@passbolt.com -ENV PASSBOLT_VERSION 1.6.3 +ENV PASSBOLT_VERSION 1.6.5 ENV PASSBOLT_URL https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VERSION}.tar.gz -ARG BASE_PHP_DEPS="php5-curl \ - php5-common \ - php5-gd \ - php5-intl \ - php5-json \ - php5-mcrypt \ - php5-mysql \ - php5-xsl \ - php5-fpm \ - php5-phar \ - php5-posix \ - php5-xml \ - php5-openssl \ - php5-zlib \ - php5-ctype \ - php5-pdo \ - php5-pdo_mysql \ - php5-pear" +ARG BASE_PHP_DEPS="php7-curl \ + php7-common \ + php7-gd \ + php7-intl \ + php7-json \ + php7-mcrypt \ + php7-mysqli \ + php7-xsl \ + php7-fpm \ + php7-phar \ + php7-posix \ + php7-xml \ + php7-openssl \ + php7-zlib \ + php7-ctype \ + php7-pdo \ + php7-pdo_mysql \ + php7-pear \ + php7-session \ + php7-iconv \ + php7-mbstring" -ARG PHP_GNUPG_DEPS="php5-dev \ +ARG BASE_PHP_DEV_DEPS="php7-tokenizer \ + php7-xmlwriter \ + php7-simplexml \ + php7-xdebug" + +ARG PHP_GNUPG_DEPS="php7-dev \ make \ gcc \ g++ \ @@ -37,6 +45,7 @@ ARG PHP_GNUPG_DEPS="php5-dev \ file" RUN apk add --no-cache $BASE_PHP_DEPS \ + $BASE_PHP_DEV_DEPS \ sed \ tar \ bash \ @@ -51,22 +60,21 @@ RUN apk add --no-cache $BASE_PHP_DEPS \ mysql-client \ ca-certificates -RUN apk add --no-cache $PHP_GNUPG_DEPS \ - && ln -s /usr/bin/php5 /usr/bin/php \ - && ln -s /usr/bin/phpize5 /usr/bin/phpize \ +RUN apk add --no-cache $PHP_GNUPG_DEPS \ #https://bugs.alpinelinux.org/issues/5378 && sed -i "s/ -n / /" $(which pecl) \ - && pecl install gnupg memcache \ - && echo "extension=memcache.so" > /etc/php5/conf.d/memcache.ini \ - && echo "extension=gnupg.so" > /etc/php5/conf.d/gnupg.ini \ + && pecl install gnupg \ + && echo "extension=gnupg.so" > /etc/php7/conf.d/gnupg.ini \ && apk del $PHP_GNUPG_DEPS \ && curl -sS https://getcomposer.org/installer | php \ - && mv composer.phar /usr/local/bin/composer \ - && mkdir /var/www/passbolt \ + && mv composer.phar /usr/local/bin/composer + +RUN mkdir /var/www/passbolt \ && curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ && chown -R nginx:nginx /var/www/passbolt \ + && chmod -R a-w /var/www/passbolt \ && chmod -R +w /var/www/passbolt/app/tmp \ - && chmod +w /var/www/passbolt/app/webroot/img/public + && chmod -R +w /var/www/passbolt/app/webroot/img/public COPY conf/passbolt.conf /etc/nginx/conf.d/default.conf COPY bin/docker-entrypoint.sh /docker-entrypoint.sh diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index e3645f2..30fd748 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -2,8 +2,8 @@ set -eo pipefail -gpg_private_key=/var/www/passbolt/app/Config/gpg/serverkey.private.asc -gpg_public_key=/var/www/passbolt/app/Config/gpg/serverkey.asc +gpg_private_key=/var/www/passbolt/config/gpg/serverkey.private.asc +gpg_public_key=/var/www/passbolt/config/gpg/serverkey.asc gpg=$(which gpg) core_config='/var/www/passbolt/app/Config/core.php' @@ -14,7 +14,7 @@ ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' gpg_gen_key() { - su -m -c "$gpg --batch --gen-key < $gpg_private_key" -ls /bin/bash nginx - su -m -c "$gpg --armor --export $KEY_EMAIL > $gpg_public_key" -ls /bin/bash nginx + $gpg --armor --export-secret-keys $KEY_EMAIL > $gpg_private_key + $gpg --armor --export $KEY_EMAIL > $gpg_public_key + gpg_auto_fingerprint=`$gpg --fingerprint $KEY_EMAIL | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}'` } gpg_import_key() { - local key_id=$(su -m -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/bash nginx) su -m -c "$gpg --batch --import $gpg_public_key" -ls /bin/bash nginx @@ -83,18 +83,14 @@ app_setup() { # REGISTRATION # SSL - local default_home='/home/www-data/.gnupg' local default_public_key='unsecure.key' local default_private_key='unsecure_private.key' local default_fingerprint='2FC8945833C51946E937F9FED47B0811573EE67E' - local gpg_home='/var/lib/nginx/.gnupg' - local auto_fingerprint=$(su -m -c "$gpg --fingerprint |grep fingerprint| awk '{for(i=4;i<=NF;++i)printf \$i}'" -ls /bin/bash nginx) cp $app_config{.default,} - sed -i s:$default_home:$gpg_home:g $app_config sed -i s:$default_public_key:serverkey.asc:g $app_config sed -i s:$default_private_key:serverkey.private.asc:g $app_config - sed -i s:$default_fingerprint:${FINGERPRINT:-$auto_fingerprint}:g $app_config + sed -i s:$default_fingerprint:${FINGERPRINT:-$gpg_auto_fingerprint}:g $app_config sed -i "/force/ s:true:${SSL:-true}:" $app_config sed -i "/'registration'/{n; s:false:${REGISTRATION:-false}:}" $app_config } @@ -152,10 +148,8 @@ install() { } php_fpm_setup() { - sed -i '/^user\s/ s:nobody:nginx:g' /etc/php5/php-fpm.conf - sed -i '/^group\s/ s:nobody:nginx:g' /etc/php5/php-fpm.conf - cp /etc/php5/php-fpm.conf /etc/php5/fpm.d/www.conf - sed -i '/^include\s/ s:^:#:' /etc/php5/fpm.d/www.conf + sed -i '/^user\s/ s:nobody:nginx:g' /etc/php7/php-fpm.d/www.conf + sed -i '/^group\s/ s:nobody:nginx:g' /etc/php7/php-fpm.d/www.conf } email_cron_job() { @@ -177,25 +171,33 @@ email_cron_job() { if [ ! -f $gpg_private_key ] && [ ! -L $gpg_private_key ] || \ [ ! -f $gpg_public_key ] && [ ! -L $gpg_public_key ]; then - gpg_gen_key + echo 'not yet implemented' + #su -c "gpg --list-keys" -ls /bin/bash nginx + #gpg_gen_key + #gpg_import_key else - gpg_import_key + echo 'not yet implemented' + #gpg_import_key fi if [ ! -f $core_config ] && [ ! -L $core_config ]; then - core_setup + echo 'not yet implemented' + #core_setup fi if [ ! -f $db_config ] && [ ! -L $db_config ]; then - db_setup + echo 'not yet implemented' + #db_setup fi if [ ! -f $app_config ] && [ ! -L $app_config ]; then - app_setup + echo 'not yet implemented' + #app_setup fi if [ ! -f $email_config ] && [ ! -L $email_config ]; then - email_setup + echo 'not yet implemented' + #email_setup fi if [ ! -f $ssl_key ] && [ ! -L $ssl_key ] && \ @@ -205,10 +207,12 @@ fi php_fpm_setup -install +# not yet implemented +#install -php-fpm5 +php-fpm7 -nginx -g "pid /tmp/nginx.pid; daemon off;" & +nginx -g "pid /tmp/nginx.pid; daemon off;" -email_cron_job +# not yet implemented +#email_cron_job diff --git a/conf/passbolt.conf b/conf/passbolt.conf index af68783..773e5c5 100644 --- a/conf/passbolt.conf +++ b/conf/passbolt.conf @@ -42,7 +42,7 @@ server { location ~* \.(jpe?g|woff|woff2|ttf|gif|png|bmp|ico|css|js|json|pdf|zip|htm|html|docx?|xlsx?|pptx?|txt|wav|swf|svg|avi|mp\d)$ { access_log off; log_not_found off; - try_files $uri /app/webroot/$uri /index.php?$args; + try_files $uri /webroot/$uri /index.php?$args; } } @@ -93,6 +93,6 @@ server { location ~* \.(jpe?g|woff|woff2|ttf|gif|png|bmp|ico|css|js|json|pdf|zip|htm|html|docx?|xlsx?|pptx?|txt|wav|swf|svg|avi|mp\d)$ { access_log off; log_not_found off; - try_files $uri /app/webroot/$uri /index.php?$args; + try_files $uri /webroot/$uri /index.php?$args; } } From c6d6ac41485969ea5bcf13504d2dde9f3b752764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Alfonsi?= Date: Wed, 25 Oct 2017 17:51:19 +0200 Subject: [PATCH 02/32] PASSBOLT-2434 Add npm dependencies for development --- Dockerfile | 14 ++++++++++---- conf/passbolt.conf | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3a0d25c..9ff8b32 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,10 +27,8 @@ ARG BASE_PHP_DEPS="php7-curl \ php7-iconv \ php7-mbstring" -ARG BASE_PHP_DEV_DEPS="php7-tokenizer \ - php7-xmlwriter \ - php7-simplexml \ - php7-xdebug" +ARG BASE_NODE_DEPS="nodejs \ + nodejs-npm" ARG PHP_GNUPG_DEPS="php7-dev \ make \ @@ -44,7 +42,15 @@ ARG PHP_GNUPG_DEPS="php7-dev \ zlib-dev \ file" +ARG BASE_PHP_DEV_DEPS="php7-tokenizer \ + php7-xmlwriter \ + php7-simplexml \ + php7-xdebug \ + git \ + openssh" + RUN apk add --no-cache $BASE_PHP_DEPS \ + $BASE_NODE_DEPS \ $BASE_PHP_DEV_DEPS \ sed \ tar \ diff --git a/conf/passbolt.conf b/conf/passbolt.conf index 773e5c5..a522ff4 100644 --- a/conf/passbolt.conf +++ b/conf/passbolt.conf @@ -39,10 +39,11 @@ server { fastcgi_param SERVER_NAME $http_host; } - location ~* \.(jpe?g|woff|woff2|ttf|gif|png|bmp|ico|css|js|json|pdf|zip|htm|html|docx?|xlsx?|pptx?|txt|wav|swf|svg|avi|mp\d)$ { + location ~* \.(jpe?g|woff|woff2|ttf|gif|png|bmp|ico|css|js|ejs|json|pdf|zip|htm|html|docx?|xlsx?|pptx?|txt|wav|swf|svg|avi|mp\d)$ { access_log off; log_not_found off; try_files $uri /webroot/$uri /index.php?$args; + #try_files $uri /app/webroot/$uri /index.php?$args; } } @@ -94,5 +95,6 @@ server { access_log off; log_not_found off; try_files $uri /webroot/$uri /index.php?$args; + #try_files $uri /app/webroot/$uri /index.php?$args; } } From d0c24ef06759bd67abfb635f46addf1fa3cac9c6 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 4 Jan 2018 14:49:09 +0100 Subject: [PATCH 03/32] moved to php7-alpine base image and initial clean up --- Dockerfile | 58 ++++++++++-------------------------------------------- 1 file changed, 10 insertions(+), 48 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9ff8b32..7001773 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,36 +1,16 @@ -FROM alpine:3.6 +FROM php:7-fpm-alpine -MAINTAINER diego@passbolt.com +LABEL MAINTAINER diego@passbolt.com ENV PASSBOLT_VERSION 1.6.5 ENV PASSBOLT_URL https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VERSION}.tar.gz -ARG BASE_PHP_DEPS="php7-curl \ - php7-common \ - php7-gd \ - php7-intl \ - php7-json \ - php7-mcrypt \ - php7-mysqli \ - php7-xsl \ - php7-fpm \ - php7-phar \ - php7-posix \ - php7-xml \ - php7-openssl \ - php7-zlib \ - php7-ctype \ - php7-pdo \ - php7-pdo_mysql \ - php7-pear \ - php7-session \ - php7-iconv \ - php7-mbstring" +ARG PHP_EXTENSIONS="gd \ + intl \ + mcrypt \ + xsl" -ARG BASE_NODE_DEPS="nodejs \ - nodejs-npm" - -ARG PHP_GNUPG_DEPS="php7-dev \ +ARG PHP_GNUPG_BUILD_DEPS="php7-dev \ make \ gcc \ g++ \ @@ -42,33 +22,15 @@ ARG PHP_GNUPG_DEPS="php7-dev \ zlib-dev \ file" -ARG BASE_PHP_DEV_DEPS="php7-tokenizer \ - php7-xmlwriter \ - php7-simplexml \ - php7-xdebug \ - git \ - openssh" - -RUN apk add --no-cache $BASE_PHP_DEPS \ - $BASE_NODE_DEPS \ - $BASE_PHP_DEV_DEPS \ +RUN apk add --no-cache $PHP_EXTENSIONS \ + $PHP_GNUPG_BUILD_DEPS \ sed \ - tar \ - bash \ - curl \ nginx \ gpgme \ gnupg1 \ - recode \ - libxml2 \ - openssl \ - libpcre32 \ - mysql-client \ - ca-certificates + mysql-client RUN apk add --no-cache $PHP_GNUPG_DEPS \ - #https://bugs.alpinelinux.org/issues/5378 - && sed -i "s/ -n / /" $(which pecl) \ && pecl install gnupg \ && echo "extension=gnupg.so" > /etc/php7/conf.d/gnupg.ini \ && apk del $PHP_GNUPG_DEPS \ From fc2701fffcef9d94b44cb9fdbd92e72b4ac4a0bb Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 4 Jan 2018 15:27:43 +0100 Subject: [PATCH 04/32] initial gemfiles --- Gemfile | 7 +++++++ Gemfile.lock | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 Gemfile create mode 100644 Gemfile.lock diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..9bd3773 --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'serverspec' +gem 'docker-api' +gem 'rake' + +gem 'pry' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..49219f5 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,58 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.2) + diff-lcs (1.3) + docker-api (1.34.0) + excon (>= 0.47.0) + multi_json + excon (0.60.0) + method_source (0.9.0) + multi_json (1.12.2) + net-scp (1.2.1) + net-ssh (>= 2.6.5) + net-ssh (4.2.0) + net-telnet (0.1.1) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + rake (12.3.0) + rspec (3.7.0) + rspec-core (~> 3.7.0) + rspec-expectations (~> 3.7.0) + rspec-mocks (~> 3.7.0) + rspec-core (3.7.1) + rspec-support (~> 3.7.0) + rspec-expectations (3.7.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.7.0) + rspec-its (1.2.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.7.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.7.0) + rspec-support (3.7.0) + serverspec (2.41.3) + multi_json + rspec (~> 3.0) + rspec-its + specinfra (~> 2.72) + sfl (2.3) + specinfra (2.73.0) + net-scp + net-ssh (>= 2.7, < 5.0) + net-telnet + sfl + +PLATFORMS + ruby + +DEPENDENCIES + docker-api + pry + rake + serverspec + +BUNDLED WITH + 1.16.1 From 1319a6f50d09fbc882952f4e6ed20da62f7c80f3 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 4 Jan 2018 15:28:10 +0100 Subject: [PATCH 05/32] initial Rakefile --- Rakefile | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Rakefile diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..11ba867 --- /dev/null +++ b/Rakefile @@ -0,0 +1,27 @@ +require 'rake' +require 'rspec/core/rake_task' + +task :spec => 'spec:all' +task :default => :spec + +namespace :spec do + targets = [] + Dir.glob('./spec/*').each do |dir| + next unless File.directory?(dir) + target = File.basename(dir) + target = "_#{target}" if target == "default" + targets << target + end + + task :all => targets + task :default => :all + + targets.each do |target| + original_target = target == "_default" ? target[1..-1] : target + desc "Run serverspec tests to #{original_target}" + RSpec::Core::RakeTask.new(target.to_sym) do |t| + ENV['TARGET_HOST'] = original_target + t.pattern = "spec/#{original_target}/*_spec.rb" + end + end +end From faaa07dff475bc52dce49c905244e547ff9f3cc6 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 4 Jan 2018 15:28:26 +0100 Subject: [PATCH 06/32] initial spec files --- spec/passbolt_api/Dockerfile_spec.rb | 97 ++++++++++++++++++++++++++++ spec/spec_helper.rb | 9 +++ 2 files changed, 106 insertions(+) create mode 100644 spec/passbolt_api/Dockerfile_spec.rb create mode 100644 spec/spec_helper.rb diff --git a/spec/passbolt_api/Dockerfile_spec.rb b/spec/passbolt_api/Dockerfile_spec.rb new file mode 100644 index 0000000..660f8de --- /dev/null +++ b/spec/passbolt_api/Dockerfile_spec.rb @@ -0,0 +1,97 @@ +require 'spec_helper' + +describe 'passbolt_api service' do + + before(:all) do + image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) + + set :docker_image, image.id + set :env, { 'DB_HOST' => '172.17.0.2' } +end + + let(:global_conf) { '/etc/nginx/nginx.conf' } + let(:site_conf) { '/etc/nginx/conf.d/default.conf' } + let(:passbolt_home) { '/var/www/passbolt' } + let(:passbolt_tmp) { '/var/www/passbolt/app/tmp' } + let(:passbolt_image) { '/var/www/passbolt/app/webroot/img/public' } + let(:passbolt_owner) { 'www-data' } + + describe "passbolt required php extension" do + + php_extensions = [ + 'curl', 'gd', 'intl', 'json', 'mcrypt', 'mysqlnd', 'xsl', 'phar', + 'posix', 'xml', 'xsl', 'zlib', 'ctype', 'pdo', 'pdo_mysql', 'gnupg' + ] + + php_extensions.each do |ext| + it "#{ext} must be installed" do + expect(command("php --ri #{ext}").exit_status).to eq 0 + end + end + end + + describe 'supervisor' do + it 'is installed' do + expect(package('supervisor')).to be_installed + end + end + + describe 'passbolt home dirs' do + it 'must exist and be directories' do + expect(file(passbolt_home)).to be_a_directory + expect(file(passbolt_tmp)).to be_a_directory + expect(file(passbolt_image)).to be_a_directory + end + + it 'must be owned by correct user' do + expect(file(passbolt_home)).to be_owned_by(passbolt_owner) + end + end + + describe 'global configuration' do + it 'is installed correctly' do + expect(file(global_conf)).to exist + end + + it 'has the correct permissions' do + expect(file(global_conf)).to be_owned_by 'root' + end + end + + describe 'site configuration' do + it 'is installed correctly' do + expect(file(site_conf)).to exist + end + + it 'has the correct permissions' do + expect(file(site_conf)).to be_owned_by 'root' + end + end + + describe 'php service' do + it 'is running supervised' do + expect(service('php-fpm')).to be_running.under('supervisor') + end + end + + describe port(9000) do + it { is_expected.to be_listening.with('tcp') } + end + + describe 'email cron' do + it 'is running supervised' do + expect(service('crond')).to be_running.under('supervisor') + end + end + + describe 'web service' do + it 'is running supervised' do + expect(service('nginx')).to be_running.under('supervisor') + end + + it 'is listening on port 80' do + expect(port(80)).to be_listening.with('tcp') + end + end + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..9620baa --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,9 @@ +require 'serverspec' +require 'docker' + +ROOT_DOCKERFILES = File.expand_path('../../', __FILE__) + +set :backend, :docker +Docker.options[:read_timeout] = 3600 +Docker.options[:write_timeout] = 3600 + From 01a94297e69200494a8c38137aef3441de4341f9 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 4 Jan 2018 22:25:28 +0100 Subject: [PATCH 07/32] initial clean up and shellcheck fixes --- bin/docker-entrypoint.sh | 125 ++++----------------------------------- 1 file changed, 13 insertions(+), 112 deletions(-) diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 30fd748..0c5a27e 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -4,7 +4,6 @@ set -eo pipefail gpg_private_key=/var/www/passbolt/config/gpg/serverkey.private.asc gpg_public_key=/var/www/passbolt/config/gpg/serverkey.asc -gpg=$(which gpg) core_config='/var/www/passbolt/app/Config/core.php' db_config='/var/www/passbolt/app/Config/database.php' @@ -14,7 +13,7 @@ ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' gpg_gen_key() { - $gpg --batch --gen-key < $gpg_private_key - $gpg --armor --export $KEY_EMAIL > $gpg_public_key - gpg_auto_fingerprint=`$gpg --fingerprint $KEY_EMAIL | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}'` + gpg --armor --export-secret-keys "$KEY_EMAIL" > "$gpg_private_key" + gpg --armor --export "$KEY_EMAIL" > "$gpg_public_key" + gpg_auto_fingerprint=$(gpg --fingerprint "$KEY_EMAIL" | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}') } gpg_import_key() { - local key_id=$(su -m -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/bash nginx) - - su -m -c "$gpg --batch --import $gpg_public_key" -ls /bin/bash nginx - su -m -c "gpg -K $key_id" -ls /bin/bash nginx || su -m -c "$gpg --batch --import $gpg_private_key" -ls /bin/bash nginx -} - -core_setup() { - #Env vars: - # SALT - # CIPHERSEED - # URL - - local default_salt='DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi' - local default_seed='76859309657453542496749683645' - local default_url='passbolt.local' - - cp $core_config{.default,} - sed -i s:$default_salt:${SALT:-$default_salt}:g $core_config - sed -i s:$default_seed:${CIPHERSEED:-$default_seed}:g $core_config - sed -i "/example.com/ s:\/\/::" $core_config - sed -i s:example.com:${URL:-$default_url}:g $core_config - if [ "$ssl" != false ]; then - sed -i s:http:https:g $core_config - fi -} - -db_setup() { - #Env vars: - # DB_HOST - # DB_USER - # DB_PASS - # DB_NAME - - local default_host='localhost' - local default_user='user' - local default_pass='password' - local default_db='database_name' - - cp $db_config{.default,} - sed -i "/$default_host/a\ \t\t'port' => '${DB_PORT:-3306}'," $db_config - sed -i s:$default_host:${DB_HOST:-db}:g $db_config - sed -i s:$default_user:${DB_USER:-passbolt}:g $db_config - sed -i s:$default_pass\',:${DB_PASS:-P4ssb0lt}\',:g $db_config - sed -i s:$default_db:${DB_NAME:-passbolt}:g $db_config -} - -app_setup() { - #Env vars: - # FINGERPRINT - # REGISTRATION - # SSL - - local default_public_key='unsecure.key' - local default_private_key='unsecure_private.key' - local default_fingerprint='2FC8945833C51946E937F9FED47B0811573EE67E' - - cp $app_config{.default,} - sed -i s:$default_public_key:serverkey.asc:g $app_config - sed -i s:$default_private_key:serverkey.private.asc:g $app_config - sed -i s:$default_fingerprint:${FINGERPRINT:-$gpg_auto_fingerprint}:g $app_config - sed -i "/force/ s:true:${SSL:-true}:" $app_config - sed -i "/'registration'/{n; s:false:${REGISTRATION:-false}:}" $app_config -} - -email_setup() { - #Env vars: - # EMAIL_TRANSPORT - # EMAIL_FROM - # EMAIL_HOST - # EMAIL_PORT - # EMAIL_TIMEOUT - # EMAIL_USERNAME - # EMAIL_PASSWORD - # EMAIL_TLS - - local default_transport='Smtp' - local default_from='contact@passbolt.com' - local default_host='smtp.mandrillapp.com' - local default_port='587' - local default_timeout='30' - local default_username="''" - local default_password="''" - - cp $email_config{.default,} - sed -i s:$default_transport:${EMAIL_TRANSPORT:-Smtp}:g $email_config - sed -i s:$default_from:${EMAIL_FROM:-contact@mydomain.local}:g $email_config - sed -i s:$default_host:${EMAIL_HOST:-localhost}:g $email_config - sed -i s:$default_port:${EMAIL_PORT:-587}:g $email_config - sed -i s:$default_timeout:${EMAIL_TIMEOUT:-30}:g $email_config - sed -i "0,/"$default_username"/s:"$default_username":'${EMAIL_USERNAME:-email_user}':" $email_config - sed -i "0,/"$default_password"/s:"$default_password":'${EMAIL_PASSWORD:-email_password}':" $email_config - sed -i "0,/tls/s:false:${EMAIL_TLS:-false}:" $email_config + local key_id="" + key_id=$(su -m -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/bash nginx) + su -m -c "gpg --batch --import $gpg_public_key" -ls /bin/bash nginx + su -m -c "gpg -K $key_id" -ls /bin/bash nginx || su -m -c "gpg --batch --import $gpg_private_key" -ls /bin/bash nginx } gen_ssl_cert() { @@ -133,25 +44,15 @@ gen_ssl_cert() { } install() { - local database_host=${DB_HOST:-$(cat $db_config | grep -m1 "'host'" | sed -r "s/\s*'host' => '(.*)',/\1/")} - local database_port=${DB_PORT:-$(cat $db_config | grep -m1 "'port' => '\d" | sed -r "s/\s*'port' => '(.*)',/\1/")} - local database_user=${DB_USER:-$(cat $db_config | grep -m1 "'login'" | sed -r "s/\s*'login' => '(.*)',/\1/")} - local database_pass=${DB_PASS:-$(cat $db_config | grep -m1 "'password'" | sed -r "s/\s*'password' => '(.*)',/\1/")} - local database_name=${DB_NAME:-$(cat $db_config | grep -m1 "'database'" | sed -r "s/\s*'database' => '(.*)',/\1/")} - tables=$(mysql -u ${database_user:-passbolt} -h $database_host -P $database_port -p -BN -e "SHOW TABLES FROM ${database_name:-passbolt}" -p${database_pass:-P4ssb0lt} |wc -l) + tables=$(mysql -u "$DATABASE_USER" -h "$DB_HOST" -P "$DB_HOST" -p -BN -e "SHOW TABLES FROM $DB_NAME" -p"$DB_PASS" |wc -l) - if [ $tables -eq 0 ]; then + if [ "$tables" -eq 0 ]; then su -c "/var/www/passbolt/app/Console/cake install --send-anonymous-statistics true --no-admin" -ls /bin/bash nginx else echo "Enjoy! ☮" fi } -php_fpm_setup() { - sed -i '/^user\s/ s:nobody:nginx:g' /etc/php7/php-fpm.d/www.conf - sed -i '/^group\s/ s:nobody:nginx:g' /etc/php7/php-fpm.d/www.conf -} - email_cron_job() { local root_crontab='/etc/crontabs/root' local cron_task_dir='/etc/periodic/1min' @@ -172,9 +73,9 @@ email_cron_job() { if [ ! -f $gpg_private_key ] && [ ! -L $gpg_private_key ] || \ [ ! -f $gpg_public_key ] && [ ! -L $gpg_public_key ]; then echo 'not yet implemented' - #su -c "gpg --list-keys" -ls /bin/bash nginx - #gpg_gen_key - #gpg_import_key + su -c "gpg --list-keys" -ls /bin/bash nginx + gpg_gen_key + gpg_import_key else echo 'not yet implemented' #gpg_import_key From 389b957f2f6b580642483057c9e35caf6f2779d5 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 4 Jan 2018 22:28:36 +0100 Subject: [PATCH 08/32] removed references to core and email --- bin/docker-entrypoint.sh | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 0c5a27e..85a4beb 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -5,10 +5,7 @@ set -eo pipefail gpg_private_key=/var/www/passbolt/config/gpg/serverkey.private.asc gpg_public_key=/var/www/passbolt/config/gpg/serverkey.asc -core_config='/var/www/passbolt/app/Config/core.php' -db_config='/var/www/passbolt/app/Config/database.php' app_config='/var/www/passbolt/app/Config/app.php' -email_config='/var/www/passbolt/app/Config/email.php' ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' @@ -72,33 +69,15 @@ email_cron_job() { if [ ! -f $gpg_private_key ] && [ ! -L $gpg_private_key ] || \ [ ! -f $gpg_public_key ] && [ ! -L $gpg_public_key ]; then - echo 'not yet implemented' su -c "gpg --list-keys" -ls /bin/bash nginx gpg_gen_key gpg_import_key else - echo 'not yet implemented' - #gpg_import_key -fi - -if [ ! -f $core_config ] && [ ! -L $core_config ]; then - echo 'not yet implemented' - #core_setup -fi - -if [ ! -f $db_config ] && [ ! -L $db_config ]; then - echo 'not yet implemented' - #db_setup + gpg_import_key fi if [ ! -f $app_config ] && [ ! -L $app_config ]; then - echo 'not yet implemented' - #app_setup -fi - -if [ ! -f $email_config ] && [ ! -L $email_config ]; then - echo 'not yet implemented' - #email_setup + app_setup fi if [ ! -f $ssl_key ] && [ ! -L $ssl_key ] && \ @@ -106,14 +85,6 @@ if [ ! -f $ssl_key ] && [ ! -L $ssl_key ] && \ gen_ssl_cert fi -php_fpm_setup +install -# not yet implemented -#install - -php-fpm7 - -nginx -g "pid /tmp/nginx.pid; daemon off;" - -# not yet implemented -#email_cron_job +email_cron_job From 5c0b52d249f87bda34a11bb4f4b7f02a46ccb8ad Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 8 Jan 2018 09:20:41 +0100 Subject: [PATCH 09/32] added supervisor, depdencies reorg and directory structure --- Dockerfile | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7001773..3d8aa26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM php:7-fpm-alpine +FROM php:7-fpm-alpine3.7 LABEL MAINTAINER diego@passbolt.com @@ -7,7 +7,6 @@ ENV PASSBOLT_URL https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VE ARG PHP_EXTENSIONS="gd \ intl \ - mcrypt \ xsl" ARG PHP_GNUPG_BUILD_DEPS="php7-dev \ @@ -20,31 +19,37 @@ ARG PHP_GNUPG_BUILD_DEPS="php7-dev \ gpgme-dev \ autoconf \ zlib-dev \ + libmcrypt-dev \ file" -RUN apk add --no-cache $PHP_EXTENSIONS \ - $PHP_GNUPG_BUILD_DEPS \ +RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ sed \ + bash \ nginx \ gpgme \ gnupg1 \ - mysql-client - -RUN apk add --no-cache $PHP_GNUPG_DEPS \ - && pecl install gnupg \ - && echo "extension=gnupg.so" > /etc/php7/conf.d/gnupg.ini \ - && apk del $PHP_GNUPG_DEPS \ + mysql-client \ + libpng-dev \ + icu-dev \ + libxslt-dev \ + libmcrypt-dev \ + supervisor \ + && pecl install gnupg redis mcrypt-snapshot \ + && docker-php-ext-install -j4 $PHP_EXTENSIONS \ + && docker-php-ext-enable $PHP_EXTENSIONS gnupg redis mcrypt \ + && apk del $PHP_GNUPG_BUILD_DEPS \ && curl -sS https://getcomposer.org/installer | php \ && mv composer.phar /usr/local/bin/composer RUN mkdir /var/www/passbolt \ && curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ && chown -R nginx:nginx /var/www/passbolt \ - && chmod -R a-w /var/www/passbolt \ - && chmod -R +w /var/www/passbolt/app/tmp \ - && chmod -R +w /var/www/passbolt/app/webroot/img/public + && chmod -R o-w /var/www/passbolt \ + && chmod -R +w /var/www/passbolt/tmp \ + && chmod -R +w /var/www/passbolt/webroot/img/public COPY conf/passbolt.conf /etc/nginx/conf.d/default.conf +COPY conf/supervisord.conf /etc/supervisord.conf COPY bin/docker-entrypoint.sh /docker-entrypoint.sh EXPOSE 80 443 From 1c2d6b343e347ee9167c6454fe6ae28b965e2765 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 8 Jan 2018 09:30:52 +0100 Subject: [PATCH 10/32] dependencies reorg --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3d8aa26..b01276d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,6 @@ ARG PHP_GNUPG_BUILD_DEPS="php7-dev \ gpgme-dev \ autoconf \ zlib-dev \ - libmcrypt-dev \ file" RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ From e64319dbbb2f584852aaf137305f68c66e769c10 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 8 Jan 2018 09:53:52 +0100 Subject: [PATCH 11/32] base checks on conf and filesystem passing --- Dockerfile | 7 ++-- bin/docker-entrypoint.sh | 60 ++++++++++++++-------------- spec/passbolt_api/Dockerfile_spec.rb | 43 ++++++++++++-------- 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/Dockerfile b/Dockerfile index b01276d..0ea71f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,9 +40,10 @@ RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ && curl -sS https://getcomposer.org/installer | php \ && mv composer.phar /usr/local/bin/composer -RUN mkdir /var/www/passbolt \ - && curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ - && chown -R nginx:nginx /var/www/passbolt \ +COPY src/passbolt_api/ /var/www/passbolt/ + +# && curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ +RUN chown -R nginx:nginx /var/www/passbolt \ && chmod -R o-w /var/www/passbolt \ && chmod -R +w /var/www/passbolt/tmp \ && chmod -R +w /var/www/passbolt/webroot/img/public diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 85a4beb..f55d543 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -2,34 +2,38 @@ set -eo pipefail -gpg_private_key=/var/www/passbolt/config/gpg/serverkey.private.asc -gpg_public_key=/var/www/passbolt/config/gpg/serverkey.asc - -app_config='/var/www/passbolt/app/Config/app.php' +base_path='/var/www/passbolt' +gpg_private_key="$base_path/config/gpg/serverkey.private.asc" +gpg_public_key="$base_path/config/gpg/serverkey.asc" +app_config="$base_path/config/app.php" ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' gpg_gen_key() { - gpg --batch --gen-key < "$gpg_private_key" - gpg --armor --export "$KEY_EMAIL" > "$gpg_public_key" - gpg_auto_fingerprint=$(gpg --fingerprint "$KEY_EMAIL" | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}') + su -m -c "gpg --batch --gen-key < $gpg_private_key" -ls /bin/bash nginx + su -m -c "gpg --armor --export $key_email > $gpg_public_key" -ls /bin/bash nginx } gpg_import_key() { local key_id="" key_id=$(su -m -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/bash nginx) - su -m -c "gpg --batch --import $gpg_public_key" -ls /bin/bash nginx su -m -c "gpg -K $key_id" -ls /bin/bash nginx || su -m -c "gpg --batch --import $gpg_private_key" -ls /bin/bash nginx } @@ -41,10 +45,12 @@ gen_ssl_cert() { } install() { - tables=$(mysql -u "$DATABASE_USER" -h "$DB_HOST" -P "$DB_HOST" -p -BN -e "SHOW TABLES FROM $DB_NAME" -p"$DB_PASS" |wc -l) - + if [ ! -f $app_config ] && [ ! -L $app_config ]; then + cp $base_path/config/app.default.php $app_config + fi + tables=$(mysql -u "$DATABASE_USER" -h "$DB_HOST" -P "$DB_PORT" -p -BN -e "SHOW TABLES FROM $DB_NAME" -p"$DB_PASS" |wc -l) if [ "$tables" -eq 0 ]; then - su -c "/var/www/passbolt/app/Console/cake install --send-anonymous-statistics true --no-admin" -ls /bin/bash nginx + su -c "/var/www/passbolt/bin/cake passbolt install --no-admin" -ls /bin/bash nginx else echo "Enjoy! ☮" fi @@ -57,34 +63,26 @@ email_cron_job() { local process_email="/var/www/passbolt/app/Console/cake EmailQueue.sender --quiet" mkdir -p $cron_task_dir - echo "* * * * * run-parts $cron_task_dir" >> $root_crontab echo "#!/bin/sh" > $cron_task chmod +x $cron_task echo "su -c \"$process_email\" -ls /bin/bash nginx" >> $cron_task - - crond -f -c /etc/crontabs } - if [ ! -f $gpg_private_key ] && [ ! -L $gpg_private_key ] || \ [ ! -f $gpg_public_key ] && [ ! -L $gpg_public_key ]; then - su -c "gpg --list-keys" -ls /bin/bash nginx gpg_gen_key gpg_import_key else gpg_import_key fi -if [ ! -f $app_config ] && [ ! -L $app_config ]; then - app_setup -fi - if [ ! -f $ssl_key ] && [ ! -L $ssl_key ] && \ [ ! -f $ssl_cert ] && [ ! -L $ssl_cert ]; then gen_ssl_cert fi +#gpg_auto_fingerprint=$(gpg --fingerprint "$key_email" | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}') install - email_cron_job +/usr/bin/supervisord -n -c /etc/supervisord.conf diff --git a/spec/passbolt_api/Dockerfile_spec.rb b/spec/passbolt_api/Dockerfile_spec.rb index 660f8de..58b859a 100644 --- a/spec/passbolt_api/Dockerfile_spec.rb +++ b/spec/passbolt_api/Dockerfile_spec.rb @@ -3,24 +3,33 @@ require 'spec_helper' describe 'passbolt_api service' do before(:all) do + mysql = Docker::Container.create( + 'Env' => [ + 'MYSQL_DATABASE=passbolt', + 'MYSQL_USER=passbolt', + 'MYSQL_PASSWORD=P4ssb0lt' + ], + 'Image' => 'mysql') + mysql.start + image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) set :docker_image, image.id - set :env, { 'DB_HOST' => '172.17.0.2' } -end + set :env, { 'DB_HOST' => mysql.json['NetworkSettings']['IPAddress'] } + end - let(:global_conf) { '/etc/nginx/nginx.conf' } + let(:nginx_conf) { '/etc/nginx/nginx.conf' } let(:site_conf) { '/etc/nginx/conf.d/default.conf' } let(:passbolt_home) { '/var/www/passbolt' } - let(:passbolt_tmp) { '/var/www/passbolt/app/tmp' } - let(:passbolt_image) { '/var/www/passbolt/app/webroot/img/public' } - let(:passbolt_owner) { 'www-data' } + let(:passbolt_tmp) { '/var/www/passbolt/tmp' } + let(:passbolt_image) { '/var/www/passbolt/webroot/img/public' } + let(:passbolt_owner) { 'nginx' } - describe "passbolt required php extension" do + describe "passbolt required php extensions" do php_extensions = [ 'curl', 'gd', 'intl', 'json', 'mcrypt', 'mysqlnd', 'xsl', 'phar', - 'posix', 'xml', 'xsl', 'zlib', 'ctype', 'pdo', 'pdo_mysql', 'gnupg' + 'posix', 'xml', 'xsl', 'zlib', 'ctype', 'pdo', 'gnupg' ] php_extensions.each do |ext| @@ -31,7 +40,7 @@ end end describe 'supervisor' do - it 'is installed' do + xit 'is installed' do expect(package('supervisor')).to be_installed end end @@ -48,13 +57,13 @@ end end end - describe 'global configuration' do + describe 'nginx configuration' do it 'is installed correctly' do - expect(file(global_conf)).to exist + expect(file(nginx_conf)).to exist end it 'has the correct permissions' do - expect(file(global_conf)).to be_owned_by 'root' + expect(file(nginx_conf)).to be_owned_by 'root' end end @@ -69,27 +78,27 @@ end end describe 'php service' do - it 'is running supervised' do + xit 'is running supervised' do expect(service('php-fpm')).to be_running.under('supervisor') end end describe port(9000) do - it { is_expected.to be_listening.with('tcp') } + xit { is_expected.to be_listening.with('tcp') } end describe 'email cron' do - it 'is running supervised' do + xit 'is running supervised' do expect(service('crond')).to be_running.under('supervisor') end end describe 'web service' do - it 'is running supervised' do + xit 'is running supervised' do expect(service('nginx')).to be_running.under('supervisor') end - it 'is listening on port 80' do + xit 'is listening on port 80' do expect(port(80)).to be_listening.with('tcp') end end From 14859f14fc7ce415cd95cc6f1dd5a848cdf4e7bb Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 8 Jan 2018 10:37:18 +0100 Subject: [PATCH 12/32] mysql as instance variable --- spec/passbolt_api/Dockerfile_spec.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/spec/passbolt_api/Dockerfile_spec.rb b/spec/passbolt_api/Dockerfile_spec.rb index 58b859a..3c3503b 100644 --- a/spec/passbolt_api/Dockerfile_spec.rb +++ b/spec/passbolt_api/Dockerfile_spec.rb @@ -3,19 +3,24 @@ require 'spec_helper' describe 'passbolt_api service' do before(:all) do - mysql = Docker::Container.create( + @mysql = Docker::Container.create( 'Env' => [ + 'MYSQL_ROOT_PASSWORD=test', 'MYSQL_DATABASE=passbolt', 'MYSQL_USER=passbolt', 'MYSQL_PASSWORD=P4ssb0lt' ], 'Image' => 'mysql') - mysql.start + @mysql.start image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) set :docker_image, image.id - set :env, { 'DB_HOST' => mysql.json['NetworkSettings']['IPAddress'] } + set :env, { 'DB_HOST' => @mysql.json['NetworkSettings']['IPAddress'] } + end + + after(:all) do + @mysql.kill end let(:nginx_conf) { '/etc/nginx/nginx.conf' } From f94ecbbfca8010beea25c1b8c8bf430d0c2ccaee Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 11 Jan 2018 10:01:19 +0100 Subject: [PATCH 13/32] added gemfiles --- Gemfile | 13 ++++++++----- Gemfile.lock | 6 ++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 9bd3773..6a6978f 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,10 @@ source 'https://rubygems.org' -gem 'serverspec' -gem 'docker-api' -gem 'rake' - -gem 'pry' +group :test do + gem 'docker-api' + gem 'rake' + gem 'serverspec' + gem 'rspec-wait' + gem 'rspec-retry' + gem 'pry' +end diff --git a/Gemfile.lock b/Gemfile.lock index 49219f5..b6f312f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -32,7 +32,11 @@ GEM rspec-mocks (3.7.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) + rspec-retry (0.5.6) + rspec-core (> 3.3, < 3.8) rspec-support (3.7.0) + rspec-wait (0.0.9) + rspec (>= 3, < 4) serverspec (2.41.3) multi_json rspec (~> 3.0) @@ -52,6 +56,8 @@ DEPENDENCIES docker-api pry rake + rspec-retry + rspec-wait serverspec BUNDLED WITH From 768f69889bb70c7581afa8985eda1d837c5d095d Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 11 Jan 2018 10:02:45 +0100 Subject: [PATCH 14/32] initial Dockerfile tests --- Dockerfile | 8 +- bin/docker-entrypoint.sh | 67 +++++++++------- conf/supervisord.conf | 36 +++++++++ spec/docker_image/Dockerfile_spec.rb | 93 ++++++++++++++++++++++ spec/passbolt_api/Dockerfile_spec.rb | 111 --------------------------- 5 files changed, 175 insertions(+), 140 deletions(-) create mode 100644 conf/supervisord.conf create mode 100644 spec/docker_image/Dockerfile_spec.rb delete mode 100644 spec/passbolt_api/Dockerfile_spec.rb diff --git a/Dockerfile b/Dockerfile index 0ea71f5..5864d1e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ ENV PASSBOLT_URL https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VE ARG PHP_EXTENSIONS="gd \ intl \ + pdo_mysql \ xsl" ARG PHP_GNUPG_BUILD_DEPS="php7-dev \ @@ -22,8 +23,6 @@ ARG PHP_GNUPG_BUILD_DEPS="php7-dev \ file" RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ - sed \ - bash \ nginx \ gpgme \ gnupg1 \ @@ -43,7 +42,10 @@ RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ COPY src/passbolt_api/ /var/www/passbolt/ # && curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ -RUN chown -R nginx:nginx /var/www/passbolt \ +RUN cd /var/www/passbolt \ + && composer global require hirak/prestissimo \ + && composer install \ + && chown -R nginx:nginx /var/www/passbolt \ && chmod -R o-w /var/www/passbolt \ && chmod -R +w /var/www/passbolt/tmp \ && chmod -R +w /var/www/passbolt/webroot/img/public diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index f55d543..4a1556f 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -1,20 +1,19 @@ -#!/bin/bash +#!/usr/bin/env sh set -eo pipefail base_path='/var/www/passbolt' -gpg_private_key="$base_path/config/gpg/serverkey.private.asc" +gpg_private_key="$base_path/config/gpg/serverkey_private.asc" gpg_public_key="$base_path/config/gpg/serverkey.asc" -app_config="$base_path/config/app.php" ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' gpg_gen_key() { - local key_email="${KEY_EMAIL:-passbolt@yourdomain.com}" - local key_name="${KEY_NAME:-Passbolt default user}" - local key_length="${KEY_LENGTH:-4096}" - local subkey_length="${SUBKEY_LENGTH:-4096}" - local expiration="${KEY_EXPIRATION:-0}" + key_email="${KEY_EMAIL:-passbolt@yourdomain.com}" + key_name="${KEY_NAME:-Passbolt default user}" + key_length="${KEY_LENGTH:-2048}" + subkey_length="${SUBKEY_LENGTH:-2048}" + expiration="${KEY_EXPIRATION:-0}" su -m -c "gpg --batch --gen-key < $gpg_private_key" -ls /bin/bash nginx - su -m -c "gpg --armor --export $key_email > $gpg_public_key" -ls /bin/bash nginx + su -m -c "gpg --armor --export-secret-keys $key_email > $gpg_private_key" -ls /bin/sh nginx + su -m -c "gpg --armor --export $key_email > $gpg_public_key" -ls /bin/sh nginx } gpg_import_key() { - local key_id="" - key_id=$(su -m -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/bash nginx) - su -m -c "gpg --batch --import $gpg_public_key" -ls /bin/bash nginx - su -m -c "gpg -K $key_id" -ls /bin/bash nginx || su -m -c "gpg --batch --import $gpg_private_key" -ls /bin/bash nginx + key_id="" + key_id=$(su -m -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/sh nginx) + su -m -c "gpg --batch --import $gpg_public_key" -ls /bin/sh nginx + su -m -c "gpg -K $key_id" -ls /bin/sh nginx || su -m -c "gpg --batch --import $gpg_private_key" -ls /bin/sh nginx } gen_ssl_cert() { @@ -45,30 +44,44 @@ gen_ssl_cert() { } install() { - if [ ! -f $app_config ] && [ ! -L $app_config ]; then - cp $base_path/config/app.default.php $app_config - fi - tables=$(mysql -u "$DATABASE_USER" -h "$DB_HOST" -P "$DB_PORT" -p -BN -e "SHOW TABLES FROM $DB_NAME" -p"$DB_PASS" |wc -l) + tables="" + tables=$(mysql \ + -u "$DATASOURCES_DEFAULT_USERNAME" \ + -h "$DATASOURCES_DEFAULT_HOST" \ + -P "$DATASOURCES_DEFAULT_PORT" \ + -BN -e "SHOW TABLES FROM $DATASOURCES_DEFAULT_DATABASE" \ + -p"$DATASOURCES_DEFAULT_PASSWORD" |wc -l) + if [ "$tables" -eq 0 ]; then - su -c "/var/www/passbolt/bin/cake passbolt install --no-admin" -ls /bin/bash nginx + su -c "cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php" -s /bin/sh nginx + su -m -c "PATH=$PATH:/usr/local/bin /var/www/passbolt/bin/cake passbolt install --no-admin --force" -s /bin/sh nginx else echo "Enjoy! ☮" fi } email_cron_job() { - local root_crontab='/etc/crontabs/root' - local cron_task_dir='/etc/periodic/1min' - local cron_task='/etc/periodic/1min/email_queue_processing' - local process_email="/var/www/passbolt/app/Console/cake EmailQueue.sender --quiet" + root_crontab='/etc/crontabs/root' + cron_task_dir='/etc/periodic/1min' + cron_task='/etc/periodic/1min/email_queue_processing' + process_email="PATH=$PATH:/usr/local/bin /var/www/passbolt/app/Console/cake EmailQueue.sender --quiet" mkdir -p $cron_task_dir echo "* * * * * run-parts $cron_task_dir" >> $root_crontab echo "#!/bin/sh" > $cron_task chmod +x $cron_task - echo "su -c \"$process_email\" -ls /bin/bash nginx" >> $cron_task + echo "su -c \"$process_email\" -s /bin/sh nginx" >> $cron_task } +if [ -z "$DATASOURCES_DEFAULT_HOST" ] \ + && [ -z "$DATASOURCES_DEFAULT_USERNAME" ] \ + && [ -z "$DATASOURCES_DEFAULT_PASSWORD" ] \ + && [ -z "$DATASOURCES_DEFAULT_DATABASE" ]; then + echo >&2 'Error: database credentials not provided' + echo >&2 'You must provide database details: hostname, username and password' + exit 1 +fi + if [ ! -f $gpg_private_key ] && [ ! -L $gpg_private_key ] || \ [ ! -f $gpg_public_key ] && [ ! -L $gpg_public_key ]; then gpg_gen_key @@ -82,7 +95,9 @@ if [ ! -f $ssl_key ] && [ ! -L $ssl_key ] && \ gen_ssl_cert fi -#gpg_auto_fingerprint=$(gpg --fingerprint "$key_email" | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}') +gpg_auto_fingerprint=$(su -m -c "gpg --with-fingerprint $gpg_public_key | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}'" -ls /bin/sh nginx) +export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint install email_cron_job + /usr/bin/supervisord -n -c /etc/supervisord.conf diff --git a/conf/supervisord.conf b/conf/supervisord.conf new file mode 100644 index 0000000..9cd1f5a --- /dev/null +++ b/conf/supervisord.conf @@ -0,0 +1,36 @@ +[unix_http_server] +file=/tmp/supervisor.sock ; (the path to the socket file) + +[supervisord] +logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log) +logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) +logfile_backups=10 ; (num of main logfile rotation backups;default 10) +loglevel=info ; (log level;default info; others: debug,warn,trace) +pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +nodaemon=false ; (start in foreground if true;default false) +minfds=1024 ; (min. avail startup file descriptors;default 1024) +minprocs=200 ; (min. avail process descriptors;default 200) + +; the below section must remain in the config file for RPC +; (supervisorctl/web interface) to work, additional interfaces may be +; added by defining them in separate rpcinterface: sections +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket + +[program:php-fpm] +command=php-fpm +autostart=true +priority=5 + +[program:nginx] +command=nginx -g "pid /tmp/nginx.pid; daemon off;" +autostart=true +priority=10 + +[program:crond] +command=crond -f -c /etc/crontabs +autostart=true +priority=20 diff --git a/spec/docker_image/Dockerfile_spec.rb b/spec/docker_image/Dockerfile_spec.rb new file mode 100644 index 0000000..387295d --- /dev/null +++ b/spec/docker_image/Dockerfile_spec.rb @@ -0,0 +1,93 @@ +require 'spec_helper' + +describe 'Dockerfile' do + + before(:all) do + set :env, { + 'DATASOURCES_DEFAULT_HOST' => '172.17.0.2', + 'DATASOURCES_DEFAULT_PASSWORD' => 'P4ssb0lt', + 'DATASOURCES_DEFAULT_USERNAME' => 'passbolt', + 'DATASOURCES_DEFAULT_DATABASE' => 'passbolt', + 'PASSBOLT_GPG_KEYRING' => '/var/lib/nginx/.gnupg' + } + + @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) + set :docker_image, @image.id + set :docker_container_create_options, { 'Cmd' => '/bin/sh' } + end + + let(:nginx_conf) { '/etc/nginx/nginx.conf' } + let(:site_conf) { '/etc/nginx/conf.d/default.conf' } + let(:passbolt_home) { '/var/www/passbolt' } + let(:passbolt_tmp) { '/var/www/passbolt/tmp' } + let(:passbolt_image) { '/var/www/passbolt/webroot/img/public' } + let(:passbolt_owner) { 'nginx' } + let(:exposed_ports) { [ '80', '443' ] } + let(:composer) { '/usr/local/bin/composer'} + let(:php_extensions) { [ + 'curl', 'gd', 'intl', 'json', 'mcrypt', 'mysqlnd', 'xsl', 'phar', + 'posix', 'xml', 'xsl', 'zlib', 'ctype', 'pdo', 'gnupg', 'pdo_mysql' + ] } + + describe 'passbolt required php extensions' do + it 'has php extensions installed' do + php_extensions.each do |ext| + expect(command("php --ri #{ext}").exit_status).to eq 0 + end + end + end + + describe 'php composer' do + it 'is installed' do + expect(file(composer)).to be_executable + end + end + + describe 'supervisor' do + it 'is installed' do + expect(package('supervisor')).to be_installed + end + end + + describe 'passbolt directory structure' do + it 'must exist and be directories' do + expect(file(passbolt_home)).to be_a_directory + expect(file(passbolt_tmp)).to be_a_directory + expect(file(passbolt_image)).to be_a_directory + end + + it 'must be owned by correct user' do + expect(file(passbolt_home)).to be_owned_by(passbolt_owner) + expect(file(passbolt_tmp)).to be_owned_by(passbolt_owner) + expect(file(passbolt_image)).to be_owned_by(passbolt_owner) + end + end + + describe 'nginx configuration' do + it 'is installed correctly' do + expect(file(nginx_conf)).to exist + end + + it 'has the correct permissions' do + expect(file(nginx_conf)).to be_owned_by 'root' + end + end + + describe 'nginx site configuration' do + it 'is installed correctly' do + expect(file(site_conf)).to exist + end + + it 'has the correct permissions' do + expect(file(site_conf)).to be_owned_by 'root' + end + end + + describe 'ports exposed' do + it 'exposes port' do + exposed_ports.each do |port| + expect(@image.json['ContainerConfig']['ExposedPorts']).to include("#{port}/tcp") + end + end + end +end diff --git a/spec/passbolt_api/Dockerfile_spec.rb b/spec/passbolt_api/Dockerfile_spec.rb deleted file mode 100644 index 3c3503b..0000000 --- a/spec/passbolt_api/Dockerfile_spec.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'spec_helper' - -describe 'passbolt_api service' do - - before(:all) do - @mysql = Docker::Container.create( - 'Env' => [ - 'MYSQL_ROOT_PASSWORD=test', - 'MYSQL_DATABASE=passbolt', - 'MYSQL_USER=passbolt', - 'MYSQL_PASSWORD=P4ssb0lt' - ], - 'Image' => 'mysql') - @mysql.start - - image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) - - set :docker_image, image.id - set :env, { 'DB_HOST' => @mysql.json['NetworkSettings']['IPAddress'] } - end - - after(:all) do - @mysql.kill - end - - let(:nginx_conf) { '/etc/nginx/nginx.conf' } - let(:site_conf) { '/etc/nginx/conf.d/default.conf' } - let(:passbolt_home) { '/var/www/passbolt' } - let(:passbolt_tmp) { '/var/www/passbolt/tmp' } - let(:passbolt_image) { '/var/www/passbolt/webroot/img/public' } - let(:passbolt_owner) { 'nginx' } - - describe "passbolt required php extensions" do - - php_extensions = [ - 'curl', 'gd', 'intl', 'json', 'mcrypt', 'mysqlnd', 'xsl', 'phar', - 'posix', 'xml', 'xsl', 'zlib', 'ctype', 'pdo', 'gnupg' - ] - - php_extensions.each do |ext| - it "#{ext} must be installed" do - expect(command("php --ri #{ext}").exit_status).to eq 0 - end - end - end - - describe 'supervisor' do - xit 'is installed' do - expect(package('supervisor')).to be_installed - end - end - - describe 'passbolt home dirs' do - it 'must exist and be directories' do - expect(file(passbolt_home)).to be_a_directory - expect(file(passbolt_tmp)).to be_a_directory - expect(file(passbolt_image)).to be_a_directory - end - - it 'must be owned by correct user' do - expect(file(passbolt_home)).to be_owned_by(passbolt_owner) - end - end - - describe 'nginx configuration' do - it 'is installed correctly' do - expect(file(nginx_conf)).to exist - end - - it 'has the correct permissions' do - expect(file(nginx_conf)).to be_owned_by 'root' - end - end - - describe 'site configuration' do - it 'is installed correctly' do - expect(file(site_conf)).to exist - end - - it 'has the correct permissions' do - expect(file(site_conf)).to be_owned_by 'root' - end - end - - describe 'php service' do - xit 'is running supervised' do - expect(service('php-fpm')).to be_running.under('supervisor') - end - end - - describe port(9000) do - xit { is_expected.to be_listening.with('tcp') } - end - - describe 'email cron' do - xit 'is running supervised' do - expect(service('crond')).to be_running.under('supervisor') - end - end - - describe 'web service' do - xit 'is running supervised' do - expect(service('nginx')).to be_running.under('supervisor') - end - - xit 'is listening on port 80' do - expect(port(80)).to be_listening.with('tcp') - end - end - -end From 7b82cdac55fc5708ac32cf8b5db649f4c91c3670 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 11 Jan 2018 10:57:04 +0100 Subject: [PATCH 15/32] spec name reorg --- spec/docker_image/{Dockerfile_spec.rb => image_spec.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spec/docker_image/{Dockerfile_spec.rb => image_spec.rb} (100%) diff --git a/spec/docker_image/Dockerfile_spec.rb b/spec/docker_image/image_spec.rb similarity index 100% rename from spec/docker_image/Dockerfile_spec.rb rename to spec/docker_image/image_spec.rb From 7547032ce74797e6251627ee0d6c9f694310a842 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 11 Jan 2018 18:08:49 +0100 Subject: [PATCH 16/32] initial runtime test passing --- Dockerfile | 12 +++-- bin/docker-entrypoint.sh | 20 +++---- spec/docker_image/image_spec.rb | 2 +- spec/docker_runtime/runtime_spec.rb | 82 +++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 16 deletions(-) create mode 100644 spec/docker_runtime/runtime_spec.rb diff --git a/Dockerfile b/Dockerfile index 5864d1e..54eb48b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM php:7-fpm-alpine3.7 LABEL MAINTAINER diego@passbolt.com -ENV PASSBOLT_VERSION 1.6.5 +ENV PASSBOLT_VERSION 2.0.0-rc1 ENV PASSBOLT_URL https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VERSION}.tar.gz ARG PHP_EXTENSIONS="gd \ @@ -32,6 +32,7 @@ RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ libxslt-dev \ libmcrypt-dev \ supervisor \ + git \ && pecl install gnupg redis mcrypt-snapshot \ && docker-php-ext-install -j4 $PHP_EXTENSIONS \ && docker-php-ext-enable $PHP_EXTENSIONS gnupg redis mcrypt \ @@ -45,10 +46,11 @@ COPY src/passbolt_api/ /var/www/passbolt/ RUN cd /var/www/passbolt \ && composer global require hirak/prestissimo \ && composer install \ - && chown -R nginx:nginx /var/www/passbolt \ - && chmod -R o-w /var/www/passbolt \ - && chmod -R +w /var/www/passbolt/tmp \ - && chmod -R +w /var/www/passbolt/webroot/img/public + && chown -R www-data:www-data /var/www/passbolt \ + && chmod 775 $(find /var/www/passbolt/tmp -type f) \ + && chmod 664 $(find /var/www/passbolt/tmp -type d) \ + && chmod 775 $(find /var/www/passbolt/webroot/img/public -type f) \ + && chmod 664 $(find /var/www/passbolt/webroot/img/public -type d) COPY conf/passbolt.conf /etc/nginx/conf.d/default.conf COPY conf/supervisord.conf /etc/supervisord.conf diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 4a1556f..805e360 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -24,17 +24,17 @@ gpg_gen_key() { Name-Email: $key_email Expire-Date: $expiration %commit -EOF" -ls /bin/sh nginx +EOF" -ls /bin/sh www-data - su -m -c "gpg --armor --export-secret-keys $key_email > $gpg_private_key" -ls /bin/sh nginx - su -m -c "gpg --armor --export $key_email > $gpg_public_key" -ls /bin/sh nginx + su -c "gpg --armor --export-secret-keys $key_email > $gpg_private_key" -ls /bin/sh www-data + su -c "gpg --armor --export $key_email > $gpg_public_key" -ls /bin/sh www-data } gpg_import_key() { key_id="" - key_id=$(su -m -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/sh nginx) - su -m -c "gpg --batch --import $gpg_public_key" -ls /bin/sh nginx - su -m -c "gpg -K $key_id" -ls /bin/sh nginx || su -m -c "gpg --batch --import $gpg_private_key" -ls /bin/sh nginx + key_id=$(su -m -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/sh www-data) + su -c "gpg --batch --import $gpg_public_key" -ls /bin/sh www-data + su -c "gpg -K $key_id" -ls /bin/sh www-data || su -m -c "gpg --batch --import $gpg_private_key" -ls /bin/sh www-data } gen_ssl_cert() { @@ -53,8 +53,8 @@ install() { -p"$DATASOURCES_DEFAULT_PASSWORD" |wc -l) if [ "$tables" -eq 0 ]; then - su -c "cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php" -s /bin/sh nginx - su -m -c "PATH=$PATH:/usr/local/bin /var/www/passbolt/bin/cake passbolt install --no-admin --force" -s /bin/sh nginx + su -c "cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php" -s /bin/sh www-data + su -c "PATH=$PATH:/usr/local/bin /var/www/passbolt/bin/cake passbolt install --no-admin --force" -s /bin/sh www-data else echo "Enjoy! ☮" fi @@ -70,7 +70,7 @@ email_cron_job() { echo "* * * * * run-parts $cron_task_dir" >> $root_crontab echo "#!/bin/sh" > $cron_task chmod +x $cron_task - echo "su -c \"$process_email\" -s /bin/sh nginx" >> $cron_task + echo "su -c \"$process_email\" -s /bin/sh www-data" >> $cron_task } if [ -z "$DATASOURCES_DEFAULT_HOST" ] \ @@ -95,7 +95,7 @@ if [ ! -f $ssl_key ] && [ ! -L $ssl_key ] && \ gen_ssl_cert fi -gpg_auto_fingerprint=$(su -m -c "gpg --with-fingerprint $gpg_public_key | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}'" -ls /bin/sh nginx) +gpg_auto_fingerprint=$(su -c "gpg --with-fingerprint $gpg_public_key | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}'" -ls /bin/sh www-data) export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint install email_cron_job diff --git a/spec/docker_image/image_spec.rb b/spec/docker_image/image_spec.rb index 387295d..97b4fd9 100644 --- a/spec/docker_image/image_spec.rb +++ b/spec/docker_image/image_spec.rb @@ -21,7 +21,7 @@ describe 'Dockerfile' do let(:passbolt_home) { '/var/www/passbolt' } let(:passbolt_tmp) { '/var/www/passbolt/tmp' } let(:passbolt_image) { '/var/www/passbolt/webroot/img/public' } - let(:passbolt_owner) { 'nginx' } + let(:passbolt_owner) { 'www-data' } let(:exposed_ports) { [ '80', '443' ] } let(:composer) { '/usr/local/bin/composer'} let(:php_extensions) { [ diff --git a/spec/docker_runtime/runtime_spec.rb b/spec/docker_runtime/runtime_spec.rb new file mode 100644 index 0000000..4021a4a --- /dev/null +++ b/spec/docker_runtime/runtime_spec.rb @@ -0,0 +1,82 @@ +require 'spec_helper' +require 'rspec/wait' + +describe 'passbolt_api service' do + + before(:all) do + @mysql = Docker::Container.create( + 'Env' => [ + 'MYSQL_ROOT_PASSWORD=test', + 'MYSQL_DATABASE=passbolt', + 'MYSQL_USER=passbolt', + 'MYSQL_PASSWORD=P4ssb0lt' + ], + "Healthcheck" => { + "Test": [ + "CMD-SHELL", + "mysqladmin ping --silent" + ] + }, + 'Image' => 'mysql') + @mysql.start + + while @mysql.json['State']['Health']['Status'] != 'healthy' + sleep 1 + end + + @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) + @container = Docker::Container.create( + 'Env' => [ + "DATASOURCES_DEFAULT_HOST=#{@mysql.json['NetworkSettings']['IPAddress']}", + 'DATASOURCES_DEFAULT_PASSWORD=P4ssb0lt', + 'DATASOURCES_DEFAULT_USERNAME=passbolt', + 'DATASOURCES_DEFAULT_DATABASE=passbolt', + #'DATASOURCES_DEFAULT_PORT=3306', + #'PASSBOLT_GPG_KEYRING=/var/lib/nginx/.gnupg', + #'PASSBOLT_GPG_SERVER_KEY_PUBLIC=/var/www/passbolt/config/gpg/serverkey.asc', + #'PASSBOLT_GPG_SERVER_KEY_PRIVATE=/var/www/passbolt/config/gpg/serverkey_private.asc' + ], + 'Image' => @image.id) + @container.start + @container.logs(stdout: true) + + set :docker_container, @container.id + sleep 17 + end + + after(:all) do + @mysql.kill + @container.kill + end + + describe 'php service' do + it 'is running supervised' do + expect(process('php-fpm')).to be_running.under('supervisor') + end + + it 'has its port open' do + expect(port(9000)).to be_listening.with('tcp') + end + end + + describe 'email cron' do + it 'is running supervised' do + expect(service('crond')).to be_running.under('supervisor') + end + end + + describe 'web service' do + it 'is running supervised' do + expect(service('nginx')).to be_running.under('supervisor') + end + + it 'is listening on port 80' do + expect(port(80)).to be_listening.with('tcp') + end + + it 'is listening on port 443' do + expect(port(443)).to be_listening.with('tcp') + end + end + +end From 8fa9490ccd2154e4d4cb55d4297515109c19abda Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Fri, 12 Jan 2018 09:33:28 +0100 Subject: [PATCH 17/32] healthcheck returns 200 status code --- Gemfile | 2 -- Gemfile.lock | 6 ------ spec/docker_runtime/runtime_spec.rb | 13 ++++++++----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index 6a6978f..cc5bf5e 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,5 @@ group :test do gem 'docker-api' gem 'rake' gem 'serverspec' - gem 'rspec-wait' - gem 'rspec-retry' gem 'pry' end diff --git a/Gemfile.lock b/Gemfile.lock index b6f312f..49219f5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -32,11 +32,7 @@ GEM rspec-mocks (3.7.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) - rspec-retry (0.5.6) - rspec-core (> 3.3, < 3.8) rspec-support (3.7.0) - rspec-wait (0.0.9) - rspec (>= 3, < 4) serverspec (2.41.3) multi_json rspec (~> 3.0) @@ -56,8 +52,6 @@ DEPENDENCIES docker-api pry rake - rspec-retry - rspec-wait serverspec BUNDLED WITH diff --git a/spec/docker_runtime/runtime_spec.rb b/spec/docker_runtime/runtime_spec.rb index 4021a4a..db8d37b 100644 --- a/spec/docker_runtime/runtime_spec.rb +++ b/spec/docker_runtime/runtime_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require 'rspec/wait' describe 'passbolt_api service' do @@ -31,10 +30,6 @@ describe 'passbolt_api service' do 'DATASOURCES_DEFAULT_PASSWORD=P4ssb0lt', 'DATASOURCES_DEFAULT_USERNAME=passbolt', 'DATASOURCES_DEFAULT_DATABASE=passbolt', - #'DATASOURCES_DEFAULT_PORT=3306', - #'PASSBOLT_GPG_KEYRING=/var/lib/nginx/.gnupg', - #'PASSBOLT_GPG_SERVER_KEY_PUBLIC=/var/www/passbolt/config/gpg/serverkey.asc', - #'PASSBOLT_GPG_SERVER_KEY_PRIVATE=/var/www/passbolt/config/gpg/serverkey_private.asc' ], 'Image' => @image.id) @container.start @@ -49,6 +44,9 @@ describe 'passbolt_api service' do @container.kill end + let(:http_path) { "/healthcheck/status.json" } + let(:healthcheck) { 'curl -s -o /dev/null -w "%{http_code}" http://localhost/healthcheck/status.json' } + describe 'php service' do it 'is running supervised' do expect(process('php-fpm')).to be_running.under('supervisor') @@ -79,4 +77,9 @@ describe 'passbolt_api service' do end end + describe 'passbolt healthcheck' do + it 'returns 200' do + expect(command(healthcheck).stdout).to eq '200' + end + end end From 93ca6f7143324452492f893c1a3dd79f84ba3cb5 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Fri, 12 Jan 2018 11:06:32 +0100 Subject: [PATCH 18/32] renamed test --- spec/docker_runtime/runtime_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/docker_runtime/runtime_spec.rb b/spec/docker_runtime/runtime_spec.rb index db8d37b..752f6a4 100644 --- a/spec/docker_runtime/runtime_spec.rb +++ b/spec/docker_runtime/runtime_spec.rb @@ -77,7 +77,7 @@ describe 'passbolt_api service' do end end - describe 'passbolt healthcheck' do + describe 'passbolt status' do it 'returns 200' do expect(command(healthcheck).stdout).to eq '200' end From a8652fc1d3810fd05146d5c8e5d9ec78211ab0a3 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Fri, 12 Jan 2018 11:17:21 +0100 Subject: [PATCH 19/32] fix directory permissions --- Dockerfile | 8 ++++---- spec/docker_image/image_spec.rb | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 54eb48b..781c67e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,10 +47,10 @@ RUN cd /var/www/passbolt \ && composer global require hirak/prestissimo \ && composer install \ && chown -R www-data:www-data /var/www/passbolt \ - && chmod 775 $(find /var/www/passbolt/tmp -type f) \ - && chmod 664 $(find /var/www/passbolt/tmp -type d) \ - && chmod 775 $(find /var/www/passbolt/webroot/img/public -type f) \ - && chmod 664 $(find /var/www/passbolt/webroot/img/public -type d) + && chmod 775 $(find /var/www/passbolt/tmp -type d) \ + && chmod 664 $(find /var/www/passbolt/tmp -type f) \ + && chmod 775 $(find /var/www/passbolt/webroot/img/public -type d) \ + && chmod 664 $(find /var/www/passbolt/webroot/img/public -type f) COPY conf/passbolt.conf /etc/nginx/conf.d/default.conf COPY conf/supervisord.conf /etc/supervisord.conf diff --git a/spec/docker_image/image_spec.rb b/spec/docker_image/image_spec.rb index 97b4fd9..ef89ec5 100644 --- a/spec/docker_image/image_spec.rb +++ b/spec/docker_image/image_spec.rb @@ -61,6 +61,14 @@ describe 'Dockerfile' do expect(file(passbolt_tmp)).to be_owned_by(passbolt_owner) expect(file(passbolt_image)).to be_owned_by(passbolt_owner) end + + it 'must have the correct permissions on tmp' do + expect(file(passbolt_tmp)).to be_mode('775') + end + + it 'must have the correct permissions on img' do + expect(file(passbolt_image)).to be_mode('775') + end end describe 'nginx configuration' do From 06dbbd84980033bd88abccc45ec0cee151e2efb9 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Fri, 12 Jan 2018 11:18:12 +0100 Subject: [PATCH 20/32] removed path declarations --- bin/docker-entrypoint.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 805e360..1a225df 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -54,7 +54,7 @@ install() { if [ "$tables" -eq 0 ]; then su -c "cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php" -s /bin/sh www-data - su -c "PATH=$PATH:/usr/local/bin /var/www/passbolt/bin/cake passbolt install --no-admin --force" -s /bin/sh www-data + su -c "/var/www/passbolt/bin/cake passbolt install --no-admin --force" -s /bin/sh www-data else echo "Enjoy! ☮" fi @@ -64,7 +64,7 @@ email_cron_job() { root_crontab='/etc/crontabs/root' cron_task_dir='/etc/periodic/1min' cron_task='/etc/periodic/1min/email_queue_processing' - process_email="PATH=$PATH:/usr/local/bin /var/www/passbolt/app/Console/cake EmailQueue.sender --quiet" + process_email="/var/www/passbolt/app/Console/cake EmailQueue.sender --quiet" mkdir -p $cron_task_dir echo "* * * * * run-parts $cron_task_dir" >> $root_crontab From d39666f86483e12c86541827933e3fab70c4053b Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Fri, 12 Jan 2018 11:24:17 +0100 Subject: [PATCH 21/32] updated ignored files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 34d6ef3..6c08575 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ fabric.properties # Generated docker files conf/*.key + +# src directory used for local development +src From 3b12c27757ed38447d34fc7774ec808878b92dfd Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Fri, 12 Jan 2018 11:56:35 +0100 Subject: [PATCH 22/32] multiple shellcheck fixes --- bin/docker-entrypoint.sh | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 1a225df..1a6e60c 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -2,18 +2,18 @@ set -eo pipefail -base_path='/var/www/passbolt' -gpg_private_key="$base_path/config/gpg/serverkey_private.asc" -gpg_public_key="$base_path/config/gpg/serverkey.asc" +gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-/var/www/passbolt/config/gpg/serverkey_private.asc}" +gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-/var/www/passbolt/config/gpg/serverkey.asc}" + ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' gpg_gen_key() { - key_email="${KEY_EMAIL:-passbolt@yourdomain.com}" - key_name="${KEY_NAME:-Passbolt default user}" - key_length="${KEY_LENGTH:-2048}" - subkey_length="${SUBKEY_LENGTH:-2048}" - expiration="${KEY_EXPIRATION:-0}" + key_email="${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com}" + key_name="${PASSBOLT_KEY_NAME:-Passbolt default user}" + key_length="${PASSBOLT_KEY_LENGTH:-2048}" + subkey_length="${PASSBOLT_SUBKEY_LENGTH:-2048}" + expiration="${PASSBOLT_KEY_EXPIRATION:-0}" su -m -c "gpg --batch --gen-key < Date: Fri, 12 Jan 2018 12:23:12 +0100 Subject: [PATCH 23/32] work in progress readme --- README.md | 147 +++++++++++++++++------------------------------------- 1 file changed, 47 insertions(+), 100 deletions(-) diff --git a/README.md b/README.md index 65c644c..37876eb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # Passbolt docker official image +# Warning + +This is a work in progress branch use at your own risk. + # What is passbolt? Passbolt is a free and open source password manager that allows team members to @@ -28,16 +32,21 @@ Passbolt requires mysql to be running. The following example use mysql official with the default passbolt credentials. ```bash -$ docker run -e MYSQL_ROOT_PASSWORD= \ - -e MYSQL_DATABASE=passbolt \ - -e MYSQL_USER=passbolt \ - -e MYSQL_PASSWORD=P4ssb0lt \ +$ docker run -e MYSQL_ROOT_PASSWORD= \ + -e MYSQL_DATABASE= \ + -e MYSQL_USER= \ + -e MYSQL_PASSWORD= \ mysql ``` Then you can start passbolt just by providing the database container ip in the `db_host` environment variable. -`$ docker run -e DB_HOST= passbolt:local` +```bash +$ docker run -e DATASOURCES_DEFAULT_HOST= \ + -e DATASOURCES_DEFAULT_PASSWORD= \ + -e DATASOURCES_DEFAULT_USERNAME= \ + -e DATASOURCES_DEFAULT_DATABASE= \ + passbolt:local``` Once the process is done, just navigate to the following url in your browser: https://passbolt_container_ip @@ -52,48 +61,40 @@ And access it using https://localhost:host_port # Configure passbolt -## Environment variables +## Environment variables reference Passbolt docker image provides several environment variables to configure different aspects: -### GnuPG key creation related variables +* APP_FULL_BASE_URL: Defines Passbolt base url (Example https://yourdomain.com) +* DATASOURCES_DEFAULT_HOST: database hostname (defaults to localhost) +* DATASOURCES_DEFAULT_PORT: database port (defaults to 3306) +* DATASOURCES_DEFAULT_USERNAME: database username (defaults to my_app) +* DATASOURCES_DEFAULT_PASSWORD: database password (defaults to secret) +* DATASOURCES_DEFAULT_DATABASE: database name (defaults to my_app) +* EMAIL_DEFAULT_FROM: from email address (defaults to contact@mydomain.local) +* EMAIL_DEFAULT_TRANSPORT: sets transport method (defaults to default) +* EMAIL_TRANSPORT_DEFAULT_HOST: server hostname (defaults to localhost) +* EMAIL_TRANSPORT_DEFAULT_PORT: server port (defaults to 25) +* EMAIL_TRANSPORT_DEFAULT_TIMEOUT: timeout (defaults to 30) +* EMAIL_TRANSPORT_DEFAULT_USERNAME: username for email server auth (defaults to null) +* EMAIL_TRANSPORT_DEFAULT_PASSWORD: password for email server auth (defaults to null) +* EMAIL_TRANSPORT_DEFAULT_CLIENT: client (defaults to null) +* EMAIL_TRANSPORT_DEFAULT_TLS: set tls (defaults to null) +* EMAIL_TRANSPORT_DEFAULT_URL: set url (defaults to null) +* GNUPGHOME: Path to gnupghome directory (defaults to web_user_home_directory/.gnupg ) +* PASSBOLT_KEY_LENGTH: gpg desired key length +* PASSBOLT_SUBKEY_LENGTH: gpg desired subkey length +* PASSBOLT_KEY_NAME: key owner name +* PASSBOLT_KEY_EMAIL: key owner email address +* PASSBOLT_KEY_EXPIRATION: key expiration date +* PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: GnuPG fingerprint +* PASSBOLT_GPG_SERVER_KEY_PUBLIC: Path to GnuPG public server key +* PASSBOLT_GPG_SERVER_KEY_PRIVATE: Path to GnuPG private server key +* PASSBOLT_REGISTRATION_PUBLIC: Defines if users can register (defaults to false) +* PASSBOLT_SSL_FORCE: Forces passbolt to redirect to SSL any non-SSL request +* PASSBOLT_SECURITY_SET_HEADERS: Forces passbolt to send CSP Headers (defaults to true) +* SECURITY_SALT: A random number user in security hashing methods. -* KEY_LENGTH: gpg desired key length -* SUBKEY_LENGTH: gpg desired subkey length -* KEY_NAME: key owner name -* KEY_EMAIL: key owner email address -* KEY_EXPIRATION: key expiration date - -### App file variables - -* FINGERPRINT: GnuPG fingerprint -* REGISTRATION: Defines if users can register (defaults to false) -* SSL: Forces passbolt to redirect to SSL any non-SSL request - -### Core file variables - -* SALT: a random string used by cakephp in security hashing methods -* CIPHERSEED: a random string used by cakephp to encrypt/decrypt strings -* URL: URL of the passbolt installation (defaults to passbolt.local) - -### Database variables - -* DB_HOST: database hostname This param has to be specified either using env var or in database.php (defaults to passbolt.local) -* DB_PORT: database port (defaults to 3306) -* DB_USER: database username (defaults to passbolt) -* DB_PASS: database password (defaults to P4ssb0lt) -* DB_NAME: database name (defaults to passbolt) - -### Email variables - -* EMAIL_TRANSPORT: transport protocol ( defaults to Smtp) -* EMAIL_FROM: from email address ( defaults to contact@mydomain.local) -* EMAIL_HOST: server hostname ( defaults to localhost) -* EMAIL_PORT: server port ( defaults to 587) -* EMAIL_TIMEOUT: timeout ( defaults to 30s) -* EMAIL_USERNAME: username for email server auth ( defaults to email_user) -* EMAIL_PASSWORD: password for email server auth ( defaults to email_password) -* EMAIL_TLS: set tls, boolean ( defaults to false) ## Advanced configuration @@ -102,12 +103,9 @@ It it possible to mount the desired configuration files as volumes. ### Configuration files subject to be persisted: -* /var/www/passbolt/app/Config/app.php -* /var/www/passbolt/app/Config/core.php -* /var/www/passbolt/app/Config/database.php -* /var/www/passbolt/app/Config/email.php -* /var/www/passbolt/app/Config/gpg/serverkey.asc -* /var/www/passbolt/app/Config/gpg/serverkey.private.asc +* /var/www/passbolt/config/app.php +* /var/www/passbolt/config/gpg/serverkey.asc +* /var/www/passbolt/config/gpg/serverkey_private.asc * /var/www/passbolt/app/webroot/img/public/images ### SSL certificate files @@ -117,57 +115,6 @@ It is also possible to mount a ssl certificate on the following paths: * /etc/ssl/certs/certificate.crt * /etc/ssl/certs/certificate.key -# Examples - -For the following examples it is assumed that passbolt container image has been built from this repo following the instructions -described on the [Build](#build-the-image) section. - -In the following example passbolt is launched with the defaults enabled usind mysql official docker container to store passbolt data: - -```bash -$ docker run -e MYSQL_ROOT_PASSWORD=c0mplexp4ss \ - -e MYSQL_DATABASE=passbolt \ - -e MYSQL_USER=passbolt \ - -e MYSQL_PASSWORD=P4ssb0lt \ - mysql -``` - -Once mysql container is running we should extract its ip address. Let's assume 172.17.0.2 for this example - -`$ docker run -e DB_HOST=172.17.0.2 passbolt:local` - -Point your browser to the passbolt container ip or localhost:exposed_port. - -## Advanced configuration - -In the following example passbolt is launched with a customized setup mounting and persisting configuration files. We also make use of -mysql official docker container to store passbolt data. - -```bash -$ docker run -e MYSQL_ROOT_PASSWORD=c0mplexp4ss \ - -e MYSQL_DATABASE=passbolt \ - -e MYSQL_USER=passbolt \ - -e MYSQL_PASSWORD=P4ssb0lt \ - mysql -``` - -Using docker inspect or any other method you can get the ip address of the mysql container. This example uses 172.17.0.2. - -Once this container is running and you have the mysql ip address we run passbolt container mounting all configuration files stored -under a example conf directory in $PWD - -```bash -$ docker run -v $PWD/conf/app.php:/var/www/passbolt/app/Config/app.php \ - -v $PWD/conf/core.php:/var/www/passbolt/app/Config/core.php \ - -v $PWD/conf/database.php:/var/www/passbolt/app/Config/database.php \ - -v $PWD/conf/email.php:/var/www/passbolt/app/Config/email.php \ - -v $PWD/conf/private.asc:/var/www/passbolt/app/Config/gpg/serverkey.private.asc \ - -v $PWD/conf/public.asc:/var/www/passbolt/app/Config/gpg/serverkey.asc \ - passbolt:local -``` - -Navigate with the browser to the passbolt container ip or localhost:exposed_port - # Requirements: * rng-tools are required on host machine to speed up entropy generation on containers. This way gpg key creation on passbolt container will be faster. From 7adbe1bb5b1a529d147ead9d83e4f79bdd2f8dcb Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Sun, 14 Jan 2018 21:10:52 +0100 Subject: [PATCH 24/32] point to develop branch --- Dockerfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 781c67e..6b0321d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,8 +2,7 @@ FROM php:7-fpm-alpine3.7 LABEL MAINTAINER diego@passbolt.com -ENV PASSBOLT_VERSION 2.0.0-rc1 -ENV PASSBOLT_URL https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VERSION}.tar.gz +ENV PASSBOLT_URL https://github.com/passbolt/passbolt_api/archive/develop.tar.gz ARG PHP_EXTENSIONS="gd \ intl \ @@ -42,8 +41,8 @@ RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ COPY src/passbolt_api/ /var/www/passbolt/ -# && curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ -RUN cd /var/www/passbolt \ +RUN curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ + && cd /var/www/passbolt \ && composer global require hirak/prestissimo \ && composer install \ && chown -R www-data:www-data /var/www/passbolt \ From 37e61adfab65cbd15305d282e41c8728484efb39 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Sun, 14 Jan 2018 21:15:13 +0100 Subject: [PATCH 25/32] formatting --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 37876eb..f5d2bb5 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,8 @@ $ docker run -e DATASOURCES_DEFAULT_HOST= \ -e DATASOURCES_DEFAULT_PASSWORD= \ -e DATASOURCES_DEFAULT_USERNAME= \ -e DATASOURCES_DEFAULT_DATABASE= \ - passbolt:local``` + passbolt:local +``` Once the process is done, just navigate to the following url in your browser: https://passbolt_container_ip @@ -95,7 +96,6 @@ Passbolt docker image provides several environment variables to configure differ * PASSBOLT_SECURITY_SET_HEADERS: Forces passbolt to send CSP Headers (defaults to true) * SECURITY_SALT: A random number user in security hashing methods. - ## Advanced configuration What if you already have a set of gpg keys and custom configuration files for passbolt? From 8ed3926bf4121acfe50cc11dfb2fb856dcc7d591 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 15 Jan 2018 10:05:08 +0100 Subject: [PATCH 26/32] removed COPY instruction --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6b0321d..5abbcc1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,8 +39,6 @@ RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ && curl -sS https://getcomposer.org/installer | php \ && mv composer.phar /usr/local/bin/composer -COPY src/passbolt_api/ /var/www/passbolt/ - RUN curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ && cd /var/www/passbolt \ && composer global require hirak/prestissimo \ From 3f60a0fc79cc789d3fbfe1892b81e8dd44f6d740 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 15 Jan 2018 16:35:31 +0100 Subject: [PATCH 27/32] database env var checks disabled --- bin/docker-entrypoint.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 1a6e60c..fde73e1 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -73,15 +73,6 @@ email_cron_job() { echo "su -c \"$process_email\" -s /bin/sh www-data" >> $cron_task } -if [ -z "$DATASOURCES_DEFAULT_HOST" ] \ - && [ -z "$DATASOURCES_DEFAULT_USERNAME" ] \ - && [ -z "$DATASOURCES_DEFAULT_PASSWORD" ] \ - && [ -z "$DATASOURCES_DEFAULT_DATABASE" ]; then - echo >&2 'Error: database credentials not provided' - echo >&2 'You must provide database details: hostname, username and password' - exit 1 -fi - if [ ! -f "$gpg_private_key" ] && [ ! -L "$gpg_private_key" ] || \ [ ! -f "$gpg_public_key" ] && [ ! -L "$gpg_public_key" ]; then gpg_gen_key From aaf8be3d1ed8a246237d0da2e439ea882520233b Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 15 Jan 2018 16:46:08 +0100 Subject: [PATCH 28/32] allow users to override PASSBOLT_GPG_SERVER_KEY_FINGERPRINT --- bin/docker-entrypoint.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index fde73e1..c3df1c5 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -31,7 +31,6 @@ EOF" -ls /bin/sh www-data } gpg_import_key() { - key_id="" key_id=$(su -m -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/sh www-data) su -c "gpg --batch --import $gpg_public_key" -ls /bin/sh www-data su -c "gpg -K $key_id" -ls /bin/sh www-data || su -m -c "gpg --batch --import $gpg_private_key" -ls /bin/sh www-data @@ -44,7 +43,6 @@ gen_ssl_cert() { } install() { - tables="" tables=$(mysql \ -u "$DATASOURCES_DEFAULT_USERNAME" \ -h "$DATASOURCES_DEFAULT_HOST" \ @@ -86,8 +84,11 @@ if [ ! -f "$ssl_key" ] && [ ! -L "$ssl_key" ] && \ gen_ssl_cert fi -gpg_auto_fingerprint="$(su -c "gpg --with-fingerprint $gpg_public_key | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}'" -ls /bin/sh www-data)" -export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint +if [ -z "$PASSBOLT_GPG_SERVER_KEY_FINGERPRINT" ]; then + gpg_auto_fingerprint="$(su -c "gpg --with-fingerprint $gpg_public_key | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}'" -ls /bin/sh www-data)" + export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint +fi + install email_cron_job From 63f22f84ba18ac6fbcebe3586637de252f81dc56 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Tue, 16 Jan 2018 12:06:05 +0100 Subject: [PATCH 29/32] created passbolt home dir --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5abbcc1..ea4da8b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,7 +39,8 @@ RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ && curl -sS https://getcomposer.org/installer | php \ && mv composer.phar /usr/local/bin/composer -RUN curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ +RUN mkdir -p /var/www/passbolt \ + && curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ && cd /var/www/passbolt \ && composer global require hirak/prestissimo \ && composer install \ From 5e42ef094d520b693c24e84070c7a8d57f177f52 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Tue, 16 Jan 2018 16:25:52 +0100 Subject: [PATCH 30/32] security headers are being sent from passbolt application --- conf/passbolt.conf | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/conf/passbolt.conf b/conf/passbolt.conf index a522ff4..8e737c8 100644 --- a/conf/passbolt.conf +++ b/conf/passbolt.conf @@ -13,18 +13,6 @@ server { root /var/www/passbolt; - # X-Frame-Options is to prevent from clickJacking attack - add_header X-Frame-Options SAMEORIGIN; - - # disable content-type sniffing on some browsers. - add_header X-Content-Type-Options nosniff; - - # This header enables the Cross-site scripting (XSS) filter - add_header X-XSS-Protection "1; mode=block"; - - # This will enforce HTTP browsing into HTTPS and avoid ssl stripping attack - add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;"; - location / { try_files $uri $uri/ /index.php?$args; index index.php; @@ -58,25 +46,9 @@ server { ssl_prefer_server_ciphers on; ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS; ssl_session_tickets off; - add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; - add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; root /var/www/passbolt; - # X-Frame-Options is to prevent from clickJacking attack - add_header X-Frame-Options SAMEORIGIN; - - # disable content-type sniffing on some browsers. - add_header X-Content-Type-Options nosniff; - - # This header enables the Cross-site scripting (XSS) filter - add_header X-XSS-Protection "1; mode=block"; - - # This will enforce HTTP browsing into HTTPS and avoid ssl stripping attack - add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;"; - location / { try_files $uri $uri/ /index.php?$args; index index.php; From 7a17ef2a80cf25620cce96dcafa7f4bc93566b5f Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Tue, 16 Jan 2018 17:10:02 +0100 Subject: [PATCH 31/32] check for file existence --- bin/docker-entrypoint.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index c3df1c5..a13ec1b 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -49,9 +49,18 @@ install() { -P "$DATASOURCES_DEFAULT_PORT" \ -BN -e "SHOW TABLES FROM $DATASOURCES_DEFAULT_DATABASE" \ -p"$DATASOURCES_DEFAULT_PASSWORD" |wc -l) + app_config="/var/www/passbolt/config/app.php" + + if [ ! -f "$app_config" ]; then + su -c 'cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php' -s /bin/sh www-data + fi + + if [ -z "$PASSBOLT_GPG_SERVER_KEY_FINGERPRINT" ]; then + gpg_auto_fingerprint="$(su -c "gpg --with-fingerprint $gpg_public_key | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}'" -ls /bin/sh www-data)" + export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint + fi if [ "$tables" -eq 0 ]; then - su -c 'cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php' -s /bin/sh www-data su -c '/var/www/passbolt/bin/cake passbolt install --no-admin --force' -s /bin/sh www-data else echo "Enjoy! ☮" @@ -62,7 +71,7 @@ email_cron_job() { root_crontab='/etc/crontabs/root' cron_task_dir='/etc/periodic/1min' cron_task='/etc/periodic/1min/email_queue_processing' - process_email="/var/www/passbolt/app/Console/cake EmailQueue.sender --quiet" + process_email="/var/www/passbolt/bin/cake EmailQueue.sender --quiet" mkdir -p $cron_task_dir echo "* * * * * run-parts $cron_task_dir" >> $root_crontab @@ -84,11 +93,6 @@ if [ ! -f "$ssl_key" ] && [ ! -L "$ssl_key" ] && \ gen_ssl_cert fi -if [ -z "$PASSBOLT_GPG_SERVER_KEY_FINGERPRINT" ]; then - gpg_auto_fingerprint="$(su -c "gpg --with-fingerprint $gpg_public_key | grep fingerprint | awk '{for(i=4;i<=NF;++i)printf \$i}'" -ls /bin/sh www-data)" - export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint -fi - install email_cron_job From 21b9e1a6cfe0dbff12b8f1852c4dfb8ff55c47d9 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Tue, 16 Jan 2018 17:42:42 +0100 Subject: [PATCH 32/32] no prestissimo and git for public builds --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index ea4da8b..0e25b8c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,6 @@ RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ libxslt-dev \ libmcrypt-dev \ supervisor \ - git \ && pecl install gnupg redis mcrypt-snapshot \ && docker-php-ext-install -j4 $PHP_EXTENSIONS \ && docker-php-ext-enable $PHP_EXTENSIONS gnupg redis mcrypt \ @@ -42,7 +41,6 @@ RUN apk add --no-cache $PHP_GNUPG_BUILD_DEPS \ RUN mkdir -p /var/www/passbolt \ && curl -sSL $PASSBOLT_URL | tar zxf - -C /var/www/passbolt --strip-components 1 \ && cd /var/www/passbolt \ - && composer global require hirak/prestissimo \ && composer install \ && chown -R www-data:www-data /var/www/passbolt \ && chmod 775 $(find /var/www/passbolt/tmp -type d) \