Skip to content

Latest commit

 

History

History
146 lines (130 loc) · 4.7 KB

deployment.md

File metadata and controls

146 lines (130 loc) · 4.7 KB

Deployment

The default Dockerfile should do a good job at running a solid web server that automatically adjusts its worker count based on traffic. This is managed by uWSGI. You need to configure the DATABASE_URL and SECRET_KEY variables. If you want to deploy to a different host than the default, configure the ALLOWED_HOSTS variable.

Static file hosting

You can either collect the static files in the container and use uWSGI to host them, or put them on your host and manage them through a web server running on the host like nginx.

Database migrations

To bring the schema up-to-date, first stop an existing database container, then start a container that just runs the migrations and exits, and then starts the main container off the new container again.

Ansible task

An example Ansible task to deploy the site is shown below, it should read fairly humanly and give you a rough idea of steps needed to deploy the site.

- name: ensure the `{{ pysite_pg_username }}` postgres user exists
  become: yes
  become_user: postgres
  postgresql_user:
    name: "{{ pysite_pg_username }}"
    password: "{{ pysite_pg_password }}"
  when: pysite_pg_host == 'localhost'

- name: ensure the `{{ pysite_pg_database }}` postgres database exists
  become: yes
  become_user: postgres
  postgresql_db:
    name: "{{ pysite_pg_database }}"
    owner: "{{ pysite_pg_username }}"
  when: pysite_pg_host == 'localhost'

- name: ensure the `{{ pysite_hub_repository }}` image is up-to-date
  become: yes
  docker_image:
    name: "{{ pysite_hub_repository }}"
    force: yes

- name: ensure the nginx HTTP vhosts are up-to-date
  become: yes
  template:
    src: "nginx/{{ item.key }}.http.conf.j2"
    dest: "/etc/nginx/sites-available/{{ item.value }}.http.conf"
  with_dict: "{{ pysite_domains }}"
  notify: reload nginx

- name: ensure the nginx HTTPS vhosts are up-to-date
  become: yes
  template:
    src: "nginx/{{ item.key }}.https.conf.j2"
    dest: "/etc/nginx/sites-available/{{ item.value }}.https.conf"
  with_dict: "{{ pysite_domains }}"
  notify: reload nginx

- name: ensure the nginx HTTP vhosts are symlinked to `/etc/nginx/sites-enabled`
  become: yes
  file:
    src: /etc/nginx/sites-available/{{ item.value }}.http.conf
    dest: /etc/nginx/sites-enabled/{{ item.value }}.http.conf
    state: link
  with_dict: "{{ pysite_domains }}"
  notify: reload nginx

- name: ensure we have HTTPS certificates
  include_role:
    name: thefinn93.letsencrypt
  vars:
    letsencrypt_cert_domains: "{{ pysite_domains | dict2items | map(attribute='value') | list }}"
    letsencrypt_email: "[email protected]"
    letsencrypt_renewal_command_args: '--renew-hook "systemctl restart nginx"'
    letsencrypt_webroot_path: /var/www/_letsencrypt

- name: ensure the nginx HTTPS vhosts are symlinked to `/etc/nginx/sites-enabled`
  become: yes
  file:
    src: /etc/nginx/sites-available/{{ item.value }}.https.conf
    dest: /etc/nginx/sites-enabled/{{ item.value }}.https.conf
    state: link
  with_dict: "{{ pysite_domains }}"
  notify: reload nginx

- name: ensure the web container is absent
  become: yes
  docker_container:
    name: pysite
    state: absent

- name: ensure the `{{ pysite_static_file_dir }}` directory exists
  become: yes
  file:
    path: "{{ pysite_static_file_dir }}"
    state: directory
    owner: root
    group: root

- name: collect static files
  become: yes
  docker_container:
    image: "{{ pysite_hub_repository }}"
    name: pysite-static-file-writer
    command: python manage.py collectstatic --noinput
    detach: no
    cleanup: yes
    network_mode: host
    env:
      DATABASE_URL: "{{ pysite_pg_database_url }}"
      SECRET_KEY: "me-dont-need-no-secret-key"
      STATIC_ROOT: "/html"
    volumes:
      - "/var/www/pythondiscord.com:/html"

- name: ensure the database schema is up-to-date
  become: yes
  docker_container:
    image: "{{ pysite_hub_repository }}"
    name: pysite-migrator
    detach: no
    cleanup: yes
    command: python manage.py migrate
    network_mode: host
    env:
      DATABASE_URL: "postgres://{{ pysite_pg_username }}:{{ pysite_pg_password }}@{{ pysite_pg_host }}/{{ pysite_pg_database }}"
      SECRET_KEY: "me-dont-need-no-secret-key"

- name: ensure the website container is started
  become: yes
  docker_container:
    image: "{{ pysite_hub_repository }}"
    name: pysite
    network_mode: host
    restart: yes
    restart_policy: unless-stopped
    ports:
      - "127.0.0.1:4000:4000"
    env:
      ALLOWED_HOSTS: "{{ pysite_domains | dict2items | map(attribute='value') | join(',') }}"
      DATABASE_URL: "postgres://{{ pysite_pg_username }}:{{ pysite_pg_password }}@{{ pysite_pg_host }}/{{ pysite_pg_database }}"
      PARENT_HOST: pysite.example.com
      SECRET_KEY: "{{ pysite_secret_key }}"