README.md 16.9 KB
Newer Older
1
2
3
4
5
---
layout: default
title: Install Decidim on Debian 12
nav_order: 1
---
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
6

7
8
Install Decidim on Debian 12
===============================
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
9

10
These instruction should work in any clean installation of Debian 12. You may have to adapt some of the step in other cases.
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
11

12
## 1. Setup a clean server
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
13

14
Use a clean installation, I'm using my own VM created at my research lab. It has 4gb of RAM, AMD EPYC 7401 24-Core Processor with 2 cores, 50gb hardrive. But you can use a DigitalOcean VM for this too.
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
15

16
Great, we have our server up and running. Now we install the required packages before installing decidim:
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
17

18
## 2. Installing necessary software
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
First, let's keep our system up to date:

```bash
sudo apt update
sudo apt upgrade
sudo apt autoremove
```

Now, configure the proper timezone for your server:

```bash
sudo dpkg-reconfigure tzdata
```

Then, install some required packages:

```bash
37
sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev imagemagick
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
```
Now, let's install ruby, by using the [rbenv](https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-with-rbenv-on-ubuntu-18-04) method.


These are the commands you need to run if you follow the guide:

```bash
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
```

Now you should check if you have rbenv correctly installed, running the command `type rbenv` should give you this answer:

```bash
decidim@decidim:~$ type rbenv
rbenv is a function
rbenv ()
{
    local command;
    command="${1:-}";
    if [ "$#" -gt 0 ]; then
        shift;
    fi;
    case "$command" in
        rehash | shell)
            eval "$(rbenv "sh-$command" "$@")"
        ;;
        *)
            command rbenv "$command" "$@"
        ;;
    esac
}
```

We still need to install ruby-build to simplify the installation of ruby:

```bash
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
```

At this point, you should be able to run the command `rbenv install -l` that will give you all ruby versions available:

```bash
decidim@decidim:~$ rbenv install -l
Available versions:
    3.0.6
    3.1.4
    3.2.3
    3.3.0
    jruby-9.4.5.0
    mruby-3.2.0
    picoruby-3.0.0
    truffleruby-23.1.2
    truffleruby+graalvm-23.1.2
```

We are going to use version 3.1.1, so run these commands:

```bash
rbenv install 3.1.1
rbenv global 3.1.1
```
Now you can verify we have everything in order by running the command `ruby -v`:

```bash
decidim@decidim:~$ ruby -v
ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-linux]
```

If everything is ok, we need to setup Gems, the package manager for Ruby, after that we will be ready to install Decidim.

To setup Gem, execute:

```bash
echo "gem: --no-document" > ~/.gemrc
gem install bundler
```

Again, you can test if everything is ok so far by running the command `gem env home`

```bash
decidim@decidim:~$ gem env home
/home/decidim/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0
```

Great, now we have the basic server setup in place, next step is to install Decidim.

## 3. Installing Decidim

Decidim uses Postgresql as a SQL database, we are going to configure it so it access another VM with a postgres being served. If you want to, you can also install it in this VM following platoniq's original guide:

```bash
sudo apt install -y postgresql libpq-dev
```

We also need NodeJS as a dependency for the decidim generator, in Debian 12 it's fine to install from the repositories (we also install imageMagick and a library needed since version 0.17, used by Decidim):

```bash
sudo apt install -y nodejs imagemagick libicu-dev
```
Now, we use the decidim generator to create our application. Note that you still need the package `libpg-dev` in order tu run the decidim generator.

You also need to install npm and yarn:

```bash
sudo apt install npm
```

Then install yarn via npm:

```bash
sudo npm install --global yarn 
```

First, install the gem Decidim (this may take a while):

```bash
gem install decidim
```
Now, run the generator to create our app:

```bash
decidim decidim-app
```

At this point, we have created a new folder in `~/decidim-app` with our code. We need to setup the database now.

To do that, first we create the user and password in the database. If you are using postgresql in another VM, you may need to ask your sys-admin team or your database team to help you with the following steps:

```bash
sudo -u postgres psql -c "CREATE USER decidim_app WITH SUPERUSER CREATEDB NOCREATEROLE PASSWORD 'Password1'"
```
Choose a good password like I did ;)

With the user created, it's time for configure Decidim to use these credentials.

Because we don't want to directly store this sensitive data in the code itself, we are going to use an additional YAML file that will store all the secrets in one place. If, in the future, we want to create a Git repository with our application, we will exclude this file from the version control.

In order to translate this file to the config system in Decidim, we are going to include the Ruby Gem "figaro" in our app to take care of it.

First, let's change to the decidim's folder:

```bash
cd ~/decidim-app
```

Then, let's edit the `Gemfile`:
```bash
188
vim Gemfile
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
```
We will modify that file to add a "production" section with our extra Gems, we add this line before the first `group` declaration:

```ruby
gem "figaro"
```

And we will create another `group` section with the production settings that will also install some additional gems needed later on.

Add at the end of the `Gemfile`:

```ruby
group :production do
  gem "passenger"
  gem 'delayed_job_active_record'
  gem "daemons"
end
```

The whole `Gemfile` should look similar to this:

```ruby
# frozen_string_literal: true

source "https://rubygems.org"

ruby RUBY_VERSION

gem "decidim", "0.28.0"
# gem "decidim-conferences", "0.28.0"
# gem "decidim-design", "0.28.0"
# gem "decidim-elections", "0.28.0"
# gem "decidim-initiatives", "0.28.0"
# gem "decidim-templates", "0.28.0"

gem "bootsnap", "~> 1.3"

gem "puma", ">= 6.3.1"

gem "wicked_pdf", "~> 2.1"

gem "figaro"

group :development, :test do
  gem "byebug", "~> 11.0", platform: :mri

  gem "brakeman", "~> 5.4"
  gem "decidim-dev", "0.28.0"
  gem "net-imap", "~> 0.2.3"
  gem "net-pop", "~> 0.1.1"
  gem "net-smtp", "~> 0.3.1"
end

group :development do
  gem "letter_opener_web", "~> 2.0"
  gem "listen", "~> 3.1"
  gem "spring", "~> 2.0"
  gem "spring-watcher-listen", "~> 2.0"
  gem "web-console", "~> 4.2"
end

group :production do
  gem "passenger"
  gem 'delayed_job_active_record'
  gem "daemons"
end

```
After that we need to update our app to include the extra gems, run the next command (inside the app folder):

```bash
bundle install
```
Now, it's time to create the configuration file with our custom values. We already have the database credentials (we've created the user before) and we need a random string that will be used by Decidim to encrypt cookies and other security stuff.

Let's generate a random string by executing the command `rake secret` inside the app folder:

```bash
cd ~/decidim-app
rake secret
e2418a1987378e36f18740d25f0360a18099a5caa5d04700ea3336d9fdefadc5362dc885a7a15f671e81f7d77bc98fa4d8abfd048f829a78d7ffd33cd8b4b287
```
Copy that generated string, and create a new config file:

```bash
274
vim ~/decidim-app/config/application.yml
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
```

Paste inside this content:

```yaml
DATABASE_URL: postgresql://<db_user>:<password>@<host>/<db_name>

SECRET_KEY_BASE: e2418a1987378e36f18740d25f0360a18099a5caa5d04700ea3336d9fdefadc5362dc885a7a15f671e81f7d77bc98fa4d8abfd048f829a78d7ffd33cd8b4b287
```

Now, just for safety, include this file in the `.gitignore` file, in case in the future you want to use GIT to manage your app.

Just execute:

```
echo "/config/application.yml" >> ~/decidim-app/.gitignore
```


> **Notes:**
> - I've named my database `decidim_prod`, change that value to whatever you want for your decidim app.
> - Be aware that line with the with the SECRET_KEY_BASE keyword is only ONE line and you MUST put your own generated secret (the one generated with the  `rake secret` command)
>
> **👉 Going pro** (optional):
> - Now it's a good time to initialize your installation as a GIT repository.
> - This will allow to keep track of your changes and revert them is something goes wrong.
> - This is optional, basically you need to execute:
> ```bash
> cd ~/decidim-app
> git init .
> git commit -m "Initial commit. Generated with Decidim 0.X https://decidim.org"
> ```
> - After that you should create commits everytime you make a relevant change.

309
At this point Decidim should be able to start working. Just be sure that your decidim has permission to create a database, this config can be changed in the pg_hba.conf and usually decidim has to be able to connect to "postges" database (default) so it can, only then, create a database. Do not try to create an empty database yourself because the rails db:create task will perform lots of actions, creating keys, tables and configurations unique to the rails framework itself. We need to initialize and update the database by doing this:
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

```bash
cd ~/decidim-app
bin/rails db:create RAILS_ENV=production
bin/rails assets:precompile db:migrate RAILS_ENV=production
```

The response to the second command should look something like this (quite long), this command compiles the static assets to prepare our app for production and migrates the database:

```bash
decidim@decidim:~/decidim-app$ bin/rails db:create RAILS_ENV=production
Created database 'decidim_prod'
decidim@decidim:~/decidim-app$ bin/rails assets:precompile db:migrate RAILS_ENV=production
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
I, [2018-07-16T13:10:56.442340 #32755]  INFO -- : Writing /home/decidim/decidim-app/public/assets/decidim/api/docs-3ca85e11b4f676d392a15494a0eb66962aaf08382c60a09ae3f1d7a6806a59ae.js

...

== 20180713145001 DeviseCreateDecidimUsers: migrating =========================
-- adapter_name()
   -> 0.0000s
-- adapter_name()
   -> 0.0000s
-- adapter_name()
   -> 0.0000s
-- create_table(:decidim_users, {:id=>:integer})
   -> 0.0056s
...
```

Now we are going to log into the Decidim console Rails app and create our first admin user:

```bash
bin/rails console -e production
```

A new prompt will appear:

```
Running via Spring preloader in process 51438
WARNING: Spring is running in production. To fix this make sure the spring gem is only present in `development` and `test` groups in your Gemfile and make sure you always use `bundle install --without development test` in production
Loading production environment (Rails 6.1.7.6)
```

In there, write these **4** lines and press enter (put your email and some secure password, you will use these credentials to login into Decidim super-admin:

```ruby
email = "my-admin@email"
password = "<a secure password>"
user = Decidim::System::Admin.new(email: email, password: password, password_confirmation: password)
user.save!
```

It returns 

```ruby
irb(main):015:0> user.save!
=> true
```

Write `quit` or press *CTRL+D* to exit the rails console.

If everything went fine, a very basic Decidim installation is ready to be shown to the world. We only are one step away from the glory, that is to configure an http web server to proxy our ruby application and handle the user petitions.

## 4. Installing Nginx

As a web server we will use Nginx. To install Nginx execute the next commands (the first installs nginx, the others enables the public ports in the firewall, otherwise our webserver won't be accessible):

```bash
sudo apt -y install nginx
```

The last 2 commands are to allow the firewall (if we have it activated) let pass the http/https connection to the server. If you don't use a firewall, you can skip them.

```bash
386
387
sudo ufw allow http
sudo ufw allow https
388
389
```

390
Nginx is a very fast and efficient web server but it doesn't handle Ruby applications by itself. We need and intermediary gateway for that, we will use [Passenger](https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/nginx/install/oss/bookworm.html).
391

392
I'll summarize here all the commands to [install Passenger in Debian 12](https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/nginx/install/oss/bookworm.html) (follow the link to get into details):
393
394

```bash
395
396
397
398
399
400
401
sudo apt-get install -y dirmngr gnupg apt-transport-https ca-certificates curl
curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/phusion.gpg >/dev/null
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bookworm main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update
sudo apt-get install -y libnginx-mod-http-passenger
if [ ! -f /etc/nginx/modules-enabled/50-mod-http-passenger.conf ]; then sudo ln -s /usr/share/nginx/modules-available/mod-http-passenger.load /etc/nginx/modules-enabled/50-mod-http-passenger.conf ; fi
sudo ls /etc/nginx/conf.d/mod-http-passenger.conf
402
sudo service nginx restart
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
403
```
404
405
406

If you run the command `passenger-config validate-install` it should give you an answer like this:

Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
407
```
408
409
410
411
decidim@decidim:~/decidim-app$ sudo /usr/bin/passenger-config validate-install
What would you like to validate?
Use <space> to select.
If the menu doesn't display correctly, press '!'
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
412

413
414
 ‣ ⬢  Passenger itself
   ⬡  Apache
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
415

416
-------------------------------------------------------------------------
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
417

418
419
 * Checking whether this Passenger install is in PATH... ✓
 * Checking whether there are no other Passenger installations... ✓
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
420

421
422
Everything looks good. :-)
```
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
423

424
If the output complains about having 2 copies of passenger installed, then passenger may be using the wrong copy of it.
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
425

426
Let's ensure everything is ok by editing the file `/etc/nginx/conf.d/mod-http-passenger.conf`:
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
427

428
```bash
429
sudo vim /etc/nginx/conf.d/mod-http-passenger.conf
430
```
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
431

432
And be sure that the line that contains `passenger_ruby` points to our `.rbenv` ruby folder, the whole file should look like this:
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
433

434
435
436
437
438
439
```nginx
### Begin automatically installed Phusion Passenger config snippet ###
passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /home/decidim/.rbenv/shims/ruby;
### End automatically installed Phusion Passenger config snippet ###
```
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
440

441
Once Nginx & Passenger are installed, we'll configure nginx to point http(s) request to our copy of Decidim. To do that, we need to create an Nginx configuration file and setup a new virtual host with our domain (ie: my-decidim.org):
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
442

443
Create/edit the new Nginx config file:
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
444

445
```bash
446
sudo vim /etc/nginx/sites-enabled/decidim.conf
447
```
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
448

449
Paste this inside (replace `my-decidim.org` with your own domain):
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
450

451
```nginx
452
453

# Directive to redirect all HTTP to HTTPS
454
455
server {
    listen 80;
456
    listen [::]:80;
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
457

458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
    # Domain name
    server_name <domain>;

    # Redirecting
    return 301 https://$host$request_uri;
}

# HTTPS directive
server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name <domain>;

    ssl_certificate <pub_cert_path>;
    ssl_certificate_key <private_cert_path>;
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
473

474
475
    passenger_enabled on;
    passenger_ruby /home/decidim/.rbenv/shims/ruby;
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
476

477
478
    client_max_body_size 32M;

479
    rails_env    production;
480
481
    root <decidim/public_path>;
    index 422.html;
482
483
}
```
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
484

485
Restart Nginx now:
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
486

487
488
489
```bash
sudo service nginx restart
```
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
490

491
**Done!** Decidim should be working now on our server, if you point your browser to your domain (ie: my-decidim.org) it will redirect you to the system admin interface (which is the web interface that will allow to create your first organization):
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
492

493
To configure it follow platoniq's guide, or just explore the app.
Richard Fernando Heise Ferreira's avatar
Richard Fernando Heise Ferreira committed
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

# Known problems

If you try to setup an (network) external email server (like mailbox) and the server is **not** configured to respond starttls request you may get a timeout on the decidim log's (`/log/production.log`, use `tail -f` to be sure). If this happens, [according to this issue](https://github.com/Platoniq/decidim-install/issues/5) you are suppouse to add

```ruby
:ssl =>                   true,
:tls =>                  true
```

In the `/config/environments/production.rb` file. like so:

```ruby
# Use default logging formatter so that PID and timestamp are not suppressed.
  config.log_formatter = ::Logger::Formatter.new
  config.action_mailer.smtp_settings = {
    :address        => Rails.application.secrets.smtp_address,
    :port           => Rails.application.secrets.smtp_port,
    :authentication => Rails.application.secrets.smtp_authentication,
    :user_name      => Rails.application.secrets.smtp_username,
    :password       => Rails.application.secrets.smtp_password,
    :domain         => Rails.application.secrets.smtp_domain,
    :enable_starttls_auto => Rails.application.secrets.smtp_starttls_auto,
    :openssl_verify_mode => 'none',
    :ssl =>                   true,
    :tls =>                  true
  }
```

This solved a **VERY HARD** to debbug problem. Thanks Marcus Reisdoefer. Also, TLS problems are relatively common when dealing with mail services, so beware of those.