├── .dockerignore ├── .github ├── CODEOWNERS ├── move.yml └── workflows │ └── blank.yml ├── .gitattributes ├── Makefile ├── test ├── docker-compose-sqlite.yml ├── docker-compose-mysql.yml ├── test_helpers.bash ├── docker_helpers.bash ├── test.sqlite.bats ├── test.mysql.bats ├── test.full.bats └── lib │ ├── output.bash │ └── batslib.bash ├── conf ├── php-fpm-pool.conf ├── nginx-site.conf ├── .env.docker ├── nginx.conf └── supervisord.conf ├── openshift ├── README.md └── cachethd-dc.yaml ├── docker-compose.yml ├── LICENSE ├── CONTRIBUTING.md ├── Dockerfile ├── release-helper.sh ├── README.md ├── entrypoint.sh └── CHANGELOG.md /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !entrypoint.sh 3 | !conf 4 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # CachetHQ Docker team 2 | * @CachetHQ/docker 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Force Linux line endings to fix issues on Windows 2 | /entrypoint.sh text eol=lf 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SILENT : 2 | .PHONY : test 3 | 4 | update-dependencies: 5 | docker pull curlimages/curl:latest 6 | docker pull postgres:9.5 7 | 8 | test: 9 | bats test 10 | 11 | compose-build: 12 | docker-compose build 13 | 14 | compose-up: 15 | docker-compose up 16 | 17 | build: 18 | docker build -t cachet/docker . 19 | -------------------------------------------------------------------------------- /test/docker-compose-sqlite.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | cachet: 5 | image: docker_cachet 6 | ports: 7 | - 80:8000 8 | environment: 9 | - DB_DRIVER=sqlite 10 | - APP_KEY=${APP_KEY:-null} 11 | - DEBUG=false 12 | volumes: 13 | - cachetdb:/var/www/html/database 14 | 15 | networks: 16 | default: 17 | external: 18 | name: docker_default 19 | 20 | volumes: 21 | cachetdb: 22 | -------------------------------------------------------------------------------- /.github/move.yml: -------------------------------------------------------------------------------- 1 | # Configuration for move-issues - https://github.com/dessant/move-issues 2 | 3 | 4 | # Delete the command comment. Ignored when the comment also contains other content 5 | deleteCommand: true 6 | # Close the source issue after moving 7 | closeSourceIssue: true 8 | # Lock the source issue after moving 9 | lockSourceIssue: true 10 | # Set custom aliases for targets 11 | # aliases: 12 | # r: repo 13 | # or: owner/repo 14 | -------------------------------------------------------------------------------- /conf/php-fpm-pool.conf: -------------------------------------------------------------------------------- 1 | [www] 2 | listen = 127.0.0.1:9000 3 | 4 | request_terminate_timeout = 120s 5 | 6 | pm = ondemand 7 | pm.max_children = {{PHP_MAX_CHILDREN}} 8 | pm.process_idle_timeout = 10s 9 | pm.max_requests = 500 10 | chdir = / 11 | 12 | env[DB_DRIVER] = $DB_DRIVER 13 | env[DB_HOST] = $DB_HOST 14 | env[DB_DATABASE] = $DB_DATABASE 15 | env[DB_USERNAME] = $DB_USERNAME 16 | env[DB_PASSWORD] = $DB_PASSWORD 17 | env[CACHE_DRIVER] = $CACHE_DRIVER 18 | 19 | catch_workers_output = yes 20 | access.log = /dev/stdout 21 | 22 | [global] 23 | daemonize = no 24 | error_log = /dev/stderr 25 | pid = /tmp/php-fpm.pid 26 | -------------------------------------------------------------------------------- /openshift/README.md: -------------------------------------------------------------------------------- 1 | ## Synopsis 2 | 3 | This is a very simple way to deploy CachetHD on to Openshift or Kubernetes. I have only tested this on OpenShift 3.3 at this time 01/29/2017. 4 | 5 | ## Motivation 6 | 7 | This was someting I did a work as we needed a dashboard to see that status of the services in our OpenShift. 8 | 9 | ## Installation 10 | 11 | To get this all work you need to have a DB you can access. 12 | 13 | Deploy the DC using `oc create -f cachethd-dc.yaml` while logged in to the project you want to deploy to. 14 | 15 | You will need to change the env values to your setup. 16 | 17 | You will then need to setup service and then a route so you can get to Cachet URL. 18 | 19 | 20 | ## Contributors 21 | 22 | Andy del Hierro 23 | andelhie@cisco.com -------------------------------------------------------------------------------- /test/docker-compose-mysql.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | mysql: 5 | image: mariadb:10.4 6 | environment: 7 | - MYSQL_ROOT_PASSWORD=mysql 8 | - MYSQL_USER=mysql 9 | - MYSQL_PASSWORD=mysql 10 | - MYSQL_DATABASE=mysql 11 | - DEBUG=false 12 | cachet: 13 | image: docker_cachet 14 | ports: 15 | - 80:8000 16 | links: 17 | - mysql:mysql 18 | environment: 19 | - DB_DRIVER=mysql 20 | - DB_HOST=mysql 21 | - DB_DATABASE=mysql 22 | - DB_USERNAME=mysql 23 | - DB_PASSWORD=mysql 24 | - DB_PREFIX=chq_ 25 | - APP_KEY=${APP_KEY:-null} 26 | depends_on: 27 | - mysql 28 | 29 | networks: 30 | default: 31 | external: 32 | name: docker_default 33 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | postgres: 5 | image: postgres:12-alpine 6 | volumes: 7 | - /var/lib/postgresql/data 8 | environment: 9 | - POSTGRES_USER=postgres 10 | - POSTGRES_PASSWORD=postgres 11 | restart: always 12 | cachet: 13 | build: 14 | context: . 15 | args: 16 | - cachet_ver=2.4 17 | ports: 18 | - 80:8000 19 | links: 20 | - postgres:postgres 21 | environment: 22 | - DB_DRIVER=pgsql 23 | - DB_HOST=postgres 24 | - DB_PORT=5432 25 | - DB_DATABASE=postgres 26 | - DB_USERNAME=postgres 27 | - DB_PASSWORD=postgres 28 | - DB_PREFIX=chq_ 29 | - APP_KEY=${APP_KEY:-null} 30 | - APP_LOG=errorlog 31 | - APP_ENV=${APP_ENV:-production} 32 | - APP_DEBUG=false 33 | - DEBUG=false 34 | depends_on: 35 | - postgres 36 | restart: on-failure 37 | -------------------------------------------------------------------------------- /conf/nginx-site.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 8000 default; ## Listen for ipv4; this line is default and implied 3 | listen [::]:8000 default; ## Listen for ipv6 4 | 5 | # Make site accessible from http://localhost/ 6 | server_name localhost; 7 | root /var/www/html/public; 8 | 9 | index index.php; 10 | 11 | charset utf-8; 12 | 13 | location / { 14 | try_files $uri /index.php$is_args$args; 15 | } 16 | # Cache images 17 | location ~* .(jpg|jpeg|png|gif|ico|css|js|ttf|svg)$ { 18 | expires 365d; 19 | } 20 | 21 | # Pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 22 | location ~ \.php$ { 23 | 24 | fastcgi_pass_header Set-Cookie; 25 | fastcgi_pass_header Cookie; 26 | fastcgi_ignore_headers Cache-Control Expires Set-Cookie; 27 | 28 | fastcgi_cache_bypass 1; 29 | fastcgi_no_cache 1; 30 | 31 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 32 | include fastcgi_params; 33 | fastcgi_pass 127.0.0.1:9000; 34 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 35 | fastcgi_index index.php; 36 | fastcgi_keep_conn on; 37 | } 38 | 39 | location ~ /\.ht { 40 | deny all; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /.github/workflows/blank.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the main branch 8 | push: 9 | branches: [ main ] 10 | pull_request: 11 | branches: [ main ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | - name: Install bats 26 | run: sudo apt-get install bats 27 | 28 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 29 | - uses: actions/checkout@v2 30 | 31 | # Runs a set of commands using the runners shell 32 | - name: Run bash automated test suite (bats) 33 | run: | 34 | docker pull curlimages/curl:latest 35 | bats test/test.full.bats 36 | bats test/test.mysql.bats 37 | bats test/test.sqlite.bats 38 | -------------------------------------------------------------------------------- /conf/.env.docker: -------------------------------------------------------------------------------- 1 | APP_ENV="{{APP_ENV}}" 2 | APP_DEBUG="{{APP_DEBUG}}" 3 | APP_URL="{{APP_URL}}" 4 | APP_LOG="{{APP_LOG}}" 5 | APP_KEY="{{APP_KEY}}" 6 | 7 | DB_DRIVER="{{DB_DRIVER}}" 8 | DB_HOST="{{DB_HOST}}" 9 | DB_DATABASE="{{DB_DATABASE}}" 10 | DB_USERNAME="{{DB_USERNAME}}" 11 | DB_PASSWORD="{{DB_PASSWORD}}" 12 | DB_PORT="{{DB_PORT}}" 13 | DB_PREFIX="{{DB_PREFIX}}" 14 | 15 | DOCKER=true 16 | 17 | CACHE_DRIVER="{{CACHE_DRIVER}}" 18 | 19 | SESSION_DRIVER="{{SESSION_DRIVER}}" 20 | SESSION_DOMAIN="{{SESSION_DOMAIN}}" 21 | SESSION_SECURE_COOKIE="{{SESSION_SECURE_COOKIE}}" 22 | 23 | QUEUE_DRIVER="{{QUEUE_DRIVER}}" 24 | 25 | CACHET_EMOJI="{{CACHET_EMOJI}}" 26 | CACHET_BEACON="{{CACHET_BEACON}}" 27 | CACHET_AUTO_TWITTER="{{CACHET_AUTO_TWITTER}}" 28 | 29 | MAIL_DRIVER="{{MAIL_DRIVER}}" 30 | MAIL_HOST="{{MAIL_HOST}}" 31 | MAIL_PORT="{{MAIL_PORT}}" 32 | MAIL_USERNAME="{{MAIL_USERNAME}}" 33 | MAIL_PASSWORD="{{MAIL_PASSWORD}}" 34 | MAIL_ADDRESS="{{MAIL_ADDRESS}}" 35 | MAIL_NAME="{{MAIL_NAME}}" 36 | MAIL_ENCRYPTION="{{MAIL_ENCRYPTION}}" 37 | 38 | REDIS_HOST="{{REDIS_HOST}}" 39 | REDIS_DATABASE="{{REDIS_DATABASE}}" 40 | REDIS_PORT="{{REDIS_PORT}}" 41 | REDIS_PASSWORD="{{REDIS_PASSWORD}}" 42 | 43 | GITHUB_TOKEN="{{GITHUB_TOKEN}}" 44 | 45 | NEXMO_KEY="{{NEXMO_KEY}}" 46 | NEXMO_SECRET="{{NEXMO_SECRET}}" 47 | NEXMO_SMS_FROM="{{NEXMO_SMS_FROM}}" 48 | 49 | TRUSTED_PROXIES="{{TRUSTED_PROXIES}}" 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2016 Alt Three Services Limited. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | 3. Neither the name of the Cachet nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /test/test_helpers.bash: -------------------------------------------------------------------------------- 1 | # Test if requirements are met 2 | ( 3 | type docker &>/dev/null || ( echo "docker is not available"; exit 1 ) 4 | )>&2 5 | 6 | # ENV vars for tests 7 | export APP_ENV=development 8 | export APP_KEY="base64:v2LwHrdgnE+RavEXdnF8LgWIibjvEcFkU2qaX5Ji708=" 9 | 10 | TEST_FILE=$(basename $BATS_TEST_FILENAME .bats) 11 | 12 | # stop all containers with the "bats-type" label (matching the optionally supplied value) 13 | # 14 | # $1 optional label value 15 | function stop_bats_containers { 16 | docker-compose stop 17 | } 18 | 19 | # delete all containers 20 | docker_cleanup() { 21 | docker-compose rm -af 22 | } 23 | 24 | # Send a HTTP request to container $1 for path $2 and 25 | # Additional curl options can be passed as $@ 26 | # 27 | # $1 container name 28 | # $2 HTTP path to query 29 | # $@ additional options to pass to the curl command 30 | function curl_container { 31 | local -r container=$1 32 | local -r path=$2 33 | shift 2 34 | docker run --rm --net=docker_default --label bats-type="curl" curlimages/curl --silent \ 35 | --connect-timeout 5 \ 36 | --max-time 20 \ 37 | --retry 4 --retry-delay 5 \ 38 | "$@" \ 39 | http://$(docker_ip $container)${path} 40 | } 41 | 42 | # Retry a command $1 times until it succeeds. Wait $2 seconds between retries. 43 | function retry { 44 | local attempts=$1 45 | shift 46 | local delay=$1 47 | shift 48 | local i 49 | 50 | for ((i=0; i < attempts; i++)); do 51 | run "$@" 52 | if [ "$status" -eq 0 ]; then 53 | echo "$output" 54 | return 0 55 | fi 56 | sleep $delay 57 | done 58 | 59 | echo "Command \"$@\" failed $attempts times. Status: $status. Output: $output" >&2 60 | false 61 | } 62 | -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | 3 | error_log /var/log/nginx/error.log warn; 4 | pid /var/run/nginx.pid; 5 | 6 | events { 7 | use epoll; 8 | worker_connections 1024; 9 | multi_accept on; 10 | } 11 | 12 | 13 | http { 14 | include /etc/nginx/mime.types; 15 | default_type application/octet-stream; 16 | 17 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 18 | '$status $body_bytes_sent "$http_referer" ' 19 | '"$http_user_agent" "$http_x_forwarded_for"'; 20 | 21 | access_log /var/log/nginx/access.log main; 22 | 23 | sendfile on; 24 | tcp_nopush on; 25 | tcp_nodelay on; 26 | 27 | keepalive_timeout 65; 28 | 29 | fastcgi_cache_path /usr/share/nginx/cache/fcgi levels=1:2 keys_zone=microcache:10m max_size=1024m inactive=1h; 30 | add_header X-Cache $upstream_cache_status; 31 | 32 | gzip on; 33 | gzip_disable "msie6"; 34 | 35 | gzip_vary on; 36 | gzip_proxied any; 37 | gzip_comp_level 6; 38 | gzip_buffers 16 8k; 39 | gzip_http_version 1.1; 40 | gzip_min_length 256; 41 | gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; 42 | 43 | include /etc/nginx/conf.d/*.conf; 44 | 45 | client_body_temp_path /tmp 1 2; 46 | client_body_buffer_size 256k; 47 | client_body_in_file_only off; 48 | 49 | proxy_temp_path /tmp/proxy 1 2; 50 | fastcgi_temp_path /tmp/fastcgi 1 2; 51 | uwsgi_temp_path /tmp/fastcgi 1 2; 52 | scgi_temp_path /tmp/scgi 1 2; 53 | } 54 | daemon off; 55 | -------------------------------------------------------------------------------- /conf/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | logfile=/dev/null ; (main log file;default $CWD/supervisord.log) 3 | logfile_maxbytes=0 ; (max main logfile bytes b4 rotation;default 50MB) 4 | logfile_backups=0 ; (num of main logfile rotation backups;default 10) 5 | loglevel=info ; (log level;default info; others: debug,warn,trace) 6 | pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid) 7 | nodaemon=true ; (start in foreground if true;default false) 8 | 9 | ; the below section must remain in the config file for RPC 10 | ; (supervisorctl/web interface) to work, additional interfaces may be 11 | ; added by defining them in separate rpcinterface: sections 12 | [rpcinterface:supervisor] 13 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 14 | 15 | [supervisorctl] 16 | serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket 17 | 18 | [program:nginx] 19 | command=/usr/sbin/nginx 20 | stdout_events_enabled=true 21 | stderr_events_enabled=true 22 | stdout_logfile_maxbytes=0 23 | stderr_logfile_maxbytes=0 24 | stdout_logfile=/dev/stdout 25 | stderr_logfile=/dev/stderr 26 | 27 | [program:php-fpm] 28 | command=/usr/sbin/php-fpm7 -c /etc/php7/fpm/pool.d/www.conf 29 | catch_workers_output = Yes 30 | stdout_events_enabled=true 31 | stderr_events_enabled=true 32 | stdout_logfile_maxbytes=0 33 | stderr_logfile_maxbytes=0 34 | stdout_logfile=/dev/stdout 35 | stderr_logfile=/dev/stderr 36 | 37 | [program:queue-worker] 38 | command=php artisan queue:work --daemon --delay=2 --sleep=1 --tries=3 39 | directory=/var/www/html/ 40 | redirect_stderr=true 41 | autostart=true 42 | autorestart=true 43 | stdout_logfile_maxbytes=0 44 | stderr_logfile_maxbytes=0 45 | stdout_logfile=/dev/stdout 46 | -------------------------------------------------------------------------------- /test/docker_helpers.bash: -------------------------------------------------------------------------------- 1 | ## functions to help deal with docker 2 | 3 | # Removes container $1 4 | function docker_clean { 5 | docker kill $1 &>/dev/null ||: 6 | sleep .25s 7 | docker rm -vf $1 &>/dev/null ||: 8 | sleep .25s 9 | } 10 | 11 | # get the ip of docker container $1 12 | function docker_ip { 13 | docker inspect --format '{{ .NetworkSettings.Networks.docker_default.IPAddress }}' $1 14 | } 15 | 16 | # get the id of docker container $1 17 | function docker_id { 18 | docker inspect --format '{{ .ID }}' $1 19 | } 20 | 21 | # get the running state of container $1 22 | # → true/false 23 | # fails if the container does not exist 24 | function docker_running_state { 25 | docker inspect -f {{.State.Running}} $1 26 | } 27 | 28 | # get the docker container $1 PID 29 | function docker_pid { 30 | docker inspect --format {{.State.Pid}} $1 31 | } 32 | 33 | # asserts logs from container $1 contains $2 34 | function docker_assert_log { 35 | local -r container=$1 36 | shift 37 | run docker logs $container 38 | assert_output -p "$*" 39 | } 40 | 41 | # wait for a container to produce a given text in its log 42 | # $1 container 43 | # $2 timeout in second 44 | # $* text to wait for 45 | function docker_wait_for_log { 46 | local -r container=$1 47 | local -ir timeout_sec=$2 48 | shift 2 49 | retry $(( $timeout_sec * 2 )) .5s docker_assert_log $container "$*" 50 | } 51 | 52 | # Create a docker container named $1 which exposes the docker host unix 53 | # socket over tcp on port 2375. 54 | # 55 | # $1 container name 56 | function docker_tcp { 57 | local container_name="$1" 58 | docker_clean $container_name 59 | docker run -d \ 60 | --label bats-type="socat" \ 61 | --name $container_name \ 62 | --expose 2375 \ 63 | -v /var/run/docker.sock:/var/run/docker.sock \ 64 | rancher/socat-docker 65 | docker run --label bats-type="docker" --link "$container_name:docker" docker:1.10 version 66 | } 67 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | ## Creating issues 4 | 5 | Feature requests and bug reports should be made by using the [issue tracker](https://github.com/cachethq/Docker/issues). This "Dockerized" version of Cachet is maintained by members the Cachet community, so support issues will be address on a best effort basis. 6 | 7 | **Always be respectful.** Organization members reserve the right to lock topics if they feel necessary. 8 | 9 | ## Branch and Tag Structure 10 | 11 | * `master`: Cachet with the upstream Cachet `master` codebase. 12 | * Minor version branches 13 | * Tags are used to denote a Cachet release, and correspond to Docker Hub automatic builds. 14 | 15 | # Releasing a new Cachet Docker image version 16 | 17 | The below example shows creating a `v2.3.1` release. 18 | 19 | ``` 20 | git checkout 2.3 21 | git checkout -b rel-2.3.1 22 | Set `ENV cachetversion v2.3.1` in Dockerfile 23 | git commit -am "Cachet v2.3.1 release" 24 | git tag -a v2.3.1 -m "Cachet Release v2.3.1" 25 | git push origin v2.3.1 26 | ``` 27 | 28 | Then to finish the process: 29 | 30 | * Add [Release on GitHub](https://github.com/CachetHQ/Docker/releases) 31 | * Add automated build for the new tag on [Docker Hub](https://hub.docker.com/r/cachethq/docker/builds/) 32 | 33 | Periodically back-port changes from most recent minor version branch to `master`. 34 | 35 | ## Multiple releases 36 | 37 | Sometimes we get a little behind the upstream Cachet project, and need to make a few releases at once. 38 | 39 | ``` 40 | gsed s/v2.3.7/v2.3.8/g -i Dockerfile 41 | git commit -am "Cachet v2.3.8 release" 42 | git tag -a v2.3.8 -m "Cachet Release v2.3.8" 43 | git push origin v2.3.8 44 | 45 | gsed s/v2.3.8/v2.3.9/g -i Dockerfile 46 | git commit -am "Cachet v2.3.9 release" 47 | git tag -a v2.3.9 -m "Cachet Release v2.3.9" 48 | git push origin v2.3.9 49 | 50 | gsed s/v2.3.9/v2.3.10/g -i Dockerfile 51 | git commit -am "Cachet v2.3.10 release" 52 | git tag -a v2.3.10 -m "Cachet Release v2.3.10" 53 | git push origin v2.3.10 54 | ``` 55 | 56 | Then setup releases on GitHub. 57 | -------------------------------------------------------------------------------- /test/test.sqlite.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helpers 3 | load docker_helpers 4 | load "lib/batslib" 5 | load "lib/output" 6 | 7 | @test "[$TEST_FILE] docker-compose up" { 8 | command docker-compose -f test/docker-compose-sqlite.yml up -d 9 | } 10 | 11 | @test "[$TEST_FILE] check for container init" { 12 | docker_wait_for_log test_cachet_1 15 "Initializing Cachet container ..." 13 | } 14 | 15 | @test "[$TEST_FILE] check for container start message" { 16 | docker_wait_for_log test_cachet_1 15 "Starting Cachet! ..." 17 | } 18 | 19 | @test "[$TEST_FILE] check for nginx startup" { 20 | docker_wait_for_log test_cachet_1 15 "INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 21 | } 22 | 23 | @test "[$TEST_FILE] check for php-fpm startup" { 24 | docker_wait_for_log test_cachet_1 15 "INFO success: php-fpm entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 25 | } 26 | 27 | @test "[$TEST_FILE] php artisan cachet:seed" { 28 | run docker exec test_cachet_1 php artisan cachet:seed 29 | assert_output -l 0 $'Database seeded with demo data successfully!' 30 | } 31 | 32 | @test "[$TEST_FILE] curl 200 response test" { 33 | run curl_container test_cachet_1 :8000/auth/login --head 34 | assert_output -l 0 $'HTTP/1.1 200 OK\r' 35 | } 36 | 37 | @test "[$TEST_FILE] login test" { 38 | run curl_container test_cachet_1 :8000/auth/login --head --user test:test123 39 | assert_output -l 0 $'HTTP/1.1 200 OK\r' 40 | } 41 | 42 | @test "[$TEST_FILE] check for curl API pong" { 43 | run curl_container test_cachet_1 :8000/api/v1/ping 44 | assert_output -l 0 $'{"data":"Pong!"}' 45 | } 46 | 47 | @test "[$TEST_FILE] restart cachet" { 48 | command docker-compose -f test/docker-compose-sqlite.yml stop cachet 49 | command docker-compose -f test/docker-compose-sqlite.yml rm -f cachet 50 | command docker-compose -f test/docker-compose-sqlite.yml up -d 51 | docker_wait_for_log test_cachet_1 15 "INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 52 | } 53 | 54 | @test "[$TEST_FILE] post-restart API pong" { 55 | run curl_container test_cachet_1 :8000/api/v1/ping 56 | assert_output -l 0 $'{"data":"Pong!"}' 57 | } 58 | 59 | @test "[$TEST_FILE] post-restart login test" { 60 | run curl_container test_cachet_1 :8000/auth/login --head --user test:test123 61 | assert_output -l 0 $'HTTP/1.1 200 OK\r' 62 | } 63 | 64 | @test "[$TEST_FILE] stop all test containers" { 65 | stop_bats_containers 66 | } 67 | 68 | @test "[$TEST_FILE] Cleanup test containers" { 69 | docker_clean test_cachet_1 70 | } 71 | -------------------------------------------------------------------------------- /test/test.mysql.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helpers 3 | load docker_helpers 4 | load "lib/batslib" 5 | load "lib/output" 6 | 7 | @test "[$TEST_FILE] docker-compose up" { 8 | command docker-compose -f test/docker-compose-mysql.yml up -d 9 | } 10 | 11 | @test "[$TEST_FILE] check for container init" { 12 | docker_wait_for_log test_cachet_1 15 "Initializing Cachet container ..." 13 | } 14 | 15 | @test "[$TEST_FILE] check for database startup" { 16 | docker_wait_for_log test_mysql_1 120 "mysqld: ready for connections." 17 | } 18 | 19 | @test "[$TEST_FILE] check for empty sessions table" { 20 | docker_wait_for_log test_cachet_1 15 "Table chq_sessions does not exist! ..." 21 | } 22 | 23 | @test "[$TEST_FILE] check for DB init" { 24 | docker_wait_for_log test_cachet_1 15 "Initializing Cachet database ..." 25 | } 26 | 27 | @test "[$TEST_FILE] check for populated sessions table" { 28 | docker_wait_for_log test_cachet_1 15 "Table chq_sessions exists! ..." 29 | } 30 | 31 | @test "[$TEST_FILE] check for container start message" { 32 | docker_wait_for_log test_cachet_1 15 "Starting Cachet! ..." 33 | } 34 | 35 | @test "[$TEST_FILE] check for nginx startup" { 36 | docker_wait_for_log test_cachet_1 15 "INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 37 | } 38 | 39 | @test "[$TEST_FILE] check for php-fpm startup" { 40 | docker_wait_for_log test_cachet_1 15 "INFO success: php-fpm entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 41 | } 42 | 43 | @test "[$TEST_FILE] php artisan cachet:seed" { 44 | run docker exec test_cachet_1 php artisan cachet:seed 45 | assert_output -l 0 $'Database seeded with demo data successfully!' 46 | } 47 | 48 | @test "[$TEST_FILE] curl 200 response test" { 49 | run curl_container test_cachet_1 :8000/auth/login --head 50 | assert_output -l 0 $'HTTP/1.1 200 OK\r' 51 | } 52 | 53 | @test "[$TEST_FILE] login test" { 54 | run curl_container test_cachet_1 :8000/auth/login --head --user test:test123 55 | assert_output -l 0 $'HTTP/1.1 200 OK\r' 56 | } 57 | 58 | @test "[$TEST_FILE] check for curl API pong" { 59 | run curl_container test_cachet_1 :8000/api/v1/ping 60 | assert_output -l 0 $'{"data":"Pong!"}' 61 | } 62 | 63 | @test "[$TEST_FILE] restart cachet" { 64 | command docker-compose -f test/docker-compose-mysql.yml stop cachet 65 | command docker-compose -f test/docker-compose-mysql.yml rm -f cachet 66 | command docker-compose -f test/docker-compose-mysql.yml up -d 67 | docker_wait_for_log test_cachet_1 15 "INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 68 | } 69 | 70 | @test "[$TEST_FILE] post-restart API pong" { 71 | run curl_container test_cachet_1 :8000/api/v1/ping 72 | assert_output -l 0 $'{"data":"Pong!"}' 73 | } 74 | 75 | @test "[$TEST_FILE] post-restart login test" { 76 | run curl_container test_cachet_1 :8000/auth/login --head --user test:test123 77 | assert_output -l 0 $'HTTP/1.1 200 OK\r' 78 | } 79 | 80 | @test "[$TEST_FILE] stop all test containers" { 81 | stop_bats_containers 82 | } 83 | 84 | @test "[$TEST_FILE] Cleanup test containers" { 85 | docker_clean test_cachet_1 86 | docker_clean test_mysql_1 87 | } 88 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.17.8-alpine 2 | 3 | EXPOSE 8000 4 | CMD ["/sbin/entrypoint.sh"] 5 | 6 | ARG cachet_ver 7 | ARG archive_url 8 | 9 | ENV cachet_ver ${cachet_ver:-2.4} 10 | ENV archive_url ${archive_url:-https://github.com/cachethq/Cachet/archive/${cachet_ver}.tar.gz} 11 | 12 | ENV COMPOSER_VERSION 1.9.0 13 | 14 | RUN apk add --no-cache --update \ 15 | mysql-client \ 16 | php7 \ 17 | php7-apcu \ 18 | php7-bcmath \ 19 | php7-ctype \ 20 | php7-curl \ 21 | php7-dom \ 22 | php7-fileinfo \ 23 | php7-fpm \ 24 | php7-gd \ 25 | php7-iconv \ 26 | php7-intl \ 27 | php7-json \ 28 | php7-mbstring \ 29 | php7-mcrypt \ 30 | php7-mysqlnd \ 31 | php7-opcache \ 32 | php7-openssl \ 33 | php7-pdo \ 34 | php7-pdo_mysql \ 35 | php7-pdo_pgsql \ 36 | php7-pdo_sqlite \ 37 | php7-phar \ 38 | php7-posix \ 39 | php7-redis \ 40 | php7-session \ 41 | php7-simplexml \ 42 | php7-soap \ 43 | php7-sqlite3 \ 44 | php7-tokenizer \ 45 | php7-xml \ 46 | php7-xmlwriter \ 47 | php7-zip \ 48 | php7-zlib \ 49 | postfix \ 50 | postgresql \ 51 | postgresql-client \ 52 | sqlite \ 53 | sudo \ 54 | wget sqlite git curl bash grep \ 55 | supervisor 56 | 57 | # forward request and error logs to docker log collector 58 | RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ 59 | ln -sf /dev/stderr /var/log/nginx/error.log && \ 60 | ln -sf /dev/stdout /var/log/php7/error.log && \ 61 | ln -sf /dev/stderr /var/log/php7/error.log 62 | 63 | RUN adduser -S -s /bin/bash -u 1001 -G root www-data 64 | 65 | RUN echo "www-data ALL=(ALL:ALL) NOPASSWD:SETENV: /usr/sbin/postfix" >> /etc/sudoers 66 | 67 | RUN touch /var/run/nginx.pid && \ 68 | chown -R www-data:root /var/run/nginx.pid 69 | 70 | RUN chown -R www-data:root /etc/php7/php-fpm.d 71 | 72 | RUN mkdir -p /var/www/html && \ 73 | mkdir -p /usr/share/nginx/cache && \ 74 | mkdir -p /var/cache/nginx && \ 75 | mkdir -p /var/lib/nginx && \ 76 | chown -R www-data:root /var/www /usr/share/nginx/cache /var/cache/nginx /var/lib/nginx/ 77 | 78 | # Install composer 79 | RUN wget https://getcomposer.org/installer -O /tmp/composer-setup.php && \ 80 | wget https://composer.github.io/installer.sig -O /tmp/composer-setup.sig && \ 81 | php -r "if (hash('SHA384', file_get_contents('/tmp/composer-setup.php')) !== trim(file_get_contents('/tmp/composer-setup.sig'))) { unlink('/tmp/composer-setup.php'); echo 'Invalid installer' . PHP_EOL; exit(1); }" && \ 82 | php /tmp/composer-setup.php --version=$COMPOSER_VERSION --install-dir=bin && \ 83 | php -r "unlink('/tmp/composer-setup.php');" 84 | 85 | WORKDIR /var/www/html/ 86 | USER 1001 87 | 88 | RUN wget ${archive_url} && \ 89 | tar xzf ${cachet_ver}.tar.gz --strip-components=1 && \ 90 | chown -R www-data:root /var/www/html && \ 91 | rm -r ${cachet_ver}.tar.gz && \ 92 | php /bin/composer.phar global require "hirak/prestissimo:^0.3" && \ 93 | php /bin/composer.phar install -o && \ 94 | rm -rf bootstrap/cache/* 95 | 96 | COPY conf/php-fpm-pool.conf /etc/php7/php-fpm.d/www.conf 97 | COPY conf/supervisord.conf /etc/supervisor/supervisord.conf 98 | COPY conf/nginx.conf /etc/nginx/nginx.conf 99 | COPY conf/nginx-site.conf /etc/nginx/conf.d/default.conf 100 | COPY conf/.env.docker /var/www/html/.env 101 | COPY entrypoint.sh /sbin/entrypoint.sh 102 | 103 | USER root 104 | RUN chmod g+rwx /var/run/nginx.pid && \ 105 | chmod -R g+rw /var/www /usr/share/nginx/cache /var/cache/nginx /var/lib/nginx/ /etc/php7/php-fpm.d storage 106 | USER 1001 107 | -------------------------------------------------------------------------------- /openshift/cachethd-dc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: cachet 5 | labels: 6 | app: cachet 7 | annotations: 8 | spec: 9 | strategy: 10 | type: Rolling 11 | rollingParams: 12 | updatePeriodSeconds: 1 13 | intervalSeconds: 1 14 | timeoutSeconds: 600 15 | maxUnavailable: 25% 16 | maxSurge: 25% 17 | resources: 18 | triggers: 19 | - 20 | type: ConfigChange 21 | replicas: 1 22 | test: false 23 | selector: 24 | app: cachet 25 | deploymentconfig: cachet 26 | template: 27 | metadata: 28 | creationTimestamp: null 29 | labels: 30 | app: cachet 31 | deploymentconfig: cachet 32 | annotations: 33 | spec: 34 | containers: 35 | - 36 | name: cachet 37 | image: cachethq/docker:2.3.10 38 | ports: 39 | - 40 | containerPort: 80 41 | protocol: TCP 42 | env: 43 | - 44 | name: APP_ENV 45 | value: nonProd 46 | - 47 | name: APP_DEBUG 48 | value: 'true' 49 | - 50 | name: APP_URL 51 | value: 'https://demo.cachethq.io/api/v1' 52 | - 53 | name: APP_KEY 54 | value: 'base64:KEY' 55 | - 56 | name: DB_DRIVER 57 | value: pgsql #pqsql mysql 58 | - 59 | name: DB_HOST 60 | value: db_hostname 61 | - 62 | name: DB_DATABASE 63 | value: cachethq 64 | - 65 | name: DB_USERNAME 66 | value: cachethq 67 | - 68 | name: DB_PASSWORD 69 | value: mypassword 70 | - 71 | name: DB_PORT 72 | value: 'null' 73 | - 74 | name: DB_PREFIX 75 | value: 'null' 76 | - 77 | name: DOCKER #this is need so when the container restarts it will not have you do setup again. 78 | value: 'true' 79 | - 80 | name: CACHE_DRIVER 81 | value: apc 82 | - 83 | name: SESSION_DRIVER 84 | value: apc 85 | - 86 | name: QUEUE_DRIVER 87 | value: database 88 | - 89 | name: CACHET_EMOJI 90 | value: 'false' 91 | - 92 | name: MAIL_DRIVER 93 | value: smtp 94 | - 95 | name: MAIL_HOST 96 | value: smtp.hostname.com 97 | - 98 | name: MAIL_PORT 99 | value: '25' 100 | - 101 | name: MAIL_USERNAME 102 | value: 'null' 103 | - 104 | name: MAIL_PASSWORD 105 | value: 'null' 106 | - 107 | name: MAIL_ADDRESS 108 | value: 'null' 109 | - 110 | name: MAIL_NAME 111 | value: 'null' 112 | - 113 | name: MAIL_ENCRYPTION 114 | value: 'null' 115 | - 116 | name: REDIS_HOST 117 | value: 'null' 118 | - 119 | name: REDIS_DATABASE 120 | value: 'null' 121 | - 122 | name: REDIS_PORT 123 | value: 'null' 124 | - 125 | name: GITHUB_TOKEN 126 | value: 'null' 127 | resources: 128 | terminationMessagePath: /dev/termination-log 129 | imagePullPolicy: Always 130 | restartPolicy: Always 131 | terminationGracePeriodSeconds: 30 132 | dnsPolicy: ClusterFirst 133 | securityContext: 134 | runAsUser: 0 135 | status: 136 | -------------------------------------------------------------------------------- /test/test.full.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helpers 3 | load docker_helpers 4 | load "lib/batslib" 5 | load "lib/output" 6 | 7 | @test "[$TEST_FILE] testing Cachet Docker image build" { 8 | command docker-compose build --no-cache cachet 9 | } 10 | 11 | @test "[$TEST_FILE] testing Cachet docker-compose up" { 12 | command docker-compose up -d 13 | } 14 | 15 | @test "[$TEST_FILE] check for container init" { 16 | docker_wait_for_log docker_cachet_1 15 "Initializing Cachet container ..." 17 | } 18 | 19 | @test "[$TEST_FILE] check for postgres database startup" { 20 | docker_wait_for_log docker_postgres_1 120 "LOG: database system is ready to accept connections" 21 | } 22 | 23 | @test "[$TEST_FILE] check for empty sessions table" { 24 | docker_wait_for_log docker_cachet_1 15 "Table chq_sessions does not exist! ..." 25 | } 26 | 27 | @test "[$TEST_FILE] check for DB init" { 28 | docker_wait_for_log docker_cachet_1 15 "Initializing Cachet database ..." 29 | } 30 | 31 | @test "[$TEST_FILE] check for populated sessions table" { 32 | docker_wait_for_log docker_cachet_1 15 "Table chq_sessions exists! ..." 33 | } 34 | 35 | @test "[$TEST_FILE] check for container start message" { 36 | docker_wait_for_log docker_cachet_1 15 "Starting Cachet! ..." 37 | } 38 | 39 | @test "[$TEST_FILE] check for nginx startup" { 40 | docker_wait_for_log docker_cachet_1 15 "INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 41 | } 42 | 43 | @test "[$TEST_FILE] check for php-fpm startup" { 44 | docker_wait_for_log docker_cachet_1 15 "INFO success: php-fpm entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 45 | } 46 | 47 | @test "[$TEST_FILE] check for queue-worker startup" { 48 | docker_wait_for_log docker_cachet_1 15 "INFO success: queue-worker entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 49 | } 50 | 51 | @test "[$TEST_FILE] php artisan cachet:seed" { 52 | run docker exec docker_cachet_1 php artisan cachet:seed 53 | assert_output -l 0 $'Database seeded with demo data successfully!' 54 | } 55 | 56 | @test "[$TEST_FILE] curl 200 response test" { 57 | run curl_container docker_cachet_1 :8000/auth/login --head 58 | assert_output -l 0 $'HTTP/1.1 200 OK\r' 59 | } 60 | 61 | @test "[$TEST_FILE] login test" { 62 | run curl_container docker_cachet_1 :8000/auth/login --head --user test:test123 63 | assert_output -l 0 $'HTTP/1.1 200 OK\r' 64 | } 65 | 66 | @test "[$TEST_FILE] check for curl API pong" { 67 | run curl_container docker_cachet_1 :8000/api/v1/ping 68 | assert_output -l 0 $'{"data":"Pong!"}' 69 | } 70 | 71 | @test "[$TEST_FILE] check for pg_dump version mismatch" { 72 | run docker exec docker_cachet_1 php artisan app:update 73 | refute_output -l 5 $'pg_dump: aborting because of server version mismatch' 74 | } 75 | 76 | @test "[$TEST_FILE] ensure there are no volumes" { 77 | run docker inspect -f '{{ .Mounts }}' docker_cachet_1 78 | assert_output -l 0 $'[]' 79 | } 80 | 81 | @test "[$TEST_FILE] restart cachet" { 82 | command docker-compose stop cachet 83 | command docker-compose rm -f cachet 84 | command docker-compose up -d 85 | docker_wait_for_log docker_cachet_1 15 "INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)" 86 | } 87 | 88 | @test "[$TEST_FILE] post-restart API pong" { 89 | run curl_container docker_cachet_1 :8000/api/v1/ping 90 | assert_output -l 0 $'{"data":"Pong!"}' 91 | } 92 | 93 | @test "[$TEST_FILE] post-restart login test" { 94 | run curl_container docker_cachet_1 :8000/auth/login --head --user test:test123 95 | assert_output -l 0 $'HTTP/1.1 200 OK\r' 96 | } 97 | 98 | @test "[$TEST_FILE] stop all test containers" { 99 | stop_bats_containers 100 | } 101 | 102 | @test "[$TEST_FILE] Cleanup test containers" { 103 | docker_clean docker_cachet_1 104 | docker_clean docker_postgres_1 105 | } 106 | -------------------------------------------------------------------------------- /release-helper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #/ Usage: release-helper.sh [-hdc] 3 | #/ 4 | #/ Creates a temporary branch from which a new release will be tagged and pushed. 5 | #/ 6 | #/ OPTIONS: 7 | #/ -h | --help Show this message. 8 | #/ -d | --delete Delete a tag / release 9 | #/ -c | --check Check current releases on GitHub 10 | #/ Target Cachet Version (ex: v2.3.13) 11 | #/ 12 | set -e 13 | 14 | usage () { 15 | grep "^#/" <"$0" | cut -c4- 16 | exit "${1:-2}" 17 | } 18 | 19 | [ $# -eq 0 ] && usage 1 20 | 21 | cachet_version= 22 | main_version=2.4 23 | 24 | do_release () { 25 | 26 | # Make sure we are on clean branch 27 | if [[ ! $(git branch --list cachet-"$cachet_version") ]]; then 28 | echo "Creating new branch cachet-$cachet_version" 29 | git checkout -b cachet-"$cachet_version" 30 | else 31 | echo "Branch cachet-$cachet_version already exists!" 32 | git checkout cachet-"$cachet_version" 33 | fi 34 | 35 | # Generate changelog (requires https://github.com/skywinder/github-changelog-generator) 36 | if hash github_changelog_generator 2>/dev/null; then 37 | github_changelog_generator -u CachetHQ --project Docker --token "$token" --future-release "$cachet_version" 38 | fi 39 | 40 | # Modify Dockerfile, commit, tag, and push 41 | echo "Creating tag for $cachet_version" 42 | gsed s/$main_version/"$cachet_version"/g -i Dockerfile 43 | git commit -am "Cachet $cachet_version release" 44 | git tag -a "$cachet_version" -m "Cachet Release $cachet_version" 45 | git push origin cachet-"$cachet_version" 46 | git push origin "$cachet_version" 47 | 48 | # Create GitHub release 49 | curl -H "Authorization: token $token" -s -H "Content-Type: application/json" -d '{"tag_name":"'"${cachet_version}"'","name":"'"${cachet_version}"'","body":"Cachet Release '"${cachet_version}"'","draft":false,"prerelease":false}' -X POST https://api.github.com/repos/CachetHQ/Docker/releases 50 | } 51 | 52 | check_releases () { 53 | # Get latest releases 54 | CACHET_APP_LATEST_REL=$(curl -H "Authorization: token $token" -s https://api.github.com/repos/cachethq/cachet/releases/latest | jq -r .name) 55 | CACHET_DOCKER_LATEST_REL=$(curl -H "Authorization: token $token" -s https://api.github.com/repos/cachethq/docker/releases/latest | jq -r .name) 56 | 57 | echo "Latest Cachet release: $CACHET_APP_LATEST_REL" 58 | echo "Latest Docker release: $CACHET_DOCKER_LATEST_REL" 59 | 60 | # Compare versions 61 | if [ "$CACHET_APP_LATEST_REL" = "$CACHET_DOCKER_LATEST_REL" ] 62 | then 63 | echo "Releases on GitHub are up to date!" 64 | else 65 | echo "Docker at "$CACHET_DOCKER_LATEST_REL" -- Releasing latest app release $CACHET_APP_LATEST_REL" 66 | cachet_version="$CACHET_APP_LATEST_REL" 67 | do_release 68 | fi 69 | 70 | } 71 | 72 | delete_release () { 73 | if [ -z "$cachet_version" ]; then 74 | echo 1>&2 "error: no version specified." 75 | exit 1 76 | fi 77 | echo "Removing release $cachet_version" 78 | release_id=$(curl -H "Authorization: token $token" -s -X GET https://api.github.com/repos/CachetHQ/Docker/releases/tags/"$cachet_version" | jq -r .id) 79 | curl -H "Authorization: token $token" -s -X DELETE https://api.github.com/repos/CachetHQ/Docker/releases/"$release_id" || true 80 | git tag -d "$cachet_version" || true 81 | git push origin :"$cachet_version" || true 82 | git branch -d cachet-"$cachet_version" || true 83 | } 84 | 85 | # GitHub API Token 86 | token=${GITHUB_TOKEN} 87 | 88 | if [ -z "$token" ] 89 | then 90 | echo 1>&2 "error: please set GITHUB_TOKEN in your local environment." 91 | exit 1 92 | fi 93 | 94 | # Parse args. 95 | ARGS=$(getopt --name "$0" --long help,delete,check,update: --options hdcu: -- "$@") || { 96 | usage 97 | exit 2 98 | } 99 | eval set -- "$ARGS" 100 | 101 | while [ $# -gt 0 ]; do 102 | shift 103 | case "$1" in 104 | -h|--help) 105 | usage 106 | exit 2 107 | ;; 108 | -d|--delete) 109 | cachet_version=$2 110 | delete_release 111 | exit 0 112 | ;; 113 | -c|--check) 114 | check_releases 115 | exit 0 116 | ;; 117 | -u|--update) 118 | cachet_version=$2 119 | echo "Updating to Cachet version: $2" 120 | do_release 121 | break 122 | exit 0 123 | ;; 124 | --) 125 | cachet_version=$2 126 | do_release 127 | shift 128 | break 129 | ;; 130 | esac 131 | shift 132 | done 133 | 134 | if [ -z "$cachet_version" ]; then 135 | echo 1>&2 "error: no version specified." 136 | exit 1 137 | fi 138 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cachet Docker Image 2 | 3 | This is the official repository of the [Docker image](https://hub.docker.com/r/cachethq/docker/) for [Cachet](https://github.com/CachetHQ/Cachet). 4 | 5 | [Cachet](https://github.com/CachetHQ/Cachet) is a beautiful and powerful open source status page system, a free replacement for services such as StatusPage.io, Status.io and others. 6 | 7 | For full documentation, visit the [Installing Cachet with Docker](https://docs.cachethq.io/docs/get-started-with-docker) page. 8 | 9 | # Supporting Cachet 10 | 11 | Cachet is a BSD-3-licensed open source project. If you'd like to support future development, check out the [Cachet Patreon](https://patreon.com/jbrooksuk) campaign. 12 | 13 | # Quickstart 14 | 15 | 1. Clone this repository 16 | 17 | ```shell 18 | git clone https://github.com/CachetHQ/Docker.git 19 | ``` 20 | 21 | 2. Edit the docker-compose.yml file to specify your [ENV variables](/conf/.env.docker). 22 | 23 | 24 | 3. To build an image containing a specific Cachet release, set the [`cachet_ver` ARG in the docker-compose.yml](/docker-compose.yml) 25 | 26 | The *main* branch and *cachethq/docker:latest* Docker automated build are a work in progress / development version of the upstream https://github.com/CachetHQ/Cachet project. As such, *main* or *latest* should not be used in a production environment as it can change at anytime. 27 | 28 | We strongly recommend specifying a stable [Cachet Release](https://github.com/CachetHQ/Cachet/releases) at build time as mentioned above. 29 | 30 | 4. Build and run the image 31 | 32 | ```shell 33 | docker-compose build 34 | docker-compose up 35 | ``` 36 | 37 | 5. `cachethq/docker` runs on port 8000 by default. This is exposed on host port 80 when using docker-compose. 38 | 39 | 40 | 6. Setup the APP_KEY 41 | 42 | Whilst the container is up and running, find the name of the Cachet container via `docker ps`. 43 | 44 | Run `docker exec -i ID_OF_THE_CONTAINER php artisan key:generate`. 45 | 46 | Replace `${APP_KEY:-null}` in `docker-compose.yml` with the newly generated Application key. 47 | 48 | __Note:__ make sure you include `base64:` prefix. E.g. `base64:YOUR_UNIQUE_KEY` 49 | 50 | Restart the Docker containers. 51 | 52 | 53 | # Docker Hub Automated build 54 | 55 | `cachethq/docker` is available as a [Docker Hub Trusted Build](https://hub.docker.com/r/cachethq/docker/). 56 | 57 | For a full list of Cachet versions released as Docker images please see the [list of Docker hub tags](https://hub.docker.com/r/cachethq/docker/tags/). 58 | 59 | Please use a [tagged Cachet Docker image release](https://github.com/CachetHQ/Docker/releases) or one of the tagged builds from https://hub.docker.com/r/cachethq/docker/tags/ with `docker pull cachethq/docker:2.3.12`. 60 | 61 | # Debugging 62 | 63 | * The services such as Cachet, supervisord, nginx, and php-fpm log to `stdout` and `stderr`, and are visible in the Docker runtime output. 64 | 65 | * Setting the `DEBUG` Docker environment variable within the `docker-compose.yml` file or at runtime to `true` will enable debugging of the container entrypoint init script. 66 | 67 | # Testing 68 | 69 | Pull requests must pass the [Bash Automated Testing System](https://github.com/sstephenson/bats) tests, which run on [Travis CI](https://travis-ci.org/CachetHQ/Docker) via located in the [test](test) directory. 70 | 71 | Use `make test` to manually run the tests. 72 | 73 | 74 | # Development of Cachet using this docker environment 75 | 76 | 1. Clone the official repo of CachetHQ/Docker: 77 | 78 | ```shell 79 | git clone https://github.com/CachetHQ/Docker.git cachet-docker 80 | cd cachet-docker 81 | git tag -l 82 | git checkout $LATEST_TAG 83 | ``` 84 | 2. Clone the official repo of CachetHQ/Cachet here and do composer install: 85 | 86 | ```shell 87 | git clone https://github.com/CachetHQ/Cachet.git 88 | ``` 89 | 90 | 3. Setup the Cachet project: 91 | 92 | Note: This requires [Composer](https://getcomposer.org/) be installed on your Docker host. 93 | 94 | ```shell 95 | cd Cachet 96 | composer install 97 | cp ../conf/.env.docker ./.env 98 | cd .. 99 | ``` 100 | 101 | 4. Edit the docker-compose.yml file to bind mount the repo as a volume: 102 | 103 | ```yaml 104 | cachet: 105 | volumes: 106 | - ./Cachet/:/var/www/html/ 107 | ... 108 | ``` 109 | 110 | 5. Build and run the container: 111 | 112 | ```shell 113 | docker-compose up 114 | ``` 115 | 116 | 6. Open new terminal and run the following commands after getting container name via `docker ps`: 117 | 118 | ```shell 119 | docker exec -i cachetdocker_cachet_1 php artisan key:generate 120 | docker exec -i cachetdocker_cachet_1 php artisan app:install 121 | ``` 122 | -------------------------------------------------------------------------------- /test/lib/output.bash: -------------------------------------------------------------------------------- 1 | # 2 | # output.bash 3 | # ----------- 4 | # 5 | # Private functions implementing output formatting. Used by public 6 | # helper functions. 7 | # 8 | 9 | # Print a message to the standard error. When no parameters are 10 | # specified, the message is read from the standard input. 11 | # 12 | # Globals: 13 | # none 14 | # Arguments: 15 | # $@ - [=STDIN] message 16 | # Returns: 17 | # none 18 | # Inputs: 19 | # STDIN - [=$@] message 20 | # Outputs: 21 | # STDERR - message 22 | batslib_err() { 23 | { if (( $# > 0 )); then 24 | echo "$@" 25 | else 26 | cat - 27 | fi 28 | } >&2 29 | } 30 | 31 | # Count the number of lines in the given string. 32 | # 33 | # TODO(ztombol): Fix tests and remove this note after #93 is resolved! 34 | # NOTE: Due to a bug in Bats, `batslib_count_lines "$output"' does not 35 | # give the same result as `${#lines[@]}' when the output contains 36 | # empty lines. 37 | # See PR #93 (https://github.com/sstephenson/bats/pull/93). 38 | # 39 | # Globals: 40 | # none 41 | # Arguments: 42 | # $1 - string 43 | # Returns: 44 | # none 45 | # Outputs: 46 | # STDOUT - number of lines 47 | batslib_count_lines() { 48 | local -i n_lines=0 49 | local line 50 | while IFS='' read -r line || [[ -n $line ]]; do 51 | (( ++n_lines )) 52 | done < <(printf '%s' "$1") 53 | echo "$n_lines" 54 | } 55 | 56 | # Determine whether all strings are single-line. 57 | # 58 | # Globals: 59 | # none 60 | # Arguments: 61 | # $@ - strings 62 | # Returns: 63 | # 0 - all strings are single-line 64 | # 1 - otherwise 65 | batslib_is_single_line() { 66 | for string in "$@"; do 67 | (( $(batslib_count_lines "$string") > 1 )) && return 1 68 | done 69 | return 0 70 | } 71 | 72 | # Determine the length of the longest key that has a single-line value. 73 | # 74 | # This function is useful in determining the correct width of the key 75 | # column in two-column format when some keys may have multi-line values 76 | # and thus should be excluded. 77 | # 78 | # Globals: 79 | # none 80 | # Arguments: 81 | # $odd - key 82 | # $even - value of the previous key 83 | # Returns: 84 | # none 85 | # Outputs: 86 | # STDOUT - length of longest key 87 | batslib_get_max_single_line_key_width() { 88 | local -i max_len=-1 89 | while (( $# != 0 )); do 90 | local -i key_len="${#1}" 91 | batslib_is_single_line "$2" && (( key_len > max_len )) && max_len="$key_len" 92 | shift 2 93 | done 94 | echo "$max_len" 95 | } 96 | 97 | # Print key-value pairs in two-column format. 98 | # 99 | # Keys are displayed in the first column, and their corresponding values 100 | # in the second. To evenly line up values, the key column is fixed-width 101 | # and its width is specified with the first parameter (possibly computed 102 | # using `batslib_get_max_single_line_key_width'). 103 | # 104 | # Globals: 105 | # none 106 | # Arguments: 107 | # $1 - width of key column 108 | # $even - key 109 | # $odd - value of the previous key 110 | # Returns: 111 | # none 112 | # Outputs: 113 | # STDOUT - formatted key-value pairs 114 | batslib_print_kv_single() { 115 | local -ir col_width="$1"; shift 116 | while (( $# != 0 )); do 117 | printf '%-*s : %s\n' "$col_width" "$1" "$2" 118 | shift 2 119 | done 120 | } 121 | 122 | # Print key-value pairs in multi-line format. 123 | # 124 | # The key is displayed first with the number of lines of its 125 | # corresponding value in parenthesis. Next, starting on the next line, 126 | # the value is displayed. For better readability, it is recommended to 127 | # indent values using `batslib_prefix'. 128 | # 129 | # Globals: 130 | # none 131 | # Arguments: 132 | # $odd - key 133 | # $even - value of the previous key 134 | # Returns: 135 | # none 136 | # Outputs: 137 | # STDOUT - formatted key-value pairs 138 | batslib_print_kv_multi() { 139 | while (( $# != 0 )); do 140 | printf '%s (%d lines):\n' "$1" "$( batslib_count_lines "$2" )" 141 | printf '%s\n' "$2" 142 | shift 2 143 | done 144 | } 145 | 146 | # Print all key-value pairs in either two-column or multi-line format 147 | # depending on whether all values are single-line. 148 | # 149 | # If all values are single-line, print all pairs in two-column format 150 | # with the specified key column width (identical to using 151 | # `batslib_print_kv_single'). 152 | # 153 | # Otherwise, print all pairs in multi-line format after indenting values 154 | # with two spaces for readability (identical to using `batslib_prefix' 155 | # and `batslib_print_kv_multi') 156 | # 157 | # Globals: 158 | # none 159 | # Arguments: 160 | # $1 - width of key column (for two-column format) 161 | # $even - key 162 | # $odd - value of the previous key 163 | # Returns: 164 | # none 165 | # Outputs: 166 | # STDOUT - formatted key-value pairs 167 | batslib_print_kv_single_or_multi() { 168 | local -ir width="$1"; shift 169 | local -a pairs=( "$@" ) 170 | 171 | local -a values=() 172 | local -i i 173 | for (( i=1; i < ${#pairs[@]}; i+=2 )); do 174 | values+=( "${pairs[$i]}" ) 175 | done 176 | 177 | if batslib_is_single_line "${values[@]}"; then 178 | batslib_print_kv_single "$width" "${pairs[@]}" 179 | else 180 | local -i i 181 | for (( i=1; i < ${#pairs[@]}; i+=2 )); do 182 | pairs[$i]="$( batslib_prefix < <(printf '%s' "${pairs[$i]}") )" 183 | done 184 | batslib_print_kv_multi "${pairs[@]}" 185 | fi 186 | } 187 | 188 | # Prefix each line read from the standard input with the given string. 189 | # 190 | # Globals: 191 | # none 192 | # Arguments: 193 | # $1 - [= ] prefix string 194 | # Returns: 195 | # none 196 | # Inputs: 197 | # STDIN - lines 198 | # Outputs: 199 | # STDOUT - prefixed lines 200 | batslib_prefix() { 201 | local -r prefix="${1:- }" 202 | local line 203 | while IFS='' read -r line || [[ -n $line ]]; do 204 | printf '%s%s\n' "$prefix" "$line" 205 | done 206 | } 207 | 208 | # Mark select lines of the text read from the standard input by 209 | # overwriting their beginning with the given string. 210 | # 211 | # Usually the input is indented by a few spaces using `batslib_prefix' 212 | # first. 213 | # 214 | # Globals: 215 | # none 216 | # Arguments: 217 | # $1 - marking string 218 | # $@ - indices (zero-based) of lines to mark 219 | # Returns: 220 | # none 221 | # Inputs: 222 | # STDIN - lines 223 | # Outputs: 224 | # STDOUT - lines after marking 225 | batslib_mark() { 226 | local -r symbol="$1"; shift 227 | # Sort line numbers. 228 | set -- $( sort -nu <<< "$( printf '%d\n' "$@" )" ) 229 | 230 | local line 231 | local -i idx=0 232 | while IFS='' read -r line || [[ -n $line ]]; do 233 | if (( ${1:--1} == idx )); then 234 | printf '%s\n' "${symbol}${line:${#symbol}}" 235 | shift 236 | else 237 | printf '%s\n' "$line" 238 | fi 239 | (( ++idx )) 240 | done 241 | } 242 | 243 | # Enclose the input text in header and footer lines. 244 | # 245 | # The header contains the given string as title. The output is preceded 246 | # and followed by an additional newline to make it stand out more. 247 | # 248 | # Globals: 249 | # none 250 | # Arguments: 251 | # $1 - title 252 | # Returns: 253 | # none 254 | # Inputs: 255 | # STDIN - text 256 | # Outputs: 257 | # STDOUT - decorated text 258 | batslib_decorate() { 259 | echo 260 | echo "-- $1 --" 261 | cat - 262 | echo '--' 263 | echo 264 | } -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit -o nounset -o pipefail 3 | 4 | [ "${DEBUG:-false}" == true ] && set -x 5 | 6 | check_database_connection() { 7 | echo "Attempting to connect to database ..." 8 | case "${DB_DRIVER}" in 9 | mysql) 10 | prog="mysqladmin -h ${DB_HOST} -u ${DB_USERNAME} ${DB_PASSWORD:+-p$DB_PASSWORD} -P ${DB_PORT} status" 11 | ;; 12 | pgsql) 13 | prog="/usr/bin/pg_isready" 14 | prog="${prog} -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USERNAME} -d ${DB_DATABASE} -t 1" 15 | ;; 16 | sqlite) 17 | prog="touch /var/www/html/database/database.sqlite" 18 | esac 19 | timeout=60 20 | while ! ${prog} >/dev/null 2>&1 21 | do 22 | timeout=$(( timeout - 1 )) 23 | if [[ "$timeout" -eq 0 ]]; then 24 | echo 25 | echo "Could not connect to database server! Aborting..." 26 | exit 1 27 | fi 28 | echo -n "." 29 | sleep 1 30 | done 31 | echo 32 | } 33 | 34 | checkdbinitmysql() { 35 | table=sessions 36 | if [[ "$(mysql -N -s -h "${DB_HOST}" -u "${DB_USERNAME}" "${DB_PASSWORD:+-p$DB_PASSWORD}" "${DB_DATABASE}" -P "${DB_PORT}" -e \ 37 | "select count(*) from information_schema.tables where \ 38 | table_schema='${DB_DATABASE}' and table_name='${DB_PREFIX}${table}';")" -eq 1 ]]; then 39 | echo "Table ${DB_PREFIX}${table} exists! ..." 40 | else 41 | echo "Table ${DB_PREFIX}${table} does not exist! ..." 42 | init_db 43 | fi 44 | 45 | } 46 | 47 | checkdbinitpsql() { 48 | table=sessions 49 | export PGPASSWORD=${DB_PASSWORD} 50 | if [[ "$(psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USERNAME}" -d "${DB_DATABASE}" -c "SELECT to_regclass('${DB_PREFIX}${table}');" | grep -c "${DB_PREFIX}${table}")" -eq 1 ]]; then 51 | echo "Table ${DB_PREFIX}${table} exists! ..." 52 | else 53 | echo "Table ${DB_PREFIX}${table} does not exist! ..." 54 | init_db 55 | fi 56 | 57 | } 58 | 59 | check_configured() { 60 | case "${DB_DRIVER}" in 61 | mysql) 62 | checkdbinitmysql 63 | ;; 64 | pgsql) 65 | checkdbinitpsql 66 | ;; 67 | esac 68 | } 69 | 70 | check_sendmail() { 71 | if [[ "${MAIL_DRIVER:-}" == "sendmail" ]]; then 72 | sudo /usr/sbin/postfix start 73 | fi 74 | } 75 | 76 | initialize_system() { 77 | echo "Initializing Cachet container ..." 78 | 79 | APP_KEY=${APP_KEY:-} 80 | APP_ENV=${APP_ENV:-development} 81 | APP_DEBUG=${APP_DEBUG:-true} 82 | APP_URL=${APP_URL:-http://localhost} 83 | APP_LOG=${APP_LOG:-errorlog} 84 | 85 | DB_DRIVER=${DB_DRIVER:-pgsql} 86 | DB_HOST=${DB_HOST:-postgres} 87 | DB_DATABASE=${DB_DATABASE:-cachet} 88 | DB_PREFIX=${DB_PREFIX:-} 89 | DB_USERNAME=${DB_USERNAME:-postgres} 90 | DB_PASSWORD=${DB_PASSWORD:-postgres} 91 | DB_PORT=${DB_PORT:-} 92 | DB_PREFIX=${DB_PREFIX:-} 93 | 94 | if [[ "${DB_DRIVER}" = "pgsql" ]]; then 95 | DB_PORT=${DB_PORT:-5432} 96 | fi 97 | 98 | if [[ "${DB_DRIVER}" = "mysql" ]]; then 99 | DB_PORT=${DB_PORT:-3306} 100 | fi 101 | 102 | if [[ "${DB_DRIVER}" = "sqlite" ]]; then 103 | DB_DATABASE="" 104 | DB_HOST="" 105 | DB_PORT="" 106 | DB_USERNAME="" 107 | DB_PASSWORD="" 108 | fi 109 | 110 | CACHE_DRIVER=${CACHE_DRIVER:-apc} 111 | 112 | SESSION_DRIVER=${SESSION_DRIVER:-apc} 113 | SESSION_DOMAIN=${SESSION_DOMAIN:-} 114 | SESSION_SECURE_COOKIE=${SESSION_SECURE_COOKIE:-} 115 | 116 | QUEUE_DRIVER=${QUEUE_DRIVER:-database} 117 | CACHET_EMOJI=${CACHET_EMOJI:-false} 118 | CACHET_BEACON=${CACHET_BEACON:-true} 119 | CACHET_AUTO_TWITTER=${CACHET_AUTO_TWITTER:-true} 120 | 121 | MAIL_DRIVER=${MAIL_DRIVER:-smtp} 122 | MAIL_HOST=${MAIL_HOST:-localhost} 123 | MAIL_PORT=${MAIL_PORT:-25} 124 | MAIL_USERNAME=${MAIL_USERNAME:-} 125 | MAIL_PASSWORD=${MAIL_PASSWORD:-} 126 | MAIL_ADDRESS=${MAIL_ADDRESS:-} 127 | MAIL_NAME=${MAIL_NAME:-} 128 | MAIL_ENCRYPTION=${MAIL_ENCRYPTION:-} 129 | 130 | REDIS_HOST=${REDIS_HOST:-} 131 | REDIS_DATABASE=${REDIS_DATABASE:-} 132 | REDIS_PORT=${REDIS_PORT:-} 133 | REDIS_PASSWORD=${REDIS_PASSWORD:-} 134 | 135 | GITHUB_TOKEN=${GITHUB_TOKEN:-} 136 | 137 | NEXMO_KEY=${NEXMO_KEY:-} 138 | NEXMO_SECRET=${NEXMO_SECRET:-} 139 | NEXMO_SMS_FROM=${NEXMO_SMS_FROM:-Cachet} 140 | 141 | PHP_MAX_CHILDREN=${PHP_MAX_CHILDREN:-5} 142 | 143 | TRUSTED_PROXIES=${TRUSTED_PROXIES:-} 144 | 145 | # configure env file 146 | 147 | sed 's,{{APP_ENV}},'"${APP_ENV}"',g' -i /var/www/html/.env 148 | sed 's,{{APP_DEBUG}},'"${APP_DEBUG}"',g' -i /var/www/html/.env 149 | sed 's,{{APP_URL}},'"${APP_URL}"',g' -i /var/www/html/.env 150 | sed 's,{{APP_LOG}},'"${APP_LOG}"',g' -i /var/www/html/.env 151 | 152 | sed 's,{{DB_DRIVER}},'"${DB_DRIVER}"',g' -i /var/www/html/.env 153 | sed 's,{{DB_HOST}},'"${DB_HOST}"',g' -i /var/www/html/.env 154 | sed 's,{{DB_DATABASE}},'"${DB_DATABASE}"',g' -i /var/www/html/.env 155 | sed 's,{{DB_PREFIX}},'"${DB_PREFIX}"',g' -i /var/www/html/.env 156 | sed 's,{{DB_USERNAME}},'"${DB_USERNAME}"',g' -i /var/www/html/.env 157 | sed 's,{{DB_PASSWORD}},'"${DB_PASSWORD}"',g' -i /var/www/html/.env 158 | sed 's,{{DB_PORT}},'"${DB_PORT}"',g' -i /var/www/html/.env 159 | sed 's,{{DB_PREFIX}},'"${DB_PREFIX}"',g' -i /var/www/html/.env 160 | 161 | sed 's,{{CACHE_DRIVER}},'"${CACHE_DRIVER}"',g' -i /var/www/html/.env 162 | 163 | sed 's,{{SESSION_DRIVER}},'"${SESSION_DRIVER}"',g' -i /var/www/html/.env 164 | sed 's,{{SESSION_DOMAIN}},'"${SESSION_DOMAIN}"',g' -i /var/www/html/.env 165 | sed 's,{{SESSION_SECURE_COOKIE}},'"${SESSION_SECURE_COOKIE}"',g' -i /var/www/html/.env 166 | 167 | sed 's,{{QUEUE_DRIVER}},'"${QUEUE_DRIVER}"',g' -i /var/www/html/.env 168 | sed 's,{{CACHET_EMOJI}},'"${CACHET_EMOJI}"',g' -i /var/www/html/.env 169 | sed 's,{{CACHET_BEACON}},'"${CACHET_BEACON}"',g' -i /var/www/html/.env 170 | sed 's,{{CACHET_AUTO_TWITTER}},'"${CACHET_AUTO_TWITTER}"',g' -i /var/www/html/.env 171 | 172 | sed 's,{{MAIL_DRIVER}},'"${MAIL_DRIVER}"',g' -i /var/www/html/.env 173 | sed 's,{{MAIL_HOST}},'"${MAIL_HOST}"',g' -i /var/www/html/.env 174 | sed 's,{{MAIL_PORT}},'"${MAIL_PORT}"',g' -i /var/www/html/.env 175 | sed 's,{{MAIL_USERNAME}},'"${MAIL_USERNAME}"',g' -i /var/www/html/.env 176 | sed 's,{{MAIL_PASSWORD}},'"${MAIL_PASSWORD}"',g' -i /var/www/html/.env 177 | sed 's,{{MAIL_ADDRESS}},'"${MAIL_ADDRESS}"',g' -i /var/www/html/.env 178 | sed 's,{{MAIL_NAME}},'"${MAIL_NAME}"',g' -i /var/www/html/.env 179 | sed 's,{{MAIL_ENCRYPTION}},'"${MAIL_ENCRYPTION}"',g' -i /var/www/html/.env 180 | 181 | sed 's,{{REDIS_HOST}},'"${REDIS_HOST}"',g' -i /var/www/html/.env 182 | sed 's,{{REDIS_DATABASE}},'"${REDIS_DATABASE}"',g' -i /var/www/html/.env 183 | sed 's,{{REDIS_PORT}},'"${REDIS_PORT}"',g' -i /var/www/html/.env 184 | sed 's,{{REDIS_PASSWORD}},'"${REDIS_PASSWORD}"',g' -i /var/www/html/.env 185 | 186 | sed 's,{{GITHUB_TOKEN}},'"${GITHUB_TOKEN}"',g' -i /var/www/html/.env 187 | 188 | sed 's,{{NEXMO_KEY}},'"${NEXMO_KEY}"',g' -i /var/www/html/.env 189 | sed 's,{{NEXMO_SECRET}},'"${NEXMO_SECRET}"',g' -i /var/www/html/.env 190 | sed 's,{{NEXMO_SMS_FROM}},'"${NEXMO_SMS_FROM}"',g' -i /var/www/html/.env 191 | 192 | sed 's,{{PHP_MAX_CHILDREN}},'"${PHP_MAX_CHILDREN}"',g' -i /etc/php7/php-fpm.d/www.conf 193 | 194 | sed 's,{{TRUSTED_PROXIES}},'"${TRUSTED_PROXIES}"',g' -i /var/www/html/.env 195 | 196 | if [[ -z "${APP_KEY}" || "${APP_KEY}" = "null" ]]; then 197 | keygen="$(php artisan key:generate --show)" 198 | APP_KEY=$(echo "${keygen}") 199 | echo "ERROR: Please set the 'APP_KEY=${APP_KEY}' environment variable at runtime or in docker-compose.yml and re-launch" 200 | exit 0 201 | fi 202 | 203 | sed "s,{{APP_KEY}},$APP_KEY,g" -i /var/www/html/.env 204 | 205 | # remove empty lines 206 | sed '/^.*=""$/d' -i /var/www/html/.env 207 | 208 | rm -rf bootstrap/cache/* 209 | } 210 | 211 | init_db() { 212 | echo "Initializing Cachet database ..." 213 | php artisan cachet:install --no-interaction 214 | check_configured 215 | } 216 | 217 | migrate_db() { 218 | force="" 219 | if [[ "${FORCE_MIGRATION:-false}" == true ]]; then 220 | force="--force" 221 | fi 222 | php artisan migrate ${force} 223 | } 224 | 225 | seed_db() { 226 | php artisan db:seed 227 | } 228 | 229 | start_system() { 230 | initialize_system 231 | check_database_connection 232 | check_configured 233 | migrate_db 234 | seed_db 235 | echo "Starting Cachet! ..." 236 | php artisan config:cache 237 | /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf 238 | } 239 | 240 | check_sendmail 241 | start_system 242 | 243 | exit 0 244 | -------------------------------------------------------------------------------- /test/lib/batslib.bash: -------------------------------------------------------------------------------- 1 | # 2 | # batslib.bash 3 | # ------------ 4 | # 5 | # The Standard Library is a collection of test helpers intended to 6 | # simplify testing. It contains the following types of test helpers. 7 | # 8 | # - Assertions are functions that perform a test and output relevant 9 | # information on failure to help debugging. They return 1 on failure 10 | # and 0 otherwise. 11 | # 12 | # All output is formatted for readability using the functions of 13 | # `output.bash' and sent to the standard error. 14 | # 15 | 16 | 17 | ######################################################################## 18 | # ASSERTIONS 19 | ######################################################################## 20 | 21 | # Fail and display a message. When no parameters are specified, the 22 | # message is read from the standard input. Other functions use this to 23 | # report failure. 24 | # 25 | # Globals: 26 | # none 27 | # Arguments: 28 | # $@ - [=STDIN] message 29 | # Returns: 30 | # 1 - always 31 | # Inputs: 32 | # STDIN - [=$@] message 33 | # Outputs: 34 | # STDERR - message 35 | fail() { 36 | (( $# == 0 )) && batslib_err || batslib_err "$@" 37 | return 1 38 | } 39 | 40 | # Fail and display details if the expression evaluates to false. Details 41 | # include the expression, `$status' and `$output'. 42 | # 43 | # NOTE: The expression must be a simple command. Compound commands, such 44 | # as `[[', can be used only when executed with `bash -c'. 45 | # 46 | # Globals: 47 | # status 48 | # output 49 | # Arguments: 50 | # $1 - expression 51 | # Returns: 52 | # 0 - expression evaluates to TRUE 53 | # 1 - otherwise 54 | # Outputs: 55 | # STDERR - details, on failure 56 | assert() { 57 | if ! "$@"; then 58 | { local -ar single=( 59 | 'expression' "$*" 60 | 'status' "$status" 61 | ) 62 | local -ar may_be_multi=( 63 | 'output' "$output" 64 | ) 65 | local -ir width="$( batslib_get_max_single_line_key_width \ 66 | "${single[@]}" "${may_be_multi[@]}" )" 67 | batslib_print_kv_single "$width" "${single[@]}" 68 | batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" 69 | } | batslib_decorate 'assertion failed' \ 70 | | fail 71 | fi 72 | } 73 | 74 | # Fail and display details if the expected and actual values do not 75 | # equal. Details include both values. 76 | # 77 | # Globals: 78 | # none 79 | # Arguments: 80 | # $1 - actual value 81 | # $2 - expected value 82 | # Returns: 83 | # 0 - values equal 84 | # 1 - otherwise 85 | # Outputs: 86 | # STDERR - details, on failure 87 | assert_equal() { 88 | if [[ $1 != "$2" ]]; then 89 | batslib_print_kv_single_or_multi 8 \ 90 | 'expected' "$2" \ 91 | 'actual' "$1" \ 92 | | batslib_decorate 'values do not equal' \ 93 | | fail 94 | fi 95 | } 96 | 97 | # Fail and display details if `$status' is not 0. Details include 98 | # `$status' and `$output'. 99 | # 100 | # Globals: 101 | # status 102 | # output 103 | # Arguments: 104 | # none 105 | # Returns: 106 | # 0 - `$status' is 0 107 | # 1 - otherwise 108 | # Outputs: 109 | # STDERR - details, on failure 110 | assert_success() { 111 | if (( status != 0 )); then 112 | { local -ir width=6 113 | batslib_print_kv_single "$width" 'status' "$status" 114 | batslib_print_kv_single_or_multi "$width" 'output' "$output" 115 | } | batslib_decorate 'command failed' \ 116 | | fail 117 | fi 118 | } 119 | 120 | # Fail and display details if `$status' is 0. Details include `$output'. 121 | # 122 | # Optionally, when the expected status is specified, fail when it does 123 | # not equal `$status'. In this case, details include the expected and 124 | # actual status, and `$output'. 125 | # 126 | # Globals: 127 | # status 128 | # output 129 | # Arguments: 130 | # $1 - [opt] expected status 131 | # Returns: 132 | # 0 - `$status' is not 0, or 133 | # `$status' equals the expected status 134 | # 1 - otherwise 135 | # Outputs: 136 | # STDERR - details, on failure 137 | assert_failure() { 138 | (( $# > 0 )) && local -r expected="$1" 139 | if (( status == 0 )); then 140 | batslib_print_kv_single_or_multi 6 'output' "$output" \ 141 | | batslib_decorate 'command succeeded, but it was expected to fail' \ 142 | | fail 143 | elif (( $# > 0 )) && (( status != expected )); then 144 | { local -ir width=8 145 | batslib_print_kv_single "$width" \ 146 | 'expected' "$expected" \ 147 | 'actual' "$status" 148 | batslib_print_kv_single_or_multi "$width" \ 149 | 'output' "$output" 150 | } | batslib_decorate 'command failed as expected, but status differs' \ 151 | | fail 152 | fi 153 | } 154 | 155 | # Fail and display details if the expected does not match the actual 156 | # output or a fragment of it. 157 | # 158 | # By default, the entire output is matched. The assertion fails if the 159 | # expected output does not equal `$output'. Details include both values. 160 | # 161 | # When `-l ' is used, only the -th line is matched. The 162 | # assertion fails if the expected line does not equal 163 | # `${lines[}'. Details include the compared lines and . 164 | # 165 | # When `-l' is used without the argument, the output is searched 166 | # for the expected line. The expected line is matched against each line 167 | # in `${lines[@]}'. If no match is found the assertion fails. Details 168 | # include the expected line and `$output'. 169 | # 170 | # By default, literal matching is performed. Options `-p' and `-r' 171 | # enable partial (i.e. substring) and extended regular expression 172 | # matching, respectively. Specifying an invalid extended regular 173 | # expression with `-r' displays an error. 174 | # 175 | # Options `-p' and `-r' are mutually exclusive. When used 176 | # simultaneously, an error is displayed. 177 | # 178 | # Globals: 179 | # output 180 | # lines 181 | # Options: 182 | # -l - match against the -th element of `${lines[@]}' 183 | # -l - search `${lines[@]}' for the expected line 184 | # -p - partial matching 185 | # -r - extended regular expression matching 186 | # Arguments: 187 | # $1 - expected output 188 | # Returns: 189 | # 0 - expected matches the actual output 190 | # 1 - otherwise 191 | # Outputs: 192 | # STDERR - details, on failure 193 | # error message, on error 194 | assert_output() { 195 | local -i is_match_line=0 196 | local -i is_match_contained=0 197 | local -i is_mode_partial=0 198 | local -i is_mode_regex=0 199 | 200 | # Handle options. 201 | while (( $# > 0 )); do 202 | case "$1" in 203 | -l) 204 | if (( $# > 2 )) && [[ $2 =~ ^([0-9]|[1-9][0-9]+)$ ]]; then 205 | is_match_line=1 206 | local -ri idx="$2" 207 | shift 208 | else 209 | is_match_contained=1; 210 | fi 211 | shift 212 | ;; 213 | -p) is_mode_partial=1; shift ;; 214 | -r) is_mode_regex=1; shift ;; 215 | --) break ;; 216 | *) break ;; 217 | esac 218 | done 219 | 220 | if (( is_match_line )) && (( is_match_contained )); then 221 | echo "\`-l' and \`-l ' are mutually exclusive" \ 222 | | batslib_decorate 'ERROR: assert_output' \ 223 | | fail 224 | return $? 225 | fi 226 | 227 | if (( is_mode_partial )) && (( is_mode_regex )); then 228 | echo "\`-p' and \`-r' are mutually exclusive" \ 229 | | batslib_decorate 'ERROR: assert_output' \ 230 | | fail 231 | return $? 232 | fi 233 | 234 | # Arguments. 235 | local -r expected="$1" 236 | 237 | if (( is_mode_regex == 1 )) && [[ '' =~ $expected ]] || (( $? == 2 )); then 238 | echo "Invalid extended regular expression: \`$expected'" \ 239 | | batslib_decorate 'ERROR: assert_output' \ 240 | | fail 241 | return $? 242 | fi 243 | 244 | # Matching. 245 | if (( is_match_contained )); then 246 | # Line contained in output. 247 | if (( is_mode_regex )); then 248 | local -i idx 249 | for (( idx = 0; idx < ${#lines[@]}; ++idx )); do 250 | [[ ${lines[$idx]} =~ $expected ]] && return 0 251 | done 252 | { local -ar single=( 253 | 'regex' "$expected" 254 | ) 255 | local -ar may_be_multi=( 256 | 'output' "$output" 257 | ) 258 | local -ir width="$( batslib_get_max_single_line_key_width \ 259 | "${single[@]}" "${may_be_multi[@]}" )" 260 | batslib_print_kv_single "$width" "${single[@]}" 261 | batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" 262 | } | batslib_decorate 'no output line matches regular expression' \ 263 | | fail 264 | elif (( is_mode_partial )); then 265 | local -i idx 266 | for (( idx = 0; idx < ${#lines[@]}; ++idx )); do 267 | [[ ${lines[$idx]} == *"$expected"* ]] && return 0 268 | done 269 | { local -ar single=( 270 | 'substring' "$expected" 271 | ) 272 | local -ar may_be_multi=( 273 | 'output' "$output" 274 | ) 275 | local -ir width="$( batslib_get_max_single_line_key_width \ 276 | "${single[@]}" "${may_be_multi[@]}" )" 277 | batslib_print_kv_single "$width" "${single[@]}" 278 | batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" 279 | } | batslib_decorate 'no output line contains substring' \ 280 | | fail 281 | else 282 | local -i idx 283 | for (( idx = 0; idx < ${#lines[@]}; ++idx )); do 284 | [[ ${lines[$idx]} == "$expected" ]] && return 0 285 | done 286 | { local -ar single=( 287 | 'line' "$expected" 288 | ) 289 | local -ar may_be_multi=( 290 | 'output' "$output" 291 | ) 292 | local -ir width="$( batslib_get_max_single_line_key_width \ 293 | "${single[@]}" "${may_be_multi[@]}" )" 294 | batslib_print_kv_single "$width" "${single[@]}" 295 | batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" 296 | } | batslib_decorate 'output does not contain line' \ 297 | | fail 298 | fi 299 | elif (( is_match_line )); then 300 | # Specific line. 301 | if (( is_mode_regex )); then 302 | if ! [[ ${lines[$idx]} =~ $expected ]]; then 303 | batslib_print_kv_single 5 \ 304 | 'index' "$idx" \ 305 | 'regex' "$expected" \ 306 | 'line' "${lines[$idx]}" \ 307 | | batslib_decorate 'regular expression does not match line' \ 308 | | fail 309 | fi 310 | elif (( is_mode_partial )); then 311 | if [[ ${lines[$idx]} != *"$expected"* ]]; then 312 | batslib_print_kv_single 9 \ 313 | 'index' "$idx" \ 314 | 'substring' "$expected" \ 315 | 'line' "${lines[$idx]}" \ 316 | | batslib_decorate 'line does not contain substring' \ 317 | | fail 318 | fi 319 | else 320 | if [[ ${lines[$idx]} != "$expected" ]]; then 321 | batslib_print_kv_single 8 \ 322 | 'index' "$idx" \ 323 | 'expected' "$expected" \ 324 | 'actual' "${lines[$idx]}" \ 325 | | batslib_decorate 'line differs' \ 326 | | fail 327 | fi 328 | fi 329 | else 330 | # Entire output. 331 | if (( is_mode_regex )); then 332 | if ! [[ $output =~ $expected ]]; then 333 | batslib_print_kv_single_or_multi 6 \ 334 | 'regex' "$expected" \ 335 | 'output' "$output" \ 336 | | batslib_decorate 'regular expression does not match output' \ 337 | | fail 338 | fi 339 | elif (( is_mode_partial )); then 340 | if [[ $output != *"$expected"* ]]; then 341 | batslib_print_kv_single_or_multi 9 \ 342 | 'substring' "$expected" \ 343 | 'output' "$output" \ 344 | | batslib_decorate 'output does not contain substring' \ 345 | | fail 346 | fi 347 | else 348 | if [[ $output != "$expected" ]]; then 349 | batslib_print_kv_single_or_multi 8 \ 350 | 'expected' "$expected" \ 351 | 'actual' "$output" \ 352 | | batslib_decorate 'output differs' \ 353 | | fail 354 | fi 355 | fi 356 | fi 357 | } 358 | 359 | # Fail and display details if the unexpected matches the actual output 360 | # or a fragment of it. 361 | # 362 | # By default, the entire output is matched. The assertion fails if the 363 | # unexpected output equals `$output'. Details include `$output'. 364 | # 365 | # When `-l ' is used, only the -th line is matched. The 366 | # assertion fails if the unexpected line equals `${lines[}'. 367 | # Details include the compared line and . 368 | # 369 | # When `-l' is used without the argument, the output is searched 370 | # for the unexpected line. The unexpected line is matched against each 371 | # line in `${lines[]}'. If a match is found the assertion fails. 372 | # Details include the unexpected line, the index where it was found and 373 | # `$output' (with the unexpected line highlighted in it if `$output` is 374 | # longer than one line). 375 | # 376 | # By default, literal matching is performed. Options `-p' and `-r' 377 | # enable partial (i.e. substring) and extended regular expression 378 | # matching, respectively. On failure, the substring or the regular 379 | # expression is added to the details (if not already displayed). 380 | # Specifying an invalid extended regular expression with `-r' displays 381 | # an error. 382 | # 383 | # Options `-p' and `-r' are mutually exclusive. When used 384 | # simultaneously, an error is displayed. 385 | # 386 | # Globals: 387 | # output 388 | # lines 389 | # Options: 390 | # -l - match against the -th element of `${lines[@]}' 391 | # -l - search `${lines[@]}' for the unexpected line 392 | # -p - partial matching 393 | # -r - extended regular expression matching 394 | # Arguments: 395 | # $1 - unexpected output 396 | # Returns: 397 | # 0 - unexpected matches the actual output 398 | # 1 - otherwise 399 | # Outputs: 400 | # STDERR - details, on failure 401 | # error message, on error 402 | refute_output() { 403 | local -i is_match_line=0 404 | local -i is_match_contained=0 405 | local -i is_mode_partial=0 406 | local -i is_mode_regex=0 407 | 408 | # Handle options. 409 | while (( $# > 0 )); do 410 | case "$1" in 411 | -l) 412 | if (( $# > 2 )) && [[ $2 =~ ^([0-9]|[1-9][0-9]+)$ ]]; then 413 | is_match_line=1 414 | local -ri idx="$2" 415 | shift 416 | else 417 | is_match_contained=1; 418 | fi 419 | shift 420 | ;; 421 | -L) is_match_contained=1; shift ;; 422 | -p) is_mode_partial=1; shift ;; 423 | -r) is_mode_regex=1; shift ;; 424 | --) break ;; 425 | *) break ;; 426 | esac 427 | done 428 | 429 | if (( is_match_line )) && (( is_match_contained )); then 430 | echo "\`-l' and \`-l ' are mutually exclusive" \ 431 | | batslib_decorate 'ERROR: refute_output' \ 432 | | fail 433 | return $? 434 | fi 435 | 436 | if (( is_mode_partial )) && (( is_mode_regex )); then 437 | echo "\`-p' and \`-r' are mutually exclusive" \ 438 | | batslib_decorate 'ERROR: refute_output' \ 439 | | fail 440 | return $? 441 | fi 442 | 443 | # Arguments. 444 | local -r unexpected="$1" 445 | 446 | if (( is_mode_regex == 1 )) && [[ '' =~ $unexpected ]] || (( $? == 2 )); then 447 | echo "Invalid extended regular expression: \`$unexpected'" \ 448 | | batslib_decorate 'ERROR: refute_output' \ 449 | | fail 450 | return $? 451 | fi 452 | 453 | # Matching. 454 | if (( is_match_contained )); then 455 | # Line contained in output. 456 | if (( is_mode_regex )); then 457 | local -i idx 458 | for (( idx = 0; idx < ${#lines[@]}; ++idx )); do 459 | if [[ ${lines[$idx]} =~ $unexpected ]]; then 460 | { local -ar single=( 461 | 'regex' "$unexpected" 462 | 'index' "$idx" 463 | ) 464 | local -a may_be_multi=( 465 | 'output' "$output" 466 | ) 467 | local -ir width="$( batslib_get_max_single_line_key_width \ 468 | "${single[@]}" "${may_be_multi[@]}" )" 469 | batslib_print_kv_single "$width" "${single[@]}" 470 | if batslib_is_single_line "${may_be_multi[1]}"; then 471 | batslib_print_kv_single "$width" "${may_be_multi[@]}" 472 | else 473 | may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" \ 474 | | batslib_prefix \ 475 | | batslib_mark '>' "$idx" )" 476 | batslib_print_kv_multi "${may_be_multi[@]}" 477 | fi 478 | } | batslib_decorate 'no line should match the regular expression' \ 479 | | fail 480 | return $? 481 | fi 482 | done 483 | elif (( is_mode_partial )); then 484 | local -i idx 485 | for (( idx = 0; idx < ${#lines[@]}; ++idx )); do 486 | if [[ ${lines[$idx]} == *"$unexpected"* ]]; then 487 | { local -ar single=( 488 | 'substring' "$unexpected" 489 | 'index' "$idx" 490 | ) 491 | local -a may_be_multi=( 492 | 'output' "$output" 493 | ) 494 | local -ir width="$( batslib_get_max_single_line_key_width \ 495 | "${single[@]}" "${may_be_multi[@]}" )" 496 | batslib_print_kv_single "$width" "${single[@]}" 497 | if batslib_is_single_line "${may_be_multi[1]}"; then 498 | batslib_print_kv_single "$width" "${may_be_multi[@]}" 499 | else 500 | may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" \ 501 | | batslib_prefix \ 502 | | batslib_mark '>' "$idx" )" 503 | batslib_print_kv_multi "${may_be_multi[@]}" 504 | fi 505 | } | batslib_decorate 'no line should contain substring' \ 506 | | fail 507 | return $? 508 | fi 509 | done 510 | else 511 | local -i idx 512 | for (( idx = 0; idx < ${#lines[@]}; ++idx )); do 513 | if [[ ${lines[$idx]} == "$unexpected" ]]; then 514 | { local -ar single=( 515 | 'line' "$unexpected" 516 | 'index' "$idx" 517 | ) 518 | local -a may_be_multi=( 519 | 'output' "$output" 520 | ) 521 | local -ir width="$( batslib_get_max_single_line_key_width \ 522 | "${single[@]}" "${may_be_multi[@]}" )" 523 | batslib_print_kv_single "$width" "${single[@]}" 524 | if batslib_is_single_line "${may_be_multi[1]}"; then 525 | batslib_print_kv_single "$width" "${may_be_multi[@]}" 526 | else 527 | may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" \ 528 | | batslib_prefix \ 529 | | batslib_mark '>' "$idx" )" 530 | batslib_print_kv_multi "${may_be_multi[@]}" 531 | fi 532 | } | batslib_decorate 'line should not be in output' \ 533 | | fail 534 | return $? 535 | fi 536 | done 537 | fi 538 | elif (( is_match_line )); then 539 | # Specific line. 540 | if (( is_mode_regex )); then 541 | if [[ ${lines[$idx]} =~ $unexpected ]] || (( $? == 0 )); then 542 | batslib_print_kv_single 5 \ 543 | 'index' "$idx" \ 544 | 'regex' "$unexpected" \ 545 | 'line' "${lines[$idx]}" \ 546 | | batslib_decorate 'regular expression should not match line' \ 547 | | fail 548 | fi 549 | elif (( is_mode_partial )); then 550 | if [[ ${lines[$idx]} == *"$unexpected"* ]]; then 551 | batslib_print_kv_single 9 \ 552 | 'index' "$idx" \ 553 | 'substring' "$unexpected" \ 554 | 'line' "${lines[$idx]}" \ 555 | | batslib_decorate 'line should not contain substring' \ 556 | | fail 557 | fi 558 | else 559 | if [[ ${lines[$idx]} == "$unexpected" ]]; then 560 | batslib_print_kv_single 5 \ 561 | 'index' "$idx" \ 562 | 'line' "${lines[$idx]}" \ 563 | | batslib_decorate 'line should differ' \ 564 | | fail 565 | fi 566 | fi 567 | else 568 | # Entire output. 569 | if (( is_mode_regex )); then 570 | if [[ $output =~ $unexpected ]] || (( $? == 0 )); then 571 | batslib_print_kv_single_or_multi 6 \ 572 | 'regex' "$unexpected" \ 573 | 'output' "$output" \ 574 | | batslib_decorate 'regular expression should not match output' \ 575 | | fail 576 | fi 577 | elif (( is_mode_partial )); then 578 | if [[ $output == *"$unexpected"* ]]; then 579 | batslib_print_kv_single_or_multi 9 \ 580 | 'substring' "$unexpected" \ 581 | 'output' "$output" \ 582 | | batslib_decorate 'output should not contain substring' \ 583 | | fail 584 | fi 585 | else 586 | if [[ $output == "$unexpected" ]]; then 587 | batslib_print_kv_single_or_multi 6 \ 588 | 'output' "$output" \ 589 | | batslib_decorate 'output equals, but it was expected to differ' \ 590 | | fail 591 | fi 592 | fi 593 | fi 594 | } 595 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [v2.3.12](https://github.com/CachetHQ/Docker/tree/v2.3.12) (2017-06-29) 4 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.11...v2.3.12) 5 | 6 | **Implemented enhancements:** 7 | 8 | - Switch to Alpine Linux [\#200](https://github.com/CachetHQ/Docker/pull/200) ([djdefi](https://github.com/djdefi)) 9 | 10 | **Fixed bugs:** 11 | 12 | - PGSQL ignores DB\_PORT [\#206](https://github.com/CachetHQ/Docker/issues/206) 13 | 14 | **Closed issues:** 15 | 16 | - Enable seedfile for auto-deploy in pipelines [\#212](https://github.com/CachetHQ/Docker/issues/212) 17 | - error 500 connection refused fastcgi [\#208](https://github.com/CachetHQ/Docker/issues/208) 18 | - 500 error during setup [\#207](https://github.com/CachetHQ/Docker/issues/207) 19 | - Error 500 after installation [\#199](https://github.com/CachetHQ/Docker/issues/199) 20 | - Set the default port to 8000 in the documentation [\#198](https://github.com/CachetHQ/Docker/issues/198) 21 | - Question: Why not use different Dockerfiles? [\#196](https://github.com/CachetHQ/Docker/issues/196) 22 | - Create new tag with Nginx in app container [\#148](https://github.com/CachetHQ/Docker/issues/148) 23 | 24 | **Merged pull requests:** 25 | 26 | - Remove docker version pin in CI [\#215](https://github.com/CachetHQ/Docker/pull/215) ([djdefi](https://github.com/djdefi)) 27 | - Fixes \#206 by using psql port defined in env var [\#211](https://github.com/CachetHQ/Docker/pull/211) ([gottfrois](https://github.com/gottfrois)) 28 | - fixing mysql ignores DB\_PORT envvar at connection [\#205](https://github.com/CachetHQ/Docker/pull/205) ([naorlivne](https://github.com/naorlivne)) 29 | - Revert "The right git repo" [\#204](https://github.com/CachetHQ/Docker/pull/204) ([jbrooksuk](https://github.com/jbrooksuk)) 30 | - The right git repo [\#203](https://github.com/CachetHQ/Docker/pull/203) ([riemers](https://github.com/riemers)) 31 | - Update Nginx 1.12 [\#202](https://github.com/CachetHQ/Docker/pull/202) ([butuh](https://github.com/butuh)) 32 | 33 | ## [v2.3.11](https://github.com/CachetHQ/Docker/tree/v2.3.11) (2017-04-16) 34 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.10...v2.3.11) 35 | 36 | **Implemented enhancements:** 37 | 38 | - Add "restart: always" property [\#194](https://github.com/CachetHQ/Docker/issues/194) 39 | - Nginx max\_children [\#162](https://github.com/CachetHQ/Docker/issues/162) 40 | - New ENV vars for notifications in 2.4 [\#149](https://github.com/CachetHQ/Docker/issues/149) 41 | - Support all possible ENV vars [\#135](https://github.com/CachetHQ/Docker/issues/135) 42 | - Upgrade pg\_dump to 9.5 to perform database backup [\#123](https://github.com/CachetHQ/Docker/issues/123) 43 | - redirect php-fpm log to stdout/stderr [\#121](https://github.com/CachetHQ/Docker/issues/121) 44 | - Script release process [\#119](https://github.com/CachetHQ/Docker/issues/119) 45 | - Consider whitelisting on .dockerignore instead of blacklisting [\#116](https://github.com/CachetHQ/Docker/issues/116) 46 | - Beacons in 2.4 [\#114](https://github.com/CachetHQ/Docker/issues/114) 47 | - single container for PaaS deployment [\#103](https://github.com/CachetHQ/Docker/issues/103) 48 | - Add CHANGELOG.md [\#191](https://github.com/CachetHQ/Docker/pull/191) ([djdefi](https://github.com/djdefi)) 49 | - APP\_KEY ENV [\#190](https://github.com/CachetHQ/Docker/pull/190) ([djdefi](https://github.com/djdefi)) 50 | - Add more ENV vars [\#189](https://github.com/CachetHQ/Docker/pull/189) ([djdefi](https://github.com/djdefi)) 51 | - Add Cachet Beacon env var [\#186](https://github.com/CachetHQ/Docker/pull/186) ([djdefi](https://github.com/djdefi)) 52 | - Nginx ttfb tweaks [\#183](https://github.com/CachetHQ/Docker/pull/183) ([djdefi](https://github.com/djdefi)) 53 | - Attempt to launch as a regular user [\#178](https://github.com/CachetHQ/Docker/pull/178) ([djdefi](https://github.com/djdefi)) 54 | - Bump to docker-compose version 3 [\#174](https://github.com/CachetHQ/Docker/pull/174) ([djdefi](https://github.com/djdefi)) 55 | - Replace cron with artisan queue worker [\#173](https://github.com/CachetHQ/Docker/pull/173) ([djdefi](https://github.com/djdefi)) 56 | - Added environment setup for pm.max\_children, default:5 [\#169](https://github.com/CachetHQ/Docker/pull/169) ([s4mur4i](https://github.com/s4mur4i)) 57 | - Add some restart tests [\#166](https://github.com/CachetHQ/Docker/pull/166) ([djdefi](https://github.com/djdefi)) 58 | - added openshift yaml files and readme [\#154](https://github.com/CachetHQ/Docker/pull/154) ([gamkiller77](https://github.com/gamkiller77)) 59 | - Add support for redis password [\#143](https://github.com/CachetHQ/Docker/pull/143) ([jadb](https://github.com/jadb)) 60 | - Added instructions for development of Cachet using this environment [\#141](https://github.com/CachetHQ/Docker/pull/141) ([xRahul](https://github.com/xRahul)) 61 | - Make composer version a variable and bump to 1.2.1 [\#140](https://github.com/CachetHQ/Docker/pull/140) ([axilleas](https://github.com/axilleas)) 62 | - update nginx to latest stable version [\#137](https://github.com/CachetHQ/Docker/pull/137) ([Madhu1512](https://github.com/Madhu1512)) 63 | - Allow caching of fonts [\#118](https://github.com/CachetHQ/Docker/pull/118) ([mcfedr](https://github.com/mcfedr)) 64 | 65 | **Fixed bugs:** 66 | 67 | - checkdbinitpsql function doesnt use DB\_DATABASE variable [\#177](https://github.com/CachetHQ/Docker/issues/177) 68 | - Add cachet\_ver ARG to docker-compose.yml [\#187](https://github.com/CachetHQ/Docker/pull/187) ([djdefi](https://github.com/djdefi)) 69 | - fix. cachet\_ver couldn't be overrided with ARG [\#142](https://github.com/CachetHQ/Docker/pull/142) ([mathieuruellan](https://github.com/mathieuruellan)) 70 | - Remove the duplicate php5-mysql package from Dockerfile [\#139](https://github.com/CachetHQ/Docker/pull/139) ([axilleas](https://github.com/axilleas)) 71 | 72 | **Closed issues:** 73 | 74 | - How to install Cachethq on synology [\#197](https://github.com/CachetHQ/Docker/issues/197) 75 | - Release with NGINX [\#170](https://github.com/CachetHQ/Docker/issues/170) 76 | - Download cachet to /usr/src [\#161](https://github.com/CachetHQ/Docker/issues/161) 77 | - Do you have a verison of the docker cachet code for deployment in kubernetes/minikube? [\#159](https://github.com/CachetHQ/Docker/issues/159) 78 | - docker-compose skips the database backup because of a postgres protocol mismatch [\#156](https://github.com/CachetHQ/Docker/issues/156) 79 | - docker-compose install instructions should use cachetdocker\_cachet\_1 as container reference [\#155](https://github.com/CachetHQ/Docker/issues/155) 80 | - Combine Cachet and nginx in same container [\#150](https://github.com/CachetHQ/Docker/issues/150) 81 | - Best way to move a docker image from one server to another. [\#147](https://github.com/CachetHQ/Docker/issues/147) 82 | - Nginx conf only accepts localhost connections [\#144](https://github.com/CachetHQ/Docker/issues/144) 83 | - Container command '/sbin/entrypoint.sh' not found or does not exist. [\#136](https://github.com/CachetHQ/Docker/issues/136) 84 | - nginx logging to stdout broken [\#132](https://github.com/CachetHQ/Docker/issues/132) 85 | - Permission denied on start cachet [\#124](https://github.com/CachetHQ/Docker/issues/124) 86 | - Don't use volumes to share code between nginx & fpm [\#106](https://github.com/CachetHQ/Docker/issues/106) 87 | 88 | **Merged pull requests:** 89 | 90 | - Added "restart: always" property [\#195](https://github.com/CachetHQ/Docker/pull/195) ([felixoi](https://github.com/felixoi)) 91 | - Updated Nginx to latest stable release [\#192](https://github.com/CachetHQ/Docker/pull/192) ([Madhu1512](https://github.com/Madhu1512)) 92 | - Backport master to 2.3 [\#188](https://github.com/CachetHQ/Docker/pull/188) ([djdefi](https://github.com/djdefi)) 93 | - Update container name in dev guide README.md [\#181](https://github.com/CachetHQ/Docker/pull/181) ([djdefi](https://github.com/djdefi)) 94 | - DB init w/ custom DB name fixes [\#179](https://github.com/CachetHQ/Docker/pull/179) ([djdefi](https://github.com/djdefi)) 95 | - Apt source add syntax [\#176](https://github.com/CachetHQ/Docker/pull/176) ([djdefi](https://github.com/djdefi)) 96 | - More process logs to stdout [\#172](https://github.com/CachetHQ/Docker/pull/172) ([djdefi](https://github.com/djdefi)) 97 | - Revert "Test backport master -\> 2.3" [\#167](https://github.com/CachetHQ/Docker/pull/167) ([djdefi](https://github.com/djdefi)) 98 | - Remove volume from Dockerfile [\#165](https://github.com/CachetHQ/Docker/pull/165) ([djdefi](https://github.com/djdefi)) 99 | - Bump docker version in travis [\#164](https://github.com/CachetHQ/Docker/pull/164) ([djdefi](https://github.com/djdefi)) 100 | - Test backport master -\> 2.3 [\#163](https://github.com/CachetHQ/Docker/pull/163) ([djdefi](https://github.com/djdefi)) 101 | - adding all the ENV to the yaml file when deploying [\#157](https://github.com/CachetHQ/Docker/pull/157) ([gamkiller77](https://github.com/gamkiller77)) 102 | - Fix readme formatting [\#153](https://github.com/CachetHQ/Docker/pull/153) ([djdefi](https://github.com/djdefi)) 103 | - Do not enclose env vars with double quotes [\#151](https://github.com/CachetHQ/Docker/pull/151) ([mattallty](https://github.com/mattallty)) 104 | - Add rest of env vars [\#145](https://github.com/CachetHQ/Docker/pull/145) ([djdefi](https://github.com/djdefi)) 105 | - Use prestissimo for parallel composer installs [\#138](https://github.com/CachetHQ/Docker/pull/138) ([djdefi](https://github.com/djdefi)) 106 | - Set entrypoint perms [\#134](https://github.com/CachetHQ/Docker/pull/134) ([djdefi](https://github.com/djdefi)) 107 | - Enable nginx logs to stdout and stderr [\#133](https://github.com/CachetHQ/Docker/pull/133) ([djdefi](https://github.com/djdefi)) 108 | - Add release-helper script [\#130](https://github.com/CachetHQ/Docker/pull/130) ([djdefi](https://github.com/djdefi)) 109 | - Include nginx in Cachet image [\#129](https://github.com/CachetHQ/Docker/pull/129) ([djdefi](https://github.com/djdefi)) 110 | - Use whitelist in .dockerignore [\#128](https://github.com/CachetHQ/Docker/pull/128) ([djdefi](https://github.com/djdefi)) 111 | - log php-fpm to stdout [\#127](https://github.com/CachetHQ/Docker/pull/127) ([djdefi](https://github.com/djdefi)) 112 | - Use apt.postgresql.org for client packages [\#126](https://github.com/CachetHQ/Docker/pull/126) ([djdefi](https://github.com/djdefi)) 113 | - 2.3.10 backport master [\#117](https://github.com/CachetHQ/Docker/pull/117) ([djdefi](https://github.com/djdefi)) 114 | 115 | ## [v2.3.10](https://github.com/CachetHQ/Docker/tree/v2.3.10) (2016-08-15) 116 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.9...v2.3.10) 117 | 118 | ## [v2.3.9](https://github.com/CachetHQ/Docker/tree/v2.3.9) (2016-08-15) 119 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.8...v2.3.9) 120 | 121 | ## [v2.3.8](https://github.com/CachetHQ/Docker/tree/v2.3.8) (2016-08-15) 122 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.7...v2.3.8) 123 | 124 | **Closed issues:** 125 | 126 | - Cachet 2.3.x releases [\#111](https://github.com/CachetHQ/Docker/issues/111) 127 | - Outdated documentation regarding key generation and app initialization ? [\#110](https://github.com/CachetHQ/Docker/issues/110) 128 | - I get an error with docker-compose --verbose up [\#108](https://github.com/CachetHQ/Docker/issues/108) 129 | 130 | ## [v2.3.7](https://github.com/CachetHQ/Docker/tree/v2.3.7) (2016-08-04) 131 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.6...v2.3.7) 132 | 133 | ## [v2.3.6](https://github.com/CachetHQ/Docker/tree/v2.3.6) (2016-08-04) 134 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.5...v2.3.6) 135 | 136 | ## [v2.3.5](https://github.com/CachetHQ/Docker/tree/v2.3.5) (2016-08-04) 137 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.4...v2.3.5) 138 | 139 | ## [v2.3.4](https://github.com/CachetHQ/Docker/tree/v2.3.4) (2016-08-04) 140 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.3...v2.3.4) 141 | 142 | ## [v2.3.3](https://github.com/CachetHQ/Docker/tree/v2.3.3) (2016-08-04) 143 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.2...v2.3.3) 144 | 145 | ## [v2.3.2](https://github.com/CachetHQ/Docker/tree/v2.3.2) (2016-08-04) 146 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.1...v2.3.2) 147 | 148 | ## [v2.3.1](https://github.com/CachetHQ/Docker/tree/v2.3.1) (2016-08-04) 149 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.0...v2.3.1) 150 | 151 | ## [v2.3.0](https://github.com/CachetHQ/Docker/tree/v2.3.0) (2016-08-04) 152 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.0-RC6...v2.3.0) 153 | 154 | **Implemented enhancements:** 155 | 156 | - Using volume to persist db data [\#92](https://github.com/CachetHQ/Docker/issues/92) 157 | 158 | **Closed issues:** 159 | 160 | - Pinned package are not present anymore in debain repo [\#112](https://github.com/CachetHQ/Docker/issues/112) 161 | - '/sbin/entrypoint.sh' not found or does not exist [\#109](https://github.com/CachetHQ/Docker/issues/109) 162 | - Error 500 \(Components and Dashboard\) [\#107](https://github.com/CachetHQ/Docker/issues/107) 163 | - HTTP 500 Error after Login [\#102](https://github.com/CachetHQ/Docker/issues/102) 164 | 165 | **Merged pull requests:** 166 | 167 | - Rel 2.3.0 [\#115](https://github.com/CachetHQ/Docker/pull/115) ([djdefi](https://github.com/djdefi)) 168 | - Unpin packages and make composer install better [\#113](https://github.com/CachetHQ/Docker/pull/113) ([djdefi](https://github.com/djdefi)) 169 | - Write-good suggestions [\#105](https://github.com/CachetHQ/Docker/pull/105) ([djdefi](https://github.com/djdefi)) 170 | - Update composer sha384 [\#104](https://github.com/CachetHQ/Docker/pull/104) ([atmosx](https://github.com/atmosx)) 171 | - Add BSD-3 clause license [\#101](https://github.com/CachetHQ/Docker/pull/101) ([djdefi](https://github.com/djdefi)) 172 | - Add testing info to readme. [\#100](https://github.com/CachetHQ/Docker/pull/100) ([djdefi](https://github.com/djdefi)) 173 | - fixes \#92 - adding postgres volume [\#99](https://github.com/CachetHQ/Docker/pull/99) ([djdefi](https://github.com/djdefi)) 174 | - Pin versions for all packages [\#98](https://github.com/CachetHQ/Docker/pull/98) ([djdefi](https://github.com/djdefi)) 175 | - Verify composer installer and version pin [\#97](https://github.com/CachetHQ/Docker/pull/97) ([djdefi](https://github.com/djdefi)) 176 | - 2.3 backports [\#96](https://github.com/CachetHQ/Docker/pull/96) ([djdefi](https://github.com/djdefi)) 177 | 178 | ## [v2.3.0-RC6](https://github.com/CachetHQ/Docker/tree/v2.3.0-RC6) (2016-06-16) 179 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.2.4...v2.3.0-RC6) 180 | 181 | **Merged pull requests:** 182 | 183 | - Rel 2.3.0 rc6 [\#95](https://github.com/CachetHQ/Docker/pull/95) ([djdefi](https://github.com/djdefi)) 184 | 185 | ## [v2.2.4](https://github.com/CachetHQ/Docker/tree/v2.2.4) (2016-06-16) 186 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.2.3...v2.2.4) 187 | 188 | **Implemented enhancements:** 189 | 190 | - Add api test [\#93](https://github.com/CachetHQ/Docker/pull/93) ([djdefi](https://github.com/djdefi)) 191 | 192 | **Merged pull requests:** 193 | 194 | - Cachet v2.2.4 release [\#94](https://github.com/CachetHQ/Docker/pull/94) ([djdefi](https://github.com/djdefi)) 195 | 196 | ## [v2.2.3](https://github.com/CachetHQ/Docker/tree/v2.2.3) (2016-06-06) 197 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.3.0-RC2...v2.2.3) 198 | 199 | **Implemented enhancements:** 200 | 201 | - Rename docker directory [\#85](https://github.com/CachetHQ/Docker/issues/85) 202 | - QA testing suite [\#83](https://github.com/CachetHQ/Docker/issues/83) 203 | 204 | **Closed issues:** 205 | 206 | - 2.3 Branch Needed [\#76](https://github.com/CachetHQ/Docker/issues/76) 207 | 208 | **Merged pull requests:** 209 | 210 | - 2.3 backport to master [\#91](https://github.com/CachetHQ/Docker/pull/91) ([djdefi](https://github.com/djdefi)) 211 | - Add bats QA tests [\#90](https://github.com/CachetHQ/Docker/pull/90) ([djdefi](https://github.com/djdefi)) 212 | - 2.3 backport [\#88](https://github.com/CachetHQ/Docker/pull/88) ([djdefi](https://github.com/djdefi)) 213 | - Fix DB connect warning message [\#87](https://github.com/CachetHQ/Docker/pull/87) ([djdefi](https://github.com/djdefi)) 214 | 215 | ## [v2.3.0-RC2](https://github.com/CachetHQ/Docker/tree/v2.3.0-RC2) (2016-05-27) 216 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.2.2...v2.3.0-RC2) 217 | 218 | **Merged pull requests:** 219 | 220 | - 2.3 Image enhancements [\#82](https://github.com/CachetHQ/Docker/pull/82) ([djdefi](https://github.com/djdefi)) 221 | - Use PgSQL default \(\#78\) \(\#79\) [\#80](https://github.com/CachetHQ/Docker/pull/80) ([djdefi](https://github.com/djdefi)) 222 | - Use PgSQL default \(\#78\) [\#79](https://github.com/CachetHQ/Docker/pull/79) ([djdefi](https://github.com/djdefi)) 223 | - Use PgSQL default [\#78](https://github.com/CachetHQ/Docker/pull/78) ([jbrooksuk](https://github.com/jbrooksuk)) 224 | - Don't generate key anymore [\#75](https://github.com/CachetHQ/Docker/pull/75) ([jbrooksuk](https://github.com/jbrooksuk)) 225 | - Add Travis CI support [\#73](https://github.com/CachetHQ/Docker/pull/73) ([djdefi](https://github.com/djdefi)) 226 | 227 | ## [v2.2.2](https://github.com/CachetHQ/Docker/tree/v2.2.2) (2016-05-24) 228 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.2.1...v2.2.2) 229 | 230 | **Closed issues:** 231 | 232 | - Master broken`? [\#72](https://github.com/CachetHQ/Docker/issues/72) 233 | - 500 error - Docker install [\#69](https://github.com/CachetHQ/Docker/issues/69) 234 | - Error 500 after restart [\#68](https://github.com/CachetHQ/Docker/issues/68) 235 | - Cachet doesnt start - Install loop [\#67](https://github.com/CachetHQ/Docker/issues/67) 236 | - Errors 500 [\#66](https://github.com/CachetHQ/Docker/issues/66) 237 | 238 | **Merged pull requests:** 239 | 240 | - Fix for APP\_KEY not being set in .env file [\#71](https://github.com/CachetHQ/Docker/pull/71) ([Jamie-Owen](https://github.com/Jamie-Owen)) 241 | - Fixes the crontab syntax [\#70](https://github.com/CachetHQ/Docker/pull/70) ([jbrooksuk](https://github.com/jbrooksuk)) 242 | - Update and simplify release process [\#65](https://github.com/CachetHQ/Docker/pull/65) ([djdefi](https://github.com/djdefi)) 243 | 244 | ## [v2.2.1](https://github.com/CachetHQ/Docker/tree/v2.2.1) (2016-04-26) 245 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.2.0...v2.2.1) 246 | 247 | **Implemented enhancements:** 248 | 249 | - Include startup actions like "migrate" [\#36](https://github.com/CachetHQ/Docker/issues/36) 250 | - SMTP mail driver won't send emails [\#30](https://github.com/CachetHQ/Docker/issues/30) 251 | - Revert to Jessie + init fixes [\#58](https://github.com/CachetHQ/Docker/pull/58) ([djdefi](https://github.com/djdefi)) 252 | 253 | **Fixed bugs:** 254 | 255 | - PHP-APC is not included to docker container [\#57](https://github.com/CachetHQ/Docker/issues/57) 256 | - Error when subscribe using version 2.0.4 \(Docker\) [\#32](https://github.com/CachetHQ/Docker/issues/32) 257 | 258 | **Closed issues:** 259 | 260 | - Incorrect default value for queue driver [\#63](https://github.com/CachetHQ/Docker/issues/63) 261 | - Container won't start [\#60](https://github.com/CachetHQ/Docker/issues/60) 262 | - Exception when trying upgrade Cachet version [\#54](https://github.com/CachetHQ/Docker/issues/54) 263 | - Error 500 after restart the container [\#34](https://github.com/CachetHQ/Docker/issues/34) 264 | 265 | **Merged pull requests:** 266 | 267 | - Use alpine based nginx [\#62](https://github.com/CachetHQ/Docker/pull/62) ([djdefi](https://github.com/djdefi)) 268 | - Fixes issue where .env file is invalid [\#61](https://github.com/CachetHQ/Docker/pull/61) ([adamlc](https://github.com/adamlc)) 269 | - Update .dockerignore [\#59](https://github.com/CachetHQ/Docker/pull/59) ([djdefi](https://github.com/djdefi)) 270 | 271 | ## [v2.2.0](https://github.com/CachetHQ/Docker/tree/v2.2.0) (2016-04-05) 272 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.1.2...v2.2.0) 273 | 274 | **Fixed bugs:** 275 | 276 | - Missing VOLUME command in Dockerfile [\#55](https://github.com/CachetHQ/Docker/issues/55) 277 | 278 | **Closed issues:** 279 | 280 | - Missing webserver on latest image [\#56](https://github.com/CachetHQ/Docker/issues/56) 281 | 282 | ## [v2.1.2](https://github.com/CachetHQ/Docker/tree/v2.1.2) (2016-03-04) 283 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.1.1...v2.1.2) 284 | 285 | **Merged pull requests:** 286 | 287 | - Cachet v2.1.2 release [\#53](https://github.com/CachetHQ/Docker/pull/53) ([djdefi](https://github.com/djdefi)) 288 | 289 | ## [v2.1.1](https://github.com/CachetHQ/Docker/tree/v2.1.1) (2016-03-04) 290 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.1.0...v2.1.1) 291 | 292 | **Merged pull requests:** 293 | 294 | - Cachet v2.1.1 release [\#52](https://github.com/CachetHQ/Docker/pull/52) ([djdefi](https://github.com/djdefi)) 295 | 296 | ## [v2.1.0](https://github.com/CachetHQ/Docker/tree/v2.1.0) (2016-03-04) 297 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.0.4...v2.1.0) 298 | 299 | **Implemented enhancements:** 300 | 301 | - Upgrade to PHP 7 for 2.1.0 [\#38](https://github.com/CachetHQ/Docker/issues/38) 302 | - Upgrade to postgres 9.5 for cachet 2.1.0 [\#27](https://github.com/CachetHQ/Docker/issues/27) 303 | - replace installed nginx with separate container [\#46](https://github.com/CachetHQ/Docker/pull/46) ([zemirco](https://github.com/zemirco)) 304 | - Improve Dockerfile based on lint test [\#33](https://github.com/CachetHQ/Docker/pull/33) ([djdefi](https://github.com/djdefi)) 305 | 306 | **Closed issues:** 307 | 308 | - rename this repo [\#44](https://github.com/CachetHQ/Docker/issues/44) 309 | - nginx as container instead internal instance [\#43](https://github.com/CachetHQ/Docker/issues/43) 310 | - Dockerfile for "cachethq/docker:base-5a0320b"? [\#35](https://github.com/CachetHQ/Docker/issues/35) 311 | - No connector for \[\] [\#29](https://github.com/CachetHQ/Docker/issues/29) 312 | - Branch names inconsistent? [\#26](https://github.com/CachetHQ/Docker/issues/26) 313 | - 1.2.1 tag name incorrect [\#25](https://github.com/CachetHQ/Docker/issues/25) 314 | - 504 Bad Gateway [\#19](https://github.com/CachetHQ/Docker/issues/19) 315 | 316 | **Merged pull requests:** 317 | 318 | - Cachet v2.1.0 release [\#51](https://github.com/CachetHQ/Docker/pull/51) ([djdefi](https://github.com/djdefi)) 319 | - Cachet v2.1.2 release [\#50](https://github.com/CachetHQ/Docker/pull/50) ([djdefi](https://github.com/djdefi)) 320 | - Cachet v2.1.1 release [\#49](https://github.com/CachetHQ/Docker/pull/49) ([djdefi](https://github.com/djdefi)) 321 | - Bump postgres to 9.5 [\#48](https://github.com/CachetHQ/Docker/pull/48) ([djdefi](https://github.com/djdefi)) 322 | - Switch to php7.0 [\#47](https://github.com/CachetHQ/Docker/pull/47) ([djdefi](https://github.com/djdefi)) 323 | - Revert "Remove unused packages ca-certificates and git" [\#41](https://github.com/CachetHQ/Docker/pull/41) ([djdefi](https://github.com/djdefi)) 324 | - Remove unused packages ca-certificates and git [\#40](https://github.com/CachetHQ/Docker/pull/40) ([andygrunwald](https://github.com/andygrunwald)) 325 | - Removed "cachethq/docker:base-5a0320b" base image and replaced with debian:jessie [\#37](https://github.com/CachetHQ/Docker/pull/37) ([andygrunwald](https://github.com/andygrunwald)) 326 | - Remove CN language hack from Dockerfile [\#31](https://github.com/CachetHQ/Docker/pull/31) ([djdefi](https://github.com/djdefi)) 327 | - Add a CONTRIBUTING.md doc [\#28](https://github.com/CachetHQ/Docker/pull/28) ([djdefi](https://github.com/djdefi)) 328 | 329 | ## [v2.0.4](https://github.com/CachetHQ/Docker/tree/v2.0.4) (2015-12-28) 330 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.0.3...v2.0.4) 331 | 332 | ## [v2.0.3](https://github.com/CachetHQ/Docker/tree/v2.0.3) (2015-12-28) 333 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.0.2...v2.0.3) 334 | 335 | **Implemented enhancements:** 336 | 337 | - Add GD extension [\#18](https://github.com/CachetHQ/Docker/issues/18) 338 | 339 | **Closed issues:** 340 | 341 | - Errors in README.md [\#23](https://github.com/CachetHQ/Docker/issues/23) 342 | 343 | **Merged pull requests:** 344 | 345 | - Fix README based on \#23 [\#24](https://github.com/CachetHQ/Docker/pull/24) ([djdefi](https://github.com/djdefi)) 346 | - Use upstream cachet master [\#21](https://github.com/CachetHQ/Docker/pull/21) ([djdefi](https://github.com/djdefi)) 347 | 348 | ## [v2.0.2](https://github.com/CachetHQ/Docker/tree/v2.0.2) (2015-12-06) 349 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.0.1...v2.0.2) 350 | 351 | ## [v2.0.1](https://github.com/CachetHQ/Docker/tree/v2.0.1) (2015-12-06) 352 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.0.0...v2.0.1) 353 | 354 | ## [v2.0.0](https://github.com/CachetHQ/Docker/tree/v2.0.0) (2015-12-06) 355 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/base-5a0320b...v2.0.0) 356 | 357 | ## [base-5a0320b](https://github.com/CachetHQ/Docker/tree/base-5a0320b) (2015-12-06) 358 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v2.0.0-beta1...base-5a0320b) 359 | 360 | **Implemented enhancements:** 361 | 362 | - Add php-gd to address \#18 [\#20](https://github.com/CachetHQ/Docker/pull/20) ([djdefi](https://github.com/djdefi)) 363 | 364 | ## [v2.0.0-beta1](https://github.com/CachetHQ/Docker/tree/v2.0.0-beta1) (2015-11-16) 365 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v1.2.1...v2.0.0-beta1) 366 | 367 | **Merged pull requests:** 368 | 369 | - Cachet 1.2.1 [\#17](https://github.com/CachetHQ/Docker/pull/17) ([djdefi](https://github.com/djdefi)) 370 | 371 | ## [v1.2.1](https://github.com/CachetHQ/Docker/tree/v1.2.1) (2015-11-16) 372 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/v1.2.0...v1.2.1) 373 | 374 | **Implemented enhancements:** 375 | 376 | - Switch to PostgreSQL [\#2](https://github.com/CachetHQ/Docker/issues/2) 377 | - Switch docker-compose.yml to use pgsql [\#11](https://github.com/CachetHQ/Docker/pull/11) ([djdefi](https://github.com/djdefi)) 378 | 379 | **Merged pull requests:** 380 | 381 | - Fix file permission for .env file [\#16](https://github.com/CachetHQ/Docker/pull/16) ([andygrunwald](https://github.com/andygrunwald)) 382 | 383 | ## [v1.2.0](https://github.com/CachetHQ/Docker/tree/v1.2.0) (2015-08-28) 384 | [Full Changelog](https://github.com/CachetHQ/Docker/compare/base-d3506c1...v1.2.0) 385 | 386 | **Implemented enhancements:** 387 | 388 | - Base image layer optimization [\#10](https://github.com/CachetHQ/Docker/issues/10) 389 | 390 | **Closed issues:** 391 | 392 | - Delete 1.1 tag [\#8](https://github.com/CachetHQ/Docker/issues/8) 393 | - Tracking of docker-hub automated build changes [\#7](https://github.com/CachetHQ/Docker/issues/7) 394 | - Create a Base image [\#4](https://github.com/CachetHQ/Docker/issues/4) 395 | - Design considerations [\#1](https://github.com/CachetHQ/Docker/issues/1) 396 | 397 | **Merged pull requests:** 398 | 399 | - move entrypoint COPY step down below the cachet setup [\#12](https://github.com/CachetHQ/Docker/pull/12) ([djdefi](https://github.com/djdefi)) 400 | - \[Test Needed\] 1.2 [\#6](https://github.com/CachetHQ/Docker/pull/6) ([wfjsw](https://github.com/wfjsw)) 401 | - Base Image [\#5](https://github.com/CachetHQ/Docker/pull/5) ([wfjsw](https://github.com/wfjsw)) 402 | 403 | ## [base-d3506c1](https://github.com/CachetHQ/Docker/tree/base-d3506c1) (2015-08-15) 404 | 405 | 406 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* --------------------------------------------------------------------------------