diff --git a/.gitlab-ci/Jobs/docker-compose-file-upload.yml b/.gitlab-ci/Jobs/docker-compose-file-upload.yml index 7969bd7..30bc2e6 100644 --- a/.gitlab-ci/Jobs/docker-compose-file-upload.yml +++ b/.gitlab-ci/Jobs/docker-compose-file-upload.yml @@ -1,6 +1,6 @@ .upload-files: stage: upload-assets - image: registry.gitlab.com/passbolt/passbolt-ci-docker-images/gcloud + image: gcr.io/google.com/cloudsdktool/google-cloud-cli:latest variables: BUCKET: "gs://download.passbolt.com" PREFIX: "ce/docker" diff --git a/.gitlab-ci/Jobs/entrypoint_test.yml b/.gitlab-ci/Jobs/entrypoint_test.yml index 5fbdba3..04f1cb0 100644 --- a/.gitlab-ci/Jobs/entrypoint_test.yml +++ b/.gitlab-ci/Jobs/entrypoint_test.yml @@ -1,7 +1,7 @@ entrypoint-tests: extends: .rules stage: test - image: registry.gitlab.com/passbolt/passbolt-ci-docker-images/debian-bullseye-11-slim:latest + image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/debian:bullseye-slim before_script: - apt update && apt install curl git -y - curl -fsSL https://git.io/shellspec | sh -s -- --yes diff --git a/.gitlab-ci/Jobs/test_images.yaml b/.gitlab-ci/Jobs/test_images.yaml index 7b261eb..10f92f5 100644 --- a/.gitlab-ci/Jobs/test_images.yaml +++ b/.gitlab-ci/Jobs/test_images.yaml @@ -1,16 +1,16 @@ services: - - name: registry.gitlab.com/passbolt/passbolt-ci-docker-images/dind:latest + - name: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/docker:dind alias: docker command: ["--tls=false"] .test-images: extends: .rules stage: test - image: - name: registry.gitlab.com/passbolt/passbolt-ci-docker-images/ruby:latest + image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/ruby:slim-bookworm script: - - bundle install - - rake spec:$TEST_NAME + - | + bundle install + rake spec:$TEST_NAME variables: PASSBOLT_COMPONENT: stable PASSBOLT_FLAVOUR: ce @@ -40,7 +40,7 @@ ce-docker-runtime-no-envs: variables: TEST_NAME: docker_runtime_no_envs -ce-docker-runtime-no-envs: +ce-docker-runtime-with-passbolt-php: extends: .test-images variables: TEST_NAME: docker_runtime_with_passbolt_php diff --git a/.gitlab-ci/Jobs/test_vulnerabilities.yaml b/.gitlab-ci/Jobs/test_vulnerabilities.yaml index 87ee7cc..bc5715a 100644 --- a/.gitlab-ci/Jobs/test_vulnerabilities.yaml +++ b/.gitlab-ci/Jobs/test_vulnerabilities.yaml @@ -2,7 +2,7 @@ extends: .rules stage: test-vulnerabilities image: - name: registry.gitlab.com/passbolt/passbolt-ci-docker-images/aquasec:latest + name: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/aquasec/trivy:latest entrypoint: [""] variables: TRIVY_USERNAME: $CI_REGISTRY_USER diff --git a/conf/php/zz-docker.conf b/conf/php/zz-docker.conf new file mode 100644 index 0000000..2febc07 --- /dev/null +++ b/conf/php/zz-docker.conf @@ -0,0 +1,9 @@ +[global] +error_log = /proc/self/fd/2 +; https://github.com/docker-library/php/pull/725#issuecomment-443540114 +log_limit = 8192 + +[www] +catch_workers_output = yes +decorate_workers_output = no + diff --git a/debian/Dockerfile b/debian/Dockerfile index 5cc909b..a68a168 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -26,6 +26,7 @@ ENV PHP_VERSION=8.2 ENV GNUPGHOME=/var/lib/passbolt/.gnupg ENV PASSBOLT_FLAVOUR=$PASSBOLT_FLAVOUR ENV PASSBOLT_PKG="passbolt-$PASSBOLT_FLAVOUR-server" +ENV LOG_ERROR_URL="console://?levels[]=warning&levels[]=error&levels[]=critical&levels[]=alert&levels[]=emergency" SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get update \ @@ -53,13 +54,13 @@ RUN apt-get update \ && sed -i 's,www-data.*$,root su -s /bin/bash -c ". /etc/environment \&\& $PASSBOLT_BASE_DIR/bin/cron" www-data >/proc/1/fd/1 2>\&1,' /etc/cron.d/$PASSBOLT_PKG \ && sed -i 's/# server_tokens/server_tokens/' /etc/nginx/nginx.conf \ && ln -sf /dev/stdout /var/log/nginx/passbolt-access.log \ - && ln -sf /dev/stderr /var/log/nginx/passbolt-error.log \ - && ln -sf /dev/stderr /var/log/passbolt/error.log \ - && ln -sf /dev/stderr /var/log/php$PHP_VERSION-fpm.log + && ln -sf /dev/stderr /var/log/nginx/passbolt-error.log COPY conf/supervisor/cron.conf /etc/supervisor/conf.d/cron.conf COPY conf/supervisor/nginx.conf /etc/supervisor/conf.d/nginx.conf COPY conf/supervisor/php.conf /etc/supervisor/conf.d/php.conf +COPY conf/php/zz-docker.conf /etc/php/$PHP_VERSION/fpm/pool.d/zz-docker.conf + COPY scripts/entrypoint/docker-entrypoint.sh /docker-entrypoint.sh COPY scripts/entrypoint/passbolt/entrypoint.sh /passbolt/entrypoint.sh COPY scripts/entrypoint/passbolt/env.sh /passbolt/env.sh @@ -67,8 +68,6 @@ COPY scripts/entrypoint/passbolt/deprecated_paths.sh /passbolt/deprecated_paths. COPY scripts/entrypoint/passbolt/entropy.sh /passbolt/entropy.sh COPY scripts/wait-for.sh /usr/bin/wait-for.sh -# Docker API does not support buildkit so we -# need to do this workaround https://github.com/docker/for-linux/issues/1136 RUN chmod 0644 /etc/supervisor/conf.d/* \ && chmod 0700 /docker-entrypoint.sh \ && chmod 0700 /passbolt/* \ diff --git a/debian/Dockerfile.rootless b/debian/Dockerfile.rootless index 384f1a9..ee2f13b 100644 --- a/debian/Dockerfile.rootless +++ b/debian/Dockerfile.rootless @@ -35,6 +35,7 @@ ENV SUPERCRONIC_VERSION=0.2.28 ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v${SUPERCRONIC_VERSION}/supercronic-linux-${SUPERCRONIC_ARCH} \ SUPERCRONIC=supercronic-linux-${SUPERCRONIC_ARCH} ENV PASSBOLT_FLAVOUR="${PASSBOLT_FLAVOUR}" +ENV LOG_ERROR_URL="console://?levels[]=warning&levels[]=error&levels[]=critical&levels[]=alert&levels[]=emergency" SHELL ["/bin/bash", "-o", "pipefail", "-c"] @@ -98,8 +99,6 @@ RUN sed -i 's,listen 80;,listen 8080;,' /etc/nginx/sites-enabled/nginx-passbolt. && chown -R www-data:0 /var/log/nginx \ && ln -sf /dev/stdout /var/log/nginx/passbolt-access.log \ && ln -sf /dev/stderr /var/log/nginx/passbolt-error.log \ - && ln -sf /dev/stderr /var/log/passbolt/error.log \ - && ln -sf /dev/stderr /var/log/php$PHP_VERSION-fpm.log \ && chown -R www-data:0 /var/log/supervisor \ && touch /var/www/.profile \ && chown www-data:www-data /var/www/.profile \ @@ -109,6 +108,7 @@ RUN sed -i 's,listen 80;,listen 8080;,' /etc/nginx/sites-enabled/nginx-passbolt. && chown www-data:www-data /etc/environment \ && chmod 600 /etc/environment +COPY conf/php/zz-docker.conf /etc/php/$PHP_VERSION/fpm/pool.d/zz-docker.conf COPY scripts/entrypoint/docker-entrypoint.rootless.sh /docker-entrypoint.sh COPY scripts/entrypoint/passbolt/entrypoint-rootless.sh /passbolt/entrypoint-rootless.sh COPY scripts/entrypoint/passbolt/env.sh /passbolt/env.sh @@ -116,8 +116,6 @@ COPY scripts/entrypoint/passbolt/deprecated_paths.sh /passbolt/deprecated_paths. COPY scripts/entrypoint/passbolt/entropy.sh /passbolt/entropy.sh COPY scripts/wait-for.sh /usr/bin/wait-for.sh -# Docker API does not support buildkit so we -# need to do this workaround https://github.com/docker/for-linux/issues/1136 RUN chmod 0644 /etc/supervisor/conf.d/* \ && chmod 0755 /docker-entrypoint.sh \ && chmod 0755 /passbolt/* \ diff --git a/dev/docker-compose-dev.yaml b/dev/docker-compose-dev.yaml index 96f1fde..452d2fb 100644 --- a/dev/docker-compose-dev.yaml +++ b/dev/docker-compose-dev.yaml @@ -1,8 +1,7 @@ -version: '3.9' services: db: - image: mariadb:10.3 + image: mariadb:10.11 container_name: db env_file: - env/mysql.env diff --git a/docker-compose/docker-compose-ce-postgresql.yaml b/docker-compose/docker-compose-ce-postgresql.yaml index f737bc6..b4fd34a 100644 --- a/docker-compose/docker-compose-ce-postgresql.yaml +++ b/docker-compose/docker-compose-ce-postgresql.yaml @@ -1,4 +1,3 @@ -version: "3.7" services: db: image: postgres:latest diff --git a/docker-compose/docker-compose-ce.yaml b/docker-compose/docker-compose-ce.yaml index 96a46aa..2a4d3e4 100644 --- a/docker-compose/docker-compose-ce.yaml +++ b/docker-compose/docker-compose-ce.yaml @@ -1,4 +1,3 @@ -version: "3.9" services: db: image: mariadb:10.11 diff --git a/docker-compose/docker-compose-pro.yaml b/docker-compose/docker-compose-pro.yaml index 50d738e..9916255 100644 --- a/docker-compose/docker-compose-pro.yaml +++ b/docker-compose/docker-compose-pro.yaml @@ -1,4 +1,3 @@ -version: "3.9" services: db: image: mariadb:10.11 diff --git a/spec/docker_runtime/runtime_spec.rb b/spec/docker_runtime/runtime_spec.rb index 57b9be4..faab70e 100644 --- a/spec/docker_runtime/runtime_spec.rb +++ b/spec/docker_runtime/runtime_spec.rb @@ -3,13 +3,9 @@ describe 'passbolt_api service' do before(:all) do @mysql_image = - if ENV['GITLAB_CI'] - Docker::Image.create( - 'fromImage' => 'registry.gitlab.com/passbolt/passbolt-ci-docker-images/mariadb-10.3:latest' - ) - else - Docker::Image.create('fromImage' => 'mariadb:latest') - end + Docker::Image.create( + 'fromImage' => ENV['CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX'] ? "#{ENV['CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX']}/mariadb:10.11" : 'mariadb:10.11' + ) @mysql = Docker::Container.create( 'Env' => [ @@ -21,7 +17,7 @@ 'Healthcheck' => { "Test": [ 'CMD-SHELL', - 'mysqladmin ping --silent' + 'mariadb-admin ping --silent' ] }, 'Image' => @mysql_image.id @@ -31,31 +27,25 @@ sleep 1 while @mysql.json['State']['Health']['Status'] != 'healthy' - if ENV['GITLAB_CI'] - Docker.authenticate!( - 'username' => ENV['CI_REGISTRY_USER'].to_s, - 'password' => ENV['CI_REGISTRY_PASSWORD'].to_s, - 'serveraddress' => 'https://registry.gitlab.com/' - ) - @image = - if ENV['ROOTLESS'] == 'true' - Docker::Image.create( - 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-rootless-latest" - ) - else - Docker::Image.create( - 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-root-latest" - ) - end - else - @image = Docker::Image.build_from_dir( - ROOT_DOCKERFILES, - { - 'dockerfile' => $dockerfile, - 'buildargs' => JSON.generate($buildargs) - } - ) - end + @image = if ENV['GITLAB_CI'] + if ENV['ROOTLESS'] == 'true' + Docker::Image.create( + 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-rootless-latest" + ) + else + Docker::Image.create( + 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-root-latest" + ) + end + else + Docker::Image.build_from_dir( + ROOT_DOCKERFILES, + { + 'dockerfile' => $dockerfile, + 'buildargs' => JSON.generate($buildargs) + } + ) + end @container = Docker::Container.create( 'Env' => [ diff --git a/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb b/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb index fb6cb5d..dbedcef 100644 --- a/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb +++ b/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb @@ -2,11 +2,11 @@ describe 'passbolt_api service' do before(:all) do - if ENV['GITLAB_CI'] - @mysql_image = Docker::Image.create('fromImage' => 'registry.gitlab.com/passbolt/passbolt-ci-docker-images/mariadb-10.3:latest') - else - @mysql_image = Docker::Image.create('fromImage' => 'mariadb:latest') - end + @mysql_image = + Docker::Image.create( + 'fromImage' => ENV['CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX'] ? "#{ENV['CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX']}/mariadb:10.11" : 'mariadb:10.11' + ) + @mysql = Docker::Container.create( 'Env' => [ 'MARIADB_ROOT_PASSWORD=test', @@ -17,7 +17,7 @@ 'Healthcheck' => { "Test": [ 'CMD-SHELL', - 'mysqladmin ping --silent' + 'mariadb-admin ping --silent' ] }, 'Image' => @mysql_image.id @@ -27,11 +27,6 @@ sleep 1 while @mysql.json['State']['Health']['Status'] != 'healthy' if ENV['GITLAB_CI'] - Docker.authenticate!( - 'username' => ENV['CI_REGISTRY_USER'].to_s, - 'password' => ENV['CI_REGISTRY_PASSWORD'].to_s, - 'serveraddress' => 'https://registry.gitlab.com/' - ) @image = if ENV['ROOTLESS'] == 'true' Docker::Image.create('fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-rootless-latest") else @@ -67,8 +62,8 @@ end let(:passbolt_host) { @container.json['NetworkSettings']['IPAddress'] } - let(:uri) { '/healthcheck/status.json' } - let(:curl) { "curl -sk -o /dev/null -w '%{http_code}' -H 'Host: passbolt.local' https://#{passbolt_host}:#{$https_port}/#{uri}" } + let(:uri) { '/install' } + let(:curl) { "curl -skL -H 'Host: passbolt.local' https://#{passbolt_host}:#{$https_port}/#{uri}" } describe 'php service' do it 'is running supervised' do @@ -96,14 +91,15 @@ end end - describe 'passbolt status' do - it 'returns 200' do - expect(command(curl).stdout).to eq '200' + describe 'passbolt install' do + it 'shows correctly' do + expect(command(curl).stdout).to match(/.*Passbolt is not configured yet!.*/) end end describe 'can not access outside webroot' do let(:uri) { '/vendor/autoload.php' } + let(:curl) { "curl -sk -o /dev/null -w '%{http_code}' -H 'Host: passbolt.local' https://#{passbolt_host}:#{$https_port}/#{uri}" } it 'returns 404' do expect(command(curl).stdout).to eq '404' end diff --git a/spec/docker_runtime_with_passbolt_php/docker_runtime_with_passbolt_php_spec.rb b/spec/docker_runtime_with_passbolt_php/docker_runtime_with_passbolt_php_spec.rb index c35281a..878b242 100644 --- a/spec/docker_runtime_with_passbolt_php/docker_runtime_with_passbolt_php_spec.rb +++ b/spec/docker_runtime_with_passbolt_php/docker_runtime_with_passbolt_php_spec.rb @@ -3,13 +3,9 @@ describe 'passbolt_api service' do before(:all) do @mysql_image = - if ENV['GITLAB_CI'] - Docker::Image.create( - 'fromImage' => 'registry.gitlab.com/passbolt/passbolt-ci-docker-images/mariadb-10.3:latest' - ) - else - Docker::Image.create('fromImage' => 'mariadb:latest') - end + Docker::Image.create( + 'fromImage' => ENV['CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX'] ? "#{ENV['CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX']}/mariadb:10.11" : 'mariadb:10.11' + ) @mysql = Docker::Container.create( 'Env' => [ @@ -21,7 +17,7 @@ 'Healthcheck' => { "Test": [ 'CMD-SHELL', - 'mysqladmin ping --silent' + 'mariadb-admin ping --silent' ] }, 'Image' => @mysql_image.id @@ -31,31 +27,25 @@ sleep 1 while @mysql.json['State']['Health']['Status'] != 'healthy' - if ENV['GITLAB_CI'] - Docker.authenticate!( - 'username' => ENV['CI_REGISTRY_USER'].to_s, - 'password' => ENV['CI_REGISTRY_PASSWORD'].to_s, - 'serveraddress' => 'https://registry.gitlab.com/' - ) - @image = - if ENV['ROOTLESS'] == 'true' - Docker::Image.create( - 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-rootless-latest" - ) - else - Docker::Image.create( - 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-root-latest" - ) - end - else - @image = Docker::Image.build_from_dir( - ROOT_DOCKERFILES, - { - 'dockerfile' => $dockerfile, - 'buildargs' => JSON.generate($buildargs) - } - ) - end + @image = if ENV['GITLAB_CI'] + if ENV['ROOTLESS'] == 'true' + Docker::Image.create( + 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-rootless-latest" + ) + else + Docker::Image.create( + 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-root-latest" + ) + end + else + Docker::Image.build_from_dir( + ROOT_DOCKERFILES, + { + 'dockerfile' => $dockerfile, + 'buildargs' => JSON.generate($buildargs) + } + ) + end @container = Docker::Container.create( 'Env' => [ @@ -64,7 +54,8 @@ 'DATASOURCES_DEFAULT_USERNAME=passbolt', 'DATASOURCES_DEFAULT_DATABASE=passbolt', 'PASSBOLT_SSL_FORCE=true', - 'PASSBOLT_GPG_SERVER_KEY_FINGERPRINT_FORCE=true' + 'PASSBOLT_GPG_SERVER_KEY_FINGERPRINT_FORCE=true', + 'PASSBOLT_HEALTHCHECK_ERROR=true' ], 'Image' => @image.id, 'Binds' => $binds.append( @@ -86,9 +77,32 @@ @container.kill end + let(:passbolt_host) { @container.json['NetworkSettings']['IPAddress'] } + let(:curl) { "curl -sk -o /dev/null -w '%{http_code}' -H 'Host: passbolt.local' https://#{passbolt_host}:#{$https_port}/#{uri}" } + describe 'force fingerprint calculation' do it 'is contains fingerprint environment variable' do expect(file('/etc/environment').content).to match(/PASSBOLT_GPG_SERVER_KEY_FINGERPRINT/) end end + + describe 'throws exception in logs' do + let(:uri) { 'healthcheck/error' } + it 'returns 500' do + expect(command(curl).stdout).to eq '500' + end + + it 'shows exception in logs' do + expect(@container.logs(stderr: true)).to match(/^.*\[Cake\\Http\\Exception\\InternalErrorException\] Internal Server Error.*/) + end + end + + describe 'can not access outside webroot' do + let(:uri) { 'vendor/autoload.php' } + let(:curl) { "curl -sk -o /dev/null -w '%{http_code}' -H 'Host: passbolt.local' https://#{passbolt_host}:#{$https_port}/#{uri}" } + it 'returns 404' do + expect(command(curl).stdout).to eq '404' + end + end + end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 347953d..0455a15 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -30,10 +30,14 @@ if ENV['GITLAB_CI'] Docker.authenticate!( - 'username' => ENV['REGISTRY_USERNAME'].to_s, - 'password' => ENV['REGISTRY_PASSWORD'].to_s, - 'email' => ENV['REGISTRY_EMAIL'].to_s, - 'serveraddress' => 'https://registry.gitlab.com/' + 'username' => ENV['CI_REGISTRY_USER'].to_s, + 'password' => ENV['CI_REGISTRY_PASSWORD'].to_s, + 'serveraddress' => ENV['CI_REGISTRY'].to_s + ) + Docker.authenticate!( + 'username' => ENV['CI_DEPENDENCY_PROXY_USER'].to_s, + 'password' => ENV['CI_DEPENDENCY_PROXY_PASSWORD'].to_s, + 'serveraddress' => ENV['CI_DEPENDENCY_PROXY_SERVER'].to_s ) end