diff --git a/.fabmanager-version b/.fabmanager-version index 30f69e8cc..ff3b2cd99 100644 --- a/.fabmanager-version +++ b/.fabmanager-version @@ -1 +1 @@ -2.5.9 +2.5.10 diff --git a/CHANGELOG.md b/CHANGELOG.md index 28b8ae100..f171b3878 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog Fab Manager +## v2.5.10 2017 August 16 + +- Updated axlsx gem for excel files generation, possible fix for #489 +- Fix a bug: on some linux hosts, a filename too long error is triggered when accessing the following API: trainings, groups, events, prices +- update docker/README.md + ## v2.5.9 2017 July 13 - Fixed invalid syntax for configuration file application.yml.default diff --git a/Gemfile b/Gemfile index 0796722e2..94257d0e0 100644 --- a/Gemfile +++ b/Gemfile @@ -149,6 +149,5 @@ gem 'has_secure_token' gem 'apipie-rails' # XLS files generation -gem 'rubyzip', '~> 1.1.0' -gem 'axlsx', '2.1.0.pre' +gem 'axlsx', git: 'https://github.com/randym/axlsx', branch: 'release-3.0.0' gem 'axlsx_rails' diff --git a/Gemfile.lock b/Gemfile.lock index 5e252f9a5..f992737be 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,14 @@ +GIT + remote: https://github.com/randym/axlsx + revision: 977c09de1515e86536f0c952c08be319fbbab870 + branch: release-3.0.0 + specs: + axlsx (3.0.0.pre) + htmlentities (~> 4.3.4) + mimemagic (~> 0.3) + nokogiri (>= 1.7.1) + rubyzip (~> 1.2, >= 1.2.1) + GEM remote: https://rubygems.org/ specs: @@ -56,10 +67,6 @@ GEM descendants_tracker (~> 0.0.4) ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) - axlsx (2.1.0.pre) - htmlentities (~> 4.3.1) - nokogiri (>= 1.4.1) - rubyzip (~> 1.1.7) axlsx_rails (0.4.0) axlsx (>= 2.0.1) rails (>= 3.1) @@ -70,7 +77,7 @@ GEM autoprefixer-rails (>= 5.0.0.1) sass (>= 3.2.19) buftok (0.2.0) - builder (3.2.2) + builder (3.2.3) byebug (8.2.3) camertron-eprun (1.1.0) capistrano (2.15.5) @@ -202,18 +209,18 @@ GEM httparty (0.13.7) json (~> 1.8) multi_xml (>= 0.5.2) - i18n (0.7.0) + i18n (0.8.6) ice_nine (0.11.1) jbuilder (2.5.0) activesupport (>= 3.0.0, < 5.1) multi_json (~> 1.2) jbuilder_cache_multi (0.0.3) jbuilder (>= 1.5.0, < 3) - jquery-rails (4.0.3) - rails-dom-testing (~> 1.0) + jquery-rails (4.3.1) + rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - json (1.8.3) + json (1.8.6) jwt (1.5.1) kaminari (0.16.3) actionpack (>= 3.0.0) @@ -237,9 +244,10 @@ GEM message_format (0.0.3) twitter_cldr (~> 3.1) mime-types (2.99) + mimemagic (0.3.2) mini_magick (4.2.0) - mini_portile2 (2.1.0) - minitest (5.9.1) + mini_portile2 (2.2.0) + minitest (5.10.3) minitest-reporters (1.1.8) ansi builder @@ -257,9 +265,8 @@ GEM net-ssh-gateway (1.2.0) net-ssh (>= 2.6.5) netrc (0.10.3) - nokogiri (1.6.8) - mini_portile2 (~> 2.1.0) - pkg-config (~> 1.1.7) + nokogiri (1.8.0) + mini_portile2 (~> 2.2.0) notify_with (0.0.2) jbuilder (~> 2.0) rails (>= 4.2.0) @@ -288,7 +295,6 @@ GEM ruby-rc4 ttfunk pg (0.18.1) - pkg-config (1.1.7) prawn (2.0.1) pdf-core (~> 0.5.1) ttfunk (~> 1.4.0) @@ -299,7 +305,7 @@ GEM rack (>= 1.1, < 2.0) pundit (1.0.0) activesupport (>= 3.0.0) - rack (1.6.4) + rack (1.6.8) rack-protection (1.5.3) rack rack-test (0.6.3) @@ -318,9 +324,9 @@ GEM sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.7) + rails-dom-testing (1.0.8) activesupport (>= 4.2.0.beta, < 5.0) - nokogiri (~> 1.6.0) + nokogiri (~> 1.6) rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) @@ -337,7 +343,7 @@ GEM rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) raindrops (0.13.0) - rake (11.3.0) + rake (12.0.0) rb-fsevent (0.9.4) rb-inotify (0.9.5) ffi (>= 0.5.0) @@ -358,7 +364,7 @@ GEM rolify (4.0.0) ruby-progressbar (1.7.5) ruby-rc4 (0.1.5) - rubyzip (1.1.7) + rubyzip (1.2.1) rufus-scheduler (3.0.9) tzinfo rvm-capistrano (1.5.6) @@ -425,8 +431,8 @@ GEM daemons (>= 1.0.9) eventmachine (>= 0.12.6) rack (>= 1.0.0) - thor (0.19.1) - thread_safe (0.3.5) + thor (0.19.4) + thread_safe (0.3.6) tilt (1.4.1) timers (4.0.1) hitimes @@ -450,7 +456,7 @@ GEM cldr-plurals-runtime-rb (~> 1.0.0) json tzinfo - tzinfo (1.2.2) + tzinfo (1.2.3) thread_safe (~> 0.1) uglifier (2.7.1) execjs (>= 0.3.0) @@ -490,7 +496,7 @@ DEPENDENCIES api-pagination apipie-rails awesome_print - axlsx (= 2.1.0.pre) + axlsx! axlsx_rails bootstrap-sass byebug @@ -542,7 +548,6 @@ DEPENDENCIES recurrence responders (~> 2.0) rolify - rubyzip (~> 1.1.0) rvm-capistrano sass-rails (= 5.0.1) sdoc (~> 0.4.0) @@ -563,4 +568,4 @@ DEPENDENCIES webmock BUNDLED WITH - 1.13.6 + 1.15.3 diff --git a/README.md b/README.md index 8bd19ad13..cbd6a1f8b 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ In you only intend to run fab-manager on your local machine for testing purposes ```bash rake db:create rake db:migrate - rake db:seed + ADMIN_EMAIL=youradminemail ADMIN_PASSWORD=youradminpassword rake db:seed ``` 9. Create the pids folder used by Sidekiq. If you want to use a different location, you can configure it in `config/sidekiq.yml` @@ -279,7 +279,7 @@ If this parameter is not specified the maximum size allowed will be 2MB. ADMIN_EMAIL, ADMIN_PASSWORD -Credentials for the first admin user created when seeding the project. +Credentials for the first admin user created when seeding the project. (not present in application.yml because they are only used once when running the database seed with the command `rake db:seed`) Settings related to Open Projects diff --git a/app/views/api/events/index.json.jbuilder b/app/views/api/events/index.json.jbuilder index 83f10f52a..8512897bd 100644 --- a/app/views/api/events/index.json.jbuilder +++ b/app/views/api/events/index.json.jbuilder @@ -1,10 +1,8 @@ total = @events.except(:offset, :limit, :order).count -json.cache! [@events, @page] do - json.array!(@events) do |event| - json.partial! 'api/events/event', event: event - json.event_image_small event.event_image.attachment.small.url if event.event_image - json.url event_url(event, format: :json) - json.nb_total_events total - end +json.array!(@events) do |event| + json.partial! 'api/events/event', event: event + json.event_image_small event.event_image.attachment.small.url if event.event_image + json.url event_url(event, format: :json) + json.nb_total_events total end diff --git a/app/views/api/events/upcoming.json.jbuilder b/app/views/api/events/upcoming.json.jbuilder index 4d97b3978..3a12b9481 100644 --- a/app/views/api/events/upcoming.json.jbuilder +++ b/app/views/api/events/upcoming.json.jbuilder @@ -1,7 +1,5 @@ -json.cache! @events do - json.array!(@events) do |event| - json.partial! 'api/events/event', event: event - json.event_image_medium event.event_image.attachment.medium.url if event.event_image - json.url event_url(event, format: :json) - end +json.array!(@events) do |event| + json.partial! 'api/events/event', event: event + json.event_image_medium event.event_image.attachment.medium.url if event.event_image + json.url event_url(event, format: :json) end diff --git a/app/views/api/groups/index.json.jbuilder b/app/views/api/groups/index.json.jbuilder index 6a8f3029e..544b158ea 100644 --- a/app/views/api/groups/index.json.jbuilder +++ b/app/views/api/groups/index.json.jbuilder @@ -1,3 +1 @@ -json.cache! ['v1', @groups] do - json.partial! 'api/groups/group', collection: @groups, as: :group -end +json.partial! 'api/groups/group', collection: @groups, as: :group diff --git a/app/views/api/prices/index.json.jbuilder b/app/views/api/prices/index.json.jbuilder index 8a03cbb34..1d35eab98 100644 --- a/app/views/api/prices/index.json.jbuilder +++ b/app/views/api/prices/index.json.jbuilder @@ -1,3 +1 @@ -json.cache! @prices do - json.partial! 'api/prices/price', collection: @prices, as: :price -end +json.partial! 'api/prices/price', collection: @prices, as: :price diff --git a/app/views/api/trainings/index.json.jbuilder b/app/views/api/trainings/index.json.jbuilder index 51550ce1b..9e78e0f3b 100644 --- a/app/views/api/trainings/index.json.jbuilder +++ b/app/views/api/trainings/index.json.jbuilder @@ -1,9 +1,7 @@ role = (current_user and current_user.is_admin?) ? 'admin' : 'user' -json.cache! [@trainings, role] do - json.array!(@trainings) do |training| - json.extract! training, :id, :name, :description, :machine_ids, :nb_total_places, :slug - json.training_image training.training_image.attachment.large.url if training.training_image - json.plan_ids training.plan_ids if role === 'admin' - end +json.array!(@trainings) do |training| + json.extract! training, :id, :name, :description, :machine_ids, :nb_total_places, :slug + json.training_image training.training_image.attachment.large.url if training.training_image + json.plan_ids training.plan_ids if role === 'admin' end diff --git a/config/application.yml.default b/config/application.yml.default index ab2e0b224..fd3b8e8f4 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -27,9 +27,6 @@ SMTP_PASSWORD: GA_ID: '' ## -ADMIN_EMAIL: 'admin@fab-manager.com' -ADMIN_PASSWORD: 'adminadmin' - DISQUS_SHORTNAME: TWITTER_NAME: 'FablabGrenoble' diff --git a/config/secrets.yml b/config/secrets.yml index d7cfafe37..451419cad 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -42,8 +42,6 @@ development: facebook_app_id: <%= ENV["FACEBOOK_APP_ID"] %> elaticsearch_host: <%= ENV["ELASTICSEARCH_HOST"] %> max_image_size: <%= ENV["MAX_IMAGE_SIZE"] %> - admin_email: <%= ENV["ADMIN_EMAIL"] %> - admin_password: <%= ENV["ADMIN_PASSWORD"] %> test: secret_key_base: 83daf5e7b80d990f037407bab78dff9904aaf3c195a50f84fa8695a22287e707dfbd9524b403b1dcf116ae1d8c06844c3d7ed942564e5b46be6ae3ead93a9d30 @@ -77,8 +75,6 @@ test: facebook_app_id: <%= ENV["FACEBOOK_APP_ID"] %> elaticsearch_host: localhost max_image_size: <%= ENV["MAX_IMAGE_SIZE"] %> - admin_email: <%= ENV["ADMIN_EMAIL"] %> - admin_password: <%= ENV["ADMIN_PASSWORD"] %> staging: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> @@ -117,8 +113,6 @@ staging: facebook_app_id: <%= ENV["FACEBOOK_APP_ID"] %> elaticsearch_host: <%= ENV["ELASTICSEARCH_HOST"] %> max_image_size: <%= ENV["MAX_IMAGE_SIZE"] %> - admin_email: <%= ENV["ADMIN_EMAIL"] %> - admin_password: <%= ENV["ADMIN_PASSWORD"] %> # Do not keep production secrets in the repository, # instead read values from the environment. @@ -159,6 +153,4 @@ production: log_level: <%= ENV["LOG_LEVEL"] %> facebook_app_id: <%= ENV["FACEBOOK_APP_ID"] %> elaticsearch_host: <%= ENV["ELASTICSEARCH_HOST"] %> - max_image_size: <%= ENV["MAX_IMAGE_SIZE"] %> - admin_email: <%= ENV["ADMIN_EMAIL"] %> - admin_password: <%= ENV["ADMIN_PASSWORD"] %> + max_image_size: <%= ENV["MAX_IMAGE_SIZE"] %> \ No newline at end of file diff --git a/db/seeds.rb b/db/seeds.rb index e88938c09..011bd0609 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -84,7 +84,7 @@ end # Create the default admin if none exists yet if Role.where(name: 'admin').joins(:users).count === 0 - admin = User.new(username: 'admin', email: Rails.application.secrets.admin_email, password: Rails.application.secrets.admin_password, password_confirmation: Rails.application.secrets.admin_password, group_id: Group.first.id, profile_attributes: {first_name: 'admin', last_name: 'admin', gender: true, phone: '0123456789', birthday: Time.now}) + admin = User.new(username: 'admin', email: ENV["ADMIN_EMAIL"], password: ENV["ADMIN_PASSWORD"], password_confirmation: Rails.application.secrets.admin_password, group_id: Group.first.id, profile_attributes: {first_name: 'admin', last_name: 'admin', gender: true, phone: '0123456789', birthday: Time.now}) admin.add_role 'admin' admin.save! end diff --git a/docker/README.md b/docker/README.md index 0454ab43e..1a7ab4dda 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,121 +1,129 @@ -# full procedure to put into production a fabmanager app with Docker +# Install Fabmanager app in production 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. +This README tries to describe all the steps to put a fabmanager app into production on a server, based on a solution using Docker and Docker-compose. +We recommend DigitalOcean, but these steps will work on any Docker-compatible cloud provider or local server. -### docker/env +In order to make it work, please use the same directories structure as described in this guide in your fabmanager app folder. +You will need to be root through the rest of the setup. -Make a copy of the **env.example** and use it as a starting point. -List all the environment variables needed by your application. +##### Table of contents -### docker/nginx_with_ssl.conf.example +1. [Preliminary steps](#preliminary-steps)
+1.1. setup the server
+1.2. buy a domain name and link it with the droplet
+1.3. connect to the droplet via SSH
+1.4. prepare server
+1.5. setup folders and env file
+1.6. setup nginx file
+1.7. SSL certificate with LetsEncrypt
+1.8. requirements +2. [Install Fabmanager](#install-fabmanager)
+2.1. Add docker-compose.yml file
+2.2. pull images
+2.3. setup database
+2.4. build assets
+2.5. prepare Elasticsearch (search engine)
+2.6. start all services +3. [Generate SSL certificate by Letsencrypt](#generate-ssl-certificate-by-letsencrypt) +4. [Docker utils](#docker-utils) +5. [Update Fabmanager](#update-fabmanager)
+5.1. Steps
+5.2. Good to know -* Use nginx.conf.example especially if you are not using **SSL** +## Preliminary steps + +### setup the server + +Go to [DigitalOcean](https://www.digitalocean.com/) and create a Droplet with One-click apps **"Docker on Ubuntu 16.04 LTS"** (Docker and Docker-compose are preinstalled). +You need at least 2GB of addressable memory (RAM + swap) to install and use FabManager. +We recommend 4 GB RAM for larger communities. +Choose a datacenter. Set the hostname as your domain name. + +### buy a domain name and link it with the server + +1. Buy a domain name on [OVH](https://www.ovh.com/fr/) +2. Replace the IP address of the domain with the droplet's IP (you can enable the flexible ip and use it) +3. **Do not** try to access your domain name right away, DNS are not aware of the change yet so **WAIT** and be patient. + +### connect to the server via SSH + +You can already connect to the server with this command: `ssh root@server-ip`. When DNS propagation will be done, you will be able to +connect to the server with `ssh root@your-domain-name`. + +### prepare server + +We recommend you to : +- ugprade your system +- add at least 2GB of swap +- verify that you are using a connection via an SSH key. If so, you can set the root passord (for the debug console) and disable password connection. +To do this, you can use the following script : + +```bash +cd /root +git clone https://github.com/sleede/lazyscripts.git +cd lazyscripts/ +chmod a+x prepare-vps.sh +./prepare-vps +``` + + +### setup folders and env file + +Create the config folder: +```bash +mkdir -p /apps/fabmanager/config +``` + +Make a copy of the **docker/env.example** file and use it as a starting point. +Set all the environment variables needed by your application. Please refer to the [FabManager README](https://github.com/LaCasemate/fab-manager/blob/master/README.md) for explanations about those variables. + + +Then, copy the previously customized `env.example` file as `/apps/fabmanager/config/env` + +### setup nginx file + +Create the nginx folder: +```bash +mkdir -p /apps/fabmanager/config/nginx +``` + +Customize the docker/nginx_with_ssl.conf.example file * 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) +**Use nginx.conf.example if you don't want SSL for your app.** +Then, +Copy the previously customized `nginx_with_ssl.conf.example` as `/apps/fabmanager/config/nginx/fabmanager.conf` -## 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 - -```bash -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: - -```bash -[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: - -```bash -systemctl enable /etc/systemd/system/swap.service -systemctl start swap -exit -``` - -### Setup folders and env file - -```bash -mkdir -p /home/core/fabmanager/config -``` - -Copy the previously customized `env.example` file as `/home/core/fabmanager/config/env` - -```bash -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 !). +**OR** +Copy the previously customized `nginx.conf.example` as `/apps/fabmanager/config/nginx/fabmanager.conf` if you do not want to use ssl (not recommended !). ### SSL certificate with LetsEncrypt + +**FOLLOW THOSE INSTRUCTIONS ONLY IF YOU WANT TO USE SSL**. + 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 +Here is the setup for a systemd timer and service to renew the certificates and reboot the app Docker container: ```bash -mkdir -p /home/core/fabmanager/config/nginx/ssl +mkdir -p /apps/fabmanager/config/nginx/ssl ``` -Run `openssl dhparam -out dhparam.pem 4096` in the folder /home/core/fabmanager/config/nginx/ssl (generate dhparam.pem file) +Run `openssl dhparam -out dhparam.pem 4096` in the folder /apps/fabmanager/config/nginx/ssl (generate dhparam.pem file) ```bash -mkdir -p /home/core/fabmanager/letsencrypt/config/ +mkdir -p /apps/fabmanager/letsencrypt/config/ ``` -Copy the previously customized `webroot.ini.example` as `/home/core/fabmanager/letsencrypt/config/webroot.ini` +Copy the previously customized `webroot.ini.example` as `/appsfabmanager/letsencrypt/config/webroot.ini` ```bash -mkdir -p /home/core/fabmanager/letsencrypt/etc/webrootauth +mkdir -p /apps/fabmanager/letsencrypt/etc/webrootauth ``` Run `docker pull quay.io/letsencrypt/letsencrypt:latest` -Create file (with sudo) /etc/systemd/system/letsencrypt.service with +Create file (with sudo) /etc/systemd/system/letsencrypt.service and paste the following configuration into it: ```bash [Unit] @@ -124,11 +132,11 @@ 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 +ExecStart=/usr/bin/docker run --rm --name letsencrypt -v "/apps/fabmanager/log:/var/log/letsencrypt" -v "/apps/fabmanager/letsencrypt/etc:/etc/letsencrypt" -v "/apps/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 +Create file (with sudo) /etc/systemd/system/letsencrypt.timer and paste the following configuration into it: ```bash [Unit] Description=letsencrypt oneshot timer @@ -143,139 +151,83 @@ Unit=letsencrypt.service WantedBy=timers.target ``` -Then deploy your app and read the "Generate SSL certificate by Letsencrypt" section to complete the installation of the letsencrypt certificate. +That's all for the moment. Keep on with the installation, we'll complete that part after deployment in the [Generate SSL certificate by Letsencrypt](#generate-ssl-cert-letsencrypt). + +### Requirements -### Deploy dockers containers on host +Verify that Docker and Docker-composer are installed : +(This is normally the case if you used a pre-configured image.) ```bash -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 +docker info +docker-compose -v ``` -### Rails specific commands +Otherwise, you can install docker to ubuntu with the following instructions : +https://docs.docker.com/engine/installation/linux/ubuntu/#install-using-the-repository -#### DB CREATE +To install docker-compose : ```bash -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 - -```bash -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 - -```bash -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 +curl -L https://github.com/docker/compose/releases/download/1.13.0/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 ``` -#### PREPARE ELASTIC + +## Install Fabmanager + +### Add docker-compose.yml file + +Copy docker-compose.yml to your app folder `/apps/fabmanager`. +The docker-compose commands must be launched from the folder `/apps/fabmanager`. + +### pull images ```bash -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 +docker-compose pull ``` - -#### BUILD ASSETS +### setup database ```bash -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 +docker-compose run --rm fabmanager bundle exec rake db:create # create the database +docker-compose run --rm fabmanager bundle exec rake db:migrate # run all the migrations +docker-compose run --rm -e ADMIN_EMAIL=xxx ADMIN_PASSWORD=xxx fabmanager bundle exec rake db:seed # seed the database ``` +### build assets -#### RUN APP +`docker-compose run --rm fabmanager bundle exec rake assets:precompile` -```bash -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 +### prepare Elasticsearch (search engine) -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 +`docker-compose run --rm fabmanager bundle exec rake fablab:es_build_stats` -``` +#### start all services +`docker-compose up -d` -### Generate SSL certificate by Letsencrypt (app must be run before start letsencrypt) +### Generate SSL certificate by Letsencrypt + +**Important: app must be run on http before starting letsencrypt** Start letsencrypt service : ```bash 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 +If the certificate was successfully generated then update the nginx configuration file and activate the ssl port and certificate +editing the file `/apps/fabmanager/config/nginx/fabmanager.conf`. + +Remove your app container and run your app to apply the changes running the following commands: +```bash +docker-compose down +docker-compose up -d +``` Finally, if everything is ok, start letsencrypt timer to update the certificate every 1st of the month : @@ -285,93 +237,93 @@ sudo systemctl start letsencrypt.timer (check) sudo systemctl list-timers ``` +## Docker utils with docker-compose -### Dockers utils +### Restart app -#### Restart app +`docker-compose restart fabmanager` -`docker restart fabmanager-app` +### Remove app -#### Remove app +`docker-compose down fabmanager` -`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 - -#### download docker compose https://github.com/docker/compose/releases - -```bash -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 - -```bash -mkdir -p /home/core/fabmanager/config -``` - -Copy the previously customized `env` file as `/home/core/fabmanager/config/env` - -```bash -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/fabmanager - -#### pull images - -`docker-compose pull` - -#### create/migrate/seed db - -```bash -docker-compose run --rm fabmanager bundle exec rake db:create -docker-compose run --rm fabmanager bundle exec rake db:migrate -docker-compose run --rm fabmanager bundle exec rake db:seed -``` - -#### 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 +### Restart all containers `docker-compose restart` -#### show services status +### Remove all containers + +`docker-compose down` + +### Start all containers + +`docker-compose up -d` + +### Open a bash in the app context + +`docker-compose run --rm fabmanager bash` + +### Show services status `docker-compose ps` -#### update service fabmanager, rebuild assets and restart fabmanager +### Restart nginx container -```bash -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 -``` +`docker-compose restart nginx` + +### Example of command passing env variables + +docker-compose run --rm -e ADMIN_EMAIL=xxx ADMIN_PASSWORD=xxx fabmanager bundle exec rake db:seed + +## update Fabmanager + +*This procedure updates fabmanager to the most recent version by default.* + +### Steps + +When a new version is available, this is how to update fabmanager app in a production environment, using docker-compose : + +1. go to your app folder + + `cd /apps/fabmanager` + +2. pull last docker images + + `docker-compose pull` + +3. stop the app + + `docker-compose stop fabmanager` + +4. remove old assets + + `rm -Rf public/assets/` + +5. compile new assets + + `docker-compose run --rm fabmanager bundle exec rake assets:precompile` + +6. run specific commands + + **Do not forget** to check if there are commands to run for your upgrade. Those commands + are always specified in the [CHANGELOG](https://github.com/LaCasemate/fab-manager/blob/master/CHANGELOG.md) and prefixed by **[TODO DEPLOY]**. + They are also present in the [releases page](https://github.com/LaCasemate/fab-manager/releases). + + Those commands execute specific tasks and have to be run by hand. + +7. restart all containers + + ```bash + docker-compose down + docker-compose up -d + ``` + +You can check that all containers are running with `docker ps`. + +### Good to know + +#### Is it possible to update several versions at the same time ? + +Yes, indeed. It's the default behaviour as `docker-compose pull` command will fetch the latest versions of the docker images. +Be sure to run all the specific commands listed in the [CHANGELOG](https://github.com/LaCasemate/fab-manager/blob/master/CHANGELOG.md) between your actual +and the new version in sequential order. (Example: to update from 2.4.0 to 2.4.3, you will run the specific commands for the 2.4.1, then for the 2.4.2 and then for the 2.4.3). \ No newline at end of file diff --git a/docker/env.example b/docker/env.example index f896f9262..778f70c11 100644 --- a/docker/env.example +++ b/docker/env.example @@ -22,9 +22,6 @@ SMTP_PORT=587 SMTP_USER_NAME= SMTP_PASSWORD= -ADMIN_EMAIL= -ADMIN_PASSWORD= - GA_ID= DISQUS_SHORTNAME=