Skip to content

Latest commit

 

History

History
373 lines (267 loc) · 11.3 KB

README.md

File metadata and controls

373 lines (267 loc) · 11.3 KB

full procedure to put into production a fabmanager app with Docker

This README tries to describe all steps to put a fabmanager app into production on a server, based on a solution using Docker and DigitalOcean. In order to make all this stuff working, please use the same directories structure as described in this guide in your fabmanager app folder.

docker/env

Make a copy of the env.example and use it as a starting point. List all the environment variables needed by your application.

docker/nginx_with_ssl.conf.example

  • Use nginx.conf.example especially if you are not using SSL
  • Replace MAIN_DOMAIN (example: fab-manager.com).
  • Replace URL_WITH_PROTOCOL_HTTPS (example: https://www.fab-manager.com).
  • Replace ANOTHER_URL_1, ANOTHER_URL_2 (example: .fab-manager.fr)

Things are getting serious, starting deployment process guys

setup the server

Go to DigitalOcean and create a Droplet with operating system coreOS stable. You need at least 2GB of addressable memory (RAM + swap) to install and use FabManager!. Choose datacenter. Set hostname as your domain name.

Buy domain name and link it with the droplet

  1. Buy a domain name on OVH
  2. Replace IP of the domain with droplet's IP (you can enable the flexible ip and use it)
  3. Do not fuck up trying to access your domain name right away, DNS are not aware of the change yet so WAIT and be patient.

Connect to the droplet via SSH

You can already connect to the server with this command: ssh core@droplet-ip. When DNS propagation will be done, you will be able to connect to the server with ssh core@your-domain-name.

Create SWAP file in coreOS

Firstly, switch to sudo and create swap file

sudo -i  
touch /2GiB.swap  
chattr +C /2GiB.swap  
fallocate -l 2048m /2GiB.swap  
chmod 600 /2GiB.swap  
mkswap /2GiB.swap  

Create file /etc/systemd/system/swap.service, filling it with the lines:

[Unit]  
Description=Turn on swap  
[Service]  
Type=oneshot  
Environment="SWAPFILE=/2GiB.swap"  
RemainAfterExit=true  
ExecStartPre=/usr/sbin/losetup -f ${SWAPFILE}  
ExecStart=/usr/bin/sh -c "/sbin/swapon $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"  
ExecStop=/usr/bin/sh -c "/sbin/swapoff $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"  
ExecStopPost=/usr/bin/sh -c "/usr/sbin/losetup -d $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"  
[Install]  
WantedBy=multi-user.target  

Then add service and start:

systemctl enable /etc/systemd/system/swap.service  
systemctl start swap
exit

Setup folders and env file

mkdir -p /home/core/fabmanager/config

Copy the previously customized env.example file as /home/core/fabmanager/config/env

mkdir -p /home/core/fabmanager/config/nginx

Copy the previously customized nginx_with_ssl.conf.example as /home/core/fabmanager/config/nginx/fabmanager.conf OR Copy the previously customized nginx.conf.example as /home/core/fabmanager/config/nginx/fabmanager.conf if you do not want ssl support (not recommended !).

SSL certificate with LetsEncrypt

Let's Encrypt is a new Certificate Authority that is free, automated, and open. Let’s Encrypt certificates expire after 90 days, so automation of renewing your certificates is important. Here is the setup for a systemd timer and service to renew the certificates and reboot the app Docker container

mkdir -p /home/core/fabmanager/config/nginx/ssl

Run openssl dhparam -out dhparam.pem 4096 in the folder /home/core/fabmanager/config/nginx/ssl (generate dhparam.pem file)

mkdir -p /home/core/fabmanager/letsencrypt/config/

Copy the previously customized webroot.ini.example as /home/core/fabmanager/letsencrypt/config/webroot.ini

mkdir -p /home/core/fabmanager/letsencrypt/etc/webrootauth

Run docker pull quay.io/letsencrypt/letsencrypt:latest

Create file (with sudo) /etc/systemd/system/letsencrypt.service with

[Unit]
Description=letsencrypt cert update oneshot
Requires=docker.service

[Service]
Type=oneshot  
ExecStart=/usr/bin/docker run --rm --name letsencrypt -v "/home/core/fabmanager/log:/var/log/letsencrypt" -v "/home/core/fabmanager/letsencrypt/etc:/etc/letsencrypt" -v "/home/core/fabmanager/letsencrypt/config:/letsencrypt-config" quay.io/letsencrypt/letsencrypt:latest -c "/letsencrypt-config/webroot.ini" certonly
ExecStartPost=-/usr/bin/docker restart fabmanager_nginx_1  

Create file (with sudo) /etc/systemd/system/letsencrypt.timer with

[Unit]
Description=letsencrypt oneshot timer  
Requires=docker.service

[Timer]
OnCalendar=*-*-1 06:00:00
Persistent=true
Unit=letsencrypt.service

[Install]
WantedBy=timers.target

Then deploy your app and read the "Generate SSL certificate by Letsencrypt" section to complete the installation of the letsencrypt certificate.

Deploy dockers containers on host

docker pull redis:3.0
docker pull postgres:9.4
docker pull elasticsearch:1.7
docker pull sleede/fab-manager

docker run --restart=always -d --name=fabmanager-postgres -v /home/core/fabmanager/postgresql:/var/lib/postgresql/data postgres:9.4
docker run --restart=always -d --name=fabmanager-redis -v /home/core/fabmanager/redis:/data redis:3.0
docker run --restart=always  -d --name=fabmanager-elastic -v /home/core/fabmanager/elasticsearch:/usr/share/elasticsearch/data elasticsearch:1.7

Rails specific commands

DB CREATE

docker run --rm \
           --link=fabmanager-postgres:postgres \
           --link=fabmanager-redis:redis \
           --link=fabmanager-elastic:elasticsearch \
           -e RAILS_ENV=production \
           --env-file /home/core/fabmanager/config/env \
           sleede/fab-manager \
           bundle exec rake db:create

DB MIGRATE

docker run --rm \
           --link=fabmanager-postgres:postgres \
           --link=fabmanager-redis:redis \
           --link=fabmanager-elastic:elasticsearch \
           -e RAILS_ENV=production \
           --env-file /home/core/fabmanager/config/env \
           -v /home/core/fabmanager/plugins:/usr/src/app/plugins \
           sleede/fab-manager \
           bundle exec rake db:migrate

DB SEED

docker run --rm \
           --link=fabmanager-postgres:postgres \
           --link=fabmanager-redis:redis \
           --link=fabmanager-elastic:elasticsearch \
           -e RAILS_ENV=production \
           --env-file /home/core/fabmanager/config/env \
           -v /home/core/fabmanager/plugins:/usr/src/app/plugins \
           sleede/fab-manager \
           bundle exec rake db:seed

PREPARE ELASTIC

docker run --rm \
             --link=fabmanager-postgres:postgres \
             --link=fabmanager-postgres:postgres \
             --link=fabmanager-redis:redis \
             --link=fabmanager-elastic:elasticsearch \
             -e RAILS_ENV=production \
             --env-file /home/core/fabmanager/config/env \
             -v /home/core/fabmanager/plugins:/usr/src/app/plugins \
             sleede/fab-manager \
             bundle exec rake fablab:es_build_stats

BUILD ASSETS

docker run --rm \
             --link=fabmanager-postgres:postgres \
             --link=fabmanager-redis:redis \
             --link=fabmanager-elastic:elasticsearch \
             -e RAILS_ENV=production \
             --env-file /home/core/fabmanager/config/env \
             -v /home/core/fabmanager/public/assets:/usr/src/app/public/assets \
             -v /home/core/fabmanager/plugins:/usr/src/app/plugins \
             sleede/fab-manager \
             bundle exec rake assets:precompile

RUN APP

docker run --restart=always -d --name=fabmanager \
             --link=fabmanager-postgres:postgres \
             --link=fabmanager-redis:redis \
             --link=fabmanager-elastic:elasticsearch \
             -e RAILS_ENV=production \
             -e RACK_ENV=production \
             --env-file /home/core/fabmanager/config/env \
             -v /home/core/fabmanager/public/assets:/usr/src/app/public/assets \
             -v /home/core/fabmanager/public/uploads:/usr/src/app/public/uploads \
             -v /home/core/fabmanager/invoices:/usr/src/app/invoices \
             -v /home/core/fabmanager/exports:/usr/src/app/exports \
             -v /home/core/fabmanager/plugins:/usr/src/app/plugins \
             -v /home/core/fabmanager/log:/var/log/supervisor \
             sleede/fab-manager

docker run --restart=always -d --name=nginx \
             -p 80:80 \
             -p 443:443 \
             --link=fabmanager:fabmanager \
             -v /home/core/fabmanager/config/nginx:/etc/nginx/conf.d \
             -v /home/core/fabmanager/letsencrypt/etc:/etc/letsencrypt \
             -v /home/core/fabmanager/log:/var/log/nginx \
             --volumes-from fabmanager:ro \
             nginx:1.9

Generate SSL certificate by Letsencrypt (app must be run before start letsencrypt)

Start letsencrypt service :

sudo systemctl start letsencrypt.service

If the certificate was successfully generated then update the nginx configuration file and activate the ssl port and certificate. Edit /home/core/fabmanager/config/nginx/fabmanager.conf Remove your app and Run your app to apply changes

Finally, if everything is ok, start letsencrypt timer to update the certificate every 1st of the month :

sudo systemctl enable letsencrypt.timer
sudo systemctl start letsencrypt.timer
(check) sudo systemctl list-timers

Dockers utils

Restart app

docker restart fabmanager-app

Remove app

docker rm -f fabmanager-app

Open a bash in the app context

docker exec -it fabmanager-app bash

If you want deploy with Docker Compose

curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` > ./docker-compose
sudo mkdir -p /opt/bin
sudo mv docker-compose /opt/bin/
sudo chmod +x /opt/bin/docker-compose

Setup folders and env file

mkdir -p /home/core/fabmanager/config

Copy the previously customized env file as /home/core/fabmanager/config/env

mkdir -p /home/core/fabmanager/config/nginx

Copy the previously customized nginx_with_ssl.conf.example as /home/core/fabmanager/config/nginx/fabmanager.conf Read the "SSL certificate with LetsEncrypt" section OR Copy the previously customized nginx.conf.example as /home/core/fabmanager/config/nginx/fabmanager.conf if you do not want ssl support (not recommended !).

copy docker-compose.yml to /home/core/

pull images

docker-compose pull

create/migrate/seed db

docker-compose run --rm fabmanager bundle exec rake db:setup

build assets

docker-compose run --rm fabmanager bundle exec rake assets:precompile

PREPARE ELASTIC

docker-compose run --rm fabmanager bundle exec rake fablab:es_build_stats

run create and run all services

docker-compose up -d

restart all services

docker-compose restart

show services status

docker-compose ps

update service fabmanager, rebuild assets and restart fabmanager

docker-compose pull fabmanager
docker-compose stop fabmanager
sudo rm -rf fabmanager/public/assets
docker-compose run --rm fabmanager bundle exec rake assets:precompile
docker-compose down
docker-compose up -d