├── .editorconfig
├── .gitignore
├── CHANGELOG.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── ansistrano
├── ansible.cfg
├── applications
│ ├── default.yml
│ ├── symfony2.yml
│ ├── symfony3.yml
│ └── typo3.yml
├── deploy
├── deploy-status.yml
├── deploy.yml
├── files
│ └── opcode-clear.php
├── inventory
│ ├── group_vars
│ │ └── .gitkeep
│ ├── host_vars
│ │ └── .gitkeep
│ └── vagrant
├── projects
│ └── default.yml
├── roles
│ ├── deployment-status-failure
│ │ └── tasks
│ │ │ └── main.yml
│ ├── deployment-status-startup
│ │ └── tasks
│ │ │ └── main.yml
│ └── deployment-status-success
│ │ └── tasks
│ │ └── main.yml
├── rsync-excludes
└── tasks
│ ├── build.yml
│ ├── build
│ ├── .gitkeep
│ ├── commands.yml
│ └── makefile.yml
│ ├── finalize.yml
│ ├── finalize
│ ├── .gitkeep
│ ├── commands.yml
│ └── php-opcode-cache.yml
│ ├── migration.yml
│ ├── migration
│ ├── .gitkeep
│ ├── commands.yml
│ └── permissions.yml
│ ├── teardown.yml
│ └── teardown
│ ├── .gitkeep
│ └── validate.yml
├── backup
└── .gitkeep
├── docker-compose.yml
├── etc
├── crontab
├── database.yml
├── environment.yml
├── known_hosts
│ ├── bitbucket.com
│ ├── github.com
│ └── gitlab.com
├── provision.yml
└── samson.conf
├── mysql
├── Dockerfile
└── conf
│ └── mysql-docker.cnf
├── provision
└── roles
│ └── samson-deployment
│ ├── defaults
│ └── main.yml
│ └── tasks
│ ├── build.yml
│ ├── build
│ ├── cron.yml
│ ├── permissions.yml
│ ├── ssh.yml
│ └── storage.yml
│ └── main.yml
└── ssh
├── .gitkeep
├── config
└── known_hosts
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 | charset = utf-8
6 | trim_trailing_whitespace = true
7 |
8 | [*]
9 | end_of_line = lf
10 | insert_final_newline = true
11 | indent_style = space
12 | indent_size = 4
13 |
14 | [Makefile]
15 | indent_style = tab
16 |
17 | [*.yml]
18 | indent_size = 2
19 |
20 | [*.conf]
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | /ssh/id_rsa
3 | /ssh/id_rsa.pub
4 | /backup/*
5 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 | All notable changes to this project will be documented in this file.
3 | This project adheres to [WebDevOps.io Samson Deployment](https://github.com/webdevops/samson-deployment).
4 |
5 | ## [1.4.0] - 2016-04-06
6 | ### Changed
7 | - Fixed ssh control path length for very long host names (see https://github.com/ansible/ansible/issues/11536)
8 | - Set default ansistrano deployment strategy to "rsync" instead of "symlink" to fix issues (see https://github.com/zendtech/ZendOptimizerPlus/issues/126)
9 |
10 | ## [1.3.0] - 2016-03-28
11 | ### Changed
12 | - Moved /app/db to /storage/db (make backup before update!)
13 | - Added storage for npm and composer
14 | - Implemented reading of samson project/group environment variables when using ansistrano
15 | - Local tasks only run once for all affected hosts
16 |
17 | ## [1.2.0] - 2016-02-24
18 | ### Changed
19 | - TYPO3 deployment support
20 | - rsync excludes because of deployment issues
21 |
22 | ### Removed
23 | - MySQL support, switched to sqlite because of stability issues
24 |
25 | ## [1.1.0] - 2016-02-16
26 | ### Added
27 | - Added basic symfony 2 und 3 support
28 | - Added support for prefetched ssh public keys (more secure)
29 | - Added Makefile for common tasks
30 | - Added `DEPLOYMENT_PROJECT` support
31 |
32 | ### Changed
33 | - Improved deployment README
34 | - Renamed /opt/deployment to /opt/ansistrano
35 | - Cleaned up etc/environment.yml
36 | - Switched to Apache 2.0 license to match zendesk/samson license
37 |
38 | ## [1.0.1] - 2016-02-16
39 | ### Changed
40 | - Updated README
41 |
42 | ## [1.0.0] - 2016-02-16
43 | Initial revision
44 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM webdevops/samson-deployment
2 |
3 | ENV RAILS_ENV="production"
4 | ENV PYTHONUNBUFFERED=1
5 |
6 | # Setup
7 | COPY etc/crontab /etc/cron.d/samson-deployment
8 | COPY etc/database.yml /app/config/database.yml
9 | COPY etc/samson.conf /app/.env
10 | COPY etc/provision.yml /app/provision.yml
11 | COPY etc/known_hosts/ /root/.known_ssh_prefetched
12 |
13 | # Deploy ansistrano scripts
14 | COPY ansistrano/ /opt/ansistrano/
15 |
16 | # Deploy ssh configuration/keys
17 | COPY ssh/ /home/application/.ssh/
18 |
19 | COPY provision/ /opt/docker/provision/
20 |
21 | RUN bash /opt/docker/bin/control.sh provision.role.build samson-deployment \
22 | && /opt/docker/bin/control.sh service.enable cron \
23 | && bash /opt/docker/bin/bootstrap.sh
24 |
25 | VOLUME ["/tmp", "/storage"]
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2016 WebDevOps.io
2 | Copyright 2014 Zendesk
3 |
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | ARGS = $(filter-out $@,$(MAKECMDGOALS))
2 | MAKEFLAGS += --silent
3 | .PHONY: backup restore
4 |
5 | list:
6 | sh -c "echo; $(MAKE) -p no_targets__ | awk -F':' '/^[a-zA-Z0-9][^\$$#\/\\t=]*:([^=]|$$)/ {split(\$$1,A,/ /);for(i in A)print A[i]}' | grep -v '__\$$' | grep -v 'Makefile'| sort"
7 |
8 | restart: rebuild
9 |
10 | start:
11 | docker-compose up -d
12 |
13 | stop:
14 | docker-compose stop
15 |
16 | log:
17 | docker-compose logs
18 |
19 | rebuild:
20 | docker-compose build
21 | docker-compose up -d --force-recreate
22 |
23 | update:
24 | docker pull webdevops/samson-deployment
25 | docker-compose build
26 | docker-compose up -d --force-recreate
27 |
28 | backup:
29 | rm -rf ./backup/db/
30 | docker exec -it -u root $$(docker-compose ps -q app) service samson stop
31 | docker cp $$(docker-compose ps -q app):/storage/db/ ./backup/db/
32 | docker exec -it -u root $$(docker-compose ps -q app) service samson start
33 |
34 | restore:
35 | docker exec -it -u root $$(docker-compose ps -q app) service samson stop
36 | docker exec -it -u root $$(docker-compose ps -q app) rm -rf /storage/db/
37 | docker cp ./backup/db/ $$(docker-compose ps -q app):/storage/db/
38 | docker exec -it -u root $$(docker-compose ps -q app) chown -R application:application /storage/db/
39 | docker exec -it -u root $$(docker-compose ps -q app) service samson start
40 |
41 | shell:
42 | docker exec -it -u application $$(docker-compose ps -q app) /bin/bash
43 |
44 | root:
45 | docker exec -it -u root $$(docker-compose ps -q app) /bin/bash
46 |
47 | ssh-key:
48 | if [ ! -f "./ssh/id_rsa" ]; then \
49 | echo "Generating ssh key, will take some time ..."; \
50 | ssh-keygen -b 6144 -N "" -C "Samson deployment service" -f "./ssh/id_rsa"; \
51 | else \
52 | echo ""; \
53 | echo "[ERROR] SSH key already exists!"; \
54 | echo ""; \
55 | exit 1; \
56 | fi
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [ZenDesk's](https://www.zendesk.com/) Deployment web ui with Ansible Ansistrano, Capistrano and PHP Deployer support
4 |
5 | Installed packages:
6 | * [Samson deployment web ui](https://github.com/zendesk/samson)
7 | * [Ansible](https://www.ansible.com/) with [Ansistrano](https://github.com/ansistrano)
8 | * [Capistrano](http://capistranorb.com/)
9 | * [PHP Deployer](http://deployer.org/)
10 | * git
11 | * rsync
12 | * docker & docker-compose (as client)
13 | * npm, gulp, grunt, bower
14 | * java (jre 7)
15 | * PHP cli & [composer](https://getcomposer.org/)
16 |
17 | ### What?
18 | (from [ZenDesk/Samson repository](https://github.com/zendesk/samson))
19 |
20 | A web interface for deployments.
21 |
22 | **View the current status of all your projects:**
23 |
24 | 
25 |
26 | **Allow anyone to watch deploys as they happen:**
27 |
28 | 
29 |
30 | **View all recent deploys across all projects:**
31 |
32 | 
33 |
34 | ## Setup
35 |
36 | * [Generate GitHub appliation key](https://github.com/settings/developers)
37 | * [Generate GitHub access token](https://github.com/settings/tokens)
38 | * Edit `conf/samson.conf`:
39 | * Set GitHub appliation credentials (`GITHUB_CLIENT_ID`, `GITHUB_SECRET`)
40 | * Set GitHub access token (`GITHUB_TOKEN`)
41 | * Set `SECRET_TOKEN` (random string with length of 128, can be generated with `openssl rand -hex 128| head -c 128`)
42 | * Set `DEFAULT_URL` (must be accessable url for SSO callbacks)
43 | * Edit `etc/provision.yml` to setup public key fetching of `.ssh/known_hosts`
44 | * Fixed known_host keys can be stored inside `etc/known_hosts` folder and can be generated with `ssh-keyscan -H HOSTNAME > etc/known_hosts/HOSTNAME` (very secure)
45 | * All hosts without stored known_host keys will be automatically fetched when Dockerfile build is running (less secure)
46 | * Add ssh keys to `ssh` (will be deployed to `/home/application/.ssh`) or generate an new one with `make ssh-key`
47 | * Run `docker-compose up -d` or `make restart`
48 |
49 | ## Ansistrano deployment
50 |
51 | For an easy project independed deployment you can use the predefined deployment runner (based on Ansistrano).
52 |
53 | Use following as deployment command:
54 |
55 | ```
56 | export DEPLOYMENT_INVENTORY=vagrant
57 | export DEPLOYMENT_DEPLOY_TO=/var/www/target-deployment-path
58 | /opt/ansistrano/deploy
59 | ```
60 |
61 | ### Deploy variables
62 |
63 | Variable | Description
64 | ------------------------------ | ------------------------------------------------------
65 | DEPLOYMENT_INVENTORY | Inventory file for deployment **(required)**
66 | DEPLOYMENT_DEPLOY_TO | Target deployment directory **(required)**
67 | DEPLOYMENT_CURRENT_DIR | Link name of the htdocs path (default: current)
68 | DEPLOYMENT_APPLICATION | Include variables for specific application (eg. for shared paths, eg `typo3` for including `deployment/applications/typo3.yml`)
69 | DEPLOYMENT_PROJECT | Include variables for specific project (eg. for shared paths, eg `foobar` for including `deployment/projects/foobar.yml`)
70 | DEPLOYMENT_OPTS | Ansible options (can also be append to `/opt/ansistrano/deploy`)
71 | DEPLOYMENT_PLAYBOOK | Ansible playbook (default is `deploy`)
72 | DEPLOYMENT_URL | URL to website (required for eg. PHP opcode cache clearing)
73 |
74 | ### Customization
75 |
76 | Variable | Description
77 | --------------------------- | ------------------------------------------------------
78 | Ansible inventory | [deployment/inventory](ansistrano/inventory)
79 | Common project build task | [deployment/tasks/build.yml](ansistrano/tasks/build.yml)
80 | Main deploy playbook | [deployment/deploy.yml](ansistrano/deploy.yml)
81 | Common rsync excludes | [deployment/rsync-excludes](ansistrano/rsync-excludes)
82 |
83 | ## PHP deployer
84 | Use following as deployment command:
85 |
86 | ```
87 | dep deploy
88 | ```
89 |
90 | ## Makefile
91 |
92 | Command | Description
93 | --------------------------- | ------------------------------------------------------
94 | `make restart` | Restart Samson (and update/deploy configuration)
95 | `make start` | Start Samson
96 | `make stop` | Stop Samson
97 | `make log` | Show logs
98 | `make update` | Update Samson docker image (`docker pull`) and restart Samson
99 | `make ssh-key` | Generate new ssh-key (will not overwrite if exists)
100 |
|
101 | `make backup` | Run backup (app:/app/db/ will be copied to ./backup/db/)
102 | `make restore` | Run restore (./backup/db/ will be copied to app:/app/db/)
103 |
|
104 | `make shell` | Jump into shell inside the container (as `application` user)
105 | `make root` | Jump into shell inside the container (as `root` user)
106 |
107 | ## Project specific deployment
108 |
109 | If you need a project specific deployment feel free to put your ansistrano deployment within your project sources.
110 | Your deployment task should look like:
111 |
112 | ansible-playbook -i inventory/server deploy.yml
113 |
114 | ## SSH - jump to servers behind gateways transparently
115 |
116 | With ssh you can jump over multiple servers transparently to reach servers behinde ssh gateways, use the `ssh/config`
117 | file for configuration:
118 |
119 | ```
120 | Host ssh-gateway
121 | Hostname ssh-gateway.example.com
122 | User foo
123 |
124 | Host server-behind-gateway
125 | Hostname server-behind-ssh-gateway.example.com
126 | User root
127 | ProxyCommand ssh ssh-gateway -W %h:%p
128 | ```
129 |
130 | Now you can use `server-behind-gateway` as target host for SSH'ing at it will automatically jump over `ssh-gateway` to
131 | reach this server.
132 |
--------------------------------------------------------------------------------
/ansistrano/ansible.cfg:
--------------------------------------------------------------------------------
1 | [defaults]
2 | ask_sudo_pass = false
3 | ask_pass = false
4 |
5 | # dont show command "better use xxx module" warning
6 | command_warnings = False
7 |
8 | # uncomment this to disable SSH key host checking
9 | #host_key_checking = False
10 |
11 | force_color = 1
12 | nocolor = 0
13 | nocows = 1
14 |
15 | [ssh_connection]
16 | control_path = %(directory)s/%%C
17 |
--------------------------------------------------------------------------------
/ansistrano/applications/default.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | #############################
4 | # Ansistrano
5 | #############################
6 |
7 | # Rsync files from this directory (with trailing /)
8 | ansistrano_deploy_from: "{{ lookup('env','DEPLOYMENT_DEPLOY_FROM') }}"
9 |
10 | # Rsync files to this directory (with releases, shared and current folder)
11 | ansistrano_deploy_to: "{{ lookup('env','DEPLOYMENT_DEPLOY_TO') }}"
12 |
13 | # Folder name for the releases
14 | ansistrano_version_dir: "releases"
15 |
16 | # Softlink name for the current release (default "current")
17 | ansistrano_current_dir: "{{ lookup('env','DEPLOYMENT_CURRENT_DIR') }}"
18 |
19 | # Deploy strategy for "current" directory (options: rsync, symlink)
20 | # For symlink for PHP see https://github.com/zendtech/ZendOptimizerPlus/issues/126
21 | # but applied to other languages as well
22 | # -> for apache use mod_realdoc
23 | # -> for nginx use realpath setting
24 | ansistrano_current_via: "rsync"
25 |
26 | # Shared paths to symlink to release dir
27 | ansistrano_shared_paths: []
28 |
29 | # Number of releases to keep in your hosts, if 0, unlimited releases will be kept
30 | ansistrano_keep_releases: 3
31 |
32 | # Rsync extra paraemters (will be append to rsync command)
33 | ansistrano_rsync_extra_params: "--exclude-from={{ playbook_dir }}/rsync-excludes --no-o --no-g"
34 |
35 | # Hooks
36 | ansistrano_before_setup_tasks_file: "{{ playbook_dir }}/tasks/build.yml"
37 | ansistrano_before_symlink_tasks_file: "{{ playbook_dir }}/tasks/migration.yml"
38 | ansistrano_after_symlink_tasks_file: "{{ playbook_dir }}/tasks/finalize.yml"
39 | ansistrano_after_cleanup_tasks_file: "{{ playbook_dir }}/tasks/teardown.yml"
40 |
41 | #############################
42 | # Deployment (Hooks)
43 | #############################
44 |
45 | # Set the deployment base directory (for running local tasks)
46 | deployment_base: "{{ lookup('env','DEPLOYMENT_DEPLOY_FROM') }}"
47 |
48 | # Run defined Makefile task (on deployment server, before rsync)
49 | deployment_makefile_task: "build"
50 |
51 | # Tasks for building up application (on deployment server, before rsync)
52 | deployment_build_tasks: []
53 |
54 | # Tasks for migration (before going live on remote server)
55 | deployment_migration_tasks: []
56 |
57 | # Tasks for finalize (after going live on remote server)
58 | deployment_finalize_tasks: []
59 |
60 | # Application name (for conditions)
61 | deployment_application: "default"
62 |
63 | # Deployment permissions (on remote server)
64 | deployment_permission_owner: ""
65 | deployment_permission_group: ""
66 | deployment_permission_mode: "u=rwX,g=rX,o=rX"
67 |
68 | # Deployment special file or directory permissions (on remote server)
69 | deployment_permissions: []
70 |
71 | # URL to instance (eg. for PHP OpCode cache clearing)
72 | deployment_web_url: "{{ lookup('env','DEPLOYMENT_URL') }}"
73 |
74 | # Path Prefix for document root
75 | deployment_web_path_prefix: ""
76 |
77 | # Enable PHP opcode cache clearing (requires deployment_web_url)
78 | deployment_php_opcode_cache_clear: False
79 |
80 | # Options for curl
81 | deployment_curl_opts: ""
82 |
83 | # Enable for final website validation check via curl request (requires deployment_web_url)
84 | deployment_validate_website: False
85 |
--------------------------------------------------------------------------------
/ansistrano/applications/symfony2.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Application name (for conditions)
4 | deployment_application: "symfony3"
5 |
6 | # Shared paths to symlink to release dir
7 | ansistrano_shared_paths:
8 | - app/logs
--------------------------------------------------------------------------------
/ansistrano/applications/symfony3.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Application name (for conditions)
4 | deployment_application: "symfony3"
5 |
6 | # Shared paths to symlink to release dir
7 | ansistrano_shared_paths:
8 | - var/logs
--------------------------------------------------------------------------------
/ansistrano/applications/typo3.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Application name (for conditions)
4 | deployment_application: "typo3"
5 |
6 | # Shared paths to symlink to release dir
7 | ansistrano_shared_paths:
8 | - web/fileadmin
9 | - web/uploads
10 | - web/typo3conf/l10n
11 |
12 | # Deployment special file or directory permissions (on remote server)
13 | deployment_permissions:
14 | - { path: "web/typo3conf/PackageStates.php", mode: "0664" }
15 | - { path: "web/typo3conf/LocalConfiguration.php", mode: "0660" }
16 |
17 | # Path Prefix for document root
18 | deployment_web_path_prefix: "/web"
19 |
20 | # Enable PHP opcode cache clearing (requires deployment_web_url)
21 | deployment_php_opcode_cache_clear: True
22 |
--------------------------------------------------------------------------------
/ansistrano/deploy:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SCRIPT_DIR="$(dirname $(readlink -f "$0"))"
4 |
5 | DEBUG=0
6 |
7 | export PYTHONUNBUFFERED=1
8 | export ANSIBLE_CONFIG="${SCRIPT_DIR}/ansible.cfg"
9 |
10 | ## Read vars from .env
11 | if [[ -f "$(pwd)/.env" ]]; then
12 | set -o allexport
13 | . "$(pwd)/.env"
14 | set +o allexport
15 | fi
16 |
17 | if [ -z "$DEPLOYMENT_INVENTORY" ]; then
18 | echo "[ERROR] DEPLOYMENT_INVENTORY not set"
19 | exit 1
20 | fi
21 |
22 | if [ -z "$DEPLOYMENT_DEPLOY_TO" ]; then
23 | echo "[ERROR] DEPLOYMENT_DEPLOY_TO not set"
24 | exit 1
25 | fi
26 |
27 | if [ -z "$DEPLOYMENT_DEPLOY_FROM" ]; then
28 | export DEPLOYMENT_DEPLOY_FROM="$(pwd)/"
29 | fi
30 |
31 | if [ -z "$DEPLOYMENT_CURRENT_DIR" ]; then
32 | export DEPLOYMENT_CURRENT_DIR="current"
33 | fi
34 |
35 | if [ -z "$DEPLOYMENT_APPLICATION" ]; then
36 | export DEPLOYMENT_APPLICATION="default"
37 | fi
38 |
39 | if [ -z "$DEPLOYMENT_PROJECT" ]; then
40 | export DEPLOYMENT_PROJECT="default"
41 | fi
42 |
43 |
44 | if [ -z "$DEPLOYMENT_OPTS" ]; then
45 | DEPLOYMENT_OPTS=""
46 | fi
47 |
48 | if [ -z "$DEPLOYMENT_PLAYBOOK" ]; then
49 | DEPLOYMENT_PLAYBOOK="deploy"
50 | fi
51 |
52 | function displayEnvVars() {
53 | env | grep DEPLOYMENT_ | sed -e 's/^/» /'
54 | }
55 |
56 | function ansibleDeployStatus() {
57 | if [[ "$DEBUG" -eq 0 ]]; then
58 | ansible-playbook -i localhost, -c local "${SCRIPT_DIR}/deploy-status.yml" &> /dev/null
59 | else
60 | ansible-playbook -i localhost, -c local "${SCRIPT_DIR}/deploy-status.yml"
61 | fi
62 | }
63 |
64 | function calcDuration() {
65 | export DEPLOYMENT_DURATION_TIME="$SECONDS"
66 | export DEPLOYMENT_DURATION_MINUTES="$(($DEPLOYMENT_DURATION_TIME / 60))"
67 | export DEPLOYMENT_DURATION_SECONDS="$(($DEPLOYMENT_DURATION_TIME % 60))"
68 | export DEPLOYMENT_DURATION="${DEPLOYMENT_DURATION_MINUTES}:$(printf "%02d" $DEPLOYMENT_DURATION_SECONDS) min"
69 | }
70 |
71 | function runDeployment() {
72 | ansible-playbook -i "${SCRIPT_DIR}/inventory/${DEPLOYMENT_INVENTORY}" "${SCRIPT_DIR}/${DEPLOYMENT_PLAYBOOK}.yml" $DEPLOYMENT_OPTS "$@"
73 | export DEPLOYMENT_RC="$?"
74 | }
75 |
76 | echo ""
77 | echo ""
78 | echo "# Environment variables"
79 | displayEnvVars
80 |
81 | ## run status report (startup)
82 | ansibleDeployStatus
83 |
84 | echo ""
85 | echo ""
86 | echo "# Executing Ansistrano"
87 |
88 | ## reset timer
89 | SECONDS=0
90 |
91 | ## run deployment
92 | runDeployment "$@"
93 |
94 | ## calculate duration
95 | calcDuration
96 |
97 | ## run status report (finish)
98 | ansibleDeployStatus
99 |
100 | echo ""
101 | echo ""
102 | echo "» Duration: ${DEPLOYMENT_DURATION}"
103 | echo ""
104 |
105 | exit "$DEPLOYMENT_RC"
106 |
107 |
--------------------------------------------------------------------------------
/ansistrano/deploy-status.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Deployment reporting tasks
3 | hosts: all
4 | gather_facts: false
5 | vars:
6 | DEPLOYMENT_RC: "{{ lookup('env','DEPLOYMENT_RC') }}"
7 | DEPLOYMENT_DURATION: "{{ lookup('env','DEPLOYMENT_DURATION') }}"
8 | roles:
9 | - { role: deployment-status-startup, when: DEPLOYMENT_RC == "" }
10 | - { role: deployment-status-failure, when: DEPLOYMENT_RC != "0" and DEPLOYMENT_RC != "" }
11 | - { role: deployment-status-success, when: DEPLOYMENT_RC == "0" }
12 |
--------------------------------------------------------------------------------
/ansistrano/deploy.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Deployment
3 | hosts: all
4 | vars_files:
5 | - applications/default.yml
6 | - applications/{{ lookup('env','DEPLOYMENT_APPLICATION') }}.yml
7 | - projects/{{ lookup('env','DEPLOYMENT_PROJECT') }}.yml
8 | roles:
9 | - { role: carlosbuenosvinos.ansistrano-deploy }
10 |
--------------------------------------------------------------------------------
/ansistrano/files/opcode-clear.php:
--------------------------------------------------------------------------------
1 | /dev/null
5 | 4 5 * * * root dep self-update &> /dev/null
--------------------------------------------------------------------------------
/etc/database.yml:
--------------------------------------------------------------------------------
1 | <%
2 | uri = URI(ENV['MYSQL_URL'] || 'mysql://root:sql@mysql:3306/samson')
3 | uri.scheme = 'mysql2'
4 | %>
5 |
6 | production:
7 | adapter: sqlite3
8 | database: /storage/db/database.sqlite3
9 | pool: 5
10 | timeout: 5000
11 |
12 | staging:
13 | adapter: sqlite3
14 | database: /storage/db/database.sqlite3
15 | pool: 5
16 | timeout: 5000
17 |
18 | development:
19 | adapter: sqlite3
20 | database: /storage/db/database.sqlite3
21 | pool: 5
22 | timeout: 5000
23 |
24 | test:
25 | adapter: sqlite3
26 | database: /storage/db/database.sqlite3
27 | pool: 5
28 | timeout: 5000
29 |
30 |
--------------------------------------------------------------------------------
/etc/environment.yml:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Environment Configuration
3 | # - feel free to edit -
4 | # -> for most changes you only have to
5 | # docker-compose up -d
6 | # to apply them
7 | #######################################
8 |
9 | #######################################
10 | # Samson settings
11 | MYSQL_URL=mysql://root:sql@mysql:3306/samson
12 |
13 | #######################################
14 | # MySQL settings
15 | # -> if you change these settings
16 | # you have to remove the database:
17 | # docker-compose rm mysql
18 | # because it's stored database in
19 | # volume and provisioning is only
20 | # done once.
21 | MYSQL_ROOT_PASSWORD=sql
22 | MYSQL_USER=samson
23 | MYSQL_PASSWORD=samson
24 | MYSQL_DATABASE=samson
25 |
26 |
27 |
--------------------------------------------------------------------------------
/etc/known_hosts/bitbucket.com:
--------------------------------------------------------------------------------
1 | # bitbucket.com:22 SSH-2.0-OpenSSH_6.4
2 | |1|36DT5/mpuswvt+2oGlCrx8DZ9EQ=|NQ9nL95+12dbGJI8JtrFHL88ogU= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
3 | # bitbucket.com:22 SSH-2.0-OpenSSH_5.3
4 | # bitbucket.com:22 SSH-2.0-OpenSSH_5.3
5 |
--------------------------------------------------------------------------------
/etc/known_hosts/github.com:
--------------------------------------------------------------------------------
1 | |1|LXmaOLU+O3acZyv84Z8EZcnOc3U=|wMsFOgS9hOl6kLuHdQySlyfT8bo= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
2 |
--------------------------------------------------------------------------------
/etc/known_hosts/gitlab.com:
--------------------------------------------------------------------------------
1 | # gitlab.com:22 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6
2 | |1|PfJ6/iOiXGYeje5RBwehqA7x0ZA=|2g4x0QIByX+yI3rr/SVWOpSwlgw= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
3 | # gitlab.com:22 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6
4 | |1|U7DzVjlR0jfPpXigqSaDY4HziEM=|WKMZ5x/b6nTCkFA/B9UI/z+ln88= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
5 | # gitlab.com:22 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6
6 | |1|4dxeUV6vHkOXBMYJXURBbEV1QNY=|YMBnqRrZZWyzfjlPIo4qVuAtwnM= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
7 |
--------------------------------------------------------------------------------
/etc/provision.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | SSH:
4 | # List of hostnames which should be automatically fetched for .ssh/known_hosts
5 | # hostname: hostname or ip of remote host
6 | # file: pre-fetched ssh-keyscan server public key
7 | # inside etc/known_hosts
8 | # (otherwise there will be on-provision key fetch)
9 | # port: ssh port of remote host
10 | # opts: ssh-keyscan additional parameters, see "man ssh-keyscan"
11 | # Examples:
12 | # - { hostname: "your-host.example" }
13 | # - { hostname: "your-host.example", port: "2222" }
14 | # - { hostname: "your-host.example", opts: "2222" }
15 | known_hosts:
16 | - { hostname: "github.com", file: "github.com" }
17 | - { hostname: "gitlab.com", file: "gitlab.com" }
18 | - { hostname: "bitbucket.com", file: "bitbucket.com" }
19 |
--------------------------------------------------------------------------------
/etc/samson.conf:
--------------------------------------------------------------------------------
1 | PLUGINS=all,-slack
2 | DEFAULT_URL=http://samson.vm:9080/
3 | SECRET_TOKEN={bundle exec rake secret}
4 |
5 | # GITHUB_CLIENT_ID={fill me in}
6 | # GITHUB_SECRET={fill me in}
7 | # GITHUB_TOKEN={fill me in}
8 | # GITHUB_ORGANIZATION={optional
9 | # GITHUB_ORGANIZATION={optional, eg. zendesk}
10 | # GITHUB_ADMIN_TEAM={optional, eg. owners}
11 | # GITHUB_DEPLOY_TEAM={optional, eg. developers}
12 | # GITHUB_WEB_URL={optional, eg. github.com}
13 | # GITHUB_API_URL={optional, eg. api.github.com}
14 |
15 | # GOOGLE_CLIENT_ID={optional, fill me in}
16 | # GOOGLE_CLIENT_SECRET={optional, fill me in}
17 | # GOOGLE_DOMAIN={optional, set to @company.com to limit login only for people at Company}
18 |
19 | #The following settings is required if auth with LDAP is enabled.
20 | # LDAP_TITLE={fill me in, eg. My LDAP Server}
21 | # LDAP_HOST=192.168.25.188
22 | # LDAP_PORT=389
23 | # LDAP_BASE='dc=domain,dc=com'
24 | # LDAP_UID=uid
25 | # LDAP_PASSWORD=myldapsecret
26 |
27 | # AUTH_GITHUB={optional, set to 0 to disable Github authentication}
28 | # AUTH_GOOGLE={optional, set to 0 to disable Google authentication}
29 | # AUTH_LDAP={optional, set to 0 to disable LDAP authentication}
30 |
31 | # BYPASS_EMAIL={optional, email destination that is alerted about buddy_check bypasses}
32 | # BYPASS_JIRA_EMAIL={optional, jira email destination that is alerted about buddy_check bypasses}
33 | # BYPASS_DETAILS={optional 'Some text explaining bypass procedure'}
34 | # BUDDY_CHECK_FEATURE={optional, set to 1 to enable buddy_check feature; 0 to disable}
35 |
36 | # BUDDY_CHECK_TIME_LIMIT={optional, set to 20 for max minutes a deploy is pending}
37 |
38 | # PROJECT_CREATED_NOTIFY_ADDRESS=bobby-the-security-auditor@yourcompany.com
39 |
40 | # DEPLOY_GROUP_FEATURE={optional, set to 1 to enable Environments and DeployGroups}
41 |
42 | # DOCKER_FEATURE={optional, set to 1 for experimental docker support}
43 |
44 | # SLACK_TOKEN={ required for the slack integration }
45 |
46 | # FLOWDOCK_API_TOKEN={ required for the flowdock integration }
47 |
48 | # FORCE_SSL={optional, set to 1 to require SSL}
49 |
50 | ## JIRA_BASE_URL, if set, would enable the auto-detection of JIRA issue keys
51 | ## (e.g., KEY-123, SAMSON-456) in the titles and bodies of the pull requests
52 | ## associated with a deploy. The auto-detected JIRA issues will be displayed
53 | ## and linked (by prepending JIRA_BASE_URL) in the "JIRA Issues" tab of a deploy
54 | ##
55 | ## Full absolute JIRA URLs will still be detected, and they will take precedence
56 | ## over generated ones (i.e., if JIRA_BASE_URL is https://a.atlassian.net/browse/
57 | ## and both "KEY-123" and "http://z.atlassian.net/browse/KEY-123" appear in a
58 | ## pull request's title and body, only "http://z.atlassian.net/browse/KEY-123"
59 | ## would appear in the "JIRA Issues" tab).
60 | ##
61 | # JIRA_BASE_URL={optional, eg. https://jira.atlassian.net/browse/}
--------------------------------------------------------------------------------
/mysql/Dockerfile:
--------------------------------------------------------------------------------
1 | #++++++++++++++++++++++++++++++++++++++
2 | # MySQL Docker container
3 | #++++++++++++++++++++++++++++++++++++++
4 | #
5 | # Official images:
6 | #
7 | # mysql - official MySQL from Oracle
8 | # https://hub.docker.com/r/library/mysql/
9 | #
10 | #++++++++++++++++++++++++++++++++++++++
11 |
12 | FROM mysql:5.7
13 |
14 | ADD conf/mysql-docker.cnf /etc/mysql/conf.d/z99-docker.cnf
15 |
--------------------------------------------------------------------------------
/mysql/conf/mysql-docker.cnf:
--------------------------------------------------------------------------------
1 | [mysqld]
2 |
3 | #################################################
4 | ## Charset
5 |
6 | character-set-server=utf8
7 | collation-server=utf8_general_ci
8 |
9 | #################################################
10 | ## Buffers
11 |
12 | key_buffer_size = 200M
13 | query_cache_size = 100M
14 |
15 | innodb_buffer_pool_size = 250M
16 | innodb_log_buffer_size = 10M
17 |
18 | tmp_table_size = 200M
19 | max_heap_table_size = 200M
20 |
21 | open-files-limit = 2048
22 | thread_cache_size = 12
23 |
24 | # Fast SQL import
25 | local-infile=1
26 |
27 | #################################################
28 | ## Misc
29 |
30 | ## direct access to files, avoid OS-caching (not posssible in docker)
31 | ; innodb_flush_method=O_DIRECT
32 |
33 | transaction-isolation=REPEATABLE-READ
34 | ;transaction-isolation=READ-COMMITTED
35 |
36 | #################################################
37 | ## Query cache
38 |
39 | query_cache_limit = 256k
40 | query_cache_size = 60M
41 | query_cache_type = 1
42 |
43 | #################################################
44 | ## Query log
45 |
46 | slow-query-log
47 | slow_query_log_file = /dev/stderr
48 | long_query_time = 1
49 | ; log-queries-not-using-indexes
50 |
51 | #################################################
52 | ## Connections
53 | ##
54 | ## keep connections low because each conncetion
55 | ## will have their own buffers
56 | ## - prevent swapping here -
57 |
58 | max_connections = 20
59 | max_allowed_packet = 16M
60 |
61 |
--------------------------------------------------------------------------------
/provision/roles/samson-deployment/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | APPLICATION_USER: "{{ lookup('env','APPLICATION_USER') }}"
4 | APPLICATION_GROUP: "{{ lookup('env','APPLICATION_GROUP') }}"
5 |
--------------------------------------------------------------------------------
/provision/roles/samson-deployment/tasks/build.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - include: build/ssh.yml
4 | - include: build/cron.yml
5 | - include: build/storage.yml
6 | - include: build/permissions.yml
7 |
8 |
--------------------------------------------------------------------------------
/provision/roles/samson-deployment/tasks/build/cron.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Add newline to crontab
4 | raw: 'echo >> /etc/cron.d/samson-deployment'
5 |
--------------------------------------------------------------------------------
/provision/roles/samson-deployment/tasks/build/permissions.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - file:
4 | path: "{{ item.path }}"
5 | owner: "{{ APPLICATION_USER }}"
6 | group: "{{ APPLICATION_GROUP }}"
7 | state: "{{ item.state }}"
8 | mode: "{{ item.mode }}"
9 | with_items:
10 | - { path: "/app", state: "directory", mode: "0755" }
11 | - { path: "/app/tmp", state: "directory", mode: "0755" }
12 |
--------------------------------------------------------------------------------
/provision/roles/samson-deployment/tasks/build/ssh.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - include_vars: /app/provision.yml
4 |
5 | - file:
6 | path: /home/application/.ssh
7 | owner: "{{ APPLICATION_USER }}"
8 | group: "{{ APPLICATION_GROUP }}"
9 | state: directory
10 | mode: 0700
11 |
12 | - name: Fix ssh owner
13 | command: find /home/application/.ssh -exec chown "{{ APPLICATION_USER }}:{{ APPLICATION_GROUP }}" {} \;
14 |
15 | - name: Fix ssh directory permissions
16 | command: find /home/application/.ssh -type d -exec chmod 0700 {} \;
17 |
18 | - name: Fix ssh file permissions
19 | command: find /home/application/.ssh -type f -exec chmod 0600 {} \;
20 |
21 | - file:
22 | path: /home/application/.ssh/known_hosts
23 | owner: "{{ APPLICATION_USER }}"
24 | group: "{{ APPLICATION_GROUP }}"
25 | state: touch
26 | mode: 0644
27 |
28 | - name: Save ssh fingerprints from known hosts (online)
29 | shell: ssh-keyscan -p "{{ item.port | default(22) }}" {{ item.opts | default() }} -H "{{ item.hostname }}" >> /home/application/.ssh/known_hosts
30 | with_items: "{{ SSH.known_hosts }}"
31 | when: SSH.known_hosts is defined and (item.file is not defined or item.file == "")
32 |
33 | - name: Save ssh fingerprints from known hosts (prefeched)
34 | shell: cat "/root/.known_ssh_prefetched/{{ item.file }}" >> /home/application/.ssh/known_hosts
35 | with_items: "{{ SSH.known_hosts }}"
36 | when: SSH.known_hosts is defined and (item.file is defined and item.file != "")
37 |
--------------------------------------------------------------------------------
/provision/roles/samson-deployment/tasks/build/storage.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Create storage directories
4 | file:
5 | path: "{{ item }}"
6 | owner: "{{ APPLICATION_USER }}"
7 | group: "{{ APPLICATION_GROUP }}"
8 | state: directory
9 | mode: 0755
10 | with_items:
11 | - /storage
12 | - /storage/db
13 | - /storage/cached_repos
14 | - /storage/build_cache
15 | - /storage/build_cache/npm
16 | - /storage/build_cache/composer
17 |
18 | - file:
19 | path: "{{ item }}"
20 | state: absent
21 | with_items:
22 | - /app/cached_repos
23 |
24 | - name: Link caching directories to /storage
25 | file:
26 | src: "{{ item.src }}"
27 | dest: "{{ item.dest }}"
28 | state: link
29 | force: yes
30 | with_items:
31 | - { src: "/storage/build_cache/composer", dest: "/home/application/.composer" }
32 | - { src: "/storage/build_cache/npm", dest: "/home/application/.npm" }
33 | - { src: "/storage/cached_repos", dest: "/app/cached_repos" }
34 |
35 |
--------------------------------------------------------------------------------
/provision/roles/samson-deployment/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - include: build.yml
4 | tags:
5 | - build
6 |
--------------------------------------------------------------------------------
/ssh/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdevops/samson-deployment/5035f72ebd4cc899b452ecb8dc873fbe60885c7e/ssh/.gitkeep
--------------------------------------------------------------------------------
/ssh/config:
--------------------------------------------------------------------------------
1 | ########################
2 | ## Default
3 | ########################
4 |
5 | Host *
6 | Compression yes
7 | CompressionLevel 6
8 | TCPKeepAlive yes
9 | KeepAlive yes
10 | ServerAliveInterval 60
11 | ForwardAgent no
12 | BatchMode yes
13 |
14 | ########################
15 | ## Server
16 | ########################
--------------------------------------------------------------------------------
/ssh/known_hosts:
--------------------------------------------------------------------------------
1 | |1|emHzrzVUn4X4a6LNoOpxK7wBW1A=|eqw6DduGz9wQqwJbC3b94ATE1pw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
2 | |1|QcmEj7cYWAopHnJx6Cjdde9e5Zw=|zfRGh6Dn92nEElLMTA11CT9olDs= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
--------------------------------------------------------------------------------