2023-08-19 16:49:47 -07:00
|
|
|
---
|
|
|
|
- name: Deploy impress from the current local version
|
|
|
|
hosts: webserver
|
|
|
|
become: yes
|
|
|
|
become_user: impress
|
|
|
|
vars:
|
|
|
|
local_app_root: "{{ playbook_dir }}/.."
|
|
|
|
remote_project_root: "/srv/impress"
|
2024-09-20 12:47:23 -07:00
|
|
|
ruby_version: "3.3.5"
|
|
|
|
|
2023-08-19 16:49:47 -07:00
|
|
|
# deploy:setup should have added us to the "impress-deployers" group, so we
|
|
|
|
# should be able to become the "impress" user without a password.
|
|
|
|
ansible_become_password: ""
|
2024-02-22 12:05:02 -08:00
|
|
|
|
|
|
|
# Set this to `yes` to skip setting this version as `current`. (We also
|
|
|
|
# skip our usual cleanup, to avoid disrupting the `current` version!)
|
|
|
|
#
|
|
|
|
# This can be useful for upgrading our Ruby version without downtime:
|
|
|
|
# 1. Install the new Ruby version, but don't uninstall the old one.
|
|
|
|
# 2. Update the app to reference the new Ruby version in the `Gemfile`.
|
|
|
|
# 3. Deploy the app with `skip_set_as_current`.
|
|
|
|
# 4. Update the service file manually to use the new Ruby to run the new
|
|
|
|
# version of the app, referenced directly by path.
|
|
|
|
# 5. Link the new version as `current` manually.
|
|
|
|
# 6. Reset the service file to use the new Ruby to run `current`.
|
|
|
|
skip_set_as_current: no
|
2023-08-19 16:49:47 -07:00
|
|
|
tasks:
|
|
|
|
- name: Generate a version name from the current timestamp
|
|
|
|
command: date '+%Y-%m-%d-%s'
|
|
|
|
register: new_app_version
|
|
|
|
|
|
|
|
- name: Print out the new version name
|
|
|
|
debug:
|
|
|
|
msg: "Deploying new version: {{ new_app_version.stdout }}"
|
|
|
|
|
|
|
|
- name: Save new remote folder path to a variable
|
|
|
|
set_fact:
|
|
|
|
remote_app_root: "{{ remote_project_root }}/versions/{{ new_app_version.stdout }}"
|
|
|
|
|
|
|
|
- name: Create new remote folder for the new version
|
|
|
|
file:
|
|
|
|
path: "{{ remote_app_root }}"
|
|
|
|
state: directory
|
|
|
|
|
2023-08-19 18:51:46 -07:00
|
|
|
# NOTE: We skip most gitignored files, except for public/assets/*, which
|
|
|
|
# contains the assets we precompiled for production.
|
2023-08-19 16:49:47 -07:00
|
|
|
- name: Copy local app's source files to new remote folder
|
|
|
|
ansible.posix.synchronize:
|
|
|
|
src: "{{ local_app_root }}/"
|
|
|
|
dest: "{{ remote_app_root }}"
|
|
|
|
rsync_opts:
|
2023-08-19 18:51:46 -07:00
|
|
|
- "--include=/public/assets/*"
|
2023-08-19 16:49:47 -07:00
|
|
|
- "--exclude=.git"
|
|
|
|
- "--filter=':- .gitignore'"
|
|
|
|
|
Create `rails public_data:commit` task, to share public data dumps
I'm starting to port over the functionality that was previously just,
me running `yarn db:export:public-data` in `impress-2020` and
committing it to Git LFS every time.
My immediate motivation is that the `impress-2020` git repository is
getting weirdly large?? Idk how these 40MB files have blown up to a
solid 16GB of Git LFS data (we don't have THAT many!!!), but I guess
there's something about Git LFS's architecture and disk usage that I'm
not understanding.
So, let's move to a simpler system in which we don't bind the public
data to the codebase, but instead just regularly dump it in production
and make it available for download.
This change adds the `rails public_data:commit` task, which when run in
production will make the latest available at
`https://impress.openneo.net/public-data/latest.sql.gz`, and will also
store a running log of previous dumps, viewable at
`https://impress.openneo.net/public-data/`.
Things left to do:
1. Create a `rails public_data:pull` task, to download `latest.sql.gz`
and import it into the local development database.
2. Set up a cron job to dump this out regularly, idk maybe weekly? That
will grow, but not very fast (about 2GB per year), and we can add
logic to rotate out old ones if it starts to grow too far. (If we
wanted to get really intricate, we could do like, daily for the past
week, then weekly for the past 3 months, then monthly for the past
year, idk. There must be tools that do this!)
2024-02-29 14:30:33 -08:00
|
|
|
- name: Link the public-data folder to the shared public-data folder
|
|
|
|
file:
|
|
|
|
src: "{{ remote_project_root }}/shared/public-data"
|
|
|
|
dest: "{{ remote_app_root }}/public/public-data"
|
|
|
|
state: link
|
|
|
|
|
2023-08-19 16:49:47 -07:00
|
|
|
- name: Configure Bundler to run in deployment mode
|
|
|
|
command:
|
|
|
|
chdir: "{{ remote_app_root }}"
|
2024-09-20 12:47:23 -07:00
|
|
|
cmd: /opt/ruby-{{ ruby_version }}/bin/bundle config set --local deployment true
|
2023-08-19 16:49:47 -07:00
|
|
|
|
|
|
|
# This ensures that, while attempting our current deploy, we don't
|
|
|
|
# accidentally delete gems out from under the currently-running version.
|
|
|
|
# NOTE: From reading the docs, I thiink this is the default behavior, but
|
|
|
|
# I can't be sure? Rather than deep-dive to find out, I'd rather just set
|
|
|
|
# it, to be clear about the default(?) behavior we're depending on.
|
|
|
|
- name: Configure Bundler to *not* clean up old gems when installing
|
|
|
|
command:
|
|
|
|
chdir: "{{ remote_app_root }}"
|
2024-09-20 12:47:23 -07:00
|
|
|
cmd: /opt/ruby-{{ ruby_version }}/bin/bundle config set --local clean false
|
2023-08-19 16:49:47 -07:00
|
|
|
|
|
|
|
# NOTE: Bundler recommends this, and they're pretty smart about it: if the
|
|
|
|
# Gemfile changes, this shouldn't disrupt the currently-running version,
|
|
|
|
# because we won't clean up its now-unused gems yet, and if we upgrade a
|
|
|
|
# gem it'll install *both* versions of the gem until we clean up.
|
|
|
|
- name: Configure Bundler to use the bundle folder shared by all app versions
|
|
|
|
command:
|
|
|
|
chdir: "{{ remote_app_root }}"
|
2024-09-20 12:47:23 -07:00
|
|
|
cmd: "/opt/ruby-{{ ruby_version }}/bin/bundle config set --local path {{ remote_project_root}}/shared/bundle"
|
2023-08-19 16:49:47 -07:00
|
|
|
|
|
|
|
- name: Run `bundle install` to install dependencies in remote folder
|
|
|
|
command:
|
|
|
|
chdir: "{{ remote_app_root }}"
|
2024-02-22 12:16:59 -08:00
|
|
|
# The `--local` flag instructs Bundler to use the cached dependencies
|
|
|
|
# in `vendor/cache`, instead of reading from the web, which is much
|
|
|
|
# faster and more reliable!
|
2024-09-20 12:47:23 -07:00
|
|
|
cmd: /opt/ruby-{{ ruby_version }}/bin/bundle install --local
|
2023-08-19 16:49:47 -07:00
|
|
|
|
|
|
|
- name: Update the `current` folder to point to the new version
|
|
|
|
file:
|
|
|
|
src: "{{ remote_app_root }}"
|
|
|
|
dest: /srv/impress/current
|
|
|
|
state: link
|
2024-02-22 12:05:02 -08:00
|
|
|
when: not skip_set_as_current
|
2023-08-19 16:49:47 -07:00
|
|
|
|
|
|
|
# NOTE: This uses the passwordless sudo rule we set up in deploy:setup.
|
|
|
|
# We write it as a command rather than using the built-in `systemd` Ansible
|
|
|
|
# module, to make sure we're invoking it exactly as we wrote in that rule.
|
2023-10-12 15:01:47 -07:00
|
|
|
#
|
|
|
|
# NOTE: We use `sudo` instead of `become_user: root`, because we don't have
|
|
|
|
# permission to *become* the root user; we only have permission to run this
|
|
|
|
# one command as them.
|
2023-08-19 16:49:47 -07:00
|
|
|
- name: Restart the app
|
|
|
|
become: no
|
|
|
|
command: sudo systemctl restart impress
|
2024-02-22 12:05:02 -08:00
|
|
|
when: not skip_set_as_current
|
2023-08-19 16:49:47 -07:00
|
|
|
|
|
|
|
- name: Clean up gems no longer used in the current app version
|
|
|
|
command:
|
|
|
|
chdir: "{{ remote_app_root }}"
|
2024-09-20 12:47:23 -07:00
|
|
|
cmd: /opt/ruby-{{ ruby_version }}/bin/bundle clean
|
2024-02-22 12:05:02 -08:00
|
|
|
when: not skip_set_as_current
|
2023-08-19 16:49:47 -07:00
|
|
|
|
|
|
|
- name: Find older app versions to clean up
|
|
|
|
# Print out all but the 5 last-recently-updated versions.
|
|
|
|
command:
|
|
|
|
chdir: "{{ remote_project_root }}/versions"
|
|
|
|
cmd: bash -c 'ls -t | tail -n +6'
|
|
|
|
register: versions_to_clean_up
|
2024-02-22 12:05:02 -08:00
|
|
|
when: not skip_set_as_current
|
2023-08-19 16:49:47 -07:00
|
|
|
|
|
|
|
- name: Clean up older versions
|
|
|
|
file:
|
|
|
|
path: "{{ remote_project_root }}/versions/{{ item }}"
|
|
|
|
state: absent
|
|
|
|
with_items: "{{ versions_to_clean_up.stdout_lines }}"
|
2024-02-22 12:05:02 -08:00
|
|
|
when: not skip_set_as_current
|