Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A "simple" shared-hosting Ansible setup for Cachet

Cachet on Docker with Ansible

This is not a "best-practice" example of doing any of these tasks. The nginx stuff could probably do with being moved into roles, and I could probably move the variables into a file handling that... however, as a POC, it works.

somehost.example.net ansible_connection=local
---
- hosts: somehost.example.net
tasks:
- name: "Apt update, Full-upgrade, autoremove, autoclean"
apt:
upgrade: full
update_cache: yes
autoremove: yes
autoclean: yes
- name: Install packages
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- git
- tcpdump
- letsencrypt
- ssl-cert
- "php{{ php_version | default('7.2') }}-fpm"
- "php{{ php_version | default('7.2') }}-gd"
- "php{{ php_version | default('7.2') }}-json"
- "php{{ php_version | default('7.2') }}-intl"
- "php{{ php_version | default('7.2') }}-bcmath"
- "php{{ php_version | default('7.2') }}-bz2"
- "php{{ php_version | default('7.2') }}-cli"
- "php{{ php_version | default('7.2') }}-curl"
- "php{{ php_version | default('7.2') }}-mbstring"
- "php{{ php_version | default('7.2') }}-mysql"
- "php{{ php_version | default('7.2') }}-sqlite3"
- "php{{ php_version | default('7.2') }}-xml"
- "php{{ php_version | default('7.2') }}-xsl"
- "php{{ php_version | default('7.2') }}-zip"
- name: Remove upstream nginx default server
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: Restart nginx
- name: Create the holding location for letsencrypt .well-known files
file:
name: /var/www/letsencrypt
state: directory
- name: Generate dhparams
shell: openssl dhparam -out /etc/nginx/dhparams.pem 4096
args:
creates: /etc/nginx/dhparams.pem
- name: Create our nginx default server
template:
dest: /etc/nginx/sites-available/default_server
src: templates/nginx/default_server.j2
owner: root
group: root
mode: 0644
vars:
ipv4_addresses: "{{ ansible_all_ipv4_addresses }} + ['127.0.0.1','127.0.1.1']"
ipv6_addresses: ["[deca:fbad:1:2::1:2]", "[::1]"]
notify: Restart nginx
- name: Link our default server to be enabled
file:
src: /etc/nginx/sites-available/default_server
dest: /etc/nginx/sites-enabled/default_server
owner: root
group: root
state: link
notify: Restart nginx
handlers:
- name: Restart nginx
systemd:
state: restarted
name: nginx
- hosts: somehost.example.net
tasks:
- name: Create the Cachet Volume
docker_volume:
name: cachet
- name: Run the Cachet container
docker_container:
name: 'cachet'
image: 'cachethq/docker:2.3.14'
state: 'started'
ports:
- 127.0.0.80:80:8000
env:
DB_DRIVER: sqlite
APP_KEY: "Some32CharsLongWhy_IsItIDontKnow"
volumes:
- "cachet:/var/www/html/database"
register: cachet_cont_metadata
- name: Create our cachet proxy config
tags: debug
template:
dest: /etc/nginx/sites-available/proxy_cachet
src: templates/nginx/proxy.j2
owner: root
group: root
mode: 0644
notify: Restart nginx
vars:
server_name: cachet.example.com www.cachet.example.com cachet.example.org www.cachet.example.org
primary_server_name: cachet.example.com
proxy_address: http://127.0.0.80
enable_letsencrypt: false
ipv4_addresses: "{{ ansible_all_ipv4_addresses }} + ['127.0.0.1','127.0.1.1']"
ipv6_addresses: ["[deca:fbad:1:2::1:2]", "[::1]"]
- name: Link our cachet proxy config to be enabled
file:
src: /etc/nginx/sites-available/proxy_cachet
dest: /etc/nginx/sites-enabled/proxy_cachet
owner: root
group: root
state: link
notify: Restart nginx
handlers:
- name: Restart nginx
systemd:
state: restarted
name: nginx
server {
{% for ipv4 in ipv4_addresses %}
listen {{ ipv4 }}:80 default_server;
{% endfor %}
{% for ipv6 in ipv6_addresses %}
listen {{ ipv6 }}:80 default_server;
{% endfor %}
root {{ webroot | default('/var/www/html/') }};
index index.html index.htm index.nginx-debian.html;
server_name {{ server_name | default('_') }};
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php-fpm (or other unix sockets):
fastcgi_pass unix:/var/run/php/php{{ php_version | default('7.2') }}-fpm.sock;
}
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
{% for ipv4 in ipv4_addresses %}
listen {{ ipv4 }}:80;
{% endfor %}
{% for ipv6 in ipv6_addresses %}
listen {{ ipv6 }}:80;
{% endfor %}
server_name {{ server_name | default('_') }};
access_log /var/log/nginx/{{ primary_server_name | default(server_name) }}_http_access.log;
error_log /var/log/nginx/{{ primary_server_name | default(server_name) }}_http_error.log;
{% if enable_letsencrypt | default(true) %}
location /.well-known/acme-challenge {
root /var/www/letsencrypt;
try_files $uri $uri/ =404;
}
{% endif %}
{% if enable_letsencrypt | default(true) or enable_tls | default(true) %}
location / {
rewrite ^ https://{{ primary_server_name | default(server_name) }}$request_uri? permanent;
}
}
server {
{% for ipv4 in ipv4_addresses %}
listen {{ ipv4 }}:443 ssl deferred;
{% endfor %}
{% for ipv6 in ipv6_addresses %}
listen {{ ipv6 }}:443 ssl deferred;
{% endfor %}
server_name {{ server_name | default('_') }};
access_log /var/log/nginx/{{ primary_server_name | default(server_name) }}_https_access.log;
error_log /var/log/nginx/{{ primary_server_name | default(server_name) }}_https_error.log;
ssl on;
{% if enable_letsencrypt | default(true) %}
ssl_certificate /etc/letsencrypt/live/{{ primary_server_name | default(server_name) }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ primary_server_name | default(server_name) }}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/{{ primary_server_name | default(server_name) }}/fullchain.pem;
{% else %}
ssl_certificate {{ tls_certificate | default('/etc/ssl/certs/ssl-cert-snakeoil.pem') }};
ssl_certificate_key {{ tls_certificate_key | default('/etc/ssl/private/ssl-cert-snakeoil.key') }};
{% endif %}
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 5m;
ssl_stapling on;
ssl_stapling_verify on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_dhparam /etc/nginx/dhparams.pem;
ssl_prefer_server_ciphers on;
{% endif %}
client_max_body_size 50G;
location / {
proxy_pass {{ proxy_address }};
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $remote_addr;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment