Develatio’s ExpressJS AMI will let you deploy a full ExpressJS project in less than a minute and with zero configuration, enabling you to focus on what’s really important: your own code!
This AMI is provisioned with several core components, configured for production usage.
Aside from easy deployments, security is another topic that we're really concerned about. That's why this AMI is also provisioned with some extra components that will let you secure, prevent and monitor your EC2 instance for attacks, intrusions, FS modification attempts, etc…
The AMI is designed in such a way that you only need to deal with one folder:
/var/www/webapp. In that folder you'll have all your configurations and your source code.
This is how the AMI will look like when you launch it:
├── conf │ ├── autorun.sh │ ├── cron │ │ ├── d │ │ ├── daily │ │ ├── hourly │ │ ├── monthly │ │ └── weekly │ ├── global │ │ ├── hostname │ │ └── timezone │ ├── mail │ │ ├── msmtprc │ │ └── notifications │ ├── netdata │ │ ├── netdata.conf │ │ ├── password │ │ └── stream.conf │ └── nginx │ ├── helloworld.crt │ ├── helloworld.key │ ├── netdata.conf │ └── web.conf └── src ├── app.js ├── bin │ └── www ├── node_modules ├── package-lock.json ├── package.json ├── public │ └── stylesheets ├── routes │ ├── index.js │ └── users.js ├── views │ ├── error.jade │ ├── index.jade │ └── layout.jade └── yarn.lock
You can check the contents of our demo project here
Let's start with the more obvious part, the
src folder. This is the usual ExpressJS folder structure.
That said, let's move on to the
conf folder. That folder contains the configuration files for each service. You'll be able to edit the behavior of all the services from here, without having to edit anything else. Just apply your changes and restart the services using the usual
Here's a quick run-trough the basic conf files:
cron/* - This folder contains the usual
/etc/cron.* folders structure you'd expect to have. Scripts inside these folders (
weekly) will be copied to the corresponding folder in
global/hostname - Sets the hostname. Use any of the available variables:
Keep in mind that the value of the resulting string will be slugified according to RFC 1123, which means that only letters, digits and hyphens are allowed
global/timezone - Sets the timezone. Use whatever you'd normally put in your
/etc/timezone file. Check
mail/msmtprc - You can configure an SMTP server which will be used to send alerts from Auditd, RKHunter, Fail2ban, etc…
mail/notifications - Write a single line containing a valid email address to which the alerts should be sent
netdata/password - This is the file you'll want to edit in order to change Netdata's basic auth user/password. Use the usual command to generate a valid NGINX username and hash:
openssl passwd -apr1 netdata. The user/password in the demo AMI is
nginx/web.conf - This is the NGINX's website configuration. The default file is configured to reverse proxy everything to the PM2 server. It will listen by default on port 80, but there is a commented section in the configuration that will enable HTTPS using your certificates (nginx/helloworld.crt and nginx/helloworld.key)
There are some extra stuff you must know. First of all, let's start with the one file that hasn't been covered yet: the
autorun.sh. This script will be executed at every boot, using the
admin user. Keep in mind that the AMI will make read-only the file on every boot, and it will chown it to
Why is this script useful? You might want to execute some extra tasks after booting. Maybe collect static files or maybe run migrations.
Secondly, there are some commands that you can run at any time in order to apply the changes you've made in the configuration files:
/etc/cron.*folders and then moves a fresh copy of the user-provided scripts, as described in the description of the cron/ folder
This AMI has two systemd services that will run unattended updates: apt-daily.service and apt-daily.timer. If you don't want to automatically
keep your system updated, feel free to disable those services using the usual systemd commands (
systemctl stop | disable).
We strongly recommend to set proper permission to your
conf and your
src folders. We set the following permissions in our base AMI.
chown root:root /var/www/webapp setfacl -R -d -m u:admin:rwx /var/www/webapp setfacl -R -d -m g:www-data:rx /var/www/webapp setfacl -R -d -m o::--- /var/www/webapp setfacl -R -m u:admin:rwx /var/www/webapp setfacl -R -m g:www-data:rx /var/www/webapp setfacl -R -m o::--- /var/www/webapp
This will make the files
You'll probably want to set write permissions to some folders (files uploaded by users?). We recommend using the
Keep in mind that the
autorun.sh will be ran with the
admin user, so you'll need to use
sudo setfacl -R -d -m u:admin:rwx /var/www/webapp/src/user_uploads/ sudo setfacl -R -d -m g:www-data:rwx /var/www/webapp/src/user_uploads/ sudo setfacl -R -d -m o::--- /var/www/webapp/src/user_uploads/ sudo setfacl -R -m u:admin:rwx /var/www/webapp/src/user_uploads/ sudo setfacl -R -m g:www-data:rwx /var/www/webapp/src/user_uploads/ sudo setfacl -R -m o::--- /var/www/webapp/src/user_uploads/
The AMI provides the following systemd services, which you can use using the usual commands (
systemctl status | start | stop) in order to manage your application:
In case of failure or unexpected errors, use
journalctl -f -u <service> to monitor the services.
We recommend to use Packer and this AMI as a base image to build your own AMIs right from your CI/CD pipeline. Use the
provisioners section in your Packer script in order to copy your configuration files to the
conf folder and your source code to the
src folder. You might also want to run any additional scripts or commands that don't require the project to be running, for example, package managers install process (
v0.1.0 - 17/02/2020