Merge branch 'release/v2.0.0'

This commit is contained in:
Diego Lendoiro 2018-04-09 14:56:28 +02:00
commit c0cb3d7ea7
19 changed files with 745 additions and 330 deletions

12
.dockerignore Normal file
View File

@ -0,0 +1,12 @@
spec
.git
.github
.editorconfig
.gitignore
Gemfile
Gemfile.lock
Rakefile
*.md
*.yml
scripts
env

5
.gitignore vendored
View File

@ -27,3 +27,8 @@ fabric.properties
# Generated docker files # Generated docker files
conf/*.key conf/*.key
# src directory used for local development
src
.ruby-version

View File

@ -2,6 +2,23 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/). This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased](https://github.com/passbolt/passbolt_docker/compare/v2.0.0...HEAD)
## [2.0.0](https://github.com/passbolt/passbolt_docker/compare/v2.0.0-rc2...v2.0.0) - 2018-04-09
### Changed
- Base image switched to php:7-fpm (debian based) due performance issues with passbolt and alpine based images
- Web user is now www-data
- Supervisor provides better logging to stdout
- Upload max filesize increased to 5M for avatar uploads
- README documentation updated
- Composer file loads images directory in passbolt container as a docker volume
### Added
- Added composer installer signature check according to official composer docs [#91](https://github.com/passbolt/passbolt_docker/pull/91)
## [Unreleased](https://github.com/passbolt/passbolt_docker/compare/v1.6.10...HEAD) ## [Unreleased](https://github.com/passbolt/passbolt_docker/compare/v1.6.10...HEAD)
## [1.6.10](https://github.com/passbolt/passbolt_docker/compare/v1.6.9-1...v1.6.10) - 2018-03-28 ## [1.6.10](https://github.com/passbolt/passbolt_docker/compare/v1.6.9-1...v1.6.10) - 2018-03-28
@ -21,6 +38,40 @@ in the structure of the container:
- Permissions check on the passbolt base dir has been removed as it was a big performance penalty on startup times. - Permissions check on the passbolt base dir has been removed as it was a big performance penalty on startup times.
- Docker hub tags will now follow the PASSBOLT_VERSION-debian pattern - Docker hub tags will now follow the PASSBOLT_VERSION-debian pattern
## [2.0.0-rc2](https://github.com/passbolt/passbolt_docker/compare/v2.0.0-rc1...v2.0.0-rc2) - 2018-02-20
### Changed
- README documentation updated
- PECL_PASSBOLT_EXTENSIONS, PASSBOLT_VERSION and PASSBOLT_URL are now a docker build arg
### Added
- Docker composer files to run passbolt_docker in different environments
- Codacy badges and reports
### Fixed
- Minor issues regarding bash syntax shellcheck SC2034 and SC2166
- Hadolint DL3003 fixed
## [2.0.0-rc1](https://github.com/passbolt/passbolt_docker/compare/v1.6.9-1...v2.0.0-rc1) - 2018-01-17
### Changed
- Moved away from plain alpine to php:7-fpm-alpine series
- Environment variables interface has been revamped and moved to application domain [default.php](https://github.com/passbolt/passbolt_api/blob/develop/config/default.php) and [app.default.php](https://github.com/passbolt/passbolt_api/blob/develop/config/app.default.php)
- PHP extensions management no longer using alpine packages
- Introduced [supervisord](http://supervisord.org/) for process monitoring
- Introduced testing framework for development purposes based on [rspec](http://rspec.info/)
- Reduced the dependencies installed in Dockerfile
- Default user moved from nginx to www-data
- Slightly changed paths of gpg serverkeys (<PASSBOLT_ROOT>/app/Config/gpg/serverkey.private.asc -> <PASSBOLT_ROOT>/config/gpg/serverkey_private.asc)
- Refactor or docker-entrypoint.sh:
- Moved away from bash to sh
- Make it compliant with [shellcheck](https://github.com/koalaman/shellcheck)
- Removed search and replace commands
## [1.6.9-1](https://github.com/passbolt/passbolt_docker/compare/v1.6.9...v1.6.9-1) - 2018-01-15 ## [1.6.9-1](https://github.com/passbolt/passbolt_docker/compare/v1.6.9...v1.6.9-1) - 2018-01-15
### Fixed ### Fixed

View File

@ -1,21 +1,28 @@
FROM php:5-fpm FROM php:7-fpm
LABEL maintainer="diego@passbolt.com" LABEL maintainer="diego@passbolt.com"
ENV PASSBOLT_VERSION 1.6.10 ARG PASSBOLT_VERSION="2.0.0"
ENV PASSBOLT_URL https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VERSION}.tar.gz ARG PASSBOLT_URL="https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VERSION}.tar.gz"
ARG PHP_EXTENSIONS="gd \
intl \
pdo_mysql \
xsl"
ARG PHP_EXTENSIONS="gd \ ARG PHP_EXTENSIONS="gd \
intl \ intl \
pdo_mysql \ pdo_mysql \
mcrypt \
xsl" xsl"
ARG PECL_PASSBOLT_EXTENSIONS="gnupg \ ARG PECL_PASSBOLT_EXTENSIONS="gnupg \
redis" redis \
mcrypt"
ARG PASSBOLT_DEV_PACKAGES="libgpgme11-dev \ ARG PASSBOLT_DEV_PACKAGES="libgpgme11-dev \
libpng-dev \ libpng-dev \
libicu-dev \
libxslt1-dev \ libxslt1-dev \
libmcrypt-dev \ libmcrypt-dev \
unzip \ unzip \
@ -31,7 +38,6 @@ RUN apt-get update \
gnupg \ gnupg \
libgpgme11 \ libgpgme11 \
libmcrypt4 \ libmcrypt4 \
libicu-dev \
mysql-client \ mysql-client \
supervisor \ supervisor \
netcat \ netcat \
@ -60,15 +66,16 @@ RUN apt-get update \
&& curl -sSL $PASSBOLT_URL | tar zxf - -C . --strip-components 1 \ && curl -sSL $PASSBOLT_URL | tar zxf - -C . --strip-components 1 \
&& composer install -n --no-dev --optimize-autoloader \ && composer install -n --no-dev --optimize-autoloader \
&& chown -R www-data:www-data . \ && chown -R www-data:www-data . \
&& chmod 775 $(find /var/www/passbolt/app/tmp -type d) \ && chmod 775 $(find /var/www/passbolt/tmp -type d) \
&& chmod 664 $(find /var/www/passbolt/app/tmp -type f) \ && chmod 664 $(find /var/www/passbolt/tmp -type f) \
&& chmod 775 $(find /var/www/passbolt/app/webroot/img/public -type d) \ && chmod 775 $(find /var/www/passbolt/webroot/img/public -type d) \
&& chmod 664 $(find /var/www/passbolt/app/webroot/img/public -type f) \ && chmod 664 $(find /var/www/passbolt/webroot/img/public -type f) \
&& rm /etc/nginx/sites-enabled/default \ && rm /etc/nginx/sites-enabled/default \
&& apt-get purge -y --auto-remove $PASSBOLT_DEV_PACKAGES \ && apt-get purge -y --auto-remove $PASSBOLT_DEV_PACKAGES \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
COPY conf/passbolt.conf /etc/nginx/conf.d/default.conf COPY conf/passbolt.conf /etc/nginx/conf.d/default.conf
COPY conf/supervisord.conf /etc/supervisor/supervisord.conf
COPY bin/docker-entrypoint.sh /docker-entrypoint.sh COPY bin/docker-entrypoint.sh /docker-entrypoint.sh
EXPOSE 80 443 EXPOSE 80 443

8
Gemfile Normal file
View File

@ -0,0 +1,8 @@
source 'https://rubygems.org'
group :test do
gem 'docker-api'
gem 'rake'
gem 'serverspec'
gem 'pry'
end

58
Gemfile.lock Normal file
View File

@ -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

217
README.md
View File

@ -1,117 +1,116 @@
# Passbolt docker official image ```
____ __ ____ .-.
/ __ \____ _____ ____/ /_ ____ / / /_ .--./ / _.---.,
/ /_/ / __ `/ ___/ ___/ __ \/ __ \/ / __/ '-, (__..-` \
/ ____/ /_/ (__ |__ ) /_/ / /_/ / / /_ \ |
/_/ \__,_/____/____/_,___/\____/_/\__/ `,.__. ^___.-/
`-./ .'...--`
The open source password manager for teams `'
(c) 2018 Passbolt SARL
https://www.passbolt.com
```
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0de4eaf7426944769a70a2d727a9012b)](https://www.codacy.com/app/passbolt/passbolt_docker?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=passbolt/passbolt_docker&amp;utm_campaign=Badge_Grade)
[![Docker Pulls](https://img.shields.io/docker/pulls/passbolt/passbolt.svg?style=flat-square)](https://hub.docker.com/r/passbolt/passbolt/tags/)
[![GitHub release](https://img.shields.io/github/release/passbolt/passbolt_docker.svg?style=flat-square)](https://github.com/passbolt/passbolt_docker/releases)
[![license](https://img.shields.io/github/license/passbolt/passbolt_docker.svg?style=flat-square)](https://github.com/passbolt/passbolt_docker/LICENSE)
[![Twitter Follow](https://img.shields.io/twitter/follow/passbolt.svg?style=social&label=Follow)](https://twitter.com/passbolt)
# What is passbolt? # What is passbolt?
Passbolt is a free and open source password manager that allows team members to Passbolt is a free and open source password manager that allows team members to
store and share credentials securely. store and share credentials securely.
# Scope of this repository # Usage
This repository will allow passbolt power users to customize their passbolt image to fit their needs on Users are encouraged to use [official docker image from the docker hub](https://hub.docker.com/r/passbolt/passbolt/).
specific environments. It is also a community meeting point to exchange feedback, request for new features
track issues and pull requests.
Users that do not require any special modifications are encouraged to `docker pull` the
[official docker image from the docker hub](https://hub.docker.com/r/passbolt/passbolt/).
There is also a yet unofficial project to use [passbolt along with docker-compose](https://github.com/dlen/passbolt-compose) for easier the setup process.
# Build the image
Inside the repo directory:
`$ docker build . -t passbolt:local`
# How to use the local image?
## Start passbolt instance ## Start passbolt instance
Passbolt requires mysql to be running. The following example use mysql official docker image Passbolt requires mysql to be running. The following example use mysql official
with the default passbolt credentials. docker image with the default passbolt credentials.
```bash ```bash
$ docker run -e MYSQL_ROOT_PASSWORD=<your_root_password> \ $ docker run -e MYSQL_ROOT_PASSWORD=<root_password> \
-e MYSQL_DATABASE=passbolt \ -e MYSQL_DATABASE=<mysql_database> \
-e MYSQL_USER=passbolt \ -e MYSQL_USER=<mysql_user> \
-e MYSQL_PASSWORD=P4ssb0lt \ -e MYSQL_PASSWORD=<mysql_password> \
mysql mysql
``` ```
Then you can start passbolt just by providing the database container ip in the `db_host` environment variable. Then you can start passbolt just by providing the database container ip in the
`db_host` environment variable.
`$ docker run -e DB_HOST=<mysql_container_ip> passbolt:local` ```bash
$ docker run --name passbolt \
-e DATASOURCES_DEFAULT_HOST=<mysql_container_host> \
-e DATASOURCES_DEFAULT_PASSWORD=<mysql_password> \
-e DATASOURCES_DEFAULT_USERNAME=<mysql_user> \
-e DATASOURCES_DEFAULT_DATABASE=<mysql_database> \
-e APP_FULL_BASE_URL=https://mydomain.com \
passbolt/passbolt:develop-debian
```
Once the process is done, just navigate to the following url in your browser: https://passbolt_container_ip Once the container is running create your first admin user:
### Note on starting passbolt container on MacOS systems ```bash
$ docker exec passbolt su -m -c "/var/www/passbolt/bin/cake passbolt register_user -u your@email.com -f yourname -l surname -r admin" -s /bin/sh www-data
```
Due to the [limitations](https://docs.docker.com/docker-for-mac/networking/#known-limitations-use-cases-and-workarounds) This registration command will return a single use url required to continue the
of docker networking under MacOS users should start the container exposing a port on the host: web browser setup and finish the registration. Your passbolt instance should be
available browsing `https://yourdomain.com`
`$ docker run -p host_port:443 -e DB_HOST=<mysql_container_ip> passbolt:local`
And access it using https://localhost:host_port
# Configure passbolt # Configure passbolt
## Environment variables ## Environment variables reference
Passbolt docker image provides several environment variables to configure different aspects: Passbolt docker image provides several environment variables to configure different aspects:
### GnuPG key creation related variables | Variable name | Description | Default value |
| ----------------------------------- | -------------------------------- | ------------------- |
| APP_FULL_BASE_URL | Passbolt base url | false |
| DATASOURCES_DEFAULT_HOST | Database hostname | localhost |
| DATASOURCES_DEFAULT_PORT | Database port | 3306 |
| DATASOURCES_DEFAULT_USERNAME | Database username | '' |
| DATASOURCES_DEFAULT_PASSWORD | Database password | '' |
| DATASOURCES_DEFAULT_DATABASE | Database name | '' |
| EMAIL_TRANSPORT_DEFAULT_CLASS_NAME | Email classname | Smtp |
| EMAIL_DEFAULT_FROM | From email address | you@localhost |
| EMAIL_DEFAULT_TRANSPORT | Sets transport method | default |
| EMAIL_TRANSPORT_DEFAULT_HOST | Server hostname | localhost |
| EMAIL_TRANSPORT_DEFAULT_PORT | Server port | 25 |
| EMAIL_TRANSPORT_DEFAULT_TIMEOUT | Timeout | 30 |
| EMAIL_TRANSPORT_DEFAULT_USERNAME | Username for email server auth | null |
| EMAIL_TRANSPORT_DEFAULT_PASSWORD | Password for email server auth | null |
| EMAIL_TRANSPORT_DEFAULT_CLIENT | Client | null |
| EMAIL_TRANSPORT_DEFAULT_TLS | Set tls | null |
| EMAIL_TRANSPORT_DEFAULT_URL | Set url | null |
| GNUPGHOME | path to gnupghome directory | /home/www-data/.gnupg |
| PASSBOLT_KEY_LENGTH | Gpg desired key length | 2048 |
| PASSBOLT_SUBKEY_LENGTH | Gpg desired subkey length | 2048 |
| PASSBOLT_KEY_NAME | Key owner name | Passbolt default user |
| PASSBOLT_KEY_EMAIL | Key owner email address | passbolt@yourdomain.com |
| PASSBOLT_KEY_EXPIRATION | Key expiration date | 0, never expires |
| PASSBOLT_GPG_SERVER_KEY_FINGERPRINT | GnuPG fingerprint | null |
| PASSBOLT_GPG_SERVER_KEY_PUBLIC | Path to GnuPG public server key | /var/www/passbolt/config/gpg/serverkey.asc |
| PASSBOLT_GPG_SERVER_KEY_PRIVATE | Path to GnuPG private server key | /var/www/passbolt/config/gpg/serverkey_private.asc |
| PASSBOLT_REGISTRATION_PUBLIC | Defines if users can register | false |
| PASSBOLT_SSL_FORCE | Redirects http to https | true |
| PASSBOLT_SECURITY_SET_HEADERS | Send CSP Headers | true |
| SECURITY_SALT | CakePHP security salt | __SALT__ |
* KEY_LENGTH: gpg desired key length For more env variables supported please check [default.php](https://github.com/passbolt/passbolt_api/blob/master/config/default.php)
* SUBKEY_LENGTH: gpg desired subkey length For more env variables supported please check [app.default.php](https://github.com/passbolt/passbolt_api/blob/master/config/app.default.php)
* KEY_NAME: key owner name
* KEY_EMAIL: key owner email address
* KEY_EXPIRATION: key expiration date
### App file variables ### Configuration files
* 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 http://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_AUTH: disable smtp auth ( defaults to true)
* EMAIL_USERNAME: username for email server auth ( defaults to email_user)
* EMAIL_PASSWORD: password for email server auth ( defaults to email_password)
* EMAIL_CLIENT: hostname to send as smtp helo ( defaults to null)
* EMAIL_TLS: set tls, boolean ( defaults to false)
## Advanced configuration
What if you already have a set of gpg keys and custom configuration files for passbolt? What if you already have a set of gpg keys and custom configuration files for passbolt?
It it possible to mount the desired configuration files as volumes. It it possible to mount the desired configuration files as volumes.
### Configuration files subject to be persisted: * /var/www/passbolt/config/app.php
* /var/www/passbolt/config/passbolt.php
* /var/www/passbolt/app/Config/app.php * /var/www/passbolt/config/gpg/serverkey.asc
* /var/www/passbolt/app/Config/core.php * /var/www/passbolt/config/gpg/serverkey_private.asc
* /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/app/webroot/img/public/images * /var/www/passbolt/app/webroot/img/public/images
### SSL certificate files ### SSL certificate files
@ -121,58 +120,16 @@ It is also possible to mount a ssl certificate on the following paths:
* /etc/ssl/certs/certificate.crt * /etc/ssl/certs/certificate.crt
* /etc/ssl/certs/certificate.key * /etc/ssl/certs/certificate.key
# Examples ### docker-compose
For the following examples it is assumed that passbolt container image has been built from this repo following the instructions Usage:
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
``` ```
$ docker-compose up
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: # 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. * rng-tools or haveged are required on host machine to speed up entropy generation on containers.
This way gpg key creation on passbolt container will be faster.
* mysql >= 5.6 * mysql >= 5.6

27
Rakefile Normal file
View File

@ -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

View File

@ -1,204 +1,98 @@
#!/bin/bash #!/usr/bin/env bash
set -eo pipefail set -euo pipefail
gpg_private_key=/var/www/passbolt/app/Config/gpg/serverkey.private.asc gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-/var/www/passbolt/config/gpg/serverkey_private.asc}"
gpg_public_key=/var/www/passbolt/app/Config/gpg/serverkey.asc gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-/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'
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_key='/etc/ssl/certs/certificate.key'
ssl_cert='/etc/ssl/certs/certificate.crt' ssl_cert='/etc/ssl/certs/certificate.crt'
export GNUPGHOME="/home/www-data/.gnupg"
gpg_gen_key() { gpg_gen_key() {
su -c "$gpg --batch --gen-key <<EOF key_email="${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com}"
Key-Type: 1 key_name="${PASSBOLT_KEY_NAME:-Passbolt default user}"
Key-Length: ${KEY_LENGTH:-2048} key_length="${PASSBOLT_KEY_LENGTH:-2048}"
Subkey-Type: 1 subkey_length="${PASSBOLT_SUBKEY_LENGTH:-2048}"
Subkey-Length: ${SUBKEY_LENGTH:-2048} expiration="${PASSBOLT_KEY_EXPIRATION:-0}"
Name-Real: ${KEY_NAME:-Passbolt default user}
Name-Email: ${KEY_EMAIL:-passbolt@yourdomain.com} su -c "gpg --batch --no-tty --gen-key <<EOF
Expire-Date: ${KEY_EXPIRATION:-0} Key-Type: default
Key-Length: $key_length
Subkey-Type: default
Subkey-Length: $subkey_length
Name-Real: $key_name
Name-Email: $key_email
Expire-Date: $expiration
%no-protection %no-protection
%commit %commit
EOF" -ls /bin/bash www-data EOF" -ls /bin/bash www-data
su -c "$gpg --armor --export-secret-keys $KEY_EMAIL > $gpg_private_key" -ls /bin/bash www-data su -c "gpg --armor --export-secret-keys $key_email > $gpg_private_key" -ls /bin/bash www-data
su -c "$gpg --armor --export $KEY_EMAIL > $gpg_public_key" -ls /bin/bash www-data su -c "gpg --armor --export $key_email > $gpg_public_key" -ls /bin/bash www-data
} }
gpg_import_key() { gpg_import_key() {
su -c "gpg --batch --import $gpg_public_key" -ls /bin/bash www-data
local key_id=$(su -c "gpg --with-colons $gpg_private_key | grep sec |cut -f5 -d:" -ls /bin/bash www-data) su -c "gpg --batch --import $gpg_private_key" -ls /bin/bash www-data
su -c "$gpg --batch --import $gpg_public_key" -ls /bin/bash www-data
su -c "gpg -K $key_id" -ls /bin/bash www-data || su -c "$gpg --batch --import $gpg_private_key" -ls /bin/bash www-data
}
core_setup() {
#Env vars:
# SALT
# CIPHERSEED
# URL
local default_salt='DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi'
local default_seed='76859309657453542496749683645'
local default_url='http://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|http://example.com|${URL:-$default_url}|g" $core_config
}
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_home='/home/www-data/.gnupg'
local default_public_key='unsecure.key'
local default_private_key='unsecure_private.key'
local default_fingerprint='2FC8945833C51946E937F9FED47B0811573EE67E'
local auto_fingerprint=$(su -c "$gpg --fingerprint |grep fingerprint| awk '{for(i=4;i<=NF;++i)printf \$i}'" -ls /bin/bash www-data)
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:-$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_AUTH
# EMAIL_USERNAME
# EMAIL_PASSWORD
# EMAIL_CLIENT
# 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="''"
local default_client=null
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
if [ "$EMAIL_AUTH" = "false" ] ; then
sed -i "0,/"$default_username"/s:"$default_username":null:" $email_config
sed -i "0,/"$default_password"/s:"$default_password":null:" $email_config
else
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
fi
if [ -n "$EMAIL_CLIENT" ] ; then
sed -i "0,/'client'/s:'client' => $default_client:'client' => '$EMAIL_CLIENT':" $email_config
fi
sed -i "0,/tls/s:false:${EMAIL_TLS:-false}:" $email_config
} }
gen_ssl_cert() { gen_ssl_cert() {
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
-subj "/C=FR/ST=Denial/L=Springfield/O=Dis/CN=www.passbolt.local" \ -subj '/C=FR/ST=Denial/L=Springfield/O=Dis/CN=www.passbolt.local' \
-keyout $ssl_key -out $ssl_cert -keyout $ssl_key -out $ssl_cert
} }
install() { install() {
local database_host=${DB_HOST:-$(cat $db_config | grep -m1 "'host'" | sed -r "s/\s*'host' => '(.*)',/\1/")} tables=$(mysql \
local database_port=${DB_PORT:-$(cat $db_config | grep -m1 "'port' => '\d" | sed -r "s/\s*'port' => '(.*)',/\1/")} -u "${DATASOURCES_DEFAULT_USERNAME:-passbolt}" \
local database_user=${DB_USER:-$(cat $db_config | grep -m1 "'login'" | sed -r "s/\s*'login' => '(.*)',/\1/")} -h "${DATASOURCES_DEFAULT_HOST:-localhost}" \
local database_pass=${DB_PASS:-$(cat $db_config | grep -m1 "'password'" | sed -r "s/\s*'password' => '(.*)',/\1/")} -P "${DATASOURCES_DEFAULT_PORT:-3306}" \
local database_name=${DB_NAME:-$(cat $db_config | grep -m1 "'database'" | sed -r "s/\s*'database' => '(.*)',/\1/")} -BN -e "SHOW TABLES FROM ${DATASOURCES_DEFAULT_DATABASE:-passbolt}" \
tables=$(mysql -u ${database_user:-passbolt} -h $database_host -P ${database_port:-3306} -p -BN -e "SHOW TABLES FROM ${database_name:-passbolt}" -p${database_pass:-P4ssb0lt} |wc -l) -p"${DATASOURCES_DEFAULT_PASSWORD:-P4ssb0lt}" |wc -l)
app_config="/var/www/passbolt/config/app.php"
if [ $tables -eq 0 ]; then if [ ! -f "$app_config" ]; then
su -c "/var/www/passbolt/app/Console/cake install --send-anonymous-statistics true --no-admin" -ls /bin/bash www-data su -c 'cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php' -s /bin/bash www-data
fi
if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ]; then
gpg_auto_fingerprint="$(su -c "gpg --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)"
export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint
fi
if [ "$tables" -eq 0 ]; then
su -c '/var/www/passbolt/bin/cake passbolt install --no-admin --force' -s /bin/bash www-data
else else
su -c '/var/www/passbolt/bin/cake migrations migrate' -s /bin/bash www-data
echo "Enjoy! ☮" echo "Enjoy! ☮"
fi fi
} }
email_cron_job() { email_cron_job() {
printenv > /etc/environment
sed -i 's/=\(.*\)/="\1"/g' /etc/environment
cron_task='/etc/cron.d/passbolt_email' cron_task='/etc/cron.d/passbolt_email'
echo "* * * * * su -c \"/var/www/passbolt/app/Console/cake EmailQueue.sender\" -s /bin/bash www-data >> /var/log/cron.log 2>&1" >> $cron_task echo "* * * * * su -c \"source /etc/environment ; /var/www/passbolt/bin/cake EmailQueue.sender\" -s /bin/bash www-data >> /var/log/cron.log 2>&1" >> $cron_task
crontab /etc/cron.d/passbolt_email crontab /etc/cron.d/passbolt_email
cron -f -l &
} }
if [ ! -f $gpg_private_key ] && [ ! -L $gpg_private_key ] || \ if [ ! -f "$gpg_private_key" ] && [ ! -L "$gpg_private_key" ] || \
[ ! -f $gpg_public_key ] && [ ! -L $gpg_public_key ]; then [ ! -f "$gpg_public_key" ] && [ ! -L "$gpg_public_key" ]; then
gpg_gen_key gpg_gen_key
gpg_import_key
else else
gpg_import_key gpg_import_key
fi fi
if [ ! -f $core_config ] && [ ! -L $core_config ]; then if [ ! -f "$ssl_key" ] && [ ! -L "$ssl_key" ] && \
core_setup [ ! -f "$ssl_cert" ] && [ ! -L "$ssl_cert" ]; then
fi
if [ ! -f $db_config ] && [ ! -L $db_config ]; then
db_setup
fi
if [ ! -f $app_config ] && [ ! -L $app_config ]; then
app_setup
fi
if [ ! -f $email_config ] && [ ! -L $email_config ]; then
email_setup
fi
if [ ! -f $ssl_key ] && [ ! -L $ssl_key ] && \
[ ! -f $ssl_cert ] && [ ! -L $ssl_cert ]; then
gen_ssl_cert gen_ssl_cert
fi fi
install install
php-fpm &
email_cron_job email_cron_job
nginx -g "daemon off;" /usr/bin/supervisord -n

View File

@ -2,8 +2,8 @@ server {
listen 80; listen 80;
client_body_buffer_size 100K; client_body_buffer_size 100K;
client_header_buffer_size 1k; client_header_buffer_size 1K;
client_max_body_size 100k; client_max_body_size 5M;
client_body_timeout 10; client_body_timeout 10;
client_header_timeout 10; client_header_timeout 10;
@ -12,18 +12,6 @@ server {
root /var/www/passbolt; 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 / { location / {
try_files $uri $uri/ /index.php?$args; try_files $uri $uri/ /index.php?$args;
index index.php; index index.php;
@ -36,12 +24,14 @@ server {
include fastcgi_params; include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SERVER_NAME $http_host; fastcgi_param SERVER_NAME $http_host;
fastcgi_param PHP_VALUE "upload_max_filesize=5M \n post_max_size=5M";
} }
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; access_log off;
log_not_found off; log_not_found off;
try_files $uri /app/webroot/$uri /index.php?$args; try_files $uri /webroot/$uri /index.php?$args;
#try_files $uri /app/webroot/$uri /index.php?$args;
} }
} }
@ -49,28 +39,25 @@ server {
server { server {
listen 443; listen 443;
client_body_buffer_size 100K;
client_header_buffer_size 1K;
client_max_body_size 5M;
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5 5;
send_timeout 10;
ssl on; ssl on;
ssl_certificate /etc/ssl/certs/certificate.crt; ssl_certificate /etc/ssl/certs/certificate.crt;
ssl_certificate_key /etc/ssl/certs/certificate.key; ssl_certificate_key /etc/ssl/certs/certificate.key;
ssl_protocols TLSv1.2; ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:@STRENGTH";
ssl_session_tickets off; ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
root /var/www/passbolt; 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";
location / { location / {
try_files $uri $uri/ /index.php?$args; try_files $uri $uri/ /index.php?$args;
index index.php; index index.php;
@ -83,11 +70,12 @@ server {
include fastcgi_params; include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SERVER_NAME $http_host; fastcgi_param SERVER_NAME $http_host;
fastcgi_param PHP_VALUE "upload_max_filesize=5M \n post_max_size=5M";
} }
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|json|pdf|zip|htm|html|docx?|xlsx?|pptx?|txt|wav|swf|svg|avi|mp\d)$ {
access_log off; access_log off;
log_not_found off; log_not_found off;
try_files $uri /app/webroot/$uri /index.php?$args; try_files $uri /webroot/$uri /index.php?$args;
} }
} }

52
conf/supervisord.conf Normal file
View File

@ -0,0 +1,52 @@
; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; 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:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[program:php-fpm]
command=php-fpm
autostart=true
priority=5
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:nginx]
command=nginx -g "daemon off;"
autostart=true
priority=10
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:cron]
command=cron -f -l
autostart=true
priority=20
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

33
docker-compose-dev.yml Normal file
View File

@ -0,0 +1,33 @@
version: '3.4'
services:
db:
image: mysql:latest
env_file:
- env/mysql.env
volumes:
- database_volume:/var/lib/mysql
ports:
- 3306
passbolt:
build:
context: .
args:
PECL_PASSBOLT_EXTENSIONS: "redis gnupg xdebug"
depends_on:
- db
env_file:
- env/passbolt.env
volumes:
- gpg_volume:/var/www/passbolt/config/gpg
- images_volume:/var/www/passbolt/webroot/img/public/images
- ./scripts/wait-for.sh:/usr/bin/wait-for.sh
command: ["/usr/bin/wait-for.sh", "db:3306", "--", "/docker-entrypoint.sh"]
ports:
- 80:80
- 443:443
volumes:
database_volume:
gpg_volume:
images_volume:

33
docker-compose.yml Normal file
View File

@ -0,0 +1,33 @@
version: '3.4'
services:
db:
image: mysql:latest
env_file:
- env/mysql.env
volumes:
- database_volume:/var/lib/mysql
ports:
- 3306
passbolt:
image: passbolt/passbolt:2.0.0-debian
tty: true
depends_on:
- db
env_file:
- env/passbolt.env
volumes:
- gpg_volume:/var/www/passbolt/config/gpg
- images_volume:/var/www/passbolt/webroot/img/public
- ./scripts/wait-for.sh:/usr/bin/wait-for.sh
tmpfs:
- /run
command: ["/usr/bin/wait-for.sh", "db:3306", "--", "/docker-entrypoint.sh"]
ports:
- 80:80
- 443:443
volumes:
database_volume:
gpg_volume:
images_volume:

4
env/mysql.env vendored Normal file
View File

@ -0,0 +1,4 @@
MYSQL_ROOT_PASSWORD=test
MYSQL_DATABASE=passbolt
MYSQL_USER=passbolt
MYSQL_PASSWORD=P4ssb0lt

12
env/passbolt.env vendored Normal file
View File

@ -0,0 +1,12 @@
# URL
APP_FULL_BASE_URL=https://passbolt.local
# Database settings
DATASOURCES_DEFAULT_HOST=db
DATASOURCES_DEFAULT_USERNAME=passbolt
DATASOURCES_DEFAULT_PASSWORD=P4ssb0lt
DATASOURCES_DEFAULT_DATABASE=passbolt
DATASOURCES_DEFAULT_PORT=3306
# Registration
PASSBOLT_REGISTRATION_PUBLIC=true

79
scripts/wait-for.sh Executable file
View File

@ -0,0 +1,79 @@
#!/bin/sh
TIMEOUT=15
QUIET=0
echoerr() {
if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
}
usage() {
exitcode="$1"
cat << USAGE >&2
Usage:
$0 host:port [-t timeout] [-- command args]
-q | --quiet Do not output any status messages
-t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit "$exitcode"
}
wait_for() {
for _ in $(seq $TIMEOUT) ; do
nc -z "$HOST" "$PORT" > /dev/null 2>&1
result=$?
if [ $result -eq 0 ] ; then
if [ $# -gt 0 ] ; then
exec "$@"
fi
exit 0
fi
sleep 1
done
echo "Operation timed out" >&2
exit 1
}
while [ $# -gt 0 ]
do
case "$1" in
*:* )
HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
shift 1
;;
-q | --quiet)
QUIET=1
shift 1
;;
-t)
TIMEOUT="$2"
if [ "$TIMEOUT" = "" ]; then break; fi
shift 2
;;
--timeout=*)
TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
break
;;
--help)
usage 0
;;
*)
echoerr "Unknown argument: $1"
usage 1
;;
esac
done
if [ "$HOST" = "" ] || [ "$PORT" = "" ]; then
echoerr "Error: you need to provide a host and port to test."
usage 2
fi
wait_for "$@"

View File

@ -0,0 +1,101 @@
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) { 'www-data' }
let(:exposed_ports) { [ '80', '443' ] }
let(:composer) { '/usr/local/bin/composer'}
let(:php_extensions) { [
'curl', 'gd', 'intl', 'json', 'mcrypt', 'mysqlnd', 'xsl', 'phar',
'posix', 'xml', '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
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
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

View File

@ -0,0 +1,85 @@
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'
],
"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',
],
'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
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(service('php-fpm')).to be_running.under('supervisor')
end
it 'has its port open' do
expect(@container.json['Config']['ExposedPorts']).to have_key('9000/tcp')
end
end
describe 'email cron' do
it 'is running supervised' do
expect(service('cron')).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(@container.json['Config']['ExposedPorts']).to have_key('80/tcp')
end
it 'is listening on port 443' do
expect(@container.json['Config']['ExposedPorts']).to have_key('443/tcp')
end
end
describe 'passbolt status' do
it 'returns 200' do
expect(command(healthcheck).stdout).to eq '200'
end
end
end

9
spec/spec_helper.rb Normal file
View File

@ -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