BustByte / coronastatus

Anonymous crowd sourcing of COVID-19 symptoms all over the world (with public data sets)!
MIT License
174 stars 89 forks source link

Add instructions to deploy on Ubuntu 18.04 #425

Closed mepa1363 closed 4 years ago

mepa1363 commented 4 years ago

This PR adds instructions on how to deploy your app on an Ubuntu 18.04 server. The app will be served securely by Nginx and managed by PM2. HTTPS certificate is provided by Let's Encrypt for free.

sbocinec commented 4 years ago

@mepa1363 thanks for the perfect instructions!

what do you think about creating a separate deployment directory and putting all those files there? The root directory is becoming pretty messy.

I'm suggesting following:

/examples/
--configuration/  (here I planned to move also `configs-examples` directory from the root)
--deployment/  (here you can put those files)
fossecode commented 4 years ago

@michaelmcmillan could you review this?

michaelmcmillan commented 4 years ago

Great idea! We've used a similar setup for all of our sites, which has made it very easy to roll out new versions at the same time. We're currently hosting 14 sites.

nginx + letsencrypt for reverse proxy and SSL certs:

server {
    server_name coronastatus.TLD www.coronastatus.TLD;

    location / {
        proxy_pass http://127.0.0.1:5000;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    error_page 502 /502.html;
    location = /502.html {
      root  /var/www/html;
    }
    error_page 401 /401.html;
    location = /401.html {
      root  /var/www/html;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/coronastatus.it/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/coronastatus.it/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = www.coronastatus.TLD) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = coronastatus.it) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name coronastatus.TLD www.coronastatus.TLD;
    listen 80;
    return 404; # managed by Certbot
}

systemd to keep the node process alive:

[Unit]
Description=Node coronastatus.TLD app
After=network.target
StartLimitIntervalSec=1
StartLimitBurst=86400

[Service]
Type=simple
User=app
Environment='NODE_ENV=production' 'PORT=5000'
ExecStart=/usr/bin/yarn start
ExecReload=/bin/kill -HUP $MAINPID
WorkingDirectory=/srv/coronastatus.TLD/
StandardError=syslog
StandardOutput=syslog
SyslogIdentifier=node-prod
Restart=always

[Install]
WantedBy=multi-user.target
sbocinec commented 4 years ago

@mepa1363 i've created PR https://github.com/BustByte/coronastatus/pull/444 to implement what I'd suggested ^^ as there are various ways how to deploy the app and makes our root directory more organized. Can you then add your changes to this examples directory? Thank you!

mepa1363 commented 4 years ago

@sbocinec @michaelmcmillan Here is my 2 cents. I like the idea of having a designated directory for deployment configs. However, I don't think having separate directories for different deployment strategies makes a ton of sense. My goal was to have a section for deployment in the main README for the folks to follow and easily deploy their solution. The deployment instructions should be categorized based on tech stack rather than the domain-specific deployments - examples could be Ubuntu, Heroku, Docker on AWS, etc.

sbocinec commented 4 years ago

@mepa1363 thanks for your view. This is not my project, I'm only a regular contributor too, so take mine opinion only as a suggestion, not official statement, i'm not in charge to decide on this :-)

I agree with you that all the files are only examples, one of the many ways how the app can be deployed. There are people who use nginx, people who use apache, people use systemd and don't need another process management (pm2), people who run it using docker, people who do use Let's Encrypt, people who don't LE or can't being behind Proxy/WAF not being able to do HTTP-only validation, etc...

I don't think the deployment examples (nginx vhost files, pm2 example, example systemd unit file, traefik config, etc) should be all stored in the project's root dir as they will only confuse users - that was my main point. I propose to organize and group all of these ops directory, configs-examples directory, and other config/deployment files into any directory with any name.

I also agree we can find better naming. Do you have any concrete idea how to name/change the directory structure? Or do you insist on keeping those nginx- and pm2- example files in the root?

PS. I don't want to spend yours, mine and others energy on long conversations, there are other interesting issues to work on :v:

mepa1363 commented 4 years ago

Yeah agreed 💯 I don't really know the best way to do it either 😅 maybe we could have directories inside the ops directory based on the stack somehow... My only intention was to help out the folks who are looking for a way to deploy their app, that's all ✌️

sbocinec commented 4 years ago

Perfect! I actually find your deployment solution elegant and will gladly try similar approach in future :+1:

To somehow move things forward, I suggest following:

  1. Let's merge in the #444 - this will add /examples/ops and /examples/config
  2. Feel free to rebase then and add/change names of these deployments as you wish (I don't honestly know how to name my sk cloudflare/traefik/docker/non-LE deployment dir running basically anywhere including Windows platform - now runs on Ubuntu 18.04 inside GCP)

Thank you for the discussion!