From 2f7a10363b0f133d7cc70309d3dfdbe6c84fc4e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 16 Oct 2025 10:19:43 +0200 Subject: [PATCH 001/115] add vagrant to test script --- Vagrantfile | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Vagrantfile diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 00000000..22a9ce35 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,77 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. + + # Every Vagrant development environment requires a box. You can search for + # boxes at https://vagrantcloud.com/search. + config.vm.box = "debian/bookworm64" + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # NOTE: This will enable public access to the opened port + config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine and only allow access + # via 127.0.0.1 to disable public access + # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + # config.vm.synced_folder "../data", "/vagrant_data" + + # Disable the default share of the current code directory. Doing this + # provides improved isolation between the vagrant box and your host + # by making sure your Vagrantfile isn't accessible to the vagrant box. + # If you use this you may want to enable additional shared subfolders as + # shown above. + # config.vm.synced_folder ".", "/vagrant", disabled: true + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + # config.vm.provider "virtualbox" do |vb| + # # Display the VirtualBox GUI when booting the machine + # vb.gui = true + # + # # Customize the amount of memory on the VM: + # vb.memory = "1024" + # end + # + # View the documentation for the provider you are using for more + # information on available options. + + # Enable provisioning with a shell script. Additional provisioners such as + # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the + # documentation for more information about their specific syntax and use. + # config.vm.provision "shell", inline: <<-SHELL + # apt-get update + # apt-get install -y apache2 + # SHELL +end From f0d97892272c46836defe24ac744a25512a1fea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 16 Oct 2025 10:31:14 +0200 Subject: [PATCH 002/115] add compose files --- app.yml | 44 ++++++++++++++++++++++++++++++++++++++++++++ cache.yml | 11 +++++++++++ db.yml | 12 ++++++++++++ traefik.yml | 15 +++++++++++++++ worker.yml | 17 +++++++++++++++++ 5 files changed, 99 insertions(+) create mode 100644 app.yml create mode 100644 cache.yml create mode 100644 db.yml create mode 100644 traefik.yml create mode 100644 worker.yml diff --git a/app.yml b/app.yml new file mode 100644 index 00000000..c12101c2 --- /dev/null +++ b/app.yml @@ -0,0 +1,44 @@ +services: + app: + container_name: decidim + image: ${DECIDIM_IMAGE} + command: "bin/rails server -b 0.0.0.0" + volumes: + - ./storage:/app/storage + restart: always + labels: + - "traefik.enable=true" + - "traefik.http.routers.app.rule=PathPrefix(`/`)" + - "traefik.http.routers.app.entrypoints=web" + - "traefik.http.services.app.loadbalancer.server.port=3000" + env_file: + - .env + environment: + - DATABASE_URL + - SECRET_KEY_BASE + - DECIDIM_FORCE_SSL=${DECIDIM_FORCE_SSL:-false} + - QUEUE_ADAPTER=${QUEUE_ADAPTER:-sidekiq} + - REDIS_URL=${REDIS_URL:-redis://redis:6379/0} + - WEB_CONCURRENCY=${WEB_CONCURRENCY:-2} + - LOG_LEVEL=${LOG_LEVEL:-info} + - DECIDIM_ENABLE_HTML_HEADER_SNIPPETS + - DECIDIM_ADMIN_PASSWORD_EXPIRATION_DAYS=${DECIDIM_ADMIN_PASSWORD_EXPIRATION_DAYS:-360} + - CHANGE_ACTIVE_STEP=${CHANGE_ACTIVE_STEP:-enabled} + - SEND_REMINDERS=${SEND_REMINDERS:-enabled} + - WEEKLY_NOTIFICATIONS_DIGEST=${WEEKLY_NOTIFICATIONS_DIGEST:-enabled} + - DAILY_NOTIFICATIONS_DIGEST=${DAILY_NOTIFICATIONS_DIGEST:-enabled} + - HEALTHCHECK_EXCLUDE_CHECKS=${HEALTHCHECK_EXCLUDE_CHECKS:-emailconf} + - SMTP_STARTTLS_AUTO=${SMTP_STARTTLS_AUTO:-true} + - SMTP_USERNAME + - SMTP_PASSWORD + - SMTP_ADDRESS + - SMTP_DOMAIN + - SMTP_PORT + - DECIDIM_MAILER_SENDER + - MAPS_API_KEY + - MAPS_PROVIDER=${MAPS_PROVIDER:-here} + - RACK_ATTACK_SECRET + depends_on: + - db + - cache + diff --git a/cache.yml b/cache.yml new file mode 100644 index 00000000..d1dc2ee2 --- /dev/null +++ b/cache.yml @@ -0,0 +1,11 @@ +services: + app: + depends_on: + - cache + cache: + image: redis + volumes: + - redis_data:/data + restart: always +volumes: + redis_data: {} diff --git a/db.yml b/db.yml new file mode 100644 index 00000000..4824e156 --- /dev/null +++ b/db.yml @@ -0,0 +1,12 @@ +services: + app: + depends_on: + - db + db: + image: postgres:17 + env_file: + - .env + environment: + POSTGRES_USER: ${POSTGRES_USER:-decidim} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-decidim} + POSTGRES_DB: ${POSTGRES_DB:-decidim} diff --git a/traefik.yml b/traefik.yml new file mode 100644 index 00000000..1910527c --- /dev/null +++ b/traefik.yml @@ -0,0 +1,15 @@ +services: + traefik: + image: traefik:v3.5 + container_name: traefik + command: + - --api + - --providers.docker=true + - --entrypoints.web.address=:80 + - --entrypoints.traefik.address=:8080 + restart: unless-stopped + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.service=api@internal" diff --git a/worker.yml b/worker.yml new file mode 100644 index 00000000..4f21d33b --- /dev/null +++ b/worker.yml @@ -0,0 +1,17 @@ +services: + sidekiq: + image: ${DECIDIM_IMAGE:-decidim/decidim:latest} + entrypoint: ["/code/vendor/sidekiq_entrypoint.sh"] + command: "bundle exec sidekiq -C config/sidekiq.yml" + env_file: + - .env + volumes: + - ./scripts:/code/vendor + environment: + - DATABASE_URL + - SECRET_KEY_BASE + - DECIDIM_FORCE_SSL=false + - QUEUE_ADAPTER=sidekiq + - REDIS_URL=redis://redis:6379/1 + links: + - cache From 8940ca0777df6884f6f57efbe9e03bf29441f773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 16 Oct 2025 10:31:41 +0200 Subject: [PATCH 003/115] add initial scripts --- scripts/dependencies/build_env.sh | 98 +++++++++++++++++++++++++ scripts/dependencies/check_docker.sh | 25 +++++++ scripts/dependencies/decidim_version.sh | 17 +++++ scripts/dependencies/open_ports.sh | 17 +++++ scripts/dependencies/os_version.sh | 9 +++ scripts/entrypoint.sh | 6 +- scripts/install.sh | 73 ++++++++++++++++++ scripts/sidekiq_entrypoint.sh | 16 ++++ scripts/up.sh | 10 +++ 9 files changed, 268 insertions(+), 3 deletions(-) create mode 100644 scripts/dependencies/build_env.sh create mode 100644 scripts/dependencies/check_docker.sh create mode 100644 scripts/dependencies/decidim_version.sh create mode 100644 scripts/dependencies/open_ports.sh create mode 100755 scripts/dependencies/os_version.sh create mode 100644 scripts/install.sh create mode 100644 scripts/sidekiq_entrypoint.sh create mode 100644 scripts/up.sh diff --git a/scripts/dependencies/build_env.sh b/scripts/dependencies/build_env.sh new file mode 100644 index 00000000..716d8473 --- /dev/null +++ b/scripts/dependencies/build_env.sh @@ -0,0 +1,98 @@ +#!/bin/bash +set -e # exit on error + +BUILD_ENV_PATH="$REPOSITORY_PATH/.env" + +echo "───────────────────────────────────────────────" +echo "📦 Now we need to get some information about the instance you are building." +echo +read -p "What are you going to name your instance? " DECIDIM_APPLICATION_NAME +echo "The name of the instance is: $DECIDIM_APPLICATION_NAME" +echo +echo "Who's going to administer this instance?" +read -p "email: " DECIDIM_SYSTEM_ADMIN_EMAIL +read -p "name: " DECIDIM_SYSTEM_ADMIN_NAME +echo "The administrator will be $DECIDIM_SYSTEM_ADMIN_NAME, $DECIDIM_SYSTEM_ADMIN_EMAIL" +echo +echo "Now we need to know how people will access this instance (e.g., decidim.example.org)" +read -p "domain: " DECIDIM_DOMAIN + +echo "───────────────────────────────────────────────" +echo "To set up the Database we also need some information" +read -p "Do you have an external database already set up? [y/N] " yn + +case $yn in +[Yy]*) + EXTERNAL_DATABASE=true + ;; +[Nn]*) + EXTERNAL_DATABASE=false + ;; +*) + echo "Please answer yes or no." + exit 1 + ;; +esac + +read -p "Name of the database: " DATABASE_NAME +read -p "Database user: " DATABASE_USER + +if [ "$EXTERNAL_DATABASE" = true ]; then + read -p "Database host (ip or domain): " DATABASE_HOST +else + DATABASE_HOST="db" +fi + +read -p "Database password: " DATABASE_PASSWORD + +DATABASE_URL="postgres://$DATABASE_USER:$DATABASE_PASSWORD@$DATABASE_HOST/$DATABASE_NAME" + +echo "───────────────────────────────────────────────" +echo "Now we have to set your SMTP server." +echo "You can check the documentation to know what to do here." +read -p "SMTP_USERNAME: " SMTP_USERNAME +read -p "SMTP_PASSWORD: " SMTP_PASSWORD +read -p "SMTP_ADDRESS: " SMTP_ADDRESS +read -p "SMTP_DOMAIN: " SMTP_DOMAIN + +echo "───────────────────────────────────────────────" +echo "To start, we are going to store assets locally" +read -p "Do you have an external database already set up? [y/N] " yn +STORAGE="local" + +echo "───────────────────────────────────────────────" +echo "To be able to have the maps working inside the Decidim application," +echo "is necessary to configure a maps provider." +read -p "Maps provider: " MAPS_PROVIDER +read -p "Maps API KEY: " MAPS_API_KEY + +if [ -f .env ]; then + echo "❌ Failing: .env file already exists." + exit 1 +else + echo "✅ Writing the environment variables to .env file..." + + cat >.env </dev/null + sudo apt-get update + sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin +else + echo "Docker is installed $(docker --version)" +fi + +sudo usermod -aG docker ${USER} +newgrp docker diff --git a/scripts/dependencies/decidim_version.sh b/scripts/dependencies/decidim_version.sh new file mode 100644 index 00000000..c4ed1c06 --- /dev/null +++ b/scripts/dependencies/decidim_version.sh @@ -0,0 +1,17 @@ +echo "───────────────────────────────────────────────" +echo "📦 What version of Decidim do you want to use?" +echo +echo "The default image is: decidim/decidim:latest" +echo +echo "You can also specify a custom image, for example:" +echo " • decidim/decidim:0.30" +echo " • ghcr.io/decidim/decidim:0.28" +echo " • ghcr.io/my-org/custom-decidim:1.0.0" +echo +read -p "👉 Enter the Decidim image (or press Enter to use the default): " DECIDIM_IMAGE + +# Use default if none entered +DECIDIM_IMAGE=${DECIDIM_IMAGE:-decidim/decidim:latest} + +echo "✅ Using Decidim image: $DECIDIM_IMAGE" +echo "───────────────────────────────────────────────" diff --git a/scripts/dependencies/open_ports.sh b/scripts/dependencies/open_ports.sh new file mode 100644 index 00000000..d962aa99 --- /dev/null +++ b/scripts/dependencies/open_ports.sh @@ -0,0 +1,17 @@ +echo "───────────────────────────────────────────────" +echo "Now we are going to open the necessary ports for Decidim to work." +echo +echo "To handle the SSL certificate we will have to open the port 80 and the port 443" +echo + +if ! command -v ufw; then + echo "UFW nos intalled. We are going to install it to allow openning ports 80 and 443 on this machine." + sudo apt install ufw +fi + +sudo ufw allow 22 +sudo ufw allow 80 +sudo ufw allow 443 +sudo ufw enable + +echo "───────────────────────────────────────────────" diff --git a/scripts/dependencies/os_version.sh b/scripts/dependencies/os_version.sh new file mode 100755 index 00000000..c3fc7880 --- /dev/null +++ b/scripts/dependencies/os_version.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [ ! -f /etc/os-release ]; then + echo "Error: Unable to determine OS. /etc/os-release file not found." + echo "Installation stopped." + exit 1 +fi + +cat /etc/os-release diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index c48d1f87..cb3982f5 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -6,9 +6,9 @@ USER_GID=$(stat -c %g /code/Gemfile) export USER_UID export USER_GID -usermod -u "$USER_UID" decidim 2> /dev/null -groupmod -g "$USER_GID" decidim 2> /dev/null -usermod -g "$USER_GID" decidim 2> /dev/null +usermod -u "$USER_UID" decidim 2>/dev/null +groupmod -g "$USER_GID" decidim 2>/dev/null +usermod -g "$USER_GID" decidim 2>/dev/null chown -R -h "$USER_UID" "$BUNDLE_PATH" chgrp -R -h "$USER_GID" "$BUNDLE_PATH" diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100644 index 00000000..4b92162c --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +echo -e "***********************************************************************" +echo -e "* This script will try to install Decidim on this machine. *" +echo -e "* Take into account that it will ask for some information that *" +echo -e "* you will have to provide. Also it will take care of installing *" +echo -e "* all necessary dependencies, such as *docker*, *git*, etc. *" +echo -e "* *" +echo -e "* You will be guided throughout the script and will be able to *" +echo -e "* stop it and restart it if necessary. *" +echo -e "* *" +echo -e "* It's not in a production-ready state. There's not guarantee *" +echo -e "* and it's up to you to take care of your systems. *" +echo -e "* *" +echo -e "***********************************************************************" + +REPOSITORY_PATH="$HOME/decidim" + +set -e + +trap "You can re-run this script to restart the installation", ERR + +if command -v git; then + echo "Git is installed. $(git --version)" +else + sudo apt update + sudo apt install -y git curl + sudo apt clean +fi + +echo "Downloading decidim-docker repository to " +if [ ! -d $REPOSITORY_PATH ]; then + git clone -b feat/decidim_install https://github.com/decidim/docker.git $REPOSITORY_PATH +fi + +cd $REPOSITORY_PATH + +echo "Checking the OS version" +source $REPOSITORY_PATH/scripts/dependencies/os_version.sh + +# Check if docker is installed, if not install it +echo "Checking if docker is installed. If not install it." +source $REPOSITORY_PATH/scripts/dependencies/check_docker.sh + +# Checking which Decidim version does the user want +echo "Checking the Decidim version to use." +source $REPOSITORY_PATH/scripts/dependencies/decidim_version.sh + +# Open necessary ports +echo "Openning necessary server ports." +source $REPOSITORY_PATH/scripts/dependencies/open_ports.sh + +# Build environment variables +echo "Asking for necessary variables." +source $REPOSITORY_PATH/scripts/dependencies/build_env.sh + +# Start decidim +echo "Starging Decidim..." +source $REPOSITORY_PATH/scripts/up.sh diff --git a/scripts/sidekiq_entrypoint.sh b/scripts/sidekiq_entrypoint.sh new file mode 100644 index 00000000..cb3982f5 --- /dev/null +++ b/scripts/sidekiq_entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/sh -x + +USER_UID=$(stat -c %u /code/Gemfile) +USER_GID=$(stat -c %g /code/Gemfile) + +export USER_UID +export USER_GID + +usermod -u "$USER_UID" decidim 2>/dev/null +groupmod -g "$USER_GID" decidim 2>/dev/null +usermod -g "$USER_GID" decidim 2>/dev/null + +chown -R -h "$USER_UID" "$BUNDLE_PATH" +chgrp -R -h "$USER_GID" "$BUNDLE_PATH" + +/usr/bin/sudo -EH -u decidim "$@" diff --git a/scripts/up.sh b/scripts/up.sh new file mode 100644 index 00000000..92ff9331 --- /dev/null +++ b/scripts/up.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +export $(cat .env | xargs) +composes="-f app.yml -f traefik.yml -f cache.yml -f worker.yml " + +if $EXTERNAL_DATABASE; then + composes+="-f db.yml" +fi + +docker compose --env-file .env ${composes} up From fc2ca20b3b986729948b12d4de6389a9d545790b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 16 Oct 2025 12:20:48 +0200 Subject: [PATCH 004/115] generate SECRET_KEY_BASE --- scripts/dependencies/build_env.sh | 6 +++++- scripts/dependencies/check_docker.sh | 1 - worker.yml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/dependencies/build_env.sh b/scripts/dependencies/build_env.sh index 716d8473..e3f2917d 100644 --- a/scripts/dependencies/build_env.sh +++ b/scripts/dependencies/build_env.sh @@ -57,7 +57,7 @@ read -p "SMTP_DOMAIN: " SMTP_DOMAIN echo "───────────────────────────────────────────────" echo "To start, we are going to store assets locally" -read -p "Do you have an external database already set up? [y/N] " yn +read -p "Do you have an external bucket [y/N] " yn STORAGE="local" echo "───────────────────────────────────────────────" @@ -72,6 +72,8 @@ if [ -f .env ]; then else echo "✅ Writing the environment variables to .env file..." + SECRET_KEY_BASE=$(openssl rand -hex 64) + cat >.env < Date: Tue, 21 Oct 2025 15:32:19 +0200 Subject: [PATCH 005/115] add memory to Vagrant --- Vagrantfile | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index 22a9ce35..753f1d84 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -56,22 +56,22 @@ Vagrant.configure("2") do |config| # backing providers for Vagrant. These expose provider-specific options. # Example for VirtualBox: # - # config.vm.provider "virtualbox" do |vb| - # # Display the VirtualBox GUI when booting the machine - # vb.gui = true - # - # # Customize the amount of memory on the VM: - # vb.memory = "1024" - # end - # + config.vm.provider "virtualbox" do |vb| + # Display the VirtualBox GUI when booting the machine + vb.gui = false + + # Customize the amount of memory on the VM: + vb.memory = "2048" + end + # View the documentation for the provider you are using for more # information on available options. # Enable provisioning with a shell script. Additional provisioners such as # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the # documentation for more information about their specific syntax and use. - # config.vm.provision "shell", inline: <<-SHELL - # apt-get update - # apt-get install -y apache2 - # SHELL + config.vm.provision "shell", inline: <<-SHELL + apt-get update + apt-get install -y curl + SHELL end From 38fc8140269c147fc66dcaedc869b0ec2beda547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 21 Oct 2025 18:18:32 +0200 Subject: [PATCH 006/115] add traefik domain and fix default decidim_image --- app.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app.yml b/app.yml index c12101c2..70581401 100644 --- a/app.yml +++ b/app.yml @@ -1,13 +1,13 @@ services: app: container_name: decidim - image: ${DECIDIM_IMAGE} + image: ${DECIDIM_IMAGE:-"decidim/decidim:latest"} command: "bin/rails server -b 0.0.0.0" - volumes: - - ./storage:/app/storage + pull_policy: always restart: always labels: - "traefik.enable=true" + - "traefik.http.routers.whoami.rule=Host(`$DECIDIM_DOMAIN`)" - "traefik.http.routers.app.rule=PathPrefix(`/`)" - "traefik.http.routers.app.entrypoints=web" - "traefik.http.services.app.loadbalancer.server.port=3000" @@ -38,7 +38,3 @@ services: - MAPS_API_KEY - MAPS_PROVIDER=${MAPS_PROVIDER:-here} - RACK_ATTACK_SECRET - depends_on: - - db - - cache - From 32e3f9b52455feb14d5ae545c6747094ddb07a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 21 Oct 2025 18:18:48 +0200 Subject: [PATCH 007/115] add pull_policy always to worker --- worker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/worker.yml b/worker.yml index c48ad0da..aa20a802 100644 --- a/worker.yml +++ b/worker.yml @@ -1,6 +1,7 @@ services: worker: image: ${DECIDIM_IMAGE:-decidim/decidim:latest} + pull_policy: always entrypoint: ["/code/vendor/sidekiq_entrypoint.sh"] command: "bundle exec sidekiq -C config/sidekiq.yml" env_file: From e9d262ea25aae090b732af31ea709dede8a9f982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 21 Oct 2025 18:19:07 +0200 Subject: [PATCH 008/115] add storage to handle volume in app if not bucket --- storage.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 storage.yml diff --git a/storage.yml b/storage.yml new file mode 100644 index 00000000..9421f935 --- /dev/null +++ b/storage.yml @@ -0,0 +1,6 @@ +services: + app: + volumes: + - storage_volume:/code/storage +volumes: + storage_volume: {} From 5181c5ffa64520e07f7bab9873840a5fb31e3b2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 21 Oct 2025 18:19:35 +0200 Subject: [PATCH 009/115] change how to handle repository path --- scripts/install.sh | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 4b92162c..655486aa 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -28,7 +28,11 @@ echo -e "* and it's up to you to take care of your systems. * echo -e "* *" echo -e "***********************************************************************" -REPOSITORY_PATH="$HOME/decidim" +REPOSITORY_PATH=${DECIDIM_PATH:-/opt/decidim} +REPOSITORY_URL="https://github.com/decidim/docker.git" +REPOSITORY_BRANCH="feat/decidim_install" + +echo $REPOSITORY_PATH set -e @@ -42,12 +46,19 @@ else sudo apt clean fi -echo "Downloading decidim-docker repository to " -if [ ! -d $REPOSITORY_PATH ]; then - git clone -b feat/decidim_install https://github.com/decidim/docker.git $REPOSITORY_PATH +if [ ! -d "$REPOSITORY_PATH" ]; then + sudo mkdir -p "$REPOSITORY_PATH" + sudo chown "$USER":"$USER" "$REPOSITORY_PATH" fi -cd $REPOSITORY_PATH +cd "$REPOSITORY_PATH" + +echo "Downloading decidim-docker repository to ${REPOSITORY_PATH}" +if [ ! -d ".git" ]; then + cp -r /vagrant/* $REPOSITORY_PATH +else + git pull +fi echo "Checking the OS version" source $REPOSITORY_PATH/scripts/dependencies/os_version.sh @@ -68,6 +79,8 @@ source $REPOSITORY_PATH/scripts/dependencies/open_ports.sh echo "Asking for necessary variables." source $REPOSITORY_PATH/scripts/dependencies/build_env.sh +echo "external database: ${EXTERNAL_DATABASE}" + # Start decidim -echo "Starging Decidim..." +echo "Starting Decidim..." source $REPOSITORY_PATH/scripts/up.sh From fe067ac69ced2d208474450408ee50dd81118ee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 21 Oct 2025 18:19:59 +0200 Subject: [PATCH 010/115] add migration execution on app entrypoint --- scripts/entrypoint.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index cb3982f5..bcd0df35 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -13,4 +13,23 @@ usermod -g "$USER_GID" decidim 2>/dev/null chown -R -h "$USER_UID" "$BUNDLE_PATH" chgrp -R -h "$USER_GID" "$BUNDLE_PATH" +# Check all the gems are installed or fails. +bundle check +if [ $? -ne 0 ]; then + echo "❌ Gems in Gemfile are not installed, aborting..." + exit 1 +else + echo "✅ Gems in Gemfile are installed" +fi + +# Check no migrations are pending migrations +if [ -z "$SKIP_MIGRATIONS" ]; then + bundle exec rails db:migrate +else + echo "⚠️ Skipping migrations" +fi + +echo "✅ Migrations are all up" + +echo "🚀 $@" /usr/bin/sudo -EH -u decidim "$@" From 1e9a000473596e75d93f3e9e7978c05cf1030c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 21 Oct 2025 18:20:26 +0200 Subject: [PATCH 011/115] fix up script to handle local database and local storage --- scripts/up.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/up.sh b/scripts/up.sh index 92ff9331..d967020b 100644 --- a/scripts/up.sh +++ b/scripts/up.sh @@ -1,10 +1,13 @@ #!/bin/bash -export $(cat .env | xargs) composes="-f app.yml -f traefik.yml -f cache.yml -f worker.yml " -if $EXTERNAL_DATABASE; then - composes+="-f db.yml" +if ! $EXTERNAL_DATABASE; then + composes+=" -f db.yml" fi -docker compose --env-file .env ${composes} up +if [ "$STORAGE" == 'local' ]; then + composes+=" -f storage.yml" +fi + +sudo docker compose --env-file .env "${composes}" up From e0b7bd572c73a5cb2bc3363ebbc3af48944b4324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 21 Oct 2025 18:21:04 +0200 Subject: [PATCH 012/115] change local database to generate user, password and database name --- scripts/dependencies/build_env.sh | 52 +++++++++++++++---------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/scripts/dependencies/build_env.sh b/scripts/dependencies/build_env.sh index e3f2917d..981456ad 100644 --- a/scripts/dependencies/build_env.sh +++ b/scripts/dependencies/build_env.sh @@ -21,12 +21,32 @@ echo "──────────────────────── echo "To set up the Database we also need some information" read -p "Do you have an external database already set up? [y/N] " yn +build_local_database() { + POSTGRES_USER="user_$(openssl rand -hex 3)" + POSTGRES_PASSWORD="$(openssl rand -base64 18)" + POSTGRES_DB="db_$(openssl rand -hex 3)" + + DATABASE_USER=$POSTGRES_USER + DATABASE_PASSWORD=$DATABASE_PASSWORD + DATABASE_NAME=$POSTGRES_DB + DATABASE_HOST="db" +} + +build_external_database() { + read -p "Name of the database: " DATABASE_NAME + read -p "Database user: " DATABASE_USER + read -p "Database host (ip or domain): " DATABASE_HOST + read -p "Database password: " DATABASE_PASSWORD +} + case $yn in [Yy]*) EXTERNAL_DATABASE=true + build_external_database ;; [Nn]*) EXTERNAL_DATABASE=false + build_local_database ;; *) echo "Please answer yes or no." @@ -34,17 +54,6 @@ case $yn in ;; esac -read -p "Name of the database: " DATABASE_NAME -read -p "Database user: " DATABASE_USER - -if [ "$EXTERNAL_DATABASE" = true ]; then - read -p "Database host (ip or domain): " DATABASE_HOST -else - DATABASE_HOST="db" -fi - -read -p "Database password: " DATABASE_PASSWORD - DATABASE_URL="postgres://$DATABASE_USER:$DATABASE_PASSWORD@$DATABASE_HOST/$DATABASE_NAME" echo "───────────────────────────────────────────────" @@ -57,23 +66,15 @@ read -p "SMTP_DOMAIN: " SMTP_DOMAIN echo "───────────────────────────────────────────────" echo "To start, we are going to store assets locally" -read -p "Do you have an external bucket [y/N] " yn +read -p "Do you have an external bucket already set up? [y/N] " yn STORAGE="local" -echo "───────────────────────────────────────────────" -echo "To be able to have the maps working inside the Decidim application," -echo "is necessary to configure a maps provider." -read -p "Maps provider: " MAPS_PROVIDER -read -p "Maps API KEY: " MAPS_API_KEY - if [ -f .env ]; then echo "❌ Failing: .env file already exists." exit 1 else echo "✅ Writing the environment variables to .env file..." - SECRET_KEY_BASE=$(openssl rand -hex 64) - cat >.env < Date: Thu, 23 Oct 2025 15:18:03 +0200 Subject: [PATCH 013/115] add script to generate gemfiles --- app.yml | 1 + scripts/dependencies/build_env.sh | 1 + scripts/dependencies/generate_gemfile.sh | 28 ++++++++++++++++++++++++ scripts/install.sh | 3 ++- worker.yml | 1 + 5 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 scripts/dependencies/generate_gemfile.sh diff --git a/app.yml b/app.yml index 70581401..c76c91eb 100644 --- a/app.yml +++ b/app.yml @@ -14,6 +14,7 @@ services: env_file: - .env environment: + - BUNDLE_GEMFILE=Gemfile.wrapper - DATABASE_URL - SECRET_KEY_BASE - DECIDIM_FORCE_SSL=${DECIDIM_FORCE_SSL:-false} diff --git a/scripts/dependencies/build_env.sh b/scripts/dependencies/build_env.sh index 981456ad..135ef7f4 100644 --- a/scripts/dependencies/build_env.sh +++ b/scripts/dependencies/build_env.sh @@ -76,6 +76,7 @@ else echo "✅ Writing the environment variables to .env file..." cat >.env <Gemfile.wrapper <Gemfile.local <>Gemfile.local +fi diff --git a/scripts/install.sh b/scripts/install.sh index 655486aa..19e438a9 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -79,7 +79,8 @@ source $REPOSITORY_PATH/scripts/dependencies/open_ports.sh echo "Asking for necessary variables." source $REPOSITORY_PATH/scripts/dependencies/build_env.sh -echo "external database: ${EXTERNAL_DATABASE}" +echo "Building dependencies" +source $REPOSITORY_PATH/scripts/dependencies/generate_gemfile.sh # Start decidim echo "Starting Decidim..." diff --git a/worker.yml b/worker.yml index aa20a802..70447380 100644 --- a/worker.yml +++ b/worker.yml @@ -9,6 +9,7 @@ services: volumes: - ./scripts:/code/vendor environment: + - BUNDLE_GEMFILE - DATABASE_URL - SECRET_KEY_BASE - DECIDIM_FORCE_SSL=false From f2955bd2ce0a22d9effd624b21ce5f34fce8d178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 23 Oct 2025 15:19:21 +0200 Subject: [PATCH 014/115] add alpine versions for cache and db --- cache.yml | 2 +- db.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cache.yml b/cache.yml index d1dc2ee2..22f38096 100644 --- a/cache.yml +++ b/cache.yml @@ -3,7 +3,7 @@ services: depends_on: - cache cache: - image: redis + image: redis:8-alpine volumes: - redis_data:/data restart: always diff --git a/db.yml b/db.yml index 4824e156..d3ccfaca 100644 --- a/db.yml +++ b/db.yml @@ -3,7 +3,7 @@ services: depends_on: - db db: - image: postgres:17 + image: postgres:17-alpine env_file: - .env environment: From 32009ec002ee02ad63d0e41311fadf8e5483fdb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Wed, 29 Oct 2025 12:54:20 +0100 Subject: [PATCH 015/115] generate vapid keys --- scripts/dependencies/build_env.sh | 7 +++++++ scripts/dependencies/decidim_version.sh | 2 ++ scripts/dependencies/generate_vapid_keys.sh | 12 ++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 scripts/dependencies/generate_vapid_keys.sh diff --git a/scripts/dependencies/build_env.sh b/scripts/dependencies/build_env.sh index 135ef7f4..3a863859 100644 --- a/scripts/dependencies/build_env.sh +++ b/scripts/dependencies/build_env.sh @@ -69,11 +69,15 @@ echo "To start, we are going to store assets locally" read -p "Do you have an external bucket already set up? [y/N] " yn STORAGE="local" +echo "Generate VAPID keys" +source $REPOSITORY_PATH/scripts/dependencies/generate_vapid_keys.sh + if [ -f .env ]; then echo "❌ Failing: .env file already exists." exit 1 else echo "✅ Writing the environment variables to .env file..." +fi cat >.env </dev/null sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin + + sudo usermod -aG docker "${USER}" + echo "Re-run the script after running `sudo newgrp docker`" + exit 1 else echo "Docker is installed $(docker --version)" fi -sudo usermod -aG docker ${USER} From acc83272747847d528fff431cf9eb89719abd3c7 Mon Sep 17 00:00:00 2001 From: David Igon Date: Wed, 29 Oct 2025 17:47:29 +0100 Subject: [PATCH 017/115] pull decidim image when deciding version --- scripts/dependencies/decidim_version.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/dependencies/decidim_version.sh b/scripts/dependencies/decidim_version.sh index 40c11e03..c5a1811f 100644 --- a/scripts/dependencies/decidim_version.sh +++ b/scripts/dependencies/decidim_version.sh @@ -17,3 +17,8 @@ docker pull "$DECIDIM_IMAGE" -d echo "✅ Using Decidim image: $DECIDIM_IMAGE" echo "───────────────────────────────────────────────" + +echo "Downloading Decidim image..." + +docker pull $DECIDIM_IMAGE + From 4035540f4bb5508490de54f32a794112f01cb979 Mon Sep 17 00:00:00 2001 From: David Igon Date: Wed, 29 Oct 2025 17:48:47 +0100 Subject: [PATCH 018/115] git clone repository to repository path --- scripts/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install.sh b/scripts/install.sh index 19e438a9..fa2ea876 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -55,7 +55,7 @@ cd "$REPOSITORY_PATH" echo "Downloading decidim-docker repository to ${REPOSITORY_PATH}" if [ ! -d ".git" ]; then - cp -r /vagrant/* $REPOSITORY_PATH + git clone $REPOSITORY_URL $REPOSITORY_PATH -b $REPOSITORY_BRANCH else git pull fi From e550ea6e8014b2ef4db5f74c8f84b9132ef3cf84 Mon Sep 17 00:00:00 2001 From: David Igon Date: Wed, 29 Oct 2025 18:24:09 +0100 Subject: [PATCH 019/115] fix on decidim version script --- scripts/dependencies/decidim_version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dependencies/decidim_version.sh b/scripts/dependencies/decidim_version.sh index c5a1811f..a286a929 100644 --- a/scripts/dependencies/decidim_version.sh +++ b/scripts/dependencies/decidim_version.sh @@ -13,7 +13,7 @@ read -p "👉 Enter the Decidim image (or press Enter to use the default): " DEC # Use default if none entered DECIDIM_IMAGE=${DECIDIM_IMAGE:-decidim/decidim:latest} -docker pull "$DECIDIM_IMAGE" -d +docker pull "$DECIDIM_IMAGE" echo "✅ Using Decidim image: $DECIDIM_IMAGE" echo "───────────────────────────────────────────────" From be2ca7957ddf1a9a581da6d0398c3a90197dd691 Mon Sep 17 00:00:00 2001 From: David Igon Date: Wed, 29 Oct 2025 19:15:45 +0100 Subject: [PATCH 020/115] change docker installation process --- scripts/dependencies/check_docker.sh | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/scripts/dependencies/check_docker.sh b/scripts/dependencies/check_docker.sh index 5b872795..f62fdeaf 100644 --- a/scripts/dependencies/check_docker.sh +++ b/scripts/dependencies/check_docker.sh @@ -7,20 +7,7 @@ if ! command -v docker >/dev/null 2>&1; then echo "Once installed it might be necessary to re-run the script so that the changes take up effect." echo "To do so you can run `newgrp docker`" - # Add Docker's official GPG key: - sudo apt update && sudo apt upgrade -y - sudo apt-get install -y ca-certificates curl - sudo install -m 0755 -d /etc/apt/keyrings - sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc - sudo chmod a+r /etc/apt/keyrings/docker.asc - - # Add the repository to Apt sources: - echo \ - "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ - $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | - sudo tee /etc/apt/sources.list.d/docker.list >/dev/null - sudo apt-get update - sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin + curl -fsSL https://get.docker.com | bash sudo usermod -aG docker "${USER}" echo "Re-run the script after running `sudo newgrp docker`" From 174af9e002c6d4546fffcee24773027ca70f985a Mon Sep 17 00:00:00 2001 From: David Igon Date: Wed, 29 Oct 2025 19:18:47 +0100 Subject: [PATCH 021/115] fix on variable assignment --- scripts/dependencies/build_env.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/dependencies/build_env.sh b/scripts/dependencies/build_env.sh index 3a863859..bab46863 100644 --- a/scripts/dependencies/build_env.sh +++ b/scripts/dependencies/build_env.sh @@ -27,7 +27,7 @@ build_local_database() { POSTGRES_DB="db_$(openssl rand -hex 3)" DATABASE_USER=$POSTGRES_USER - DATABASE_PASSWORD=$DATABASE_PASSWORD + DATABASE_PASSWORD=$POSTGRES_PASSWORD DATABASE_NAME=$POSTGRES_DB DATABASE_HOST="db" } @@ -79,7 +79,7 @@ else echo "✅ Writing the environment variables to .env file..." fi - cat >.env <.env < Date: Wed, 29 Oct 2025 19:22:22 +0100 Subject: [PATCH 022/115] fix use of variable --- scripts/dependencies/generate_gemfile.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dependencies/generate_gemfile.sh b/scripts/dependencies/generate_gemfile.sh index 2c5e3cf0..1c918a9d 100644 --- a/scripts/dependencies/generate_gemfile.sh +++ b/scripts/dependencies/generate_gemfile.sh @@ -23,6 +23,6 @@ gem "sidekiq" gem "sidekiq-cron" EOF -if [ $EXTERNAL_STORAGE == "s3" ]; then +if [ $STORAGE == "s3" ]; then echo "gem \"aws-sdk-s3\"" >>Gemfile.local fi From 4917f61b72656142ba1d12d1153dc4f6bc6bfb23 Mon Sep 17 00:00:00 2001 From: David Igon Date: Thu, 30 Oct 2025 08:57:59 +0100 Subject: [PATCH 023/115] add volumes for Gemfile.wrapper and Gemfile.local --- app.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app.yml b/app.yml index c76c91eb..95374baf 100644 --- a/app.yml +++ b/app.yml @@ -3,8 +3,14 @@ services: container_name: decidim image: ${DECIDIM_IMAGE:-"decidim/decidim:latest"} command: "bin/rails server -b 0.0.0.0" + entrypoint: ["/code/vendor/entrypoint.sh"] pull_policy: always restart: always + volumes: + - ${PWD}/Gemfile.wrapper: /code/Gemfile.wrapper + - ${PWD}/Gemfile.local: /code/Gemfile.local + - ${PWD}/scripts/entrypoint.sh:/code/entrypoint.sh + labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`$DECIDIM_DOMAIN`)" From a47284b21ecb56f750fa4d47d5dbd4f58ccea0d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 13 Nov 2025 16:55:18 +0100 Subject: [PATCH 024/115] read from /dev/tty --- scripts/dependencies/build_env.sh | 30 ++++++++++++------------- scripts/dependencies/decidim_version.sh | 7 +++--- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/scripts/dependencies/build_env.sh b/scripts/dependencies/build_env.sh index bab46863..52c2882a 100644 --- a/scripts/dependencies/build_env.sh +++ b/scripts/dependencies/build_env.sh @@ -6,20 +6,20 @@ BUILD_ENV_PATH="$REPOSITORY_PATH/.env" echo "───────────────────────────────────────────────" echo "📦 Now we need to get some information about the instance you are building." echo -read -p "What are you going to name your instance? " DECIDIM_APPLICATION_NAME +read -p "What are you going to name your instance? " DECIDIM_APPLICATION_NAME Date: Mon, 24 Nov 2025 08:55:27 +0100 Subject: [PATCH 025/115] check before deleting .env file --- scripts/dependencies/build_env.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/dependencies/build_env.sh b/scripts/dependencies/build_env.sh index 52c2882a..81ab6d9f 100644 --- a/scripts/dependencies/build_env.sh +++ b/scripts/dependencies/build_env.sh @@ -74,11 +74,15 @@ source $REPOSITORY_PATH/scripts/dependencies/generate_vapid_keys.sh if [ -f .env ]; then echo "❌ Failing: .env file already exists." - exit 1 -else - echo "✅ Writing the environment variables to .env file..." + read -p "Do you want to delete the .env file and create a new one? You can make a back-up of it before answering." yn .env < Date: Mon, 24 Nov 2025 09:12:40 +0100 Subject: [PATCH 026/115] ask before openning ports --- scripts/dependencies/open_ports.sh | 39 +++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/scripts/dependencies/open_ports.sh b/scripts/dependencies/open_ports.sh index d962aa99..9aa7d754 100644 --- a/scripts/dependencies/open_ports.sh +++ b/scripts/dependencies/open_ports.sh @@ -1,17 +1,32 @@ +open_ports() { + echo + echo "To handle the SSL certificate we will have to open the port 80 and the port 443" + echo + + if ! command -v ufw; then + echo "UFW nos intalled. We are going to install it to allow openning ports 80 and 443 on this machine." + sudo apt install ufw + fi + + sudo ufw allow 22 + sudo ufw allow 80 + sudo ufw allow 443 + sudo ufw enable Date: Mon, 24 Nov 2025 09:12:58 +0100 Subject: [PATCH 027/115] fix parameters passed to docker compose --- scripts/up.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/up.sh b/scripts/up.sh index d967020b..17e35985 100644 --- a/scripts/up.sh +++ b/scripts/up.sh @@ -10,4 +10,4 @@ if [ "$STORAGE" == 'local' ]; then composes+=" -f storage.yml" fi -sudo docker compose --env-file .env "${composes}" up +sudo docker compose --env-file .env ${composes} up From dc42a99ae99da4808f1d5b6680f13d764062a78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 09:13:37 +0100 Subject: [PATCH 028/115] don't exit on open_ports script --- scripts/dependencies/open_ports.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/dependencies/open_ports.sh b/scripts/dependencies/open_ports.sh index 9aa7d754..82fb6ed2 100644 --- a/scripts/dependencies/open_ports.sh +++ b/scripts/dependencies/open_ports.sh @@ -25,7 +25,6 @@ case $yn in ;; *) echo "Not openning ports." - exit 1 ;; esac From 5c15d5d02cb88e8ad5203ee37728368431849071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 09:17:04 +0100 Subject: [PATCH 029/115] fix volumes on app.yml --- app.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app.yml b/app.yml index 95374baf..0c086d35 100644 --- a/app.yml +++ b/app.yml @@ -7,10 +7,9 @@ services: pull_policy: always restart: always volumes: - - ${PWD}/Gemfile.wrapper: /code/Gemfile.wrapper - - ${PWD}/Gemfile.local: /code/Gemfile.local + - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper + - ${PWD}/Gemfile.local:/code/Gemfile.local - ${PWD}/scripts/entrypoint.sh:/code/entrypoint.sh - labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`$DECIDIM_DOMAIN`)" From fa87b32ce09bfb0f2c9afea29386e41ff264eead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 09:49:40 +0100 Subject: [PATCH 030/115] change bash errors --- scripts/dependencies/generate_gemfile.sh | 2 +- scripts/dependencies/generate_vapid_keys.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/dependencies/generate_gemfile.sh b/scripts/dependencies/generate_gemfile.sh index 1c918a9d..456e848f 100644 --- a/scripts/dependencies/generate_gemfile.sh +++ b/scripts/dependencies/generate_gemfile.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -xe +set -e echo "───────────────────────────────────────────────" echo "Now we are going to generate some Gemfiles so that we can track gem dependencies" diff --git a/scripts/dependencies/generate_vapid_keys.sh b/scripts/dependencies/generate_vapid_keys.sh index b2de5072..2d0b124c 100644 --- a/scripts/dependencies/generate_vapid_keys.sh +++ b/scripts/dependencies/generate_vapid_keys.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -xe +set -e echo "Generating VAPID keys" output=$(docker run --rm \ "$DECIDIM_IMAGE" \ From 4cad4c7d3a57d343c4470203ea67e12d041f7a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 09:49:48 +0100 Subject: [PATCH 031/115] update traefik version --- traefik.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traefik.yml b/traefik.yml index 1910527c..4a46f8b7 100644 --- a/traefik.yml +++ b/traefik.yml @@ -1,6 +1,6 @@ services: traefik: - image: traefik:v3.5 + image: traefik:v3.6 container_name: traefik command: - --api From 4c2ca22797ab9d1db9d1dc58e4df5fc39da053f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 09:53:43 +0100 Subject: [PATCH 032/115] fix use of sidekiq_entrypoint --- worker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worker.yml b/worker.yml index 70447380..592759c3 100644 --- a/worker.yml +++ b/worker.yml @@ -7,7 +7,7 @@ services: env_file: - .env volumes: - - ./scripts:/code/vendor + - ${PWD}/scripts/sidekiq_entrypoint.sh:/code/vendor/sidekiq_entrypoint.sh environment: - BUNDLE_GEMFILE - DATABASE_URL From 79211965d15ebecfd01c853bf67bf1b5e26db5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 10:17:34 +0100 Subject: [PATCH 033/115] fix on entrypoints paths --- app.yml | 2 +- worker.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app.yml b/app.yml index 0c086d35..dde0a0ea 100644 --- a/app.yml +++ b/app.yml @@ -3,7 +3,7 @@ services: container_name: decidim image: ${DECIDIM_IMAGE:-"decidim/decidim:latest"} command: "bin/rails server -b 0.0.0.0" - entrypoint: ["/code/vendor/entrypoint.sh"] + entrypoint: ["/code/entrypoint.sh"] pull_policy: always restart: always volumes: diff --git a/worker.yml b/worker.yml index 592759c3..3459df67 100644 --- a/worker.yml +++ b/worker.yml @@ -2,12 +2,12 @@ services: worker: image: ${DECIDIM_IMAGE:-decidim/decidim:latest} pull_policy: always - entrypoint: ["/code/vendor/sidekiq_entrypoint.sh"] + entrypoint: ["/code/sidekiq_entrypoint.sh"] command: "bundle exec sidekiq -C config/sidekiq.yml" env_file: - .env volumes: - - ${PWD}/scripts/sidekiq_entrypoint.sh:/code/vendor/sidekiq_entrypoint.sh + - ${PWD}/scripts/sidekiq_entrypoint.sh:/code/sidekiq_entrypoint.sh environment: - BUNDLE_GEMFILE - DATABASE_URL From 6cc99b8aa7f8ad05132c2e2467bd080706df186c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 10:19:22 +0100 Subject: [PATCH 034/115] make scripts executable --- scripts/entrypoint.sh | 0 scripts/sidekiq_entrypoint.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/entrypoint.sh mode change 100644 => 100755 scripts/sidekiq_entrypoint.sh diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh old mode 100644 new mode 100755 diff --git a/scripts/sidekiq_entrypoint.sh b/scripts/sidekiq_entrypoint.sh old mode 100644 new mode 100755 From add55e362a6b95bd780aafcb85d1347029f89fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 10:23:07 +0100 Subject: [PATCH 035/115] make entrypoints execute bundle install --- scripts/entrypoint.sh | 2 +- scripts/sidekiq_entrypoint.sh | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index bcd0df35..8eeb3d69 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -17,7 +17,7 @@ chgrp -R -h "$USER_GID" "$BUNDLE_PATH" bundle check if [ $? -ne 0 ]; then echo "❌ Gems in Gemfile are not installed, aborting..." - exit 1 + bundle install else echo "✅ Gems in Gemfile are installed" fi diff --git a/scripts/sidekiq_entrypoint.sh b/scripts/sidekiq_entrypoint.sh index cb3982f5..383a704d 100755 --- a/scripts/sidekiq_entrypoint.sh +++ b/scripts/sidekiq_entrypoint.sh @@ -13,4 +13,14 @@ usermod -g "$USER_GID" decidim 2>/dev/null chown -R -h "$USER_UID" "$BUNDLE_PATH" chgrp -R -h "$USER_GID" "$BUNDLE_PATH" +# Check all the gems are installed or fails. +bundle check +if [ $? -ne 0 ]; then + echo "❌ Gems in Gemfile are not installed, aborting..." + bundle install +else + echo "✅ Gems in Gemfile are installed" +fi + +echo "🚀 $@" /usr/bin/sudo -EH -u decidim "$@" From 2feb6f7bf1edac74402b5bbd10ddc58dd00605e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 10:48:27 +0100 Subject: [PATCH 036/115] remove sudo from entrypoints --- scripts/entrypoint.sh | 2 +- scripts/sidekiq_entrypoint.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 8eeb3d69..c2dec630 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -32,4 +32,4 @@ fi echo "✅ Migrations are all up" echo "🚀 $@" -/usr/bin/sudo -EH -u decidim "$@" +exec "$0" diff --git a/scripts/sidekiq_entrypoint.sh b/scripts/sidekiq_entrypoint.sh index 383a704d..d89b5d2d 100755 --- a/scripts/sidekiq_entrypoint.sh +++ b/scripts/sidekiq_entrypoint.sh @@ -23,4 +23,4 @@ else fi echo "🚀 $@" -/usr/bin/sudo -EH -u decidim "$@" +exec "$0" From a30dcb50eddc9fa0182a07e99b982a3b9238520a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 11:02:45 +0100 Subject: [PATCH 037/115] change database env variables --- db.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db.yml b/db.yml index d3ccfaca..4998f89b 100644 --- a/db.yml +++ b/db.yml @@ -7,6 +7,6 @@ services: env_file: - .env environment: - POSTGRES_USER: ${POSTGRES_USER:-decidim} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-decidim} - POSTGRES_DB: ${POSTGRES_DB:-decidim} + POSTGRES_USER: ${DATABASE_USER:-decidim} + POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-decidim} + POSTGRES_DB: ${DATABASE_NAME:-decidim} From 9ddd38f5a8e9514b23bad76a1f1b062e6ebdd125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 11:09:38 +0100 Subject: [PATCH 038/115] change password generated base --- scripts/dependencies/build_env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dependencies/build_env.sh b/scripts/dependencies/build_env.sh index 81ab6d9f..dc7e14b7 100644 --- a/scripts/dependencies/build_env.sh +++ b/scripts/dependencies/build_env.sh @@ -23,7 +23,7 @@ read -p "Do you have an external database already set up? [y/N] " yn Date: Mon, 24 Nov 2025 11:37:10 +0100 Subject: [PATCH 039/115] update composes --- app.yml | 8 +++++--- traefik.yml | 7 +++++++ worker.yml | 7 +++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/app.yml b/app.yml index dde0a0ea..f89e06a5 100644 --- a/app.yml +++ b/app.yml @@ -6,15 +6,17 @@ services: entrypoint: ["/code/entrypoint.sh"] pull_policy: always restart: always + expose: + - 3000 volumes: - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper - ${PWD}/Gemfile.local:/code/Gemfile.local - ${PWD}/scripts/entrypoint.sh:/code/entrypoint.sh labels: - "traefik.enable=true" - - "traefik.http.routers.whoami.rule=Host(`$DECIDIM_DOMAIN`)" - - "traefik.http.routers.app.rule=PathPrefix(`/`)" - - "traefik.http.routers.app.entrypoints=web" + - "traefik.http.routers.app.rule=Host(`$DECIDIM_DOMAIN`)" + - "traefik.http.routers.app.entrypoints=web,websecure" + - "traefik.http.routers.app.tls=true" - "traefik.http.services.app.loadbalancer.server.port=3000" env_file: - .env diff --git a/traefik.yml b/traefik.yml index 4a46f8b7..8ab708b8 100644 --- a/traefik.yml +++ b/traefik.yml @@ -6,10 +6,17 @@ services: - --api - --providers.docker=true - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 - --entrypoints.traefik.address=:8080 + - --entrypoints.web.http.redirections.entryPoint.to=websecure + - --entrypoints.web.http.redirections.entryPoint.scheme=https + ports: + - "80:80" + - "443:443" restart: unless-stopped volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" labels: - "traefik.enable=true" - "traefik.http.routers.traefik.service=api@internal" + network_mode: host diff --git a/worker.yml b/worker.yml index 3459df67..56a7c94e 100644 --- a/worker.yml +++ b/worker.yml @@ -1,12 +1,15 @@ services: worker: image: ${DECIDIM_IMAGE:-decidim/decidim:latest} - pull_policy: always - entrypoint: ["/code/sidekiq_entrypoint.sh"] command: "bundle exec sidekiq -C config/sidekiq.yml" + entrypoint: ["/code/sidekiq_entrypoint.sh"] + pull_policy: always + restart: always env_file: - .env volumes: + - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper + - ${PWD}/Gemfile.local:/code/Gemfile.local - ${PWD}/scripts/sidekiq_entrypoint.sh:/code/sidekiq_entrypoint.sh environment: - BUNDLE_GEMFILE From a144c41daab06250c8077c4763bf14145b80d865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 11:41:24 +0100 Subject: [PATCH 040/115] fix commands --- app.yml | 2 +- worker.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app.yml b/app.yml index f89e06a5..4cc48d36 100644 --- a/app.yml +++ b/app.yml @@ -2,7 +2,7 @@ services: app: container_name: decidim image: ${DECIDIM_IMAGE:-"decidim/decidim:latest"} - command: "bin/rails server -b 0.0.0.0" + command: ["bin/rails", "server", "-b", "0.0.0.0"] entrypoint: ["/code/entrypoint.sh"] pull_policy: always restart: always diff --git a/worker.yml b/worker.yml index 56a7c94e..6691716e 100644 --- a/worker.yml +++ b/worker.yml @@ -1,7 +1,7 @@ services: worker: image: ${DECIDIM_IMAGE:-decidim/decidim:latest} - command: "bundle exec sidekiq -C config/sidekiq.yml" + command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"] entrypoint: ["/code/sidekiq_entrypoint.sh"] pull_policy: always restart: always From 1408e793001fbec0e3b3ad39d6e9115cb716e290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 11:46:14 +0100 Subject: [PATCH 041/115] fix reference passed to exec --- scripts/entrypoint.sh | 2 +- scripts/sidekiq_entrypoint.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index c2dec630..c02d5f99 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -32,4 +32,4 @@ fi echo "✅ Migrations are all up" echo "🚀 $@" -exec "$0" +exec "$@" diff --git a/scripts/sidekiq_entrypoint.sh b/scripts/sidekiq_entrypoint.sh index d89b5d2d..a1659c9f 100755 --- a/scripts/sidekiq_entrypoint.sh +++ b/scripts/sidekiq_entrypoint.sh @@ -23,4 +23,4 @@ else fi echo "🚀 $@" -exec "$0" +exec "$@" From 87796f27bfa9df86ea436b60f7df342b6c41aab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 24 Nov 2025 11:51:13 +0100 Subject: [PATCH 042/115] remove network mode --- traefik.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/traefik.yml b/traefik.yml index 8ab708b8..a523534d 100644 --- a/traefik.yml +++ b/traefik.yml @@ -19,4 +19,3 @@ services: labels: - "traefik.enable=true" - "traefik.http.routers.traefik.service=api@internal" - network_mode: host From 59c7f59565af844f3c6064d0401de0ecc36f161f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Wed, 26 Nov 2025 12:16:29 +0100 Subject: [PATCH 043/115] move scripts and add action to build release zip --- .github/workflows/build_install_folder.yml | 24 +++++++++++++++++++++ app.yml => scripts/composes/app.yml | 0 cache.yml => scripts/composes/cache.yml | 0 db.yml => scripts/composes/db.yml | 0 storage.yml => scripts/composes/storage.yml | 0 traefik.yml => scripts/composes/traefik.yml | 0 worker.yml => scripts/composes/worker.yml | 0 7 files changed, 24 insertions(+) create mode 100644 .github/workflows/build_install_folder.yml rename app.yml => scripts/composes/app.yml (100%) rename cache.yml => scripts/composes/cache.yml (100%) rename db.yml => scripts/composes/db.yml (100%) rename storage.yml => scripts/composes/storage.yml (100%) rename traefik.yml => scripts/composes/traefik.yml (100%) rename worker.yml => scripts/composes/worker.yml (100%) diff --git a/.github/workflows/build_install_folder.yml b/.github/workflows/build_install_folder.yml new file mode 100644 index 00000000..d9c56e7e --- /dev/null +++ b/.github/workflows/build_install_folder.yml @@ -0,0 +1,24 @@ +name: Build Deployment Zip + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Create deployment ZIP + run: | + zip -r deploy_bundle.zip \ + scripts/ \ + + - name: Release + uses: softprops/action-gh-release@v2 + with: + files: deploy_bundle.zip diff --git a/app.yml b/scripts/composes/app.yml similarity index 100% rename from app.yml rename to scripts/composes/app.yml diff --git a/cache.yml b/scripts/composes/cache.yml similarity index 100% rename from cache.yml rename to scripts/composes/cache.yml diff --git a/db.yml b/scripts/composes/db.yml similarity index 100% rename from db.yml rename to scripts/composes/db.yml diff --git a/storage.yml b/scripts/composes/storage.yml similarity index 100% rename from storage.yml rename to scripts/composes/storage.yml diff --git a/traefik.yml b/scripts/composes/traefik.yml similarity index 100% rename from traefik.yml rename to scripts/composes/traefik.yml diff --git a/worker.yml b/scripts/composes/worker.yml similarity index 100% rename from worker.yml rename to scripts/composes/worker.yml From 74c7c9ccfa5c1344a23d32be328a2d36961cdb4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Wed, 26 Nov 2025 16:15:05 +0100 Subject: [PATCH 044/115] move scripts to install folder --- {scripts/composes => install}/app.yml | 0 {scripts/composes => install}/cache.yml | 0 {scripts/composes => install}/db.yml | 0 .../dependencies/build_env.sh | 2 +- .../dependencies/check_docker.sh | 0 install/dependencies/create_dependencies.sh | 11 +++++ .../dependencies/decidim_version.sh | 0 .../dependencies/generate_gemfile.sh | 0 .../dependencies/generate_vapid_keys.sh | 0 .../dependencies/open_ports.sh | 0 .../dependencies/os_version.sh | 0 {scripts => install}/install.sh | 41 ++++++++++--------- {scripts => install/scripts}/entrypoint.sh | 0 {scripts => install/scripts}/hello-world.sh | 0 .../scripts}/sidekiq_entrypoint.sh | 0 {scripts/composes => install}/storage.yml | 0 {scripts/composes => install}/traefik.yml | 0 {scripts => install}/up.sh | 0 {scripts/composes => install}/worker.yml | 0 19 files changed, 33 insertions(+), 21 deletions(-) rename {scripts/composes => install}/app.yml (100%) rename {scripts/composes => install}/cache.yml (100%) rename {scripts/composes => install}/db.yml (100%) rename {scripts => install}/dependencies/build_env.sh (98%) rename {scripts => install}/dependencies/check_docker.sh (100%) create mode 100644 install/dependencies/create_dependencies.sh rename {scripts => install}/dependencies/decidim_version.sh (100%) rename {scripts => install}/dependencies/generate_gemfile.sh (100%) rename {scripts => install}/dependencies/generate_vapid_keys.sh (100%) rename {scripts => install}/dependencies/open_ports.sh (100%) rename {scripts => install}/dependencies/os_version.sh (100%) rename {scripts => install}/install.sh (76%) rename {scripts => install/scripts}/entrypoint.sh (100%) rename {scripts => install/scripts}/hello-world.sh (100%) rename {scripts => install/scripts}/sidekiq_entrypoint.sh (100%) rename {scripts/composes => install}/storage.yml (100%) rename {scripts/composes => install}/traefik.yml (100%) rename {scripts => install}/up.sh (100%) rename {scripts/composes => install}/worker.yml (100%) diff --git a/scripts/composes/app.yml b/install/app.yml similarity index 100% rename from scripts/composes/app.yml rename to install/app.yml diff --git a/scripts/composes/cache.yml b/install/cache.yml similarity index 100% rename from scripts/composes/cache.yml rename to install/cache.yml diff --git a/scripts/composes/db.yml b/install/db.yml similarity index 100% rename from scripts/composes/db.yml rename to install/db.yml diff --git a/scripts/dependencies/build_env.sh b/install/dependencies/build_env.sh similarity index 98% rename from scripts/dependencies/build_env.sh rename to install/dependencies/build_env.sh index dc7e14b7..18f1d534 100644 --- a/scripts/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -70,7 +70,7 @@ read -p "Do you have an external bucket already set up? [y/N] " yn Date: Thu, 27 Nov 2025 10:53:20 +0100 Subject: [PATCH 045/115] add log debug to traefik --- install/traefik.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/install/traefik.yml b/install/traefik.yml index a523534d..e38b8421 100644 --- a/install/traefik.yml +++ b/install/traefik.yml @@ -5,6 +5,7 @@ services: command: - --api - --providers.docker=true + - --log.level=DEBUG - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 - --entrypoints.traefik.address=:8080 From fb9d9faa5db3e999314c0fd299f461791ff73120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 27 Nov 2025 12:17:45 +0100 Subject: [PATCH 046/115] exit if not a correct distribution --- install/dependencies/os_version.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/install/dependencies/os_version.sh b/install/dependencies/os_version.sh index c3fc7880..a4dfa0e4 100755 --- a/install/dependencies/os_version.sh +++ b/install/dependencies/os_version.sh @@ -1,9 +1,17 @@ #!/bin/bash -if [ ! -f /etc/os-release ]; then - echo "Error: Unable to determine OS. /etc/os-release file not found." - echo "Installation stopped." +echo "───────────────────────────────────────────────" +echo "Now we are going to make sure that this distribution" +echo "is based on Debian/Ubuntu." + +if [ $(uname) != "Linux" ]; then + echo "This installation process must be run on Linux" + exit 1 +fi + +if [ ! -n $(lsb_release -d | grep Ubuntu/Debian) ]; then + echo "This installation process must be run on a Debian/Ubuntu distribution." exit 1 fi -cat /etc/os-release +echo "Correct distribution." From b1e12ff6dedc7efb2d033024225ac10e32c70646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 27 Nov 2025 14:56:30 +0100 Subject: [PATCH 047/115] add container name --- install/cache.yml | 1 + install/db.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/install/cache.yml b/install/cache.yml index 22f38096..07c908c7 100644 --- a/install/cache.yml +++ b/install/cache.yml @@ -4,6 +4,7 @@ services: - cache cache: image: redis:8-alpine + container_name: decidim_cache volumes: - redis_data:/data restart: always diff --git a/install/db.yml b/install/db.yml index 4998f89b..8bc2d1fc 100644 --- a/install/db.yml +++ b/install/db.yml @@ -4,6 +4,7 @@ services: - db db: image: postgres:17-alpine + container_name: decidim_db env_file: - .env environment: From 94a9f10946dc7266c1127d10de78322b81ff363e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 27 Nov 2025 15:40:54 +0100 Subject: [PATCH 048/115] add keys for s3-compatible buckets --- install/dependencies/build_env.sh | 59 ++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 18f1d534..296e4a33 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -20,6 +20,7 @@ read -p "domain: " DECIDIM_DOMAIN >.env < Date: Thu, 27 Nov 2025 15:41:28 +0100 Subject: [PATCH 049/115] script to create system admin --- install/dependencies/create_system_admin.sh | 22 +++++++++++++++++++++ install/dependencies/generate_vapid_keys.sh | 2 +- install/dependencies/open_ports.sh | 1 + install/install.sh | 7 +++++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 install/dependencies/create_system_admin.sh diff --git a/install/dependencies/create_system_admin.sh b/install/dependencies/create_system_admin.sh new file mode 100644 index 00000000..26d9b64f --- /dev/null +++ b/install/dependencies/create_system_admin.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +generate_system_admin() { + docker exec -ti \ + decidim \ + bin/rails decidim_system:create_admin Date: Thu, 27 Nov 2025 16:04:59 +0100 Subject: [PATCH 051/115] remove env for system admin --- install/dependencies/build_env.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 06157cf1..7274dc96 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -9,11 +9,6 @@ echo read -p "What are you going to name your instance? " DECIDIM_APPLICATION_NAME .env < Date: Thu, 27 Nov 2025 17:26:53 +0100 Subject: [PATCH 052/115] unify composes --- install/app.yml | 48 ---------- install/cache.yml | 12 --- install/db.yml | 13 --- install/docker-compose.yml | 122 ++++++++++++++++++++++++++ install/scripts/entrypoint.sh | 5 +- install/scripts/sidekiq_entrypoint.sh | 15 +--- install/storage.yml | 6 -- install/traefik.yml | 22 ----- install/up.sh | 5 +- install/worker.yml | 22 ----- 10 files changed, 131 insertions(+), 139 deletions(-) delete mode 100644 install/app.yml delete mode 100644 install/cache.yml delete mode 100644 install/db.yml create mode 100644 install/docker-compose.yml delete mode 100644 install/storage.yml delete mode 100644 install/traefik.yml delete mode 100644 install/worker.yml diff --git a/install/app.yml b/install/app.yml deleted file mode 100644 index 4cc48d36..00000000 --- a/install/app.yml +++ /dev/null @@ -1,48 +0,0 @@ -services: - app: - container_name: decidim - image: ${DECIDIM_IMAGE:-"decidim/decidim:latest"} - command: ["bin/rails", "server", "-b", "0.0.0.0"] - entrypoint: ["/code/entrypoint.sh"] - pull_policy: always - restart: always - expose: - - 3000 - volumes: - - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper - - ${PWD}/Gemfile.local:/code/Gemfile.local - - ${PWD}/scripts/entrypoint.sh:/code/entrypoint.sh - labels: - - "traefik.enable=true" - - "traefik.http.routers.app.rule=Host(`$DECIDIM_DOMAIN`)" - - "traefik.http.routers.app.entrypoints=web,websecure" - - "traefik.http.routers.app.tls=true" - - "traefik.http.services.app.loadbalancer.server.port=3000" - env_file: - - .env - environment: - - BUNDLE_GEMFILE=Gemfile.wrapper - - DATABASE_URL - - SECRET_KEY_BASE - - DECIDIM_FORCE_SSL=${DECIDIM_FORCE_SSL:-false} - - QUEUE_ADAPTER=${QUEUE_ADAPTER:-sidekiq} - - REDIS_URL=${REDIS_URL:-redis://redis:6379/0} - - WEB_CONCURRENCY=${WEB_CONCURRENCY:-2} - - LOG_LEVEL=${LOG_LEVEL:-info} - - DECIDIM_ENABLE_HTML_HEADER_SNIPPETS - - DECIDIM_ADMIN_PASSWORD_EXPIRATION_DAYS=${DECIDIM_ADMIN_PASSWORD_EXPIRATION_DAYS:-360} - - CHANGE_ACTIVE_STEP=${CHANGE_ACTIVE_STEP:-enabled} - - SEND_REMINDERS=${SEND_REMINDERS:-enabled} - - WEEKLY_NOTIFICATIONS_DIGEST=${WEEKLY_NOTIFICATIONS_DIGEST:-enabled} - - DAILY_NOTIFICATIONS_DIGEST=${DAILY_NOTIFICATIONS_DIGEST:-enabled} - - HEALTHCHECK_EXCLUDE_CHECKS=${HEALTHCHECK_EXCLUDE_CHECKS:-emailconf} - - SMTP_STARTTLS_AUTO=${SMTP_STARTTLS_AUTO:-true} - - SMTP_USERNAME - - SMTP_PASSWORD - - SMTP_ADDRESS - - SMTP_DOMAIN - - SMTP_PORT - - DECIDIM_MAILER_SENDER - - MAPS_API_KEY - - MAPS_PROVIDER=${MAPS_PROVIDER:-here} - - RACK_ATTACK_SECRET diff --git a/install/cache.yml b/install/cache.yml deleted file mode 100644 index 07c908c7..00000000 --- a/install/cache.yml +++ /dev/null @@ -1,12 +0,0 @@ -services: - app: - depends_on: - - cache - cache: - image: redis:8-alpine - container_name: decidim_cache - volumes: - - redis_data:/data - restart: always -volumes: - redis_data: {} diff --git a/install/db.yml b/install/db.yml deleted file mode 100644 index 8bc2d1fc..00000000 --- a/install/db.yml +++ /dev/null @@ -1,13 +0,0 @@ -services: - app: - depends_on: - - db - db: - image: postgres:17-alpine - container_name: decidim_db - env_file: - - .env - environment: - POSTGRES_USER: ${DATABASE_USER:-decidim} - POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-decidim} - POSTGRES_DB: ${DATABASE_NAME:-decidim} diff --git a/install/docker-compose.yml b/install/docker-compose.yml new file mode 100644 index 00000000..73393d1d --- /dev/null +++ b/install/docker-compose.yml @@ -0,0 +1,122 @@ +services: + app: + container_name: decidim + image: ${DECIDIM_IMAGE:-"decidim/decidim:latest"} + command: ["bin/rails", "server", "-b", "0.0.0.0"] + entrypoint: ["/code/entrypoint.sh"] + pull_policy: always + restart: always + depends_on: + - cache + expose: + - 3000 + volumes: + - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper + - ${PWD}/Gemfile.local:/code/Gemfile.local + - ${PWD}/scripts/entrypoint.sh:/code/entrypoint.sh + - storage_data:/code/storage + - migrations_data:/code/db/migrate + labels: + - "traefik.enable=true" + - "traefik.http.routers.app.rule=Host(`$DECIDIM_DOMAIN`)" + - "traefik.http.routers.app.entrypoints=web,websecure" + - "traefik.http.routers.app.tls=true" + - "traefik.http.services.app.loadbalancer.server.port=3000" + env_file: + - .env + environment: + - BUNDLE_GEMFILE=Gemfile.wrapper + - DATABASE_URL + - SECRET_KEY_BASE + - DECIDIM_FORCE_SSL=${DECIDIM_FORCE_SSL:-false} + - QUEUE_ADAPTER=${QUEUE_ADAPTER:-sidekiq} + - REDIS_URL=${REDIS_URL:-redis://redis:6379/0} + - WEB_CONCURRENCY=${WEB_CONCURRENCY:-2} + - LOG_LEVEL=${LOG_LEVEL:-info} + - DECIDIM_ENABLE_HTML_HEADER_SNIPPETS + - DECIDIM_ADMIN_PASSWORD_EXPIRATION_DAYS=${DECIDIM_ADMIN_PASSWORD_EXPIRATION_DAYS:-360} + - CHANGE_ACTIVE_STEP=${CHANGE_ACTIVE_STEP:-enabled} + - SEND_REMINDERS=${SEND_REMINDERS:-enabled} + - WEEKLY_NOTIFICATIONS_DIGEST=${WEEKLY_NOTIFICATIONS_DIGEST:-enabled} + - DAILY_NOTIFICATIONS_DIGEST=${DAILY_NOTIFICATIONS_DIGEST:-enabled} + - HEALTHCHECK_EXCLUDE_CHECKS=${HEALTHCHECK_EXCLUDE_CHECKS:-emailconf} + - SMTP_STARTTLS_AUTO=${SMTP_STARTTLS_AUTO:-true} + - SMTP_USERNAME + - SMTP_PASSWORD + - SMTP_ADDRESS + - SMTP_DOMAIN + - SMTP_PORT + - DECIDIM_MAILER_SENDER + - MAPS_API_KEY + - MAPS_PROVIDER=${MAPS_PROVIDER:-here} + - RACK_ATTACK_SECRET + worker: + image: ${DECIDIM_IMAGE:-decidim/decidim:latest} + command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"] + entrypoint: ["/code/sidekiq_entrypoint.sh"] + pull_policy: always + restart: always + env_file: + - .env + volumes: + - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper + - ${PWD}/Gemfile.local:/code/Gemfile.local + - ${PWD}/scripts/sidekiq_entrypoint.sh:/code/sidekiq_entrypoint.sh + environment: + - BUNDLE_GEMFILE + - DATABASE_URL + - SECRET_KEY_BASE + - DECIDIM_FORCE_SSL=false + - QUEUE_ADAPTER=sidekiq + - REDIS_URL=redis://redis:6379/1 + - SMTP_USERNAME + - SMTP_PASSWORD + - SMTP_ADDRESS + - SMTP_DOMAIN + - SMTP_PORT + links: + - cache + traefik: + image: traefik:v3.6 + container_name: traefik + command: + - --api + - --providers.docker=true + - --log.level=DEBUG + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + - --entrypoints.traefik.address=:8080 + - --entrypoints.web.http.redirections.entryPoint.to=websecure + - --entrypoints.web.http.redirections.entryPoint.scheme=https + ports: + - "80:80" + - "443:443" + restart: unless-stopped + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.service=api@internal" + db: + image: postgres:17-alpine + container_name: decidim_db + profiles: ["db"] + env_file: + - .env + environment: + POSTGRES_USER: ${DATABASE_USER:-decidim} + POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-decidim} + POSTGRES_DB: ${DATABASE_NAME:-decidim} + volumes: + - pg_data:/var/lib/postgresql/data + cache: + image: redis:8-alpine + container_name: decidim_cache + volumes: + - cache_data:/data + restart: always +volumes: + pg_data: {} + cache_data: {} + storage_data: {} + migrations_data: {} diff --git a/install/scripts/entrypoint.sh b/install/scripts/entrypoint.sh index c02d5f99..76f2dae2 100755 --- a/install/scripts/entrypoint.sh +++ b/install/scripts/entrypoint.sh @@ -16,12 +16,15 @@ chgrp -R -h "$USER_GID" "$BUNDLE_PATH" # Check all the gems are installed or fails. bundle check if [ $? -ne 0 ]; then - echo "❌ Gems in Gemfile are not installed, aborting..." + echo "❌ Gems in Gemfile are not installed. Installing them with \"bundle install\"..." bundle install else echo "✅ Gems in Gemfile are installed" fi +# Check to see if there are migrations to install +bundle exec rake railties:install:migrations + # Check no migrations are pending migrations if [ -z "$SKIP_MIGRATIONS" ]; then bundle exec rails db:migrate diff --git a/install/scripts/sidekiq_entrypoint.sh b/install/scripts/sidekiq_entrypoint.sh index a1659c9f..ef08280c 100755 --- a/install/scripts/sidekiq_entrypoint.sh +++ b/install/scripts/sidekiq_entrypoint.sh @@ -1,22 +1,9 @@ #!/bin/sh -x -USER_UID=$(stat -c %u /code/Gemfile) -USER_GID=$(stat -c %g /code/Gemfile) - -export USER_UID -export USER_GID - -usermod -u "$USER_UID" decidim 2>/dev/null -groupmod -g "$USER_GID" decidim 2>/dev/null -usermod -g "$USER_GID" decidim 2>/dev/null - -chown -R -h "$USER_UID" "$BUNDLE_PATH" -chgrp -R -h "$USER_GID" "$BUNDLE_PATH" - # Check all the gems are installed or fails. bundle check if [ $? -ne 0 ]; then - echo "❌ Gems in Gemfile are not installed, aborting..." + echo "❌ Gems in Gemfile are not installed. Installing them with \"bundle install\"..." bundle install else echo "✅ Gems in Gemfile are installed" diff --git a/install/storage.yml b/install/storage.yml deleted file mode 100644 index 9421f935..00000000 --- a/install/storage.yml +++ /dev/null @@ -1,6 +0,0 @@ -services: - app: - volumes: - - storage_volume:/code/storage -volumes: - storage_volume: {} diff --git a/install/traefik.yml b/install/traefik.yml deleted file mode 100644 index e38b8421..00000000 --- a/install/traefik.yml +++ /dev/null @@ -1,22 +0,0 @@ -services: - traefik: - image: traefik:v3.6 - container_name: traefik - command: - - --api - - --providers.docker=true - - --log.level=DEBUG - - --entrypoints.web.address=:80 - - --entrypoints.websecure.address=:443 - - --entrypoints.traefik.address=:8080 - - --entrypoints.web.http.redirections.entryPoint.to=websecure - - --entrypoints.web.http.redirections.entryPoint.scheme=https - ports: - - "80:80" - - "443:443" - restart: unless-stopped - volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - labels: - - "traefik.enable=true" - - "traefik.http.routers.traefik.service=api@internal" diff --git a/install/up.sh b/install/up.sh index 17e35985..4a81fcc9 100644 --- a/install/up.sh +++ b/install/up.sh @@ -10,4 +10,7 @@ if [ "$STORAGE" == 'local' ]; then composes+=" -f storage.yml" fi -sudo docker compose --env-file .env ${composes} up +echo "Starting containers..." +docker compose --env-file .env up -d + +docker compose logs --tail=20 diff --git a/install/worker.yml b/install/worker.yml deleted file mode 100644 index 6691716e..00000000 --- a/install/worker.yml +++ /dev/null @@ -1,22 +0,0 @@ -services: - worker: - image: ${DECIDIM_IMAGE:-decidim/decidim:latest} - command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"] - entrypoint: ["/code/sidekiq_entrypoint.sh"] - pull_policy: always - restart: always - env_file: - - .env - volumes: - - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper - - ${PWD}/Gemfile.local:/code/Gemfile.local - - ${PWD}/scripts/sidekiq_entrypoint.sh:/code/sidekiq_entrypoint.sh - environment: - - BUNDLE_GEMFILE - - DATABASE_URL - - SECRET_KEY_BASE - - DECIDIM_FORCE_SSL=false - - QUEUE_ADAPTER=sidekiq - - REDIS_URL=redis://redis:6379/1 - links: - - cache From cc10b73918fccb03a6821072ec64037d10bdeb85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 27 Nov 2025 17:27:09 +0100 Subject: [PATCH 053/115] some fixes --- install/dependencies/build_env.sh | 18 +++++++++--------- install/install.sh | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 7274dc96..143ef223 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -91,14 +91,14 @@ if [ -f .env ]; then yn=${yn:-Y} case $yn in - [Yy]*) - echo "Deleting .env file." - rm .env - ;; - [Nn]*) - echo "Can't continue without a new .env file" - exit 1; - ;; + [Yy]*) + echo "Deleting .env file." + rm .env + ;; + [Nn]*) + echo "Can't continue without a new .env file" + exit 1 + ;; esac fi @@ -135,7 +135,7 @@ if [ $STORAGE != 'local' ]; then AWS_BUCKET="$AWS_SECRET_ACCESS_KEY" AWS_REGION="$AWS_SECRET_ACCESS_KEY" AWS_ENDPOINT="$AWS_SECRET_ACCESS_KEY" +EOF fi - echo "✅ All environment variables saved to .env successfully!" diff --git a/install/install.sh b/install/install.sh index 056b325f..009f62fa 100644 --- a/install/install.sh +++ b/install/install.sh @@ -88,7 +88,7 @@ echo "Starting Decidim..." source $REPOSITORY_PATH/up.sh # Generate the system admin -source $REPOSITORY_PATH/create_system_admin.sh +source $REPOSITORY_PATH/dependencies/create_system_admin.sh # Close up script echo "Now you should be able to access ${DECIDIM_DOMAIN}/system and log in with the system you already created." From c4806542ddfc14fc19266a21e1a43d796e92f7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Fri, 28 Nov 2025 13:52:49 +0100 Subject: [PATCH 054/115] add certificates and make worker wait for app first --- install/dependencies/build_env.sh | 5 +++++ install/dependencies/create_system_admin.sh | 6 ++++++ install/docker-compose.yml | 19 ++++++++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 143ef223..e6cf803d 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -102,6 +102,9 @@ if [ -f .env ]; then esac fi +# Variable to handle the let's encrypt email. +CERTIFICATE_EMAIL="${CERTIFICATE_EMAIL:-postmaster@${DECIDIM_DOMAIN}}" + echo "✅ Writing the environment variables to .env file..." cat >.env < Date: Fri, 28 Nov 2025 14:12:09 +0100 Subject: [PATCH 055/115] fixes on aws variables --- install/dependencies/build_env.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index e6cf803d..bfcce6de 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -134,12 +134,12 @@ CERTIFICATE_EMAIL="$CERTIFICATE_EMAIL" EOF if [ $STORAGE != 'local' ]; then - cat >>.env <> .env < Date: Wed, 3 Dec 2025 17:36:30 +0100 Subject: [PATCH 056/115] remove wait for healthy --- install/docker-compose.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/install/docker-compose.yml b/install/docker-compose.yml index e9385cff..04bff1de 100644 --- a/install/docker-compose.yml +++ b/install/docker-compose.yml @@ -50,20 +50,11 @@ services: - MAPS_API_KEY - MAPS_PROVIDER=${MAPS_PROVIDER:-here} - RACK_ATTACK_SECRET - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000/"] - interval: 10s - timeout: 5s - retries: 10 - start_period: 30s worker: image: ${DECIDIM_IMAGE:-decidim/decidim:latest} command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"] entrypoint: ["/code/sidekiq_entrypoint.sh"] pull_policy: always - depends_on: - app: - condition: service_healthy restart: always env_file: - .env From df615ea6ac94fffe6d3bf9781acf4d31e4740088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Wed, 3 Dec 2025 17:37:11 +0100 Subject: [PATCH 057/115] add interactivity to some missing commands --- install/install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/install.sh b/install/install.sh index 009f62fa..834dd599 100644 --- a/install/install.sh +++ b/install/install.sh @@ -54,9 +54,9 @@ cp /tmp/decidim-docker/install/deploy.zip $TMP/deploy.zip sudo apt install unzip -y if [ ! -d $REPOSITORY_PATH ]; then - unzip -f $TMP/deploy.zip -d $REPOSITORY_PATH + unzip -f $TMP/deploy.zip -d $REPOSITORY_PATH Date: Tue, 9 Dec 2025 15:48:11 +0100 Subject: [PATCH 058/115] update README --- README.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/README.md b/README.md index 4b0e703a..d3a49f33 100644 --- a/README.md +++ b/README.md @@ -101,3 +101,76 @@ sudo chown -R $(whoami): ${APP_NAME} ``` From here on you can follow the steps on the [Getting Started](https://docs.decidim.org/en/install/) guide. + +## Using a production deploy script + +We've been working on a script that you can use to have a fully functional, production ready decidim instance. + +``` +curl -fsSL https://decidim.org/install | bash +``` + +It will install the necessary tools to make decidim work on your server. + +- Docker +- unzip +- UFW + +The application will be hosted in the `/opt/decidim` directory by default, even though you can change it with `REPOSITOIRY_PATH` + +## App - Main Decidim Web Application +The app itself will be the container with the base image you decide (By default is the latest Decidim version: `decidim/decidim:latest`). You can change it with the `DECIDIM_IMAGE` environment variable. + +This is the front-end web process users access in the browser. + +## Worker +The worker will be the one responsible for all the background jobs that the application needs to run. + +## Cache +The app needs a cache server. This will be a `redis:8-alpine` instance. + +## Database + +The application needs a database to run. Through the installation process you will be asked if you have an already working database, if not, you will have a postgres container with all the schema and migrations run (It will be a `postgres:17-alpine`) + +## Configuration + +To configure the application you will have to answer some questions, that will, at the end, generate a `.env` file. + +### Environment Variables Reference + +| Variable | Default | Used In | Description | +|----------|---------|---------|-------------| +| **BUNDLE_GEMFILE** | `Gemfile.wrapper` | app, worker | Selects which Gemfile the container should use. | +| **DECIDIM_IMAGE** | `decidim/decidim:latest` | app, worker | Overrides the Decidim Docker image version. | +| **DECIDIM_APPLICATION_NAME** | — | app | Application name shown in UI and configuration. | +| **DECIDIM_DOMAIN** | — | app, traefik | Domain for HTTPS routing and URL generation. | +| **SECRET_KEY_BASE** | — | app, worker | Rails secret key used for sessions and cookies. | + +| **DATABASE_NAME** | `decidim` | db | PostgreSQL database name. | +| **DATABASE_USER** | `decidim` | db | PostgreSQL username. | +| **DATABASE_HOST** | `db` | app, worker | Hostname of your PostgreSQL instance. | +| **DATABASE_PASSWORD** | `decidim` | db | PostgreSQL user password. | +| **DATABASE_URL** | — | app, worker | Full PostgreSQL connection URL (overrides other DB vars). | + +| **SMTP_USERNAME** | — | app, worker | Username for SMTP authentication. | +| **SMTP_PASSWORD** | — | app, worker | Password for SMTP authentication. | +| **SMTP_ADDRESS** | — | app, worker | SMTP server hostname. | +| **SMTP_DOMAIN** | — | app, worker | SMTP HELO domain. | +| **SMTP_PORT** | — | app, worker | SMTP port. | +| **SMTP_STARTTLS_AUTO** | `true` | app | Enables STARTTLS automatically. | + +| **REDIS_URL** | `redis://redis:6379/0` | app | Redis URL for cache + sessions. | + +| **VAPID_PUBLIC_KEY** | — | app | Web Push public key for browser notifications. | +| **VAPID_PRIVATE_KEY** | — | app | Web Push private key (keep secret). | + +| **CERTIFICATE_EMAIL** | — | traefik | Email used by Let's Encrypt for certificate issues/renewals. | + +| **WEB_CONCURRENCY** | `2` | app | Puma concurrency setting. | +| **LOG_LEVEL** | `info` | app | Log level for Rails. | +| **DECIDIM_FORCE_SSL** | `false` | app | Enforce HTTPS-only traffic. | +| **MAPS_API_KEY** | — | app | API key for maps provider. | +| **MAPS_PROVIDER** | `here` | app | Selects map provider (here, mapbox, google, etc). | +| **RACK_ATTACK_SECRET** | — | app | Secret key used for Rack::Attack throttling. | + From a7d459ce8b0d1d248ce92325f7000fb6e3e9ae6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 9 Dec 2025 15:48:28 +0100 Subject: [PATCH 059/115] clean up a bit --- install/docker-compose.yml | 7 ------- install/up.sh | 10 ---------- 2 files changed, 17 deletions(-) diff --git a/install/docker-compose.yml b/install/docker-compose.yml index 04bff1de..aef374a8 100644 --- a/install/docker-compose.yml +++ b/install/docker-compose.yml @@ -29,17 +29,10 @@ services: - DATABASE_URL - SECRET_KEY_BASE - DECIDIM_FORCE_SSL=${DECIDIM_FORCE_SSL:-false} - - QUEUE_ADAPTER=${QUEUE_ADAPTER:-sidekiq} - REDIS_URL=${REDIS_URL:-redis://redis:6379/0} - WEB_CONCURRENCY=${WEB_CONCURRENCY:-2} - LOG_LEVEL=${LOG_LEVEL:-info} - DECIDIM_ENABLE_HTML_HEADER_SNIPPETS - - DECIDIM_ADMIN_PASSWORD_EXPIRATION_DAYS=${DECIDIM_ADMIN_PASSWORD_EXPIRATION_DAYS:-360} - - CHANGE_ACTIVE_STEP=${CHANGE_ACTIVE_STEP:-enabled} - - SEND_REMINDERS=${SEND_REMINDERS:-enabled} - - WEEKLY_NOTIFICATIONS_DIGEST=${WEEKLY_NOTIFICATIONS_DIGEST:-enabled} - - DAILY_NOTIFICATIONS_DIGEST=${DAILY_NOTIFICATIONS_DIGEST:-enabled} - - HEALTHCHECK_EXCLUDE_CHECKS=${HEALTHCHECK_EXCLUDE_CHECKS:-emailconf} - SMTP_STARTTLS_AUTO=${SMTP_STARTTLS_AUTO:-true} - SMTP_USERNAME - SMTP_PASSWORD diff --git a/install/up.sh b/install/up.sh index 4a81fcc9..8cb2ab7d 100644 --- a/install/up.sh +++ b/install/up.sh @@ -1,15 +1,5 @@ #!/bin/bash -composes="-f app.yml -f traefik.yml -f cache.yml -f worker.yml " - -if ! $EXTERNAL_DATABASE; then - composes+=" -f db.yml" -fi - -if [ "$STORAGE" == 'local' ]; then - composes+=" -f storage.yml" -fi - echo "Starting containers..." docker compose --env-file .env up -d From 2100eb9a12addbedfed5019946643342340aa00b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 11 Dec 2025 09:54:00 +0100 Subject: [PATCH 060/115] add sidekiq config --- install/config/sidekiq.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 install/config/sidekiq.yml diff --git a/install/config/sidekiq.yml b/install/config/sidekiq.yml new file mode 100644 index 00000000..c9e659c4 --- /dev/null +++ b/install/config/sidekiq.yml @@ -0,0 +1,16 @@ +:concurrency: <%= ENV.fetch("SIDEKIQ_CONCURRENCY", 5) %> +:queues: + - [mailers, 4] + - [vote_reminder, 2] + - [reminders, 2] + - [default, 2] + - [newsletter, 2] + - [newsletters_opt_in, 2] + - [conference_diplomas, 2] + - [events, 2] + - [translations, 2] + - [user_report, 2] + - [block_user, 2] + - [metrics, 1] + - [exports, 1] + - [close_meeting_reminder, 1] From f828cdb2b47d0c2e3afb02c5e50481525de8b520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 11 Dec 2025 09:54:13 +0100 Subject: [PATCH 061/115] add some readme documentation --- README.md | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d3a49f33..bc462e00 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ This is the front-end web process users access in the browser. The worker will be the one responsible for all the background jobs that the application needs to run. ## Cache -The app needs a cache server. This will be a `redis:8-alpine` instance. +The app needs a cache server. This will be a `redis:8-alpine` instance. This cache will be used both by the app and the worker. ## Database @@ -135,42 +135,36 @@ The application needs a database to run. Through the installation process you wi ## Configuration -To configure the application you will have to answer some questions, that will, at the end, generate a `.env` file. +To configure the application you will have to answer some questions that will, at the end, generate a `.env` file. ### Environment Variables Reference +To see the full list of Decidim Environment Variables, and that you can add to your generated `.env` file, you can take a look at the oficial [documentation](https://docs.decidim.org/en/develop/configure/environment_variables) + | Variable | Default | Used In | Description | |----------|---------|---------|-------------| | **BUNDLE_GEMFILE** | `Gemfile.wrapper` | app, worker | Selects which Gemfile the container should use. | | **DECIDIM_IMAGE** | `decidim/decidim:latest` | app, worker | Overrides the Decidim Docker image version. | -| **DECIDIM_APPLICATION_NAME** | — | app | Application name shown in UI and configuration. | | **DECIDIM_DOMAIN** | — | app, traefik | Domain for HTTPS routing and URL generation. | | **SECRET_KEY_BASE** | — | app, worker | Rails secret key used for sessions and cookies. | - | **DATABASE_NAME** | `decidim` | db | PostgreSQL database name. | | **DATABASE_USER** | `decidim` | db | PostgreSQL username. | | **DATABASE_HOST** | `db` | app, worker | Hostname of your PostgreSQL instance. | | **DATABASE_PASSWORD** | `decidim` | db | PostgreSQL user password. | | **DATABASE_URL** | — | app, worker | Full PostgreSQL connection URL (overrides other DB vars). | - | **SMTP_USERNAME** | — | app, worker | Username for SMTP authentication. | | **SMTP_PASSWORD** | — | app, worker | Password for SMTP authentication. | | **SMTP_ADDRESS** | — | app, worker | SMTP server hostname. | -| **SMTP_DOMAIN** | — | app, worker | SMTP HELO domain. | +| **SMTP_DOMAIN** | — | app, worker | SMTP domain. | | **SMTP_PORT** | — | app, worker | SMTP port. | | **SMTP_STARTTLS_AUTO** | `true` | app | Enables STARTTLS automatically. | - -| **REDIS_URL** | `redis://redis:6379/0` | app | Redis URL for cache + sessions. | - +| **REDIS_URL** | `redis://decidim_cache:6379/0` | app | Redis URL for cache + sessions. | | **VAPID_PUBLIC_KEY** | — | app | Web Push public key for browser notifications. | | **VAPID_PRIVATE_KEY** | — | app | Web Push private key (keep secret). | - | **CERTIFICATE_EMAIL** | — | traefik | Email used by Let's Encrypt for certificate issues/renewals. | - | **WEB_CONCURRENCY** | `2` | app | Puma concurrency setting. | | **LOG_LEVEL** | `info` | app | Log level for Rails. | | **DECIDIM_FORCE_SSL** | `false` | app | Enforce HTTPS-only traffic. | | **MAPS_API_KEY** | — | app | API key for maps provider. | | **MAPS_PROVIDER** | `here` | app | Selects map provider (here, mapbox, google, etc). | | **RACK_ATTACK_SECRET** | — | app | Secret key used for Rack::Attack throttling. | - From 9a4fc1dc9ec4d3829752450a0a818929662545e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 11 Dec 2025 09:54:50 +0100 Subject: [PATCH 062/115] shell linting --- install/dependencies/build_env.sh | 58 ++++++++++++--------- install/dependencies/check_docker.sh | 5 +- install/dependencies/create_dependencies.sh | 11 ---- install/dependencies/create_system_admin.sh | 4 +- install/dependencies/decidim_version.sh | 24 +++++---- install/dependencies/generate_gemfile.sh | 2 +- install/dependencies/open_ports.sh | 4 +- install/dependencies/os_version.sh | 4 +- install/docker-compose.yml | 11 ++-- install/install.sh | 2 +- install/up.sh | 2 + 11 files changed, 70 insertions(+), 57 deletions(-) delete mode 100644 install/dependencies/create_dependencies.sh diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index bfcce6de..2c8e85c3 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -6,15 +6,15 @@ BUILD_ENV_PATH="$REPOSITORY_PATH/.env" echo "───────────────────────────────────────────────" echo "📦 Now we need to get some information about the instance you are building." echo -read -p "What are you going to name your instance? " DECIDIM_APPLICATION_NAME .env <"$BUILD_ENV_PATH" <> .env <>"$BUILD_ENV_PATH" <> .env </dev/null 2>&1; then echo "Installing docker..." echo "Once installed it might be necessary to re-run the script so that the changes take up effect." - echo "To do so you can run `newgrp docker`" + echo "To do so you can run 'newgrp docker'" curl -fsSL https://get.docker.com | bash sudo usermod -aG docker "${USER}" - echo "Re-run the script after running `sudo newgrp docker`" + echo "Re-run the script after running 'sudo newgrp docker'" exit 1 else echo "Docker is installed $(docker --version)" fi - diff --git a/install/dependencies/create_dependencies.sh b/install/dependencies/create_dependencies.sh deleted file mode 100644 index 2e44b953..00000000 --- a/install/dependencies/create_dependencies.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -FILES=( - "dependencies/build_env.sh" - "dependencies/check_docker.sh" - "dependencies/decidim_version.sh" - "dependencies/generate_gemfile.sh" - "entrypoint.sh" - "sidekiq_entrypoint.sh" - "up.sh" -) diff --git a/install/dependencies/create_system_admin.sh b/install/dependencies/create_system_admin.sh index 22390219..fceea275 100644 --- a/install/dependencies/create_system_admin.sh +++ b/install/dependencies/create_system_admin.sh @@ -6,7 +6,7 @@ generate_system_admin() { bin/rails decidim_system:create_admin >Gemfile.local fi diff --git a/install/dependencies/open_ports.sh b/install/dependencies/open_ports.sh index 9c63343a..5e032d36 100644 --- a/install/dependencies/open_ports.sh +++ b/install/dependencies/open_ports.sh @@ -1,3 +1,5 @@ +#!/bin/bash + open_ports() { echo echo "To handle the SSL certificate we will have to open the port 80 and the port 443" @@ -17,7 +19,7 @@ open_ports() { echo "───────────────────────────────────────────────" echo "Now we are going to open the necessary ports for Decidim to work ussing UFW." echo -read -p "Can we proceed openning ports 22, 80 and 443? [y/N] " yn /dev/null | grep -Eq "Ubuntu|Debian"; then echo "This installation process must be run on a Debian/Ubuntu distribution." exit 1 fi diff --git a/install/docker-compose.yml b/install/docker-compose.yml index aef374a8..d04c3154 100644 --- a/install/docker-compose.yml +++ b/install/docker-compose.yml @@ -14,6 +14,7 @@ services: - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper - ${PWD}/Gemfile.local:/code/Gemfile.local - ${PWD}/scripts/entrypoint.sh:/code/entrypoint.sh + - app_gems:/usr/local/bundle - storage_data:/code/storage - migrations_data:/code/db/migrate labels: @@ -29,7 +30,7 @@ services: - DATABASE_URL - SECRET_KEY_BASE - DECIDIM_FORCE_SSL=${DECIDIM_FORCE_SSL:-false} - - REDIS_URL=${REDIS_URL:-redis://redis:6379/0} + - REDIS_URL=${REDIS_URL:-redis://decidim_cache:6379/0} - WEB_CONCURRENCY=${WEB_CONCURRENCY:-2} - LOG_LEVEL=${LOG_LEVEL:-info} - DECIDIM_ENABLE_HTML_HEADER_SNIPPETS @@ -42,7 +43,6 @@ services: - DECIDIM_MAILER_SENDER - MAPS_API_KEY - MAPS_PROVIDER=${MAPS_PROVIDER:-here} - - RACK_ATTACK_SECRET worker: image: ${DECIDIM_IMAGE:-decidim/decidim:latest} command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"] @@ -55,6 +55,8 @@ services: - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper - ${PWD}/Gemfile.local:/code/Gemfile.local - ${PWD}/scripts/sidekiq_entrypoint.sh:/code/sidekiq_entrypoint.sh + - ${PWD}/scripts/config/sidekiq.yml:/code/config/sidekiq.yml + - worker_gems:/usr/local/bundle - storage_data:/code/storage - migrations_data:/code/db/migrate environment: @@ -63,12 +65,13 @@ services: - SECRET_KEY_BASE - DECIDIM_FORCE_SSL=false - QUEUE_ADAPTER=sidekiq - - REDIS_URL=redis://redis:6379/1 + - REDIS_URL=${REDIS_URL:-redis://decidim_cache:6379/0} - SMTP_USERNAME - SMTP_PASSWORD - SMTP_ADDRESS - SMTP_DOMAIN - SMTP_PORT + - DECIDIM_MAILER_SENDER links: - cache traefik: @@ -116,6 +119,8 @@ services: - cache_data:/data restart: always volumes: + app_gems: {} + worker_gems: {} pg_data: {} cache_data: {} storage_data: {} diff --git a/install/install.sh b/install/install.sh index 834dd599..2423022e 100644 --- a/install/install.sh +++ b/install/install.sh @@ -44,7 +44,7 @@ if [ ! -d "$REPOSITORY_PATH" ]; then fi TMP=/tmp/decidim-docker-files -if [! -d $TMP]; then +if [ ! -d $TMP ]; then mkdir $TMP fi diff --git a/install/up.sh b/install/up.sh index 8cb2ab7d..04b94575 100644 --- a/install/up.sh +++ b/install/up.sh @@ -4,3 +4,5 @@ echo "Starting containers..." docker compose --env-file .env up -d docker compose logs --tail=20 + +echo "Containers started successfully." From 553c013210dfe2d6ae5de056adf47d7f55c5d509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 16 Dec 2025 13:41:42 +0100 Subject: [PATCH 063/115] remove vagrantfile --- Vagrantfile | 77 ----------------------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 Vagrantfile diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 753f1d84..00000000 --- a/Vagrantfile +++ /dev/null @@ -1,77 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# All Vagrant configuration is done below. The "2" in Vagrant.configure -# configures the configuration version (we support older styles for -# backwards compatibility). Please don't change it unless you know what -# you're doing. -Vagrant.configure("2") do |config| - # The most common configuration options are documented and commented below. - # For a complete reference, please see the online documentation at - # https://docs.vagrantup.com. - - # Every Vagrant development environment requires a box. You can search for - # boxes at https://vagrantcloud.com/search. - config.vm.box = "debian/bookworm64" - - # Disable automatic box update checking. If you disable this, then - # boxes will only be checked for updates when the user runs - # `vagrant box outdated`. This is not recommended. - # config.vm.box_check_update = false - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - # NOTE: This will enable public access to the opened port - config.vm.network "forwarded_port", guest: 80, host: 8080 - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine and only allow access - # via 127.0.0.1 to disable public access - # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - # config.vm.network "private_network", ip: "192.168.33.10" - - # Create a public network, which generally matched to bridged network. - # Bridged networks make the machine appear as another physical device on - # your network. - # config.vm.network "public_network" - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - # config.vm.synced_folder "../data", "/vagrant_data" - - # Disable the default share of the current code directory. Doing this - # provides improved isolation between the vagrant box and your host - # by making sure your Vagrantfile isn't accessible to the vagrant box. - # If you use this you may want to enable additional shared subfolders as - # shown above. - # config.vm.synced_folder ".", "/vagrant", disabled: true - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - config.vm.provider "virtualbox" do |vb| - # Display the VirtualBox GUI when booting the machine - vb.gui = false - - # Customize the amount of memory on the VM: - vb.memory = "2048" - end - - # View the documentation for the provider you are using for more - # information on available options. - - # Enable provisioning with a shell script. Additional provisioners such as - # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the - # documentation for more information about their specific syntax and use. - config.vm.provision "shell", inline: <<-SHELL - apt-get update - apt-get install -y curl - SHELL -end From a65ab0bab9d073ec082356ebc82de6eb2ed313b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 16 Dec 2025 15:38:20 +0100 Subject: [PATCH 064/115] improve messages to choose decidim version --- install/dependencies/decidim_version.sh | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/install/dependencies/decidim_version.sh b/install/dependencies/decidim_version.sh index 4dbf3e8b..b6f93684 100644 --- a/install/dependencies/decidim_version.sh +++ b/install/dependencies/decidim_version.sh @@ -1,14 +1,22 @@ #!/bin/bash echo "───────────────────────────────────────────────" -echo "📦 What version of Decidim do you want to use?" +echo "📦 Choose Your Decidim Version" echo -echo "The default image is: decidim/decidim:latest" +echo "💡 About Decidim versions:" +echo " • latest - Most recent stable release (recommended)" +echo " • 0.30, 0.28, etc. - Specific stable versions" +echo " • Custom images - Your own modified Decidim builds" echo -echo "You can also specify a custom image, for example:" -echo " • decidim/decidim:0.30" -echo " • ghcr.io/decidim/decidim:0.28" -echo " • ghcr.io/my-org/custom-decidim:1.0.0" +echo "Default image: decidim/decidim:latest" +echo +echo "Example options:" +echo " • decidim/decidim:latest (official stable)" +echo " • decidim/decidim:0.30 (specific version)" +echo " • ghcr.io/decidim/decidim:0.28 (GitHub Container Registry)" +echo " • ghcr.io/my-org/custom-decidim:1.0.0 (your custom build)" +echo +echo "🔍 Want to see available versions? Check: https://hub.docker.com/r/decidim/decidim/tags" echo while true; do From 5ec5764e014ca81c80e5dd72f52ca4d3cd183d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 16 Dec 2025 15:40:37 +0100 Subject: [PATCH 065/115] add more context to vapid and export vars --- install/dependencies/generate_vapid_keys.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/install/dependencies/generate_vapid_keys.sh b/install/dependencies/generate_vapid_keys.sh index 3d3524cf..4dc68a46 100644 --- a/install/dependencies/generate_vapid_keys.sh +++ b/install/dependencies/generate_vapid_keys.sh @@ -1,12 +1,28 @@ #!/bin/bash set -e -echo "Generating VAPID keys" +set -u +set -o pipefail + +echo "🔐 Generating VAPID keys..." + +# Check if DECIDIM_IMAGE is set +if [ -z "${DECIDIM_IMAGE:-}" ]; then + echo "❌ Error: DECIDIM_IMAGE is not set" + exit 1 +fi + output=$(docker run --rm \ "$DECIDIM_IMAGE" \ bin/rails decidim:pwa:generate_vapid_keys) -echo "The VAPID keys have been generated correctly" +echo "✅ The VAPID keys have been generated correctly" VAPID_PUBLIC_KEY=$(echo "$output" | grep 'VAPID_PUBLIC_KEY' | cut -d'=' -f2) VAPID_PRIVATE_KEY=$(echo "$output" | grep 'VAPID_PRIVATE_KEY' | cut -d'=' -f2) + +# Export the keys for use by calling script +export VAPID_PUBLIC_KEY +export VAPID_PRIVATE_KEY + +echo "🔑 Keys successfully extracted" From 712467f6c79055d3cc3c59188d8afb836715d81a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 16 Dec 2025 15:41:18 +0100 Subject: [PATCH 066/115] change check of decidim running to create system admin --- install/dependencies/create_system_admin.sh | 23 +++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/install/dependencies/create_system_admin.sh b/install/dependencies/create_system_admin.sh index fceea275..09636254 100644 --- a/install/dependencies/create_system_admin.sh +++ b/install/dependencies/create_system_admin.sh @@ -1,4 +1,7 @@ #!/bin/bash +set -e +set -u +set -o pipefail generate_system_admin() { docker exec -ti \ @@ -14,10 +17,10 @@ if [ -z "$EXTERNAL_DATABASE" ]; then done fi -echo "Waiting for decidim application to be running" -until docker ps --filter "name=decidim" --filter "status=running" --quiet; do - echo "Container is not running yet..." - sleep 2 +# Simple health check for Rails server +until docker exec -ti decidim curl -s http://localhost:3000 >/dev/null; do + echo "Waiting for Rails server to start..." + sleep 5 done echo "Container is running correctly... Now we are going to create the system admin." @@ -25,6 +28,14 @@ echo "Container is running correctly... Now we are going to create the system ad generate_system_admin if [ $? -eq 1 ]; then - echo "Seems like there was a problem. Try again." - echo "Just execute \"docker exec -ti decidim bin/rails decidim_system_create_admin\"" + echo "❌ Seems like there was a problem creating the system admin." + echo + echo "🔧 Troubleshooting:" + echo " • Try running the command manually:" + echo " docker exec -ti decidim bin/rails decidim_system:create_admin" + echo " • Review the logs for any errors:" + echo " docker compose logs decidim" +else + echo "✅ System administrator created successfully!" + echo "📍 You can now access the admin panel at: https://${DECIDIM_DOMAIN}/system" fi From 6750e1c3589524393995e322a9f5dcd269d78c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 16 Dec 2025 15:41:54 +0100 Subject: [PATCH 067/115] Improve messages and flow of docker installation --- install/dependencies/check_docker.sh | 39 +++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/install/dependencies/check_docker.sh b/install/dependencies/check_docker.sh index 5f8f133b..59a1e03e 100644 --- a/install/dependencies/check_docker.sh +++ b/install/dependencies/check_docker.sh @@ -1,17 +1,42 @@ #!/bin/bash set -e +set -u +set -o pipefail if ! command -v docker >/dev/null 2>&1; then - echo "Installing docker..." - echo "Once installed it might be necessary to re-run the script so that the changes take up effect." - echo "To do so you can run 'newgrp docker'" + echo "🐳 Docker not found. Installing Docker..." + echo "⚠️ After installation, you'll need to re-run this script for changes to take effect." + echo "💡 You can run 'newgrp docker' to activate Docker group membership." - curl -fsSL https://get.docker.com | bash + if ! curl -fsSL https://get.docker.com | bash; then + echo "❌ Failed to install Docker" + exit 1 + fi - sudo usermod -aG docker "${USER}" - echo "Re-run the script after running 'sudo newgrp docker'" + if ! sudo usermod -aG docker "${USER}"; then + echo "❌ Failed to add user to Docker group" + exit 1 + fi + + echo "" + echo "🔄 Docker installation completed!" + echo "📋 Next steps:" + echo " 1. Log out and log back in, OR run: 'newgrp docker'" + echo " 2. Re-run this installation script" + echo "" + echo "⏹️ Exiting for user session refresh..." exit 1 else - echo "Docker is installed $(docker --version)" + echo "✅ Docker is installed: $(docker --version)" + + # Check if user can run docker commands + if ! docker info >/dev/null 2>&1; then + echo "⚠️ Docker is installed but current user cannot run Docker commands." + echo "💡 Try running: 'newgrp docker' or log out and log back in." + echo " If that doesn't work, you may need to: 'sudo usermod -aG docker \$USER'" + exit 1 + fi + + echo "✅ Docker is accessible for current user" fi From dccb70b8852707edfcbcd9e5605785442fb83724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 16 Dec 2025 15:42:41 +0100 Subject: [PATCH 068/115] change messages of up.sh --- install/up.sh | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/install/up.sh b/install/up.sh index 04b94575..892685b4 100644 --- a/install/up.sh +++ b/install/up.sh @@ -1,8 +1,23 @@ #!/bin/bash +set -e +set -u +set -o pipefail -echo "Starting containers..." -docker compose --env-file .env up -d +ENV_FILE="${REPOSITORY_PATH}/.env" -docker compose logs --tail=20 +# Check if .env file exists +if [ ! -f "$ENV_FILE" ]; then + echo "❌ Error: .env file not found at $ENV_FILE" + echo " Please run the installation script first or create the .env file manually." + exit 1 +fi -echo "Containers started successfully." +echo "🚀 Starting Decidim containers..." + +docker compose --env-file "$ENV_FILE" up -d + +echo "📋 Showing recent container logs..." +docker compose logs --tail=30 + +echo "✅ Containers started successfully!" +echo "🔍 You can monitor logs with: docker compose logs -f" From 26ebc1fbb9e09d61e63f137ea189eb127bbe09c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 16 Dec 2025 15:44:18 +0100 Subject: [PATCH 069/115] add new messages and bash fixes --- install/install.sh | 129 +++++++++++++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 41 deletions(-) diff --git a/install/install.sh b/install/install.sh index 2423022e..71794833 100644 --- a/install/install.sh +++ b/install/install.sh @@ -14,17 +14,25 @@ # along with this program. If not, see . # +set -e +set -u +set -o pipefail + echo -e "***********************************************************************" -echo -e "* This script will try to install Decidim on this machine. *" -echo -e "* Take into account that it will ask for some information that *" -echo -e "* you will have to provide. Also it will take care of installing *" -echo -e "* all necessary dependencies, such as *docker*, *git*, etc. *" +echo -e "* 🚀 Welcome to Decidim Installation Script! *" +echo -e "* *" +echo -e "* This script will install Decidim on this machine and guide you *" +echo -e "* through the complete configuration process. *" echo -e "* *" -echo -e "* You will be guided throughout the script and will be able to *" -echo -e "* stop it and restart it if necessary. *" +echo -e "* You'll need to provide: *" +echo -e "* • Instance name and domain *" +echo -e "* • Database configuration (local or external) *" +echo -e "* • SMTP server settings for emails *" +echo -e "* • File storage settings (local or S3) *" echo -e "* *" -echo -e "* It's not in a production-ready state. There's not guarantee *" -echo -e "* and it's up to you to take care of your systems. *" +echo -e "* 💡 All dependencies (Docker, etc.) will be installed for you *" +echo -e "* *" +echo -e "* ⚠️ For production use, review security settings and documentation. *" echo -e "* *" echo -e "***********************************************************************" @@ -32,64 +40,103 @@ REPOSITORY_PATH=${DECIDIM_PATH:-/opt/decidim} REPOSITORY_URL="https://github.com/decidim/docker.git" REPOSITORY_BRANCH="feat/decidim_install" -echo $REPOSITORY_PATH - -set -e +echo "📁 Installation directory: $REPOSITORY_PATH" -trap "You can re-run this script to restart the installation", ERR +trap 'echo "❌ Error occurred at line $LINENO. You can re-run this script to restart the installation."' ERR if [ ! -d "$REPOSITORY_PATH" ]; then - sudo mkdir -p "$REPOSITORY_PATH" - sudo chown "$USER":"$USER" "$REPOSITORY_PATH" + echo "📁 Creating installation directory: $REPOSITORY_PATH" + if ! sudo mkdir -p "$REPOSITORY_PATH"; then + echo "❌ Failed to create directory $REPOSITORY_PATH" + exit 1 + fi + if ! sudo chown "$USER":"$USER" "$REPOSITORY_PATH"; then + echo "❌ Failed to set ownership of $REPOSITORY_PATH" + exit 1 + fi fi -TMP=/tmp/decidim-docker-files -if [ ! -d $TMP ]; then - mkdir $TMP +TMP="/tmp/decidim-docker-files" +if [ ! -d "$TMP" ]; then + mkdir "$TMP" fi -echo "Downloading the installation necessary files." +echo "📥 Downloading the installation necessary files." #curl -L -o "$TMP/deploy.tar.gz" "$REPOSITORY_URL/releases/latest/download/deploy_bundle.zip" -cp /tmp/decidim-docker/install/deploy.zip $TMP/deploy.zip -sudo apt install unzip -y +cp /tmp/decidim-docker/install/deploy.zip "$TMP/deploy.zip" + +echo "📦 Installing unzip package..." +if ! sudo apt update && sudo apt install unzip -y; then + echo "❌ Failed to install unzip package" + exit 1 +fi -if [ ! -d $REPOSITORY_PATH ]; then - unzip -f $TMP/deploy.zip -d $REPOSITORY_PATH Date: Tue, 16 Dec 2025 15:46:42 +0100 Subject: [PATCH 070/115] refactor and add maps envs --- install/dependencies/build_env.sh | 167 ++++++++++++++++++++++++++---- 1 file changed, 147 insertions(+), 20 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 2c8e85c3..aa68c4d9 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -1,23 +1,61 @@ #!/bin/bash -set -e # exit on error +set -e +set -u +set -o pipefail BUILD_ENV_PATH="$REPOSITORY_PATH/.env" +if [ -z "${REPOSITORY_PATH:-}" ]; then + echo "❌ Error: REPOSITORY_PATH is not set" + exit 1 +fi + +echo "───────────────────────────────────────────────" +echo "🔧 Environment Configuration Phase" +echo " We'll now collect all the information needed to configure your Decidim instance." +echo " All responses will be saved in a .env file that you can edit later." +echo +echo "📝 Information we'll collect:" +echo " • Instance details (name, domain)" +echo " • Database settings (local PostgreSQL or external)" +echo " • Email configuration (SMTP server)" +echo " • File storage (local filesystem or S3 bucket)" +echo " • Security keys (auto-generated)" +echo +echo "💡 Don't worry if you don't have all the details ready!" +echo " You can always modify the .env file after installation." +echo +echo "Press Enter to continue..." +read "$BUILD_ENV_PATH" < Date: Tue, 16 Dec 2025 15:46:52 +0100 Subject: [PATCH 071/115] remove env var --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index bc462e00..8159ba3a 100644 --- a/README.md +++ b/README.md @@ -167,4 +167,3 @@ To see the full list of Decidim Environment Variables, and that you can add to y | **DECIDIM_FORCE_SSL** | `false` | app | Enforce HTTPS-only traffic. | | **MAPS_API_KEY** | — | app | API key for maps provider. | | **MAPS_PROVIDER** | `here` | app | Selects map provider (here, mapbox, google, etc). | -| **RACK_ATTACK_SECRET** | — | app | Secret key used for Rack::Attack throttling. | From 5344a7bd0935a7fe9f876cdf68ef5fcba5a8364c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 16 Dec 2025 15:58:11 +0100 Subject: [PATCH 072/115] shellcheck fixes --- install/dependencies/build_env.sh | 17 ++++------------- install/dependencies/open_ports.sh | 2 +- install/install.sh | 3 +++ install/scripts/entrypoint.sh | 5 ++--- install/scripts/sidekiq_entrypoint.sh | 5 ++--- 5 files changed, 12 insertions(+), 20 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index aa68c4d9..1e68bf0e 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -26,7 +26,7 @@ echo "💡 Don't worry if you don't have all the details ready!" echo " You can always modify the .env file after installation." echo echo "Press Enter to continue..." -read Date: Tue, 16 Dec 2025 16:02:33 +0100 Subject: [PATCH 073/115] shellcheck 1091 --- install/dependencies/build_env.sh | 2 +- install/install.sh | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 1e68bf0e..ddc382b7 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -177,7 +177,7 @@ esac echo "───────────────────────────────────────────────" echo "🔐 Security Configuration" echo " Generating VAPID keys for secure push notifications..." -source "$REPOSITORY_PATH/dependencies/generate_vapid_keys.sh" +source "./dependencies/generate_vapid_keys.sh" echo "───────────────────────────────────────────────" echo "Maps and Geocoding Configuration" diff --git a/install/install.sh b/install/install.sh index 140d862e..5cf550f9 100644 --- a/install/install.sh +++ b/install/install.sh @@ -93,32 +93,32 @@ if ! cd "$REPOSITORY_PATH"; then fi echo "🔍 Checking the OS version..." -source "$REPOSITORY_PATH/dependencies/os_version.sh" +source "./dependencies/os_version.sh" # Check if docker is installed, if not install it echo "🐳 Checking if Docker is installed..." -source "$REPOSITORY_PATH/dependencies/check_docker.sh" +source "./dependencies/check_docker.sh" # Checking which Decidim version does the user want echo "📦 Checking the Decidim version to use..." -source "$REPOSITORY_PATH/dependencies/decidim_version.sh" +source "./dependencies/decidim_version.sh" # Open necessary ports echo "🔌 Opening necessary server ports..." -source "$REPOSITORY_PATH/dependencies/open_ports.sh" +source "./dependencies/open_ports.sh" # Build environment variables -source "$REPOSITORY_PATH/dependencies/build_env.sh" +source "./dependencies/build_env.sh" echo "🔧 Building dependencies..." -source "$REPOSITORY_PATH/dependencies/generate_gemfile.sh" +source "./dependencies/generate_gemfile.sh" # Start decidim echo "🚀 Starting Decidim..." -source "$REPOSITORY_PATH/up.sh" +source "./up.sh" # Generate the system admin -source "$REPOSITORY_PATH/dependencies/create_system_admin.sh" +source "./dependencies/create_system_admin.sh" # Close up script echo "───────────────────────────────────────────────" From 39315908b147509d9350c6d7e0c020f314297ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 16 Dec 2025 16:17:27 +0100 Subject: [PATCH 074/115] disable sc1091 --- install/dependencies/build_env.sh | 1 + install/install.sh | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index ddc382b7..d390c512 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -177,6 +177,7 @@ esac echo "───────────────────────────────────────────────" echo "🔐 Security Configuration" echo " Generating VAPID keys for secure push notifications..." +# shellcheck disable=SC1091 source "./dependencies/generate_vapid_keys.sh" echo "───────────────────────────────────────────────" diff --git a/install/install.sh b/install/install.sh index 5cf550f9..ec01604f 100644 --- a/install/install.sh +++ b/install/install.sh @@ -93,31 +93,39 @@ if ! cd "$REPOSITORY_PATH"; then fi echo "🔍 Checking the OS version..." +# shellcheck disable=SC1091 source "./dependencies/os_version.sh" # Check if docker is installed, if not install it echo "🐳 Checking if Docker is installed..." +# shellcheck disable=SC1091 source "./dependencies/check_docker.sh" # Checking which Decidim version does the user want echo "📦 Checking the Decidim version to use..." +# shellcheck disable=SC1091 source "./dependencies/decidim_version.sh" # Open necessary ports echo "🔌 Opening necessary server ports..." +# shellcheck disable=SC1091 source "./dependencies/open_ports.sh" # Build environment variables +# shellcheck disable=SC1091 source "./dependencies/build_env.sh" echo "🔧 Building dependencies..." +# shellcheck disable=SC1091 source "./dependencies/generate_gemfile.sh" # Start decidim echo "🚀 Starting Decidim..." +# shellcheck disable=SC1091 source "./up.sh" # Generate the system admin +# shellcheck disable=SC1091 source "./dependencies/create_system_admin.sh" # Close up script From 96ac72f376dc4445d40d063d6f0b9e880c366a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 18 Dec 2025 16:20:45 +0100 Subject: [PATCH 075/115] fixes on certs and health_check --- install/dependencies/create_system_admin.sh | 4 ++-- install/docker-compose.yml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/install/dependencies/create_system_admin.sh b/install/dependencies/create_system_admin.sh index 09636254..63e606a2 100644 --- a/install/dependencies/create_system_admin.sh +++ b/install/dependencies/create_system_admin.sh @@ -18,9 +18,9 @@ if [ -z "$EXTERNAL_DATABASE" ]; then fi # Simple health check for Rails server -until docker exec -ti decidim curl -s http://localhost:3000 >/dev/null; do +until docker exec decidim curl -s http://localhost:3000/up >/dev/null; do echo "Waiting for Rails server to start..." - sleep 5 + sleep 10 done echo "Container is running correctly... Now we are going to create the system admin." diff --git a/install/docker-compose.yml b/install/docker-compose.yml index d04c3154..51490e6d 100644 --- a/install/docker-compose.yml +++ b/install/docker-compose.yml @@ -22,6 +22,7 @@ services: - "traefik.http.routers.app.rule=Host(`$DECIDIM_DOMAIN`)" - "traefik.http.routers.app.entrypoints=websecure" - "traefik.http.routers.app.tls=true" + - "traefik.http.routers.app.tls.certresolver=myresolver" - "traefik.http.services.app.loadbalancer.server.port=3000" env_file: - .env @@ -45,6 +46,7 @@ services: - MAPS_PROVIDER=${MAPS_PROVIDER:-here} worker: image: ${DECIDIM_IMAGE:-decidim/decidim:latest} + container_name: decidim_worker command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"] entrypoint: ["/code/sidekiq_entrypoint.sh"] pull_policy: always From 7aa5159cbb8964ed64c7afa4c3ce36c2b5163709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 18 Dec 2025 17:00:13 +0100 Subject: [PATCH 076/115] update release zip url --- install/install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/install.sh b/install/install.sh index ec01604f..c14fbb17 100644 --- a/install/install.sh +++ b/install/install.sh @@ -65,11 +65,10 @@ if [ ! -d "$TMP" ]; then fi echo "📥 Downloading the installation necessary files." -#curl -L -o "$TMP/deploy.tar.gz" "$REPOSITORY_URL/releases/latest/download/deploy_bundle.zip" -cp /tmp/decidim-docker/install/deploy.zip "$TMP/deploy.zip" +curl -L -o "$TMP/deploy.zip" "$REPOSITORY_URL/releases/download/latest/deploy.zip" echo "📦 Installing unzip package..." -if ! sudo apt update && sudo apt install unzip -y; then +if ! (sudo apt update && sudo apt install unzip -y); then echo "❌ Failed to install unzip package" exit 1 fi From 5fa1536610c212061898957461aa3cd4384ad8e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 18 Dec 2025 17:12:51 +0100 Subject: [PATCH 077/115] improve and fix zip download --- install/install.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/install/install.sh b/install/install.sh index c14fbb17..3f33d323 100644 --- a/install/install.sh +++ b/install/install.sh @@ -37,7 +37,7 @@ echo -e "* * echo -e "***********************************************************************" REPOSITORY_PATH=${DECIDIM_PATH:-/opt/decidim} -REPOSITORY_URL="https://github.com/decidim/docker.git" +REPOSITORY_URL="https://github.com/decidim/docker" REPOSITORY_BRANCH="feat/decidim_install" export REPOSITORY_URL @@ -65,7 +65,14 @@ if [ ! -d "$TMP" ]; then fi echo "📥 Downloading the installation necessary files." -curl -L -o "$TMP/deploy.zip" "$REPOSITORY_URL/releases/download/latest/deploy.zip" +curl -fsSL \ + --retry 3 \ + --retry-delay 2 \ + --connect-timeout 30 \ + --max-time 300 \ + --progress-bar \ + -o "$TMP/deploy.zip" \ + "$REPOSITORY_URL/releases/download/latest/deploy.zip" echo "📦 Installing unzip package..." if ! (sudo apt update && sudo apt install unzip -y); then From 75b462c0edfb0e572af5f946d703debffe7c75c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 22 Dec 2025 11:29:54 +0100 Subject: [PATCH 078/115] force overrite of extracted files --- install/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/install.sh b/install/install.sh index 3f33d323..8837f428 100644 --- a/install/install.sh +++ b/install/install.sh @@ -82,7 +82,7 @@ fi echo "📂 Extracting files to $REPOSITORY_PATH..." if [ ! -d "$REPOSITORY_PATH" ]; then - if ! unzip -u "$TMP/deploy.zip" -d "$REPOSITORY_PATH" Date: Mon, 22 Dec 2025 12:02:06 +0100 Subject: [PATCH 079/115] add minor improvements --- install/dependencies/build_env.sh | 6 +++--- install/install.sh | 13 +++---------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index d390c512..c10260a1 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -31,13 +31,13 @@ read -r Date: Mon, 22 Dec 2025 12:49:28 +0100 Subject: [PATCH 080/115] remove pull_policy --- install/docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/install/docker-compose.yml b/install/docker-compose.yml index 51490e6d..905ded49 100644 --- a/install/docker-compose.yml +++ b/install/docker-compose.yml @@ -4,7 +4,6 @@ services: image: ${DECIDIM_IMAGE:-"decidim/decidim:latest"} command: ["bin/rails", "server", "-b", "0.0.0.0"] entrypoint: ["/code/entrypoint.sh"] - pull_policy: always restart: always depends_on: - cache From 9e7b7b80b28d066d5d3c402fdcb828633f5bbfdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 22 Dec 2025 12:50:59 +0100 Subject: [PATCH 081/115] open ports by default --- install/dependencies/open_ports.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/dependencies/open_ports.sh b/install/dependencies/open_ports.sh index 44df9725..fce59011 100644 --- a/install/dependencies/open_ports.sh +++ b/install/dependencies/open_ports.sh @@ -18,9 +18,10 @@ open_ports() { echo "───────────────────────────────────────────────" echo "Now we are going to open the necessary ports for Decidim to work ussing UFW." +echo "This is a standard practice to protect your server." echo -read -r -p "Can we proceed openning ports 22, 80 and 443? [y/N] " yn Date: Mon, 22 Dec 2025 12:53:37 +0100 Subject: [PATCH 082/115] remove option to change decidim version, only install latest --- install/dependencies/decidim_version.sh | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/install/dependencies/decidim_version.sh b/install/dependencies/decidim_version.sh index b6f93684..2908b405 100644 --- a/install/dependencies/decidim_version.sh +++ b/install/dependencies/decidim_version.sh @@ -1,26 +1,19 @@ #!/bin/bash echo "───────────────────────────────────────────────" -echo "📦 Choose Your Decidim Version" +echo "📦 Decidim version" echo echo "💡 About Decidim versions:" echo " • latest - Most recent stable release (recommended)" -echo " • 0.30, 0.28, etc. - Specific stable versions" echo " • Custom images - Your own modified Decidim builds" echo -echo "Default image: decidim/decidim:latest" -echo -echo "Example options:" -echo " • decidim/decidim:latest (official stable)" -echo " • decidim/decidim:0.30 (specific version)" -echo " • ghcr.io/decidim/decidim:0.28 (GitHub Container Registry)" -echo " • ghcr.io/my-org/custom-decidim:1.0.0 (your custom build)" +echo "If you want, later on, you can modify the 'docker-compose.yml' to change the Decidim version" echo -echo "🔍 Want to see available versions? Check: https://hub.docker.com/r/decidim/decidim/tags" +echo "Default image: decidim/decidim:latest" echo while true; do - read -r -p "👉 Enter the Decidim image (or press Enter to use the default): " DECIDIM_IMAGE Date: Mon, 22 Dec 2025 13:01:15 +0100 Subject: [PATCH 083/115] automatically create system password --- install/dependencies/create_system_admin.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/install/dependencies/create_system_admin.sh b/install/dependencies/create_system_admin.sh index 63e606a2..4fedd9cd 100644 --- a/install/dependencies/create_system_admin.sh +++ b/install/dependencies/create_system_admin.sh @@ -4,9 +4,15 @@ set -u set -o pipefail generate_system_admin() { + # docker exec -ti \ + # decidim \ + # bin/rails decidim_system:create_admin Date: Wed, 7 Jan 2026 09:53:01 +0100 Subject: [PATCH 084/115] fix generate system --- install/dependencies/create_system_admin.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/install/dependencies/create_system_admin.sh b/install/dependencies/create_system_admin.sh index 4fedd9cd..0c4a5d20 100644 --- a/install/dependencies/create_system_admin.sh +++ b/install/dependencies/create_system_admin.sh @@ -4,15 +4,12 @@ set -u set -o pipefail generate_system_admin() { - # docker exec -ti \ - # decidim \ - # bin/rails decidim_system:create_admin Date: Thu, 22 Jan 2026 10:14:34 +0100 Subject: [PATCH 085/115] fix typos --- install/dependencies/create_system_admin.sh | 2 +- install/dependencies/decidim_version.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/install/dependencies/create_system_admin.sh b/install/dependencies/create_system_admin.sh index 0c4a5d20..4296aa03 100644 --- a/install/dependencies/create_system_admin.sh +++ b/install/dependencies/create_system_admin.sh @@ -5,7 +5,7 @@ set -o pipefail generate_system_admin() { read -r -p "email: " SYSTEM_EMAIL Date: Thu, 22 Jan 2026 10:40:58 +0100 Subject: [PATCH 086/115] Update install/scripts/entrypoint.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/scripts/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/scripts/entrypoint.sh b/install/scripts/entrypoint.sh index 693f47c4..f40de5d0 100755 --- a/install/scripts/entrypoint.sh +++ b/install/scripts/entrypoint.sh @@ -28,7 +28,7 @@ bundle exec rake railties:install:migrations if [ -z "$SKIP_MIGRATIONS" ]; then bundle exec rails db:migrate else - echo "⚠️ Skipping migrations" + echo "⚠️ Skipping migrations!" fi echo "✅ Migrations are all up" From 2bce55a6864859b9b6b524a1c9a0c92af564b608 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 22 Jan 2026 10:41:16 +0100 Subject: [PATCH 087/115] Update install/install.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/install.sh b/install/install.sh index 34e85ba1..a22d95de 100644 --- a/install/install.sh +++ b/install/install.sh @@ -30,7 +30,7 @@ echo -e "* • Database configuration (local or external) echo -e "* • SMTP server settings for emails *" echo -e "* • File storage settings (local or S3) *" echo -e "* *" -echo -e "* 💡 All dependencies (Docker, etc.) will be installed for you *" +echo -e "* 💡 All dependencies (Docker, etc) will be installed for you. *" echo -e "* *" echo -e "* ⚠️ For production use, review security settings and documentation. *" echo -e "* *" From fc9dd766e099d5c0d43dad97987645da4cd1cb90 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 22 Jan 2026 10:41:31 +0100 Subject: [PATCH 088/115] Update install/up.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/up.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/up.sh b/install/up.sh index 892685b4..513ee4db 100644 --- a/install/up.sh +++ b/install/up.sh @@ -8,7 +8,7 @@ ENV_FILE="${REPOSITORY_PATH}/.env" # Check if .env file exists if [ ! -f "$ENV_FILE" ]; then echo "❌ Error: .env file not found at $ENV_FILE" - echo " Please run the installation script first or create the .env file manually." + echo "Please run the installation script first or create the .env file manually." exit 1 fi From 8cf9f5ad8b424a07640dfa775fdeaa83e0521bd4 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 22 Jan 2026 10:41:43 +0100 Subject: [PATCH 089/115] Update install/install.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/install.sh b/install/install.sh index a22d95de..b4e3315a 100644 --- a/install/install.sh +++ b/install/install.sh @@ -64,7 +64,7 @@ if [ ! -d "$TMP" ]; then mkdir "$TMP" fi -echo "📥 Downloading the installation necessary files." +echo "📥 Downloading the necessary installation files." curl -fsSL \ --retry 3 \ --retry-delay 2 \ From b9e594199bfdcb6bb9aeafc18b6cda724e14e585 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 22 Jan 2026 10:42:01 +0100 Subject: [PATCH 090/115] Update install/up.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/up.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/up.sh b/install/up.sh index 513ee4db..07ff5ee4 100644 --- a/install/up.sh +++ b/install/up.sh @@ -16,7 +16,7 @@ echo "🚀 Starting Decidim containers..." docker compose --env-file "$ENV_FILE" up -d -echo "📋 Showing recent container logs..." +echo "📋 Displaying recent container logs..." docker compose logs --tail=30 echo "✅ Containers started successfully!" From f698509c89fa861fbcf3a6ca47b92db7e2a73414 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 22 Jan 2026 10:44:00 +0100 Subject: [PATCH 091/115] Update install/install.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/install.sh b/install/install.sh index b4e3315a..bc9fdf50 100644 --- a/install/install.sh +++ b/install/install.sh @@ -149,4 +149,4 @@ echo "📚 Documentation: https://docs.decidim.org" echo "🐛 Issues: https://github.com/decidim/decidim/issues" echo "🐛 Installation Issues: https://github.com/decidim/docker/issues" echo -echo "Have fun using Decidim! 🗳️" +echo "Enjoy using Decidim! 🗳️" From c18e59ed1bb6fdc74106847e7a033ce3da304a55 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 22 Jan 2026 10:44:25 +0100 Subject: [PATCH 092/115] Update install/dependencies/build_env.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/dependencies/build_env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index c10260a1..3d5290b9 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -77,7 +77,7 @@ build_local_database() { build_external_database() { echo "📋 External Database Configuration" echo " Please provide your external database details:" - echo " 💡 Make sure your database server allows connections from this machine" + echo " 💡 Make sure your database server allows connections from this machine." echo while [ -z "${DATABASE_NAME:-}" ]; do From 47b2a838e29ff517377a05d23599c6a5bd8a0c87 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 22 Jan 2026 10:44:44 +0100 Subject: [PATCH 093/115] Update install/dependencies/os_version.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/dependencies/os_version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dependencies/os_version.sh b/install/dependencies/os_version.sh index 6a244359..10e4a45d 100755 --- a/install/dependencies/os_version.sh +++ b/install/dependencies/os_version.sh @@ -14,4 +14,4 @@ if ! lsb_release -d 2>/dev/null | grep -Eq "Ubuntu|Debian"; then exit 1 fi -echo "Correct distribution." +echo "✅ Correct distribution." From 36720e7963e46b2c658634d649c22663f4bfae50 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 22 Jan 2026 10:44:56 +0100 Subject: [PATCH 094/115] Update install/dependencies/generate_vapid_keys.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/dependencies/generate_vapid_keys.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dependencies/generate_vapid_keys.sh b/install/dependencies/generate_vapid_keys.sh index 4dc68a46..2b045dd2 100644 --- a/install/dependencies/generate_vapid_keys.sh +++ b/install/dependencies/generate_vapid_keys.sh @@ -25,4 +25,4 @@ VAPID_PRIVATE_KEY=$(echo "$output" | grep 'VAPID_PRIVATE_KEY' | cut -d'=' -f2) export VAPID_PUBLIC_KEY export VAPID_PRIVATE_KEY -echo "🔑 Keys successfully extracted" +echo "🔑 Keys successfully extracted!" From 1107d92bb28af3239d1b47995420c647c2352a9b Mon Sep 17 00:00:00 2001 From: David Date: Thu, 22 Jan 2026 10:45:05 +0100 Subject: [PATCH 095/115] Update install/dependencies/build_env.sh Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/dependencies/build_env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 3d5290b9..988f1ac0 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -192,7 +192,7 @@ read -r -p "HERE API KEY: " MAPS_API_KEY Date: Thu, 22 Jan 2026 11:13:37 +0100 Subject: [PATCH 096/115] apply fixes by coderabbit --- .github/workflows/build_install_folder.yml | 2 +- README.md | 8 ++++---- install/dependencies/build_env.sh | 18 +++++++++++------- install/dependencies/generate_gemfile.sh | 2 +- install/scripts/sidekiq_entrypoint.sh | 5 ++++- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build_install_folder.yml b/.github/workflows/build_install_folder.yml index d9c56e7e..936cd10f 100644 --- a/.github/workflows/build_install_folder.yml +++ b/.github/workflows/build_install_folder.yml @@ -16,7 +16,7 @@ jobs: - name: Create deployment ZIP run: | zip -r deploy_bundle.zip \ - scripts/ \ + install/ \ - name: Release uses: softprops/action-gh-release@v2 diff --git a/README.md b/README.md index 8159ba3a..56606c53 100644 --- a/README.md +++ b/README.md @@ -104,9 +104,9 @@ From here on you can follow the steps on the [Getting Started](https://docs.deci ## Using a production deploy script -We've been working on a script that you can use to have a fully functional, production ready decidim instance. +We've been working on a script that you can use to have a fully functional, production-ready decidim instance. -``` +```bash curl -fsSL https://decidim.org/install | bash ``` @@ -116,7 +116,7 @@ It will install the necessary tools to make decidim work on your server. - unzip - UFW -The application will be hosted in the `/opt/decidim` directory by default, even though you can change it with `REPOSITOIRY_PATH` +The application will be hosted in the `/opt/decidim` directory by default, even though you can change it with `REPOSITORY_PATH` environment variable. ## App - Main Decidim Web Application The app itself will be the container with the base image you decide (By default is the latest Decidim version: `decidim/decidim:latest`). You can change it with the `DECIDIM_IMAGE` environment variable. @@ -139,7 +139,7 @@ To configure the application you will have to answer some questions that will, a ### Environment Variables Reference -To see the full list of Decidim Environment Variables, and that you can add to your generated `.env` file, you can take a look at the oficial [documentation](https://docs.decidim.org/en/develop/configure/environment_variables) +To see the full list of Decidim Environment Variables, and that you can add to your generated `.env` file, you can take a look at the official [documentation](https://docs.decidim.org/en/develop/configure/environment_variables) | Variable | Default | Used In | Description | |----------|---------|---------|-------------| diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 988f1ac0..099f48c6 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -3,13 +3,15 @@ set -e set -u set -o pipefail -BUILD_ENV_PATH="$REPOSITORY_PATH/.env" - if [ -z "${REPOSITORY_PATH:-}" ]; then echo "❌ Error: REPOSITORY_PATH is not set" exit 1 fi +BUILD_ENV_PATH="$REPOSITORY_PATH/.env" + +COMPOSE_PROFILES="" + echo "───────────────────────────────────────────────" echo "🔧 Environment Configuration Phase" echo " We'll now collect all the information needed to configure your Decidim instance." @@ -168,9 +170,10 @@ get_storage_keys() { case "$yn" in [Yy]*) get_storage_keys + STORAGE_PROVIDER="s3" ;; *) - STORAGE="local" + STORAGE_PROVIDER="local" ;; esac @@ -189,7 +192,7 @@ echo " Currently, this installation process only handles HERE Maps." echo " You will need to provide the API KEY provided by HERE." echo " This will be saved in the .env file, but you'll be always able to change it." read -r -p "HERE API KEY: " MAPS_API_KEY >"$BUILD_ENV_PATH" <>Gemfile.local fi diff --git a/install/scripts/sidekiq_entrypoint.sh b/install/scripts/sidekiq_entrypoint.sh index 6068aae3..4abed28c 100755 --- a/install/scripts/sidekiq_entrypoint.sh +++ b/install/scripts/sidekiq_entrypoint.sh @@ -3,7 +3,10 @@ # Check all the gems are installed or fails. if ! bundle check; then echo "❌ Gems in Gemfile are not installed. Installing them with \"bundle install\"..." - bundle install + if ! bundle install; then + echo "❌ bundle install failed." + exit 1 + fi else echo "✅ Gems in Gemfile are installed" fi From 66e0d91e2334cffaa0b1d07cef0aae1a767df610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 22 Jan 2026 11:15:22 +0100 Subject: [PATCH 097/115] more fixes --- install/dependencies/build_env.sh | 10 +++++----- install/scripts/entrypoint.sh | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 099f48c6..fc78f5d8 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -266,11 +266,11 @@ EOF STORAGE_PROVIDER=${STORAGE_PROVIDER:-local} if [ "$STORAGE_PROVIDER" == 's3' ]; then cat >>"$BUILD_ENV_PATH" < Date: Thu, 22 Jan 2026 14:49:59 +0100 Subject: [PATCH 098/115] add install readme --- install/README.md | 450 +++++++++++++++++++++++++++++++++++++ install/docker-compose.yml | 2 +- 2 files changed, 451 insertions(+), 1 deletion(-) create mode 100644 install/README.md diff --git a/install/README.md b/install/README.md new file mode 100644 index 00000000..0a6bc58d --- /dev/null +++ b/install/README.md @@ -0,0 +1,450 @@ +# Decidim Installation Guide 🗳️ + +This guide will help you install Decidim on your own server, even with minimal technical knowledge. We'll walk through everything from setting up a server to launching your democracy platform. + +## 📋 Table of Contents + +1. [Prerequisites](#prerequisites) +2. [Step 1: Create a Server](#step-1-create-a-server) +3. [Step 2: Connect to Your Server](#step-2-connect-to-your-server) +4. [Step 3: Configure DNS](#step-3-configure-dns) +5. [Step 4: Install Decidim](#step-4-install-decidim) +6. [Step 5: Configure Email (SMTP)](#step-5-configure-email-smtp) +7. [Step 6: Complete Setup](#step-6-complete-setup) +8. [Troubleshooting](#troubleshooting) + +--- + +## 🎯 Prerequisites + +Before you start, you'll need: + +- **A domain name** (like `example.org`) - you can buy one from any domain registrar +- **Patience** - the installation takes about 20-30 minutes + +### Server Requirements + +**Minimum specifications:** +- **RAM**: 2GB minimum (4GB+ recommended for production) +- **Storage**: 20GB+ +- **OS**: Ubuntu 24.04 (required) + +**Recommended providers:** +- **Hetzner** - Used in this guide +- **Here Maps** - For geolocation features +- **SMTP Email Provider** - For sending emails (Gmail, Scaleway, Rapidmail, etc.) + +--- + +## 📦 Step 1: Create a Server (Hetzner Example) + +We recommend using Hetzner for affordable, reliable hosting. Here's how to set up a server: + +### 1.1 Create a Hetzner Account + +1. Go to [hetzner.com](https://hetzner.com) +2. Click "Register" and create an account + +This process might take some time until Hetzner verifies your account. + +### 1.2 Create a New Server + +1. Log into your Hetzner account +2. Click "Servers" → "Create Server" +3. **Server Location**: Choose a location near your users +4. **Server Type**: + - Click "Shared" (cheaper option, perfect for small organizations) + - Choose "CAX21" +5. **Image**: Select **Ubuntu 24.04** (important! or a newer LTS if available) +6. **SSH Key** (Recommended): + - Create SSH key if you don't have one + - If unsure, skip this and use password +7. **Server Name**: Give it a name like "decidim-server" +8. Click "Create & Buy Now" + +**How to create an SSH key (if needed)**: + +If you don't have an SSH key, create one on your local machine: + + ```bash + ssh-keygen -t rsa -b 4096 -C " + ``` + +This will generate a public/private key pair. Copy the contents of `~/.ssh/id_rsa.pub` and paste it into Hetzner's SSH key field. + +### 1.3 Wait for Server to be Ready + +Your server will be ready in 1-2 minutes. You'll see: +- Server IP address (e.g., `123.45.67.89`) +- Root password (if you chose password instead of SSH key) + +**Save this information! You'll need it immediately.** + +--- + +## 🔐 Step 2: Connect to Your Server + +### Option A: Using SSH Key (More Secure) + +If you created an SSH key: +1. Open your terminal (Terminal on Mac, PowerShell on Windows) +2. Type: `ssh root@YOUR_SERVER_IP` +3. Replace `YOUR_SERVER_IP` with your actual IP address + +### Option B: Using Password (Easier) + +1. Open your terminal (Terminal on Mac, PowerShell on Windows) +2. Type: `ssh root@YOUR_SERVER_IP` +3. When prompted for password, paste the root password from Hetzner +4. It won't show characters while typing - that's normal! + +**First time only**: You'll see a warning about "authenticity of host can't be established". Type `yes` and press Enter. + +--- + +## 🌐 Step 3: Configure DNS + +Before installing Decidim, you need to point your domain to your server. + +### 3.1 Find Your Server's IP Address + +If you lost it, you can find it in the Hetzner dashboard for that server. + +### 3.2 Update DNS Settings + +Go to where you bought your domain (Namecheap, GoDaddy, etc.) and add these DNS records: + +| Type | Host/Name | Value | TTL | +|------|-----------|-------|-----| +| A | @ | YOUR_SERVER_IP | auto | +| CNAME | www | @ | auto | + +**Example**: If your server IP is `123.45.67.89` and your domain is `example.org` and you want the platform to be accessible in `decidim.example.org`, you would set: +- A record: `decidim.example.org` → `123.45.67.89` + +### 3.3 Wait for DNS Propagation + +DNS changes take 5-30 minutes to work worldwide. You can check if it's ready: +```bash +ping decidim.example.org +``` + +--- + +## 🚀 Step 4: Install Decidim + +Now for the main installation! Run these commands one by one on your server. + +### 4.1 Download and Run the Installer + +```bash +curl -fsSL https://decidim.org/install | bash +``` + +### 4.2 Follow the Prompts + +The installer will ask for: + +**Instance Information:** +- **Organization Name**: e.g., "City Hall Democracy Platform" +- **Domain**: e.g., `decidim.example.org` (must match your DNS setup) + +**Database Configuration:** +- **Local Database** (Recommended): PostgreSQL with auto-generated credentials +- **External Database**: Only if you have your own database server + +**Important Database Notes:** +- The installer creates a secure database user with random password +- Database URL is stored in `/opt/decidim/.env` file +- For production, consider regular backups of PostgreSQL + +**File Storage:** +- **Local Storage** (Default): Perfect for most users +- **S3 Storage**: Only if you use Amazon S3 + +**Configuration Files Generated:** +- `.env`: Contains all your configuration (database, SMTP, secrets) +- `docker-compose.yml`: Defines services and networks +- **Important**: Never commit `.env` to version control - it contains passwords! + +**Email Configuration** (Step 5 covers this in detail) + +**SSL Certificate**: The installer will automatically set up free SSL certificates + +--- + +## 📧 Step 5: Configure Email (SMTP) + +Email is crucial for user notifications and password resets. You'll need an SMTP provider. + +### 5.1 Choose an Email Provider + +**Free Options** +- [Gmail SMTP](https://support.google.com/a/answer/176600) (500 emails/day limit) + +**Paid Options** +- [Scaleway](https://www.scaleway.com/en/transactional-email-tem/) +- [Mailgun](https://mailgun.com) + +### 5.2 Get SMTP Settings + +Each provider will give you: +- **SMTP Server**: e.g., `smtp.sendgrid.net` +- **Port**: e.g., `587` +- **Username**: Your email or API key +- **Password**: Your password or API key +- **From Address**: e.g., `noreply@decidim.example.org` + +### 5.3 Configure SMTP during Installation + +When the installer asks for email settings, enter: +- **SMTP Host**: Your provider's SMTP server +- **SMTP Port**: 587 (most common) +- **SMTP Username**: Your SMTP username +- **SMTP Password**: Your SMTP password +- **From Email**: noreply@decidim.example.org +- **From Name**: Your Organization Name + +--- + +## 🔒 Step 6: Security & Firewall Setup + +### 6.1 Firewall Configuration + +The installer will configure firewall rules automatically. You can check the status: + +```bash +# Check firewall status +sudo ufw status + +# Allow SSH (don't lock yourself out!) +sudo ufw allow ssh + +# Enable firewall if not already active +sudo ufw enable +``` + +### 6.2 SSL Certificate (Automatic) + +The installer uses Traefik to handle SSL certificates automatically through Let's Encrypt: +- **Automatic renewal**: Certificates renew themselves +- **No manual intervention needed** +- **HTTPS enforced**: All traffic redirected to secure connections + +If you experience SSL issues: +- Ensure your domain correctly points to the server IP +- Wait 5-10 minutes for DNS propagation +- Check that ports 80 and 443 are accessible from the internet + +### 6.3 Security Best Practices + +Based on the traditional Decidim setup experience: + +1. **Never expose database**: Use firewalls and network segmentation +2. **Keep software updated**: Run updates regularly +3. **Use strong passwords**: For admin users and database +4. **Monitor logs**: Check for suspicious activity +5. **Backup regularly**: Database and configuration files + +### 6.3 Email Domain Authentication + +For better email deliverability, configure these DNS records (advanced): + +- **SPF Record**: `v=spf1 include:_spf.google.com ~all` (if using Gmail) +- **DKIM**: Generate keys from your email provider +- **DMARC**: `v=DMARC1; p=quarantine; rua=mailto:dmarc@decidim.example.org` + +## ✅ Step 7: Complete Setup + +### 6.1 Create System Administrator + +During installation, you'll be prompted to create a system admin: +- **Email**: Use your admin email +- **Password**: The installer will auto-generate a secure password +- **Save the password!** You'll need it to log in + +### 6.2 Access Your Decidim Instance + +1. Open your web browser +2. Go to `https://decidim.example.org/system` +3. Log in with: + - Email: Your system admin email + - Password: The password shown during installation + +### 6.3 Configure Your Organization + +Once logged in, you'll need to: +1. Set up your organization details +2. Create your first participatory space +3. Configure user registration settings + +### 6.4 Background Jobs & Maintenance + +The Docker setup includes automatic background job processing using Sidekiq. Here's what's running: + +**Background Processing**: +- Sidekiq handles email sending and other background tasks +- Automatically restarts if it crashes +- Monitored and managed through Docker Compose + +**To manually check Sidekiq jobs:** +```bash +# Check Sidekiq status +docker compose logs worker + +# Restart Sidekiq if needed +docker compose restart sidekiq +``` + +--- + +## 🔧 Useful Commands + +### Managing Your Decidim Instance + +```bash +# Go to the Decidim directory +cd /opt/decidim + +# View live logs +docker compose logs -f + +# Stop Decidim +docker compose down + +# Start Decidim +docker compose up -d + +# Restart services +docker compose restart + +# Check service status +docker compose ps +``` + +### Updating Decidim + +```bash +cd /opt/decidim +git pull +docker compose pull +docker compose up -d +``` + +--- + +## 🆘 Troubleshooting + +### Common Issues + +**"Connection refused" when connecting to server:** +- Wait 2-3 minutes after server creation +- Check that you're using the correct IP address +- Try `ping YOUR_SERVER_IP` first + +**DNS not working:** +- Wait at least 30 minutes after changing DNS records +- Use `dig example.org` to check DNS +- Make sure A records point to your server IP +- Check records + +**Email not sending:** +- Double-check SMTP settings in `/opt/decidim/.env` +- Verify your firewall allows port 587 outbound +- Check with your email provider about authentication +- **Gmail issues**: May need "App Password" if 2FA enabled +- Check for IPv6 conflicts (installer handles this automatically) + +**Installation fails:** +- Run `./install.sh` again +- Check the error message carefully +- Check available disk space +- Verify internet connection + +**Performance issues on low-memory servers:** +- **Memory optimization**: Consider upgrading to 4GB RAM for production +- **Monitor memory**: `free -h` to check usage +- **Check Docker resource limits**: `docker stats` + +**SSL Certificate problems:** +- Domain must resolve to server IP before certificate issuance +- Port 80 and 443 must be accessible from internet +- Check Traefik logs: `docker compose logs traefik` +- Wait 5-10 minutes for certificate issuance + +### Getting Help + +- **Documentation**: [docs.decidim.org](https://docs.decidim.org) +- **Installation Issues**: [GitHub Issues](https://github.com/decidim/docker/issues) +- **Community**: [Decidim Community Forum](https://meta.decidim.org) +- **Alternative Installation**: [Platoniq Manual Guide](https://platoniq.github.io/decidim-install/) (comprehensive traditional setup) + +## 🎯 Advanced Configuration Options + +### Geolocation & Maps + +For mapping features (meeting locations, proposals with addresses): + +1. **Get HERE Maps API Key**: + - Register at [HERE Developer Portal](https://developer.here.com/) + - Create free account and get API credentials + +2. **Configure in Decidim**: + ```bash + # Edit environment file + nano /opt/decidim/.env + # Add: + # MAPS_API_KEY=your-here-api-key + # MAPS_PROVIDER=here + ``` + +3. **Restart services**: + ```bash + docker compose restart + ``` + +### Important Files + +After installation, your configuration is stored in: +- `/opt/decidim/.env` - **All your settings** (database, email, secrets) 🔐 +- `/opt/decidim/docker-compose.yml` - Service definitions +- `/opt/decidim/storage/` - Persistent data (database, uploads, logs) + +**🚨 Security Warning**: +- **Never commit `.env` to version control** +- **Keep backup of `.env` file in secure location** +- **Contains database passwords, SMTP credentials, and secret keys** + +### Log Locations + +For troubleshooting, check these logs: +```bash +# Application logs +docker compose logs -f decidim + +# Database logs +docker compose logs -f db + +# All services +docker compose logs -f +``` + +--- + +## 🎉 Congratulations! + +You now have a fully functional Decidim instance running on your own server! + +Your democracy platform is ready to: +- Accept user registrations +- Host discussions and debates +- Run participatory budgeting processes +- Enable collaborative decision-making + +Remember to: +- Regularly update your server (`apt update && apt upgrade`) +- Back up your data +- Monitor your email deliverability +- Engage with your community! + +Happy democracy building! 🗳️✨ diff --git a/install/docker-compose.yml b/install/docker-compose.yml index 905ded49..21b0cfa8 100644 --- a/install/docker-compose.yml +++ b/install/docker-compose.yml @@ -1,7 +1,7 @@ services: app: container_name: decidim - image: ${DECIDIM_IMAGE:-"decidim/decidim:latest"} + image: ${DECIDIM_IMAGE:-decidim/decidim:latest} command: ["bin/rails", "server", "-b", "0.0.0.0"] entrypoint: ["/code/entrypoint.sh"] restart: always From 4da520b17945e0dfb6416467a6a7000d886c1e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Fri, 23 Jan 2026 09:50:54 +0100 Subject: [PATCH 099/115] fix typos in readme --- install/README.md | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/install/README.md b/install/README.md index 0a6bc58d..5edda7e9 100644 --- a/install/README.md +++ b/install/README.md @@ -10,12 +10,13 @@ This guide will help you install Decidim on your own server, even with minimal t 4. [Step 3: Configure DNS](#step-3-configure-dns) 5. [Step 4: Install Decidim](#step-4-install-decidim) 6. [Step 5: Configure Email (SMTP)](#step-5-configure-email-smtp) -7. [Step 6: Complete Setup](#step-6-complete-setup) +7. [Step 6: Security & Firewall Setup](#step-6-security--firewall-setup) +8. [Step 7: Complete Setup](#step-7-complete-setup) 8. [Troubleshooting](#troubleshooting) --- -## 🎯 Prerequisites +## Prerequisites Before you start, you'll need: @@ -26,7 +27,7 @@ Before you start, you'll need: **Minimum specifications:** - **RAM**: 2GB minimum (4GB+ recommended for production) -- **Storage**: 20GB+ +- **Storage**: 20GB+ - **OS**: Ubuntu 24.04 (required) **Recommended providers:** @@ -36,7 +37,7 @@ Before you start, you'll need: --- -## 📦 Step 1: Create a Server (Hetzner Example) +## Step 1: Create a Server We recommend using Hetzner for affordable, reliable hosting. Here's how to set up a server: @@ -52,7 +53,7 @@ This process might take some time until Hetzner verifies your account. 1. Log into your Hetzner account 2. Click "Servers" → "Create Server" 3. **Server Location**: Choose a location near your users -4. **Server Type**: +4. **Server Type**: - Click "Shared" (cheaper option, perfect for small organizations) - Choose "CAX21" 5. **Image**: Select **Ubuntu 24.04** (important! or a newer LTS if available) @@ -67,7 +68,7 @@ This process might take some time until Hetzner verifies your account. If you don't have an SSH key, create one on your local machine: ```bash - ssh-keygen -t rsa -b 4096 -C " +ssh-keygen -t rsa -b 4096 -C "your_email@example.com" ``` This will generate a public/private key pair. Copy the contents of `~/.ssh/id_rsa.pub` and paste it into Hetzner's SSH key field. @@ -82,7 +83,7 @@ Your server will be ready in 1-2 minutes. You'll see: --- -## 🔐 Step 2: Connect to Your Server +## Step 2: Connect to Your Server ### Option A: Using SSH Key (More Secure) @@ -102,7 +103,7 @@ If you created an SSH key: --- -## 🌐 Step 3: Configure DNS +## Step 3: Configure DNS Before installing Decidim, you need to point your domain to your server. @@ -131,7 +132,7 @@ ping decidim.example.org --- -## 🚀 Step 4: Install Decidim +## Step 4: Install Decidim Now for the main installation! Run these commands one by one on your server. @@ -173,7 +174,7 @@ The installer will ask for: --- -## 📧 Step 5: Configure Email (SMTP) +## Step 5: Configure Email (SMTP) Email is crucial for user notifications and password resets. You'll need an SMTP provider. @@ -207,7 +208,7 @@ When the installer asks for email settings, enter: --- -## 🔒 Step 6: Security & Firewall Setup +## Step 6: Security & Firewall Setup ### 6.1 Firewall Configuration @@ -254,16 +255,16 @@ For better email deliverability, configure these DNS records (advanced): - **DKIM**: Generate keys from your email provider - **DMARC**: `v=DMARC1; p=quarantine; rua=mailto:dmarc@decidim.example.org` -## ✅ Step 7: Complete Setup +## Step 7: Complete Setup -### 6.1 Create System Administrator +### 7.1 Create System Administrator During installation, you'll be prompted to create a system admin: - **Email**: Use your admin email - **Password**: The installer will auto-generate a secure password - **Save the password!** You'll need it to log in -### 6.2 Access Your Decidim Instance +### 7.2 Access Your Decidim Instance 1. Open your web browser 2. Go to `https://decidim.example.org/system` @@ -271,18 +272,18 @@ During installation, you'll be prompted to create a system admin: - Email: Your system admin email - Password: The password shown during installation -### 6.3 Configure Your Organization +### 7.3 Configure Your Organization Once logged in, you'll need to: 1. Set up your organization details 2. Create your first participatory space 3. Configure user registration settings -### 6.4 Background Jobs & Maintenance +### 7.4 Background Jobs & Maintenance The Docker setup includes automatic background job processing using Sidekiq. Here's what's running: -**Background Processing**: +**Background Processing**: - Sidekiq handles email sending and other background tasks - Automatically restarts if it crashes - Monitored and managed through Docker Compose @@ -333,7 +334,7 @@ docker compose up -d --- -## 🆘 Troubleshooting +## Troubleshooting ### Common Issues @@ -393,7 +394,7 @@ For mapping features (meeting locations, proposals with addresses): ```bash # Edit environment file nano /opt/decidim/.env - # Add: + # Add: # MAPS_API_KEY=your-here-api-key # MAPS_PROVIDER=here ``` @@ -410,7 +411,7 @@ After installation, your configuration is stored in: - `/opt/decidim/docker-compose.yml` - Service definitions - `/opt/decidim/storage/` - Persistent data (database, uploads, logs) -**🚨 Security Warning**: +**🚨 Security Warning**: - **Never commit `.env` to version control** - **Keep backup of `.env` file in secure location** - **Contains database passwords, SMTP credentials, and secret keys** @@ -433,7 +434,7 @@ docker compose logs -f ## 🎉 Congratulations! -You now have a fully functional Decidim instance running on your own server! +You now have a fully functional Decidim instance running on your own server! Your democracy platform is ready to: - Accept user registrations From 163681ec6d41c117b93f9ad1db7a2ee61d486361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Wed, 4 Feb 2026 11:36:00 +0100 Subject: [PATCH 100/115] apply some coderabbit suggestions --- install/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/README.md b/install/README.md index 5edda7e9..eef1a13b 100644 --- a/install/README.md +++ b/install/README.md @@ -12,7 +12,7 @@ This guide will help you install Decidim on your own server, even with minimal t 6. [Step 5: Configure Email (SMTP)](#step-5-configure-email-smtp) 7. [Step 6: Security & Firewall Setup](#step-6-security--firewall-setup) 8. [Step 7: Complete Setup](#step-7-complete-setup) -8. [Troubleshooting](#troubleshooting) +9. [Troubleshooting](#troubleshooting) --- @@ -357,7 +357,7 @@ docker compose up -d - Check for IPv6 conflicts (installer handles this automatically) **Installation fails:** -- Run `./install.sh` again +- Run `curl -fsSL https://decidim.org/install | bash` again - Check the error message carefully - Check available disk space - Verify internet connection From e3626041eca98ab98f43a1c8ec18bffe36c532bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Wed, 4 Feb 2026 11:44:35 +0100 Subject: [PATCH 101/115] change references --- install/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/README.md b/install/README.md index eef1a13b..e9502b54 100644 --- a/install/README.md +++ b/install/README.md @@ -377,8 +377,7 @@ docker compose up -d - **Documentation**: [docs.decidim.org](https://docs.decidim.org) - **Installation Issues**: [GitHub Issues](https://github.com/decidim/docker/issues) -- **Community**: [Decidim Community Forum](https://meta.decidim.org) -- **Alternative Installation**: [Platoniq Manual Guide](https://platoniq.github.io/decidim-install/) (comprehensive traditional setup) +- **Community**: [MetaDecidim](https://meta.decidim.org) ## 🎯 Advanced Configuration Options From bddeaba838d04dfaff5228d0ce155030e2acee76 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 5 Feb 2026 16:35:07 +0100 Subject: [PATCH 102/115] Update install/README.md Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/README.md b/install/README.md index e9502b54..fc774274 100644 --- a/install/README.md +++ b/install/README.md @@ -1,6 +1,6 @@ # Decidim Installation Guide 🗳️ -This guide will help you install Decidim on your own server, even with minimal technical knowledge. We'll walk through everything from setting up a server to launching your democracy platform. +This guide will help you install Decidim on your own server, even with minimal technical knowledge. We'll walk you through everything needed from, setting up a server to launching your digital democratic platform. ## 📋 Table of Contents From 6c5faaf64d4d93545e24e174b7d6005bb0acec1f Mon Sep 17 00:00:00 2001 From: David Date: Thu, 26 Feb 2026 10:46:25 +0100 Subject: [PATCH 103/115] Apply suggestions from code review Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/dependencies/build_env.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index fc78f5d8..2f185e1a 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -4,7 +4,7 @@ set -u set -o pipefail if [ -z "${REPOSITORY_PATH:-}" ]; then - echo "❌ Error: REPOSITORY_PATH is not set" + echo "❌ Error: REPOSITORY_PATH is not set." exit 1 fi @@ -33,7 +33,7 @@ read -r "$BUILD_ENV_PATH" < Date: Thu, 26 Feb 2026 10:48:52 +0100 Subject: [PATCH 104/115] Apply suggestions from code review Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com> --- install/dependencies/check_docker.sh | 2 +- install/dependencies/create_system_admin.sh | 2 +- install/dependencies/decidim_version.sh | 6 +++--- install/dependencies/generate_gemfile.sh | 2 +- install/dependencies/generate_vapid_keys.sh | 2 +- install/dependencies/open_ports.sh | 2 +- install/scripts/entrypoint.sh | 2 +- install/scripts/sidekiq_entrypoint.sh | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/install/dependencies/check_docker.sh b/install/dependencies/check_docker.sh index 59a1e03e..a73bfbf0 100644 --- a/install/dependencies/check_docker.sh +++ b/install/dependencies/check_docker.sh @@ -38,5 +38,5 @@ else exit 1 fi - echo "✅ Docker is accessible for current user" + echo "✅ Docker is accessible for current user!" fi diff --git a/install/dependencies/create_system_admin.sh b/install/dependencies/create_system_admin.sh index 4296aa03..f7a51f04 100644 --- a/install/dependencies/create_system_admin.sh +++ b/install/dependencies/create_system_admin.sh @@ -13,7 +13,7 @@ generate_system_admin() { } if [ -z "$EXTERNAL_DATABASE" ]; then - echo "Checking if database is already running" + echo "Checking if database is already running..." until docker ps --filter "name=decidim-db" --filter "status=running" --quiet; do echo "Container not running yet..." sleep 2 diff --git a/install/dependencies/decidim_version.sh b/install/dependencies/decidim_version.sh index f8f29296..525dd2e4 100644 --- a/install/dependencies/decidim_version.sh +++ b/install/dependencies/decidim_version.sh @@ -7,7 +7,7 @@ echo "💡 About Decidim versions:" echo " • latest - Most recent stable release (recommended)" echo " • Custom images - Your own modified Decidim builds" echo -echo "If you want, later on, you can modify the 'docker-compose.yml' to change the Decidim version" +echo "If you want, later on you can modify the 'docker-compose.yml' to change the Decidim version." echo echo "Default image: decidim/decidim:latest" echo @@ -17,13 +17,13 @@ while true; do DECIDIM_IMAGE=${DECIDIM_IMAGE:-decidim/decidim:latest} - echo "Trying to pull: $DECIDIM_IMAGE" + echo "Attempting to pull: $DECIDIM_IMAGE" if docker pull "$DECIDIM_IMAGE"; then echo "✅ Successfully pulled image: $DECIDIM_IMAGE" break else - echo "Failed to pull image: $DECIDIM_IMAGE" + echo "❌ Failed to pull image: $DECIDIM_IMAGE" echo "Please try again." echo fi diff --git a/install/dependencies/generate_gemfile.sh b/install/dependencies/generate_gemfile.sh index ffc26202..06a6ab46 100644 --- a/install/dependencies/generate_gemfile.sh +++ b/install/dependencies/generate_gemfile.sh @@ -3,7 +3,7 @@ set -e echo "───────────────────────────────────────────────" -echo "Now we are going to generate some Gemfiles so that we can track gem dependencies" +echo "Now we are going to generate some Gemfiles, in order to track gem dependencies." echo echo "You will find everything in the Gemfile.wrapper and Gemfile.local" diff --git a/install/dependencies/generate_vapid_keys.sh b/install/dependencies/generate_vapid_keys.sh index 2b045dd2..81c35e49 100644 --- a/install/dependencies/generate_vapid_keys.sh +++ b/install/dependencies/generate_vapid_keys.sh @@ -16,7 +16,7 @@ output=$(docker run --rm \ "$DECIDIM_IMAGE" \ bin/rails decidim:pwa:generate_vapid_keys) -echo "✅ The VAPID keys have been generated correctly" +echo "✅ The VAPID keys have been generated correctly!" VAPID_PUBLIC_KEY=$(echo "$output" | grep 'VAPID_PUBLIC_KEY' | cut -d'=' -f2) VAPID_PRIVATE_KEY=$(echo "$output" | grep 'VAPID_PRIVATE_KEY' | cut -d'=' -f2) diff --git a/install/dependencies/open_ports.sh b/install/dependencies/open_ports.sh index fce59011..6970e6ab 100644 --- a/install/dependencies/open_ports.sh +++ b/install/dependencies/open_ports.sh @@ -2,7 +2,7 @@ open_ports() { echo - echo "To handle the SSL certificate we will have to open the port 80 and the port 443" + echo "To handle the SSL certificate, we will have to open the port 80 and the port 443." echo if ! command -v ufw; then diff --git a/install/scripts/entrypoint.sh b/install/scripts/entrypoint.sh index e70c0af4..cd311093 100755 --- a/install/scripts/entrypoint.sh +++ b/install/scripts/entrypoint.sh @@ -18,7 +18,7 @@ if ! bundle check; then echo "❌ Gems in Gemfile are not installed. Installing them with \"bundle install\"..." bundle install else - echo "✅ Gems in Gemfile are installed" + echo "✅ Gems in Gemfile are installed!" fi # Check to see if there are migrations to install diff --git a/install/scripts/sidekiq_entrypoint.sh b/install/scripts/sidekiq_entrypoint.sh index 4abed28c..6b4d0bb4 100755 --- a/install/scripts/sidekiq_entrypoint.sh +++ b/install/scripts/sidekiq_entrypoint.sh @@ -2,13 +2,13 @@ # Check all the gems are installed or fails. if ! bundle check; then - echo "❌ Gems in Gemfile are not installed. Installing them with \"bundle install\"..." + echo "❌ Gems within the Gemfile are not installed. Installing them with \"bundle install\"..." if ! bundle install; then echo "❌ bundle install failed." exit 1 fi else - echo "✅ Gems in Gemfile are installed" + echo "✅ Gems in Gemfile are installed!" fi echo "🚀" "$@" From 0319ea1016fa61343282eb37f28cebf2bc188e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 26 Feb 2026 11:33:08 +0100 Subject: [PATCH 105/115] apply more coderabbit fixes --- README.md | 6 +----- install/README.md | 27 ++++++++++++++++--------- install/dependencies/build_env.sh | 23 ++++++++++++++------- install/dependencies/decidim_version.sh | 2 +- install/docker-compose.yml | 16 ++++++--------- install/install.sh | 4 +--- install/scripts/entrypoint.sh | 2 +- install/up.sh | 3 +++ 8 files changed, 46 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 56606c53..5b070ce6 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,6 @@ sudo chown -R $(whoami): ${APP_NAME} From here on you can follow the steps on the [Getting Started](https://docs.decidim.org/en/install/) guide. ## Using a production deploy script - We've been working on a script that you can use to have a fully functional, production-ready decidim instance. ```bash @@ -130,15 +129,12 @@ The worker will be the one responsible for all the background jobs that the appl The app needs a cache server. This will be a `redis:8-alpine` instance. This cache will be used both by the app and the worker. ## Database - The application needs a database to run. Through the installation process you will be asked if you have an already working database, if not, you will have a postgres container with all the schema and migrations run (It will be a `postgres:17-alpine`) ## Configuration - To configure the application you will have to answer some questions that will, at the end, generate a `.env` file. ### Environment Variables Reference - To see the full list of Decidim Environment Variables, and that you can add to your generated `.env` file, you can take a look at the official [documentation](https://docs.decidim.org/en/develop/configure/environment_variables) | Variable | Default | Used In | Description | @@ -158,7 +154,7 @@ To see the full list of Decidim Environment Variables, and that you can add to y | **SMTP_DOMAIN** | — | app, worker | SMTP domain. | | **SMTP_PORT** | — | app, worker | SMTP port. | | **SMTP_STARTTLS_AUTO** | `true` | app | Enables STARTTLS automatically. | -| **REDIS_URL** | `redis://decidim_cache:6379/0` | app | Redis URL for cache + sessions. | +| **REDIS_URL** | `redis://cache:6379/0` | app | Redis URL for cache + sessions. | | **VAPID_PUBLIC_KEY** | — | app | Web Push public key for browser notifications. | | **VAPID_PRIVATE_KEY** | — | app | Web Push private key (keep secret). | | **CERTIFICATE_EMAIL** | — | traefik | Email used by Let's Encrypt for certificate issues/renewals. | diff --git a/install/README.md b/install/README.md index fc774274..3540431c 100644 --- a/install/README.md +++ b/install/README.md @@ -20,8 +20,8 @@ This guide will help you install Decidim on your own server, even with minimal t Before you start, you'll need: -- **A domain name** (like `example.org`) - you can buy one from any domain registrar -- **Patience** - the installation takes about 20-30 minutes +- **A domain name** (like `example.org`) - You can buy one from any domain registrar +- **Patience** - The installation can take about 20-30 minutes ### Server Requirements @@ -32,7 +32,7 @@ Before you start, you'll need: **Recommended providers:** - **Hetzner** - Used in this guide -- **Here Maps** - For geolocation features +- **Here Maps** - For geo-location features - **SMTP Email Provider** - For sending emails (Gmail, Scaleway, Rapidmail, etc.) --- @@ -79,7 +79,7 @@ Your server will be ready in 1-2 minutes. You'll see: - Server IP address (e.g., `123.45.67.89`) - Root password (if you chose password instead of SSH key) -**Save this information! You'll need it immediately.** +**PLEASE SAVE THIS INFORMATION!! You'll need it immediately!!** --- @@ -294,7 +294,7 @@ The Docker setup includes automatic background job processing using Sidekiq. Her docker compose logs worker # Restart Sidekiq if needed -docker compose restart sidekiq +docker compose restart worker ``` --- @@ -325,13 +325,17 @@ docker compose ps ### Updating Decidim +To update to the latest docker image available you can execute the following commands. + ```bash -cd /opt/decidim -git pull -docker compose pull -docker compose up -d ++# Pull the latest Docker images ++docker compose pull ++# Restart with updated images ++docker compose up -d ``` +In case there were new files and configurations in a release of the decidim installer, then you would have to execute the script again. + --- ## Troubleshooting @@ -420,11 +424,14 @@ After installation, your configuration is stored in: For troubleshooting, check these logs: ```bash # Application logs -docker compose logs -f decidim +docker compose logs -f app # Database logs docker compose logs -f db +# Worker logs +docker compose logs -f worker + # All services docker compose logs -f ``` diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index 2f185e1a..fa0c3a69 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -36,14 +36,26 @@ echo echo "💡 The application name will be displayed throughout the interface." echo " and used in email subjects. Make it descriptive!" echo -read -r -p "What is the name of your organization? (For example: Decidim Barcelona)" DECIDIM_APPLICATION_NAME "$BUILD_ENV_PATH" < Date: Thu, 26 Feb 2026 17:32:55 +0100 Subject: [PATCH 106/115] fixes on sidekiq --- install/docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/docker-compose.yml b/install/docker-compose.yml index 4e767e46..d786e63c 100644 --- a/install/docker-compose.yml +++ b/install/docker-compose.yml @@ -34,6 +34,7 @@ services: - LOG_LEVEL=${LOG_LEVEL:-info} - DECIDIM_ENABLE_HTML_HEADER_SNIPPETS - SMTP_STARTTLS_AUTO=${SMTP_STARTTLS_AUTO:-true} + - QUEUE_ADAPTER=sidekiq - SMTP_USERNAME - SMTP_PASSWORD - SMTP_ADDRESS @@ -54,7 +55,7 @@ services: - ${PWD}/Gemfile.wrapper:/code/Gemfile.wrapper - ${PWD}/Gemfile.local:/code/Gemfile.local - ${PWD}/scripts/sidekiq_entrypoint.sh:/code/sidekiq_entrypoint.sh - - ${PWD}/scripts/config/sidekiq.yml:/code/config/sidekiq.yml + - ${PWD}/config/sidekiq.yml:/code/config/sidekiq.yml - worker_gems:/usr/local/bundle - storage_data:/code/storage - migrations_data:/code/db/migrate From 0b3d38b1abcfdbef90adb5fc8d1a69ddc0fa1ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 26 Feb 2026 17:53:00 +0100 Subject: [PATCH 107/115] make sidekiq default queu for decidim --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6815b4a6..23d37f87 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG base_image=ghcr.io/decidim/decidim-generator:latest FROM $base_image LABEL maintainer="hola@decidim.org" -RUN decidim . +RUN decidim --queue sidekiq . RUN bundle check || bundle install RUN bundle exec rake assets:precompile From e545a1ef6bbcc84efd9d4dca59611d9e63394d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Thu, 26 Feb 2026 18:21:36 +0100 Subject: [PATCH 108/115] add decidim mailer sender env --- install/dependencies/build_env.sh | 3 +++ install/deploy_bundle.zip | Bin 0 -> 19505 bytes 2 files changed, 3 insertions(+) create mode 100644 install/deploy_bundle.zip diff --git a/install/dependencies/build_env.sh b/install/dependencies/build_env.sh index fa0c3a69..3516a9aa 100644 --- a/install/dependencies/build_env.sh +++ b/install/dependencies/build_env.sh @@ -227,6 +227,7 @@ fi # Variable to handle the let's encrypt email. CERTIFICATE_EMAIL="${CERTIFICATE_EMAIL:-postmaster@${DECIDIM_DOMAIN}}" +DECIDIM_MAILER_SENDER="${DECIDIM_MAILER_SENDER:-noreply@${DECIDIM_DOMAIN}}" echo "───────────────────────────────────────────────" echo "🎯 Final Configuration Summary:" @@ -259,6 +260,8 @@ SMTP_ADDRESS="$SMTP_ADDRESS" SMTP_DOMAIN="$SMTP_DOMAIN" SMTP_PORT="$SMTP_PORT" +DECIDIM_MAILER_SENDER="$DECIDIM_MAILER_SENDER" + MAPS_API_KEY="$MAPS_API_KEY" REDIS_URL="redis://cache:6379" diff --git a/install/deploy_bundle.zip b/install/deploy_bundle.zip new file mode 100644 index 0000000000000000000000000000000000000000..fe05e6b972027c69ea184b852a8e2b1607f0f3f6 GIT binary patch literal 19505 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 Date: Thu, 26 Feb 2026 18:27:07 +0100 Subject: [PATCH 109/115] changes in bundle of deploy.zip --- .github/workflows/build_install_folder.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_install_folder.yml b/.github/workflows/build_install_folder.yml index 936cd10f..366fcfb9 100644 --- a/.github/workflows/build_install_folder.yml +++ b/.github/workflows/build_install_folder.yml @@ -15,10 +15,10 @@ jobs: - name: Create deployment ZIP run: | - zip -r deploy_bundle.zip \ - install/ \ + cd install + zip -r ../deploy.zip . - name: Release uses: softprops/action-gh-release@v2 with: - files: deploy_bundle.zip + files: deploy.zip From 7fcc8ec1238f5d73389b655a644e7abf84589dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Mon, 2 Mar 2026 12:12:56 +0100 Subject: [PATCH 110/115] remove zip file --- install/deploy_bundle.zip | Bin 19505 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 install/deploy_bundle.zip diff --git a/install/deploy_bundle.zip b/install/deploy_bundle.zip deleted file mode 100644 index fe05e6b972027c69ea184b852a8e2b1607f0f3f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19505 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 Date: Tue, 3 Mar 2026 10:33:25 +0100 Subject: [PATCH 111/115] add schedule.yml and invoke_rake_task_job --- install/config/schedule.yml | 64 ++++++++++++++++++++++++++++ install/docker-compose.yml | 2 + install/jobs/invoke_rake_task_job.rb | 11 +++++ 3 files changed, 77 insertions(+) create mode 100644 install/config/schedule.yml create mode 100644 install/jobs/invoke_rake_task_job.rb diff --git a/install/config/schedule.yml b/install/config/schedule.yml new file mode 100644 index 00000000..fda5045b --- /dev/null +++ b/install/config/schedule.yml @@ -0,0 +1,64 @@ +hourly_active_step_job: + cron: "0 * * * *" + class: "InvokeRakeTaskJob" + queue: default + status: <%= ENV.fetch("CHANGE_ACTIVE_STEP", "enabled") %> # enabled by default + args: + task: decidim_participatory_processes:change_active_step + +daily_open_data_job: + cron: "3 3 * * *" + class: "InvokeRakeTaskJob" + queue: default + status: <%= ENV.fetch("EXPORT_OPEN_DATA", "enabled") %> # enabled by default + args: + task: decidim:open_data:export + +daily_delete_download_your_data_files_job: + cron: "33 3 * * *" + class: "InvokeRakeTaskJob" + queue: default + status: <%= ENV.fetch("DELETE_DOWNLOAD_YOUR_DATA_FILES", "enabled") %> # enabled by default + args: + task: decidim:delete_download_your_data_files + +daily_metrics_job: + cron: "30 1 * * *" + class: "InvokeRakeTaskJob" + queue: metrics + status: <%= ENV.fetch("GENERATE_METRICS", "enabled") %> # enabled by default + args: + task: decidim:metrics:all + +daily_notifications_digest_job: + cron: "5 18 * * *" + class: "InvokeRakeTaskJob" + queue: mailers + status: <%= ENV.fetch("DAILY_NOTIFICATIONS_DIGEST", "enabled") %> # enabled by default + args: + task: decidim:mailers:notifications_digest_daily + +daily_reminders_job: + cron: "1 11 * * *" + class: "InvokeRakeTaskJob" + queue: default + status: <%= ENV.fetch("SEND_REMINDERS", "enabled") %> # enabled by default + args: + task: decidim:reminders:all + +weekly_clean_registration_forms_job: + cron: "0 3 * * 0" + class: "InvokeRakeTaskJob" + queue: default + status: <%= ENV.fetch("CLEAN_REGISTRATION_FORMS", "enabled") %> # enabled by default + args: + task: decidim_meetings:clean_registration_forms + +weekly_notifications_digest_job: + cron: "5 18 * * 0" + class: "InvokeRakeTaskJob" + queue: mailers + status: <%= ENV.fetch("WEEKLY_NOTIFICATIONS_DIGEST", "enabled") %> # enabled by default + args: + task: decidim:mailers:notifications_digest_weekly + diff --git a/install/docker-compose.yml b/install/docker-compose.yml index d786e63c..d6353491 100644 --- a/install/docker-compose.yml +++ b/install/docker-compose.yml @@ -56,6 +56,8 @@ services: - ${PWD}/Gemfile.local:/code/Gemfile.local - ${PWD}/scripts/sidekiq_entrypoint.sh:/code/sidekiq_entrypoint.sh - ${PWD}/config/sidekiq.yml:/code/config/sidekiq.yml + - ${PWD}/config/schedule.yml:/code/config/schedule.yml + - ${PWD}/jobs/invoke_rake_task_job.rb:/code/app/jobs/invoke_rake_task_job.rb - worker_gems:/usr/local/bundle - storage_data:/code/storage - migrations_data:/code/db/migrate diff --git a/install/jobs/invoke_rake_task_job.rb b/install/jobs/invoke_rake_task_job.rb new file mode 100644 index 00000000..8c3ce70d --- /dev/null +++ b/install/jobs/invoke_rake_task_job.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "rake" +Rails.application.load_tasks + +class InvokeRakeTaskJob < ApplicationJob + def perform(args) + Rake::Task[args["task"]].reenable + Rake::Task[args["task"]].invoke(args["args"]) + end +end From c899e0bd8cfca381fa14606d92acde10f16182f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 3 Mar 2026 10:38:07 +0100 Subject: [PATCH 112/115] add readme info about schedule.yml --- install/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/install/README.md b/install/README.md index 3540431c..62cfee39 100644 --- a/install/README.md +++ b/install/README.md @@ -297,6 +297,17 @@ docker compose logs worker docker compose restart worker ``` +To have a perfectly functional decidim instance, it's necessary to run some commands in a periodic way. To do so we have provided the installer with a `config/schedule.yml` that will be used by the worker and the `sidekiq-cron` gem. There you will see all the tasks that need to run. Here's a list of some of them: + +- decidim_participatory_processes:change_active_step +- decidim:open_data:export +- decidim:delete_download_your_data_files +- decidim:metrics:all + +In the `schedule.yml` you will find some environment variables that you can configure if you want to disable the execution of some of those jobs. They will be executed thanks to the job in `jobs/invoke_rake_task_job.rb`. + +You can modify the `schedule.yml` file if you want to include some other jobs to be executed, or if there are some new ones. It will still be taken care of from this repository. + --- ## 🔧 Useful Commands From 71d0296157797fd9945abb376652e8bc7b48a00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 3 Mar 2026 15:47:05 +0100 Subject: [PATCH 113/115] change scheduled job --- install/config/schedule.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/install/config/schedule.yml b/install/config/schedule.yml index fda5045b..9209aedd 100644 --- a/install/config/schedule.yml +++ b/install/config/schedule.yml @@ -22,14 +22,6 @@ daily_delete_download_your_data_files_job: args: task: decidim:delete_download_your_data_files -daily_metrics_job: - cron: "30 1 * * *" - class: "InvokeRakeTaskJob" - queue: metrics - status: <%= ENV.fetch("GENERATE_METRICS", "enabled") %> # enabled by default - args: - task: decidim:metrics:all - daily_notifications_digest_job: cron: "5 18 * * *" class: "InvokeRakeTaskJob" @@ -46,6 +38,14 @@ daily_reminders_job: args: task: decidim:reminders:all +daily_delete_inactive_participants_job: + cron: "30 1 * * *" + class: "InvokeRakeTaskJob" + queue: default + status: <%= ENV.fetch("DELETE_INACTIVE_PARTICIPANTS", "enabled") %> + args: + task: decidim:participants:delete_inactive_participants + weekly_clean_registration_forms_job: cron: "0 3 * * 0" class: "InvokeRakeTaskJob" From a07e2bce39a30f595f568486395f5fcc355f4686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 3 Mar 2026 15:47:15 +0100 Subject: [PATCH 114/115] remove duplicated sidekiq gem --- install/dependencies/generate_gemfile.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/dependencies/generate_gemfile.sh b/install/dependencies/generate_gemfile.sh index 06a6ab46..1558aa68 100644 --- a/install/dependencies/generate_gemfile.sh +++ b/install/dependencies/generate_gemfile.sh @@ -19,7 +19,6 @@ source "https://rubygems.org" ruby RUBY_VERSION -gem "sidekiq" gem "sidekiq-cron" EOF From e72e3b826572b9855d87df7c866628b13cbc320e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ig=C3=B3n?= Date: Tue, 3 Mar 2026 16:33:04 +0100 Subject: [PATCH 115/115] remove reference to hello-world.sh --- docker-compose.yml | 8 -------- install/scripts/hello-world.sh | 12 ------------ 2 files changed, 20 deletions(-) delete mode 100755 install/scripts/hello-world.sh diff --git a/docker-compose.yml b/docker-compose.yml index cf5bcd45..d4a9900e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,17 +2,9 @@ version: '3' services: decidim: image: decidim/decidim:latest - entrypoint: ["/code/vendor/hello-world.sh"] - # The entrypoint override above wipes out the CMD - # on the Dockerfile-deploy, so we need to declare it - # again here (https://github.com/docker/compose/issues/3140) command: ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"] ports: - 3000:3000 - volumes: - # Makes our entrypoint scripts available to the container - # under /code/vendor - - ./scripts:/code/vendor environment: - RAILS_ENV=development - DATABASE_HOST=pg diff --git a/install/scripts/hello-world.sh b/install/scripts/hello-world.sh deleted file mode 100755 index bf467914..00000000 --- a/install/scripts/hello-world.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -set -e - -# runs db:drop, db:create and db:migrate. -# We can't use db:schema:load because we don't have the db/schema.rb -# file when we create the app for the first time and migrations haven't -# been run yet. -bundle exec rake db:migrate:reset -# Adds basic system, admin and user accounts, and lorem ipsum content. -bundle exec rake db:seed - -exec "$@"