Go to production
This commit is contained in:
parent
0c962473ad
commit
b6e38107c2
|
@ -0,0 +1,3 @@
|
|||
*.retry
|
||||
.venv/
|
||||
Pipfile.lock
|
|
@ -0,0 +1,5 @@
|
|||
# Run ansble
|
||||
|
||||
```
|
||||
ansible-playbook website.yml
|
||||
```
|
|
@ -0,0 +1,4 @@
|
|||
[defaults]
|
||||
inventory = inventory
|
||||
nocows = 1
|
||||
vault_password_file = ~/.ansible-hkis-vault
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
ansible_python_interpreter: "/usr/bin/python3"
|
||||
ansible_user: root
|
||||
|
||||
gandi_api_key: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
65306331316361633033373833316433313632336336653030623733363936643363393236393637
|
||||
6635326137663133333038336665613566373365356364610a386437646238636336343965323730
|
||||
61306638653939653437386530386663313338396266666136396637653061313036643730613335
|
||||
6538613861643632310a386561343237303137633066343130333764353263663364326161653638
|
||||
62313561333737313864303335626264636562626536613465326162323164666262
|
|
@ -0,0 +1,17 @@
|
|||
$ANSIBLE_VAULT;1.1;AES256
|
||||
65356533653563626232346137616263306533353638653434623434373466373639316433653261
|
||||
6333616531306439383331313035306563656366303363610a646432353865323836396533343966
|
||||
37383835633362616466646138666335663437393463346535656136373266313161336464316462
|
||||
3335376432633766380a666437356434656564636536313162663630643034373338653366313334
|
||||
32346562386136353531373361346139363733626261383031633762326137383031326136646563
|
||||
63313939356236626138366538616361636230633530303633646562366237626462383736373262
|
||||
37636632393839636531333237356537646465613962353835636262653531333063386338366139
|
||||
63663563393134663064623461326537663935323832383730313863613130396633323533366566
|
||||
66313465383931393965386261653233333039383363333364613163393637306134393762396262
|
||||
37666164313661633866643037656466623136646161366531323433386639633334333236313337
|
||||
62343835303461636330326531333564376630633339343030336163643566363930383531663861
|
||||
32353961646336326238636236303539626661303864626135626638613865373738373131316365
|
||||
66313666393331646235643664633061653162633962303664336263643466316632303738303833
|
||||
36616439343238383463396139626134336131363666313164373033333964626630386463653134
|
||||
34623263666433326530376665313962373531383966646534336336363136336463633037633065
|
||||
35663537343339393866
|
|
@ -0,0 +1,2 @@
|
|||
[website]
|
||||
eqy.fr
|
|
@ -0,0 +1 @@
|
|||
ansible
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
|
||||
- name: sshd
|
||||
service: name=sshd state=reloaded
|
||||
|
||||
- name: nftables
|
||||
service: name=nftables state=reloaded
|
|
@ -0,0 +1,93 @@
|
|||
---
|
||||
|
||||
- name: Configure hostname
|
||||
hostname:
|
||||
name: "{{ inventory_hostname_short }}"
|
||||
|
||||
- name: Configure FQDN
|
||||
lineinfile:
|
||||
path: /etc/hosts
|
||||
regexp: '^127\.0\.0\.1'
|
||||
line: "127.0.0.1 {{ inventory_hostname }} {{ inventory_hostname_short }} localhost"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: apt-get some packages
|
||||
apt:
|
||||
state: present
|
||||
name:
|
||||
- aptitude
|
||||
- fail2ban
|
||||
- nftables
|
||||
- python3
|
||||
- python3-dev
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- rsync
|
||||
|
||||
- name: nftable service is started
|
||||
service:
|
||||
name: nftables
|
||||
enabled: yes
|
||||
state: started
|
||||
daemon_reload: yes
|
||||
|
||||
- name: Copy nftables config
|
||||
copy:
|
||||
content: |
|
||||
#!/usr/sbin/nft -f
|
||||
|
||||
table inet filter
|
||||
flush table inet filter
|
||||
|
||||
table inet filter {
|
||||
chain input {
|
||||
type filter hook input priority 0;
|
||||
iif lo accept
|
||||
ct state established,related accept
|
||||
tcp dport { ssh, http, https } ct state new accept
|
||||
# accept neighbour discovery otherwise connectivity breaks:
|
||||
icmpv6 type { echo-request, nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
|
||||
ip protocol icmp icmp type { destination-unreachable, echo-reply, echo-request, source-quench, time-exceeded } accept
|
||||
counter drop
|
||||
}
|
||||
}
|
||||
|
||||
dest: /etc/nftables.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0755
|
||||
notify: nftables
|
||||
|
||||
- name: Set some authorized keys
|
||||
authorized_key: user=root key="{{item}}"
|
||||
with_items:
|
||||
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKA7DgTQ0G7+kdsX0lIUOAAOllwGSCu8s8TxPvr/61Y8q+pIO5mrZycI0xYcKP5NZaABqlFyXUUNfLj7RLqteBxqq2QZP4NOJ1MutYRIkzJ9YW0f565jHaOqSguz0MY+1sCHtuEPiUUZoNexkKN7SIx60SfoaMEvGjAj46txA7VFbJUuKcJtA1Yvmn0C0KoXUUQ/G+JqvjQ7QuKLQYdTZ8S9OEvNaqNfwNSwvy1/LCnuajFw0O+H5bz7AcS5Iuj+9k8wgHPK1a1rQEdteOcn2XBCvta/VOVlFLv6/9K3iU3EJ1pyaZ88UkuJef8aWnH/AJGaF2gLqUbBuL+UeXyD41 julien+yubikey4@palard.fr"
|
||||
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8vv8vwmbyhFEa0chj8LklnnY6DRLKj2OM0NgaMTd9SsrtBeLMqTt34pU+kKl6/9EIe9P8Z1/fWFyOiTsE7Khf3rkNsoILPmEV14i18Bvtp4nMtljqZaKVkAcRjPvo7flRWNxxL2Zbo+BEr3wVCl3Sc6YV8oQzCwVPKf34AB39b+PW4f3580Aqcd4Ci6zca0Ol95tLDv1slX1A7QcpoZAne8kj5h6bb4cC7FLBC9+xOSKmzoLOlP7LsyxaUUGRyi/FeMoma1VES65aIJ5U23GtZrzZI3tKz+vpQvOVaozNTDkNLiiJkjd3Ew1I10wArpZixjwSndP8CvGFyJc1XUXZ julien+yubikey5@palard.fr"
|
||||
|
||||
- name: Drop mlocate or locate
|
||||
apt:
|
||||
name: ["mlocate", "locate"]
|
||||
state: absent
|
||||
|
||||
# From https://infosec.mozilla.org/guidelines/openssh
|
||||
- name: SSHd hardening
|
||||
blockinfile:
|
||||
marker: "# {mark} ANSIBLE MANAGED BLOCK (KexAlgorithms, Ciphers, MACs)"
|
||||
path: /etc/ssh/sshd_config
|
||||
state: present
|
||||
create: yes
|
||||
block: |
|
||||
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
|
||||
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
|
||||
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
|
||||
|
||||
HostKey /etc/ssh/ssh_host_ed25519_key
|
||||
HostKey /etc/ssh/ssh_host_rsa_key
|
||||
HostKey /etc/ssh/ssh_host_ecdsa_key
|
||||
|
||||
AuthenticationMethods publickey
|
||||
LogLevel VERBOSE
|
||||
notify: sshd
|
||||
tags: ssh
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
|
||||
- include_role:
|
||||
name: exim4
|
||||
|
||||
- include_tasks: common.yml
|
||||
tags: common
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016 Tobias Schifftner, ambimax® GmbH
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
exim4_sendonly_fqdn: '{{ ansible_fqdn }}'
|
||||
|
||||
exim4_aws_access_key_id: ''
|
||||
exim4_aws_secret_access_key: ''
|
||||
|
||||
exim4_aws_ses_region: 'eu-west-1'
|
||||
|
||||
exim4_sendonly_enable_tls: true
|
||||
exim4_sendonly_smarthost: ''
|
||||
exim4_sendonly_username: ''
|
||||
exim4_sendonly_password: ''
|
||||
|
||||
exim4_sendonly_email_addresses: []
|
||||
# root: 'your@email.com'
|
||||
|
||||
exim4_sendonly_email_aliases: []
|
||||
# - regexp: '^root:'
|
||||
# line: 'root: your@email.com'
|
||||
|
||||
exim4_sendonly_apt_packages:
|
||||
- exim4-daemon-light
|
||||
- mailutils
|
|
@ -0,0 +1,14 @@
|
|||
/var/mail/* {
|
||||
su root mail
|
||||
daily
|
||||
missingok
|
||||
rotate 8
|
||||
size 5M
|
||||
maxage 30
|
||||
notifempty
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
create 0640 root root
|
||||
sharedscripts
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
- name: restart exim4
|
||||
service:
|
||||
name: 'exim4'
|
||||
state: restarted
|
||||
enabled: yes
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
|
||||
- name: Configure exim4
|
||||
notify: restart exim4
|
||||
template:
|
||||
src: 'update-exim4.conf.conf'
|
||||
dest: /etc/exim4/update-exim4.conf.conf
|
||||
|
||||
- name: Update mailname
|
||||
notify: restart exim4
|
||||
copy:
|
||||
content: '{{ exim4_sendonly_fqdn }}'
|
||||
dest: '/etc/mailname'
|
||||
|
||||
- name: Define email aliases
|
||||
notify: restart exim4
|
||||
lineinfile:
|
||||
dest: /etc/aliases
|
||||
regexp: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
with_items: '{{ exim4_sendonly_email_aliases }}'
|
||||
when: exim4_sendonly_email_aliases|length
|
||||
|
||||
- name: Define email addresses
|
||||
notify: restart exim4
|
||||
template:
|
||||
src: 'email-addresses.j2'
|
||||
dest: '/etc/email-addresses'
|
||||
when: exim4_sendonly_email_addresses|length
|
||||
|
||||
- name: Set auth for relay host
|
||||
notify: restart exim4
|
||||
template:
|
||||
src: 'passwd.client'
|
||||
dest: '/etc/exim4/passwd.client'
|
||||
|
||||
- name: Enable TLS
|
||||
notify: restart exim4
|
||||
template:
|
||||
src: 'exim4.conf.localmacros'
|
||||
dest: '/etc/exim4/exim4.conf.localmacros'
|
||||
when: exim4_sendonly_enable_tls
|
||||
|
||||
- name: 'Set logrotate for local user mails in /var/mail'
|
||||
copy:
|
||||
src: 'logrotate'
|
||||
dest: /etc/logrotate.d/local_user_mails
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
|
||||
- name: Install exim4 packages
|
||||
apt:
|
||||
name: '{{ exim4_sendonly_apt_packages }}'
|
||||
state: present
|
||||
cache_valid_time: 86400
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
|
||||
- name: Install exim4
|
||||
import_tasks: install.yml
|
||||
|
||||
- name: Configure exim4
|
||||
import_tasks: configure.yml
|
||||
|
||||
- name: Start exim4
|
||||
service:
|
||||
name: exim4
|
||||
state: started
|
||||
enabled: true
|
||||
changed_when: false
|
||||
tags: ['always']
|
|
@ -0,0 +1,3 @@
|
|||
{% for user, email in exim4_sendonly_email_addresses.items() %}
|
||||
{{ user }}: {{ email }}
|
||||
{% endfor %}
|
|
@ -0,0 +1 @@
|
|||
MAIN_TLS_ENABLE = 1
|
|
@ -0,0 +1,10 @@
|
|||
# password file used when the local exim is authenticating to a remote
|
||||
# host as a client.
|
||||
#
|
||||
# see exim4_passwd_client(5) for more documentation
|
||||
#
|
||||
# Example:
|
||||
### target.mail.server.example:login:password
|
||||
{% if exim4_sendonly_username != '' %}
|
||||
*:{{ exim4_sendonly_username }}:{{ exim4_sendonly_password }}
|
||||
{% endif %}
|
|
@ -0,0 +1,30 @@
|
|||
# /etc/exim4/update-exim4.conf.conf
|
||||
#
|
||||
# Edit this file and /etc/mailname by hand and execute update-exim4.conf
|
||||
# yourself or use 'dpkg-reconfigure exim4-config'
|
||||
#
|
||||
# Please note that this is _not_ a dpkg-conffile and that automatic changes
|
||||
# to this file might happen. The code handling this will honor your local
|
||||
# changes, so this is usually fine, but will break local schemes that mess
|
||||
# around with multiple versions of the file.
|
||||
#
|
||||
# update-exim4.conf uses this file to determine variable values to generate
|
||||
# exim configuration macros for the configuration file.
|
||||
#
|
||||
# Most settings found in here do have corresponding questions in the
|
||||
# Debconf configuration, but not all of them.
|
||||
#
|
||||
# This is a Debian specific file
|
||||
dc_eximconfig_configtype="{{ 'internet' if exim4_sendonly_smarthost == '' else 'satellite' }}"
|
||||
dc_other_hostnames='{{ ansible_hostname }}; localhost.localdomain; localhost'
|
||||
dc_local_interfaces='127.0.0.1'
|
||||
dc_readhost=''
|
||||
dc_relay_domains=''
|
||||
dc_minimaldns='false'
|
||||
dc_relay_nets=''
|
||||
dc_smarthost='{{ exim4_sendonly_smarthost }}'
|
||||
CFILEMODE='644'
|
||||
dc_use_split_config='true'
|
||||
dc_hide_mailname='true'
|
||||
dc_mailname_in_oh='true'
|
||||
dc_localdelivery='mail_spool'
|
|
@ -0,0 +1,10 @@
|
|||
# Letsencrypt role
|
||||
|
||||
This role uses the standalone mode of certbot if no webserver is
|
||||
running (typically during the first installation), else uses the nginx
|
||||
module.
|
||||
|
||||
Note that existing certificates are renewed (using the nginx module)
|
||||
as a cron task/systemd timer.
|
||||
|
||||
It creates snippets in `/etc/nginx/snippets/letsencrypt-{{ fqdn }}.conf`.
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
|
||||
domains: [example.com]
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
|
||||
- name: Install ca-certificates
|
||||
apt:
|
||||
state: present
|
||||
name: [cron, ca-certificates, nginx]
|
||||
|
||||
- name: Setup or upgrade venv
|
||||
command: python3 -m venv --upgrade-deps /root/certbot-venv/
|
||||
changed_when: false
|
||||
|
||||
- name: Prepare certbot+gandi venv
|
||||
pip:
|
||||
chdir: /root/
|
||||
virtualenv_command: /usr/bin/python3 -m venv
|
||||
virtualenv: /root/certbot-venv/
|
||||
state: latest
|
||||
name:
|
||||
- pip
|
||||
|
||||
- name: Install certbot+gandi in venv
|
||||
pip:
|
||||
chdir: /root/
|
||||
state: latest
|
||||
virtualenv_command: /usr/bin/python3 -m venv
|
||||
virtualenv: /root/certbot-venv/
|
||||
name:
|
||||
- certbot
|
||||
- certbot-plugin-gandi
|
||||
|
||||
- name: Setup Gandi credentials
|
||||
copy:
|
||||
content: "dns_gandi_api_key = {{ gandi_api_key }}"
|
||||
mode: 0600
|
||||
dest: /root/gandi.ini
|
||||
|
||||
- name: Create SSL dhparam
|
||||
get_url:
|
||||
url: https://ssl-config.mozilla.org/ffdhe2048.txt
|
||||
dest: /etc/ssl/certs/dhparam.pem
|
||||
mode: 0644
|
||||
|
||||
- name: Generate TLS certificates
|
||||
command: /root/certbot-venv/bin/certbot certonly --cert-name {{ cert_name | quote }} -n --agree-tos -d {{ domains | join(",") | quote }} -m {{ admin_email | quote }} --authenticator dns-gandi --dns-gandi-credentials /root/gandi.ini
|
||||
register: certbot
|
||||
changed_when: '"no action taken." not in certbot.stdout'
|
||||
|
||||
- name: Create letsencrypt snippets
|
||||
template:
|
||||
src: letsencrypt.conf.j2
|
||||
dest: '/etc/nginx/snippets/letsencrypt-{{ cert_name }}.conf'
|
||||
|
||||
- name: Setup renewal cron
|
||||
cron:
|
||||
name: certbot
|
||||
minute: "55"
|
||||
hour: "8"
|
||||
job: '/root/certbot-venv/bin/certbot -q renew'
|
||||
|
||||
- name: Setup renewal hook to reload nginx
|
||||
copy:
|
||||
mode: 0755
|
||||
content: |
|
||||
#!/bin/sh
|
||||
systemctl reload nginx
|
||||
dest: /etc/letsencrypt/renewal-hooks/deploy/01-reload-nginx
|
|
@ -0,0 +1,29 @@
|
|||
# https://ssl-config.mozilla.org/
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/{{ cert_name }}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/{{ cert_name }}/privkey.pem;
|
||||
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
|
||||
ssl_session_tickets off;
|
||||
|
||||
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
|
||||
ssl_dhparam /etc/ssl/certs/dhparam.pem;
|
||||
|
||||
# intermediate configuration
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
|
||||
add_header Strict-Transport-Security "max-age=63072000" always;
|
||||
|
||||
# OCSP stapling
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
|
||||
# verify chain of trust of OCSP response using Root CA and Intermediate certs
|
||||
ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
|
||||
|
||||
# replace with the IP address of your resolver
|
||||
resolver 155.133.140.130;
|
|
@ -0,0 +1,19 @@
|
|||
[Unit]
|
||||
Description=website daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
PIDFile=/opt/website/website.pid
|
||||
User=website
|
||||
Group=website
|
||||
WorkingDirectory=/opt/website/src
|
||||
ExecStart=/opt/website/venv/bin/gunicorn --pid /opt/website/website.pid \
|
||||
--bind unix:/opt/website/website.sock --timeout 60 eqy_fr.wsgi \
|
||||
--access-logfile -
|
||||
ExecReload=/bin/kill -s HUP $MAINPID
|
||||
ExecStop=/bin/kill -s TERM $MAINPID
|
||||
PrivateTmp=true
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
|
||||
- name: restart website
|
||||
systemd: name=website state=restarted daemon_reload=yes
|
||||
|
||||
- name: reload nginx
|
||||
service: name=nginx state=reloaded
|
||||
|
||||
- name: reload psql
|
||||
service: name=postgresql state=reloaded
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
|
||||
dependencies:
|
||||
- role: letsencrypt
|
|
@ -0,0 +1,212 @@
|
|||
---
|
||||
|
||||
- name: Install dependencies
|
||||
apt:
|
||||
state: present
|
||||
name:
|
||||
- cron
|
||||
- gettext
|
||||
- git
|
||||
- nginx
|
||||
- postgresql
|
||||
- postgresql-server-dev-all # To compile Python client.
|
||||
- pgbadger
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-psycopg2
|
||||
- python3-venv
|
||||
update_cache: true
|
||||
tags: website
|
||||
|
||||
- name: Add unix user website
|
||||
user:
|
||||
name: website
|
||||
shell: /bin/false
|
||||
system: yes
|
||||
home: /opt/website
|
||||
tags: website
|
||||
|
||||
- name: install website.service (systemd)
|
||||
copy:
|
||||
src: systemd/website.service
|
||||
dest: /etc/systemd/system/website.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify: restart website
|
||||
tags: website
|
||||
|
||||
- name: add user website to pgsql
|
||||
become: true
|
||||
become_user: postgres
|
||||
postgresql_user:
|
||||
user: website
|
||||
tags: website
|
||||
|
||||
- name: add database media
|
||||
become: true
|
||||
become_user: postgres
|
||||
postgresql_db:
|
||||
name: media
|
||||
owner: website
|
||||
tags: website
|
||||
|
||||
- name: Collect PostgreSQL version and extensions
|
||||
become: yes
|
||||
become_user: postgres
|
||||
postgresql_info:
|
||||
filter: ver*
|
||||
register: db_info
|
||||
|
||||
- name: Configure psql
|
||||
notify: reload psql
|
||||
copy:
|
||||
dest: "/etc/postgresql/{{ db_info.version.major }}/main/conf.d/media.conf"
|
||||
owner: postgres
|
||||
group: postgres
|
||||
mode: 0644
|
||||
content: |
|
||||
log_min_duration_statement = 0
|
||||
log_checkpoints = on
|
||||
log_connections = on
|
||||
log_disconnections = on
|
||||
log_lock_waits = on
|
||||
log_temp_files = 0
|
||||
log_autovacuum_min_duration = 0
|
||||
log_error_verbosity = default
|
||||
lc_messages='en_US.UTF-8'
|
||||
lc_messages='C'
|
||||
|
||||
- name: Synchronize source
|
||||
ansible.posix.synchronize:
|
||||
src: /home/mdk/eqy.fr/
|
||||
dest: /opt/website/src/
|
||||
notify: restart website
|
||||
|
||||
- name: Creates a /opt/website/venv for virtual environments
|
||||
file:
|
||||
path: /opt/website/venv
|
||||
state: directory
|
||||
mode: 0755
|
||||
tags: website
|
||||
|
||||
- name: Setup or upgrade venv
|
||||
command: python3 -m venv --upgrade-deps /opt/website/venv
|
||||
changed_when: false
|
||||
|
||||
- name: Creates a /opt/website/locale for translations
|
||||
file:
|
||||
path: /opt/website/locale
|
||||
state: directory
|
||||
mode: 0755
|
||||
owner: root
|
||||
group: root
|
||||
tags: website
|
||||
|
||||
- name: Creates a /opt/website/media for medias
|
||||
file:
|
||||
path: /opt/website/media
|
||||
state: directory
|
||||
mode: 0755
|
||||
owner: website
|
||||
group: website
|
||||
tags: website
|
||||
|
||||
- name: Creates a /opt/website/static for static
|
||||
file:
|
||||
path: /opt/website/locale
|
||||
state: directory
|
||||
mode: 0755
|
||||
owner: root
|
||||
group: root
|
||||
tags: website
|
||||
|
||||
- name: pip installs requirements
|
||||
pip:
|
||||
chdir: /opt/website/src
|
||||
requirements: requirements.txt
|
||||
virtualenv: /opt/website/venv
|
||||
virtualenv_command: /usr/bin/python3 -m venv
|
||||
tags: website
|
||||
|
||||
- name: pip installs psycopg2
|
||||
pip:
|
||||
chdir: /opt/website/src
|
||||
name: psycopg2
|
||||
virtualenv: /opt/website/venv
|
||||
virtualenv_command: /usr/bin/python3 -m venv
|
||||
tags: website
|
||||
|
||||
- name: pip installs gunicorn
|
||||
pip:
|
||||
chdir: /opt/website/src
|
||||
name: gunicorn
|
||||
virtualenv: /opt/website/venv
|
||||
virtualenv_command: /usr/bin/python3 -m venv
|
||||
tags: website
|
||||
|
||||
- name: Install website configuration
|
||||
template:
|
||||
src: local_settings.py.j2
|
||||
dest: /opt/website/src/local_settings.py
|
||||
owner: root
|
||||
group: website
|
||||
mode: 0640
|
||||
notify: restart website
|
||||
tags: website
|
||||
|
||||
- name: Migrate db
|
||||
command: "/opt/website/venv/bin/python manage.py migrate"
|
||||
args:
|
||||
chdir: "/opt/website/src"
|
||||
register: migrate_result
|
||||
changed_when: '" Applying " in migrate_result.stdout'
|
||||
run_once: true
|
||||
become: true
|
||||
become_user: website
|
||||
tags: [website, test]
|
||||
|
||||
- name: Collectstatic
|
||||
command: "/opt/website/venv/bin/python manage.py collectstatic --noinput"
|
||||
args:
|
||||
chdir: "/opt/website/src"
|
||||
register: collectstatic_result
|
||||
changed_when: '"Copying " in collectstatic_result.stdout'
|
||||
tags: [website, test]
|
||||
|
||||
- name: Compile gettext
|
||||
command: "/opt/website/venv/bin/python manage.py compilemessages"
|
||||
args:
|
||||
chdir: "/opt/website/src"
|
||||
notify: restart website
|
||||
tags: [website, test]
|
||||
|
||||
- name: Ensure website is running
|
||||
service: name=website state=started enabled=yes
|
||||
tags: website
|
||||
|
||||
- name: Configure nginx host
|
||||
template:
|
||||
src: nginx-vhost
|
||||
dest: "/etc/nginx/sites-available/{{ website_vhost }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify: reload nginx
|
||||
tags: website
|
||||
|
||||
- name: Create symlink for API nginx site
|
||||
file:
|
||||
src: "/etc/nginx/sites-available/{{ website_vhost }}"
|
||||
dest: "/etc/nginx/sites-enabled/{{ website_vhost }}"
|
||||
state: link
|
||||
notify: reload nginx
|
||||
tags: website
|
||||
|
||||
- name: Daily backup
|
||||
cron:
|
||||
user: website
|
||||
name: "backup"
|
||||
job: "/usr/bin/pg_dump --clean media > backup.sql"
|
||||
hour: '2'
|
||||
minute: '0'
|
|
@ -0,0 +1,22 @@
|
|||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": "media",
|
||||
"USER": "website",
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_ROOT = "/opt/website/static/"
|
||||
MEDIA_ROOT = "/opt/website/media/"
|
||||
|
||||
DEBUG = False
|
||||
|
||||
SERVER_EMAIL = "julien@palard.fr"
|
||||
|
||||
ALLOWED_HOSTS = ["eqy.fr"]
|
||||
|
||||
SECRET_KEY = r'ephae4Xo Aeve8aic eeph7Eed Sho9oloo johY4ae5 ish0Eela areiy3Ia Joechoo6'
|
||||
|
||||
LOCALE_PATHS = ["/opt/website/locale"]
|
||||
|
||||
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTOCOL", "https")
|
|
@ -0,0 +1,34 @@
|
|||
server {
|
||||
listen [::]:80;
|
||||
listen 80;
|
||||
server_name {{ website_vhost }};
|
||||
|
||||
location / {
|
||||
return 301 https://{{ website_vhost }}$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 http2 ssl;
|
||||
listen [::]:443 http2 ssl;
|
||||
server_name {{ website_vhost }};
|
||||
|
||||
client_max_body_size 666M;
|
||||
|
||||
include snippets/letsencrypt-{{ cert_name }}.conf;
|
||||
|
||||
location /static/ {
|
||||
alias /opt/website/static/;
|
||||
}
|
||||
|
||||
location /media/ {
|
||||
alias /opt/website/media/;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://unix:/opt/website/website.sock;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Protocol $scheme;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
|
||||
- hosts: website
|
||||
roles:
|
||||
- common
|
||||
- website
|
||||
vars:
|
||||
website_vhost: eqy.fr
|
||||
admin_email: julien+photos@palard.fr
|
||||
cert_name: eqy
|
||||
domains:
|
||||
- eqy.fr
|
|
@ -123,3 +123,8 @@ MEDIA_URL = 'media/'
|
|||
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
try:
|
||||
from local_settings import *
|
||||
except ImportError:
|
||||
pass
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
django
|
Loading…
Reference in New Issue