2021-11-02 14:45:05 -07:00
|
|
|
---
|
2021-11-02 16:29:52 -07:00
|
|
|
- name: Set up the environment for the impress-2020 app
|
2021-11-02 16:01:30 -07:00
|
|
|
hosts: webserver
|
2021-11-03 01:00:28 -07:00
|
|
|
vars:
|
|
|
|
email_address: "emi@matchu.dev" # TODO: Extract this to personal config?
|
2021-11-02 14:45:05 -07:00
|
|
|
tasks:
|
2021-11-02 16:01:30 -07:00
|
|
|
- name: Create the app folder
|
|
|
|
become: yes
|
|
|
|
file:
|
|
|
|
path: /srv/impress-2020
|
2021-11-03 16:59:23 -07:00
|
|
|
owner: "{{ ansible_user_id }}"
|
2021-11-02 18:47:13 -07:00
|
|
|
|
2021-11-02 16:01:30 -07:00
|
|
|
- name: Add Nodesource apt key
|
|
|
|
become: yes
|
|
|
|
apt_key:
|
|
|
|
id: 9FD3B784BC1C6FC31A8A0A1C1655A0AB68576280
|
|
|
|
url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key
|
2021-11-02 18:47:13 -07:00
|
|
|
|
2021-11-02 16:01:30 -07:00
|
|
|
- name: Add Node v16 apt repository
|
|
|
|
become: yes
|
|
|
|
apt_repository:
|
|
|
|
repo: deb https://deb.nodesource.com/node_16.x focal main
|
2021-11-02 18:47:13 -07:00
|
|
|
|
2021-11-02 16:01:30 -07:00
|
|
|
- name: Install Node v16
|
|
|
|
become: yes
|
|
|
|
apt:
|
|
|
|
update_cache: yes
|
|
|
|
name: nodejs
|
|
|
|
state: present
|
2021-11-02 18:47:13 -07:00
|
|
|
|
2021-11-02 16:29:52 -07:00
|
|
|
- name: Install Yarn
|
|
|
|
become: yes
|
|
|
|
npm:
|
|
|
|
name: yarn
|
|
|
|
global: yes
|
2021-11-02 18:47:13 -07:00
|
|
|
|
2021-11-02 22:49:45 -07:00
|
|
|
- name: Install pm2
|
|
|
|
become: yes
|
|
|
|
npm:
|
|
|
|
name: pm2
|
|
|
|
global: yes
|
|
|
|
|
|
|
|
- name: Create pm2 startup script
|
|
|
|
# The current user is going to become the pm2 owner of the app server
|
|
|
|
# process. They'll be able to manage it without `sudo`, including during
|
|
|
|
# normal deploys, and run `pm2 monit` from their shell to see status.
|
|
|
|
become: yes
|
|
|
|
command: "pm2 startup systemd {{ ansible_user_id }} --hp /home/{{ ansible_user_id }}"
|
|
|
|
|
|
|
|
- name: Create pm2 ecosystem file
|
|
|
|
copy:
|
2021-11-03 15:43:37 -07:00
|
|
|
content: |
|
2021-11-02 22:49:45 -07:00
|
|
|
module.exports = {
|
|
|
|
apps: [
|
|
|
|
{
|
|
|
|
name: "impress-2020",
|
|
|
|
cwd: "/srv/impress-2020/current",
|
2021-11-03 16:46:35 -07:00
|
|
|
// Instead of `yarn start`, we specify the `next` binary
|
|
|
|
// directly, because it helps pm2 monitor our app correctly.
|
|
|
|
// https://github.com/vercel/next.js/discussions/10675#discussioncomment-34615
|
|
|
|
script: "./node_modules/.bin/next",
|
|
|
|
args: "start --port=3000",
|
2021-11-02 22:49:45 -07:00
|
|
|
instances: "max",
|
|
|
|
exec_mode: "cluster",
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
2021-11-03 15:43:37 -07:00
|
|
|
dest: "~/ecosystem.config.js"
|
|
|
|
# Create a temporary backup file, so we can use it to delete the old
|
|
|
|
# version of the services. (This is important if e.g. a service is
|
|
|
|
# removed or renamed, in which case deleting from the *new* config file
|
|
|
|
# wouldn't include it.)
|
|
|
|
backup: yes
|
|
|
|
register: pm2_ecosystem_file
|
2021-11-02 22:49:45 -07:00
|
|
|
|
2021-11-03 15:43:37 -07:00
|
|
|
- name: Delete old pm2 services if config file changed
|
|
|
|
command: "pm2 delete {{ pm2_ecosystem_file.backup_file | quote }}"
|
|
|
|
when: pm2_ecosystem_file is changed and pm2_ecosystem_file.backup_file is defined
|
|
|
|
|
|
|
|
- name: Delete old pm2 config file if it changed
|
|
|
|
file:
|
|
|
|
path: "{{ pm2_ecosystem_file.backup_file }}"
|
|
|
|
state: absent
|
|
|
|
when: pm2_ecosystem_file is changed and pm2_ecosystem_file.backup_file is defined
|
|
|
|
|
|
|
|
- name: Start pm2 services
|
|
|
|
command: "pm2 start ~/ecosystem.config.js"
|
2021-11-02 22:49:45 -07:00
|
|
|
|
|
|
|
- name: Save pm2 startup script
|
|
|
|
command: pm2 save
|
|
|
|
|
2021-11-03 01:00:28 -07:00
|
|
|
- name: Install core snap
|
|
|
|
become: yes
|
|
|
|
community.general.snap:
|
|
|
|
name: core
|
|
|
|
|
|
|
|
- name: Install certbot as a snap
|
|
|
|
become: yes
|
|
|
|
community.general.snap:
|
|
|
|
name: certbot
|
|
|
|
classic: yes
|
|
|
|
|
|
|
|
- name: Set up certbot
|
|
|
|
become: yes
|
|
|
|
command: "certbot certonly --nginx -n --agree-tos --email {{ email_address }} --domains impress-2020-box.openneo.net"
|
|
|
|
|
2021-11-03 00:07:30 -07:00
|
|
|
- name: Install nginx
|
|
|
|
become: yes
|
|
|
|
apt:
|
|
|
|
update_cache: yes
|
|
|
|
name: nginx
|
|
|
|
|
|
|
|
- name: Add impress-2020 config file to nginx
|
|
|
|
become: yes
|
|
|
|
copy:
|
Add monit watching for nginx and pm2
When I woke up this morning, the app had crashed because the mysql connection was closed!
I'm not sure, why that caused a _crash_? Or why pm2 didn't pick up on it, and said the process was still online? (Maybe the process was running, but the server had stopped?) Those could be good to investigate?…
…but better than diving too far into the details, is to just address the high-level problem: if the app goes down for unexpected reasons, I want it back up!! lol
In this change, we add `monit`, a solid system for monitoring processes (including checking for behavior, like responding to net requests), and configure it to watch the app process and the nginx process.
To test, you can run `pm2 stop impress-2020`, or `systemctl stop nginx`, to see that Monit brings them back up within seconds!
This does add some potential surprise if you're _trying_ to take the processes down. The easiest way is to send the stop command through monit, like `monit stop nginx`. This will disable monitoring until you start it again through monit, I think? (You can also disable/enable monitoring as a direct command, regardless of app state.)
2021-11-03 16:32:14 -07:00
|
|
|
content: |
|
2021-11-03 00:07:30 -07:00
|
|
|
server {
|
2021-11-03 01:00:28 -07:00
|
|
|
server_name impress-2020-box.openneo.net;
|
2021-11-03 00:07:30 -07:00
|
|
|
listen 80;
|
2021-11-03 01:00:28 -07:00
|
|
|
if ($host = impress-2020-box.openneo.net) {
|
|
|
|
return 301 https://$host$request_uri;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
server {
|
2021-11-03 00:07:30 -07:00
|
|
|
server_name impress-2020-box.openneo.net;
|
2021-11-03 01:00:28 -07:00
|
|
|
listen 443 ssl;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/impress-2020-box.openneo.net/fullchain.pem;
|
|
|
|
ssl_certificate_key /etc/letsencrypt/live/impress-2020-box.openneo.net/privkey.pem;
|
|
|
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
|
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
|
|
ssl_session_cache shared:SSL:10m; # https://superuser.com/q/1484466/14127
|
|
|
|
|
2021-11-03 00:07:30 -07:00
|
|
|
# TODO: Serve static files directly, instead of through the proxy
|
|
|
|
location / {
|
|
|
|
proxy_pass http://127.0.0.1:3000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dest: /etc/nginx/sites-enabled/impress-2020
|
|
|
|
notify:
|
|
|
|
- Restart nginx
|
|
|
|
|
2021-11-02 22:49:45 -07:00
|
|
|
- name: Install dependencies for the npm module node-canvas
|
2021-11-02 16:29:52 -07:00
|
|
|
become: yes
|
|
|
|
apt:
|
|
|
|
update_cache: yes
|
|
|
|
name:
|
|
|
|
- build-essential
|
|
|
|
- libcairo2-dev
|
|
|
|
- libpango1.0-dev
|
|
|
|
- libjpeg-dev
|
|
|
|
- libgif-dev
|
|
|
|
- librsvg2-dev
|
2021-11-03 00:07:30 -07:00
|
|
|
|
|
|
|
handlers:
|
|
|
|
- name: Restart nginx
|
|
|
|
become: yes
|
Add monit watching for nginx and pm2
When I woke up this morning, the app had crashed because the mysql connection was closed!
I'm not sure, why that caused a _crash_? Or why pm2 didn't pick up on it, and said the process was still online? (Maybe the process was running, but the server had stopped?) Those could be good to investigate?…
…but better than diving too far into the details, is to just address the high-level problem: if the app goes down for unexpected reasons, I want it back up!! lol
In this change, we add `monit`, a solid system for monitoring processes (including checking for behavior, like responding to net requests), and configure it to watch the app process and the nginx process.
To test, you can run `pm2 stop impress-2020`, or `systemctl stop nginx`, to see that Monit brings them back up within seconds!
This does add some potential surprise if you're _trying_ to take the processes down. The easiest way is to send the stop command through monit, like `monit stop nginx`. This will disable monitoring until you start it again through monit, I think? (You can also disable/enable monitoring as a direct command, regardless of app state.)
2021-11-03 16:32:14 -07:00
|
|
|
systemd:
|
2021-11-03 00:07:30 -07:00
|
|
|
name: nginx
|
|
|
|
state: restarted
|