diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000..1111d0c --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,3 @@ +[defaults] +inventory = ./hosts + diff --git a/ansible/debshots.yml b/ansible/debshots.yml new file mode 100644 index 0000000..d94b39a --- /dev/null +++ b/ansible/debshots.yml @@ -0,0 +1,89 @@ +--- +- hosts: all + vars: + ruby_version: 2.4.1 + handlers: + - name: restart nginx + service: name=nginx state=restarted + tasks: + - name: Install packages + apt: name="{{item}}" state=installed + with_items: + - htop + - python-psycopg2 + - ruby + #- passenger + #- nginx-full + - apt-transport-https + - ca-certificates + #- build-essential + #- ruby-dev + - libssl-dev + - libreadline-dev + - zlib1g-dev + #- libcurl4-gnutls-dev + #- ruby-bundler + #- nodejs + - git + - name: Enable Jessie backports repository + apt_repository: repo="deb http://ftp.debian.org/debian jessie-backports main" + - name: Set up american locales to avoid warnings about missing locales + locale_gen: name=en_US.UTF-8 state=present + - name: Install PostgreSQL + apt: name=postgresql state=installed + - name: Create PostgreSQL user + become: yes + become_user: postgres + postgresql_user: name=debshots + - name: Create PostgreSQL database + become: yes + become_user: postgres + postgresql_db: name=debshots owner=debshots encoding=UTF-8 template=template0 + - name: Create application user + user: name=debshots groups=adm home=/opt/debshots shell=/bin/bash + #- name: Install Passenger Gem + # gem: name=passenger state=present + #- name: Install Passenger and Nginx + # shell: passenger-install-nginx-module --auto + #- name: Validate installation + # shell: passenger-config validate-install --auto + - apt_key: keyserver=keyserver.ubuntu.com id=561F9B9CAC40B2F7 + - apt_repository: repo="deb https://oss-binaries.phusionpassenger.com/apt/passenger jessie main" + - apt: name="{{item}}" state=installed + with_items: + - nginx-extras + - passenger + + # Install newer Ruby version using rbenv + - name: Get rbenv + become: yes + become_user: debshots + git: + repo: https://github.com/rbenv/rbenv.git + dest: /opt/debshots/.rbenv + - name: Get rbenv-install + become: yes + become_user: debshots + git: + repo: https://github.com/rbenv/ruby-build.git + dest: /opt/debshots/.rbenv/plugins/ruby-build + - name: enable rbenv + copy: + src: files/debshots-bash-profile + dest: /opt/debshots/.profile + owner: debshots + - name: Build Ruby version + shell: sudo -iu debshots rbenv install -v {{ruby_version}} creates=/opt/debshots/.rbenv/versions/{{ruby_version}} + + - name: Install certbot to get certificates from Let's Encrypt + apt: name=certbot default_release=jessie-backports + + - name: Deploy nginx config + copy: + src: files/nginx.conf + dest: /etc/nginx/sites-available/default + notify: + restart nginx + + - debug: msg="Please run 'certbot certonly --webroot -w /opt/debshots/public -d screenshots.debian.net'" + diff --git a/ansible/files/debshots-bash-profile b/ansible/files/debshots-bash-profile new file mode 100644 index 0000000..be9b016 --- /dev/null +++ b/ansible/files/debshots-bash-profile @@ -0,0 +1,27 @@ +# ~/.profile: executed by the command interpreter for login shells. +# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login +# exists. +# see /usr/share/doc/bash/examples/startup-files for examples. +# the files are located in the bash-doc package. + +# the default umask is set in /etc/profile; for setting the umask +# for ssh logins, install and configure the libpam-umask package. +#umask 022 + +# if running bash +if [ -n "$BASH_VERSION" ]; then + # include .bashrc if it exists + if [ -f "$HOME/.bashrc" ]; then + . "$HOME/.bashrc" + fi +fi + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/bin" ] ; then + PATH="$HOME/bin:$PATH" +fi + +# rbenv +export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/plugins/ruby-build/bin:$PATH" +eval "$(rbenv init -)" + diff --git a/ansible/files/nginx.conf b/ansible/files/nginx.conf new file mode 100644 index 0000000..30e54cf --- /dev/null +++ b/ansible/files/nginx.conf @@ -0,0 +1,153 @@ +## +# You should look at the following URL's in order to grasp a solid understanding +# of Nginx configuration files in order to fully unleash the power of Nginx. +# http://wiki.nginx.org/Pitfalls +# http://wiki.nginx.org/QuickStart +# http://wiki.nginx.org/Configuration +# +# Generally, you will want to move this file somewhere, and start with a clean +# file but keep this around for reference. Or just disable in sites-enabled. +# +# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. +## + +#proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=assets:768m use_temp_path=off; + +#add_header X-Cache-Status $upstream_cache_status; +#add_header X-Runtime 42; +more_clear_headers 'X-Runtime'; +more_clear_headers 'X-Powered-By'; +more_clear_headers 'Server'; +server_tokens off; + +proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; + +log_format proxy '[$time_local] Cache: $upstream_cache_status $upstream_addr $upstream_response_time $status $bytes_sent $remote_addr $request_uri "$http_referer" "$http_user_agent" $scheme'; + +# Performance +passenger_max_pool_size 8; +passenger_max_request_queue_size 200; + +limit_req_zone $binary_remote_addr zone=one:20m rate=5r/s; + +# Frontend caching and static asset delivery +server { + listen *:80 default_server; + listen *:443 ssl; + ssl_certificate /etc/letsencrypt/live/screenshots.debian.net/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/screenshots.debian.net/privkey.pem; + + root /opt/debshots/public; + server_name _; + access_log /var/log/nginx/cache-access.log proxy; + + add_header X-Cache-Status $upstream_cache_status; + + # Tell the backend if the protocol used was HTTPS. Otherwise you get an infinite + # redirection loop because the backend assumes that HTTP was spoken behind the + # proxy. + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + # Pass on the actual HTTP_HOST ("Host:" header) so that Rails can build proper absolute URLs + proxy_set_header Host $host; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + gzip_proxied any; + + location / { + try_files /maintenance.html @backend; + add_header X-Coffee front-main; + } + + location /json/ { + try_files /maintenance.html @backend; + proxy_cache my_cache; + proxy_pass http://127.0.0.1:8888/; + proxy_cache_lock on; + proxy_cache_use_stale updating; + add_header X-Coffee front-json; + } + + location /favicon.ico { + alias /opt/debshots/public/favicon.ico; + } + + location @backend { + proxy_cache my_cache; + proxy_pass http://127.0.0.1:8888; + + # Avoid cache stampede - rather update once and deliver stale content + proxy_cache_lock on; + proxy_cache_use_stale updating; + add_header X-Coffee front-rails; + } + + location /assets/ { + alias /opt/debshots/public/assets/; + expires 1h; + add_header X-Coffee front-assets; + } + location /logo/ { + alias /opt/debshots/public/logo/; + expires 1h; + add_header X-Coffee front-logo; + } + location /screenshots/ { + alias /opt/debshots/public/screenshots/; + expires max; + add_header X-Coffee front-screenshots; + } + location /images/ { + alias /opt/debshots/public/images/; + expires 1h; + add_header X-Coffee front-images; + } +} + +# Backend rails application +server { + listen 127.0.0.1:8888; + + root /opt/debshots/public; + + server_name _; + access_log /var/log/nginx/rails-access.log; + + passenger_enabled on; + passenger_ruby /opt/debshots/.rbenv/versions/2.4.1/bin/ruby; + + + # Send thumbnails using X-Sendfile / X-Accel-Redirect + # The correct thumbnail is computed by the Rails application so it cannot be served directly. + location /thumbnail/ { + expires 1h; + proxy_cache_valid 404 15m; + add_header X-Coffee back-thumbnail; + limit_req zone=one burst=30; + } + + # Send public assets using X-Sendfile / X-Accel-Redirect (e.g. public/images/dummy/...) + location /public/ { + expires 1h; + add_header X-Coffee back-public; + + passenger_set_header X-Sendfile-Type X-Accel-Redirect; + passenger_env_var HTTP_X_ACCEL_MAPPING /opt/debshots/public/=/__send_file_accel/; + passenger_pass_header X-Accel-Redirect; + } + + location /__send_file_accel/ { + internal; + alias /opt/debshots/public/; + add_header X-Coffee back-accel; + expires 1d; + more_clear_headers 'Set-Cookie'; + } + + location /secretstatus { + stub_status; + access_log off; + allow all; + add_header X-Coffee back-status; + } +} diff --git a/ansible/hosts b/ansible/hosts new file mode 100644 index 0000000..49d4fe2 --- /dev/null +++ b/ansible/hosts @@ -0,0 +1,2 @@ +localhost ansible_connection=local +