-
Notifications
You must be signed in to change notification settings - Fork 26
Create install.sh script
#119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some standard but very minor changes to wording of script language communicating to the implementer during the installation. Also adding consistency to what you've already done.
Take a long and let me know what you think @davidbeig :)
All in all really beautifully described!
📝 WalkthroughWalkthroughAdds a production installer and supporting scripts, a docker-compose multi-service deployment (app, worker, traefik, db, cache), Sidekiq config and container entrypoints, extensive deployment documentation, and a GitHub Actions workflow that packages and publishes the install/ folder as a release ZIP. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant GH_Releases as "GitHub Releases"
participant Installer as "install/install.sh"
participant Host as "Server (Docker)"
participant Compose as "docker-compose"
participant Traefik as "Traefik"
participant App as "Decidim App"
participant Worker as "Sidekiq"
participant DB as "Postgres"
participant Cache as "Redis"
User->>Installer: run installer (curl ... | bash) / trigger workflow
Installer->>GH_Releases: download `deploy_bundle.zip`
GH_Releases-->>Installer: return ZIP
Installer->>Host: extract files into REPOSITORY_PATH (/opt/decidim)
Installer->>Host: run dependencies/*.sh (os_version, check_docker, open_ports, build_env...)
Installer->>Host: generate VAPID, Gemfiles, create .env
Installer->>Compose: docker compose --env-file .env up -d
Compose->>DB: start postgres container
Compose->>Cache: start redis container
Compose->>Traefik: start reverse proxy
Compose->>App: start app container
Compose->>Worker: start sidekiq container
App->>DB: connect and run migrations
Worker->>DB: connect
Traefik->>App: route external requests
Installer->>Host: run create_system_admin.sh (rails runner) -> returns admin credentials
Host-->>User: installation complete, admin credentials displayed
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 19
🤖 Fix all issues with AI agents
In @.github/workflows/build_install_folder.yml:
- Around line 16-20: The "Create deployment ZIP" workflow step is zipping a
non-existent scripts/ directory; update the zip command that produces
deploy_bundle.zip to include the correct installer path (e.g., install/ or
install/scripts/) so the actual installer files are packaged (modify the zip
source arguments in the step named "Create deployment ZIP" to reference install/
instead of scripts/).
- Around line 3-7: The release step using softprops/action-gh-release is
vulnerable because tag_name defaults to github.ref and the workflow is triggered
on branch pushes; either restrict the workflow trigger to tag pushes (e.g.,
change on: push to push: tags: ['v*']) or add a conditional on the release
job/step (use if: startsWith(github.ref, 'refs/tags/')) so the
softprops/action-gh-release step (the step invoking softprops/action-gh-release
and setting tag_name) only runs for tag refs.
In `@install/dependencies/build_env.sh`:
- Around line 114-126: The script fails under set -u when choosing the external
DB because COMPOSE_PROFILES is only defined in build_local_database; initialize
a safe default before it's referenced. Modify the top-level flow near the
EXTERNAL_DATABASE logic so that COMPOSE_PROFILES is exported with a default
empty value (or appropriate default profile) when EXTERNAL_DATABASE=true, and
ensure build_external_database and build_local_database do not assume
COMPOSE_PROFILES is already set; update any places that expand COMPOSE_PROFILES
to use a safe expansion pattern or rely on the newly exported default. Reference
the existing symbols build_external_database, build_local_database,
EXTERNAL_DATABASE, and COMPOSE_PROFILES when making the change.
- Around line 191-193: The script has a typo and inconsistent variable names:
correct MAPS_API_PROIVDER to MAPS_API_PROVIDER wherever present and ensure the
final exported/used variable matches what docker-compose expects
(MAPS_PROVIDER). Update the assignments so MAPS_PROVIDER is set from the
(correctly spelled) MAPS_API_PROVIDER (or replace usages to consistently use
MAPS_PROVIDER), and fix the same typo occurrences later in the file (the
repeated MAPS_API_PROIVDER instances) so the container receives the intended
provider value.
In `@install/dependencies/check_docker.sh`:
- Around line 12-15: Replace the direct pipe of the remote script to bash with a
two-step download-and-execute flow: change the curl | bash usage so the script
is first fetched to a temporary file (the code that currently uses the curl ->
bash pipeline in install/dependencies/check_docker.sh), allow for inspection or
checksum/GPG validation, then explicitly execute the saved file with bash and
remove it afterwards; ensure failure of either download or execution returns
non-zero and prints a clear error message (the same "Failed to install Docker"
handling should remain but triggered after validating and running the downloaded
script).
In `@install/dependencies/create_system_admin.sh`:
- Around line 15-21: The if-test references EXTERNAL_DATABASE and will fail
under set -u if the variable is unset; update the condition in that block to use
shell parameter expansion to provide a safe default (use the ":-" expansion to
default EXTERNAL_DATABASE to an empty string) when testing for emptiness so the
script won't crash under set -u — adjust the if [ -z ... ] check accordingly
around the EXTERNAL_DATABASE usage.
- Around line 31-45: The current flow calls generate_system_admin with set -e
enabled so the script will exit on failure and never reach the if [ $? -eq 1 ]
branch; move the generate_system_admin invocation into the conditional test
instead (e.g., run it as part of the if statement) so you can test its exit
status and handle both success and failure paths, updating the existing branches
that reference SYSTEM_PASSWORD and DECIDIM_DOMAIN accordingly and keeping the
same log messages for success and the troubleshooting block for failures.
In `@install/dependencies/decidim_version.sh`:
- Around line 15-27: The loop currently keeps retrying the same DECIDIM_IMAGE
forever; after a failed docker pull (inside the while-true loop around docker
pull "$DECIDIM_IMAGE") prompt the user to optionally enter a new image name (or
press Enter to retry the same), read that input into DECIDIM_IMAGE (falling back
to the previous value if empty), and then continue the loop so the next docker
pull uses the updated DECIDIM_IMAGE; make sure to reference the DECIDIM_IMAGE
variable and the docker pull retry block when applying the change.
In `@install/dependencies/generate_vapid_keys.sh`:
- Around line 21-28: The script currently exports VAPID_PUBLIC_KEY and
VAPID_PRIVATE_KEY even if extraction failed; update the block that assigns and
exports these variables to validate that both VAPID_PUBLIC_KEY and
VAPID_PRIVATE_KEY are non-empty after extraction (or check the grep/cut exit
status), and if either is empty print an error message including which key is
missing and exit with a non-zero status to fail fast instead of continuing.
In `@install/dependencies/os_version.sh`:
- Around line 12-15: The current check using lsb_release in the if block (the
lsb_release -d | grep -Eq "Ubuntu|Debian" check) will falsely fail on minimal
images where lsb_release is not installed; update the validation to first detect
whether the lsb_release command exists and only use it if present, otherwise
parse /etc/os-release (or /etc/debian_version as a fallback) to look for
"Ubuntu" or "Debian"; change the if condition around the lsb_release usage to
try lsb_release when available and fall back to checking /etc/os-release, and
keep the same error message/exit behavior if neither check indicates
Debian/Ubuntu.
In `@install/docker-compose.yml`:
- Around line 4-5: The image value uses a shell-style default substitution with
quoted default which becomes literal in Docker Compose; change the image key's
value from using ${DECIDIM_IMAGE:-"decidim/decidim:latest"} to an unquoted
default ${DECIDIM_IMAGE:-decidim/decidim:latest} so the DECIDIM_IMAGE
substitution resolves to decidim/decidim:latest when unset (match the worker
service's approach), ensuring the image name has no embedded quotes.
In `@install/install.sh`:
- Around line 67-75: After downloading "$TMP/deploy.zip" from "$REPOSITORY_URL"
but before unzipping or sourcing anything, add integrity/authenticity
verification: fetch the release checksum (e.g. deploy.zip.sha256) or signature
(e.g. deploy.zip.asc) from the same releases endpoint, verify the archive using
a strong hash (SHA256) or GPG public-key verification, and abort with a clear
error if verification fails; ensure this logic references the same
"$TMP/deploy.zip" artifact and exits the installer on mismatch so no untrusted
content is executed.
In `@install/scripts/entrypoint.sh`:
- Around line 1-22: The script lacks fail-fast shell options, so add strict
error handling (e.g., set -euo pipefail) immediately after the shebang in
entrypoint.sh so any failing command (like bundle install or migrations) causes
the container to exit; also avoid swallowing errors from critical commands by
removing stderr redirection on usermod/groupmod (or explicitly check their exit
status) so failures in usermod/groupmod or bundle install propagate and stop the
script.
In `@install/scripts/sidekiq_entrypoint.sh`:
- Line 1: The shebang currently enables shell tracing (-x) unconditionally in
sidekiq_entrypoint.sh; remove -x from the shebang and make tracing opt‑in by
checking an environment flag (e.g., SH_TRACE or TRACE_SHELL) at the top of the
script and running set -x only when that flag is enabled, ensuring tracing is
off by default to avoid leaking sensitive args.
- Around line 4-6: The script currently runs `bundle install` when `bundle
check` fails but does not stop if the install fails, causing confusing errors
later; update the sidekiq_entrypoint.sh logic so after running `bundle install`
you check its exit status and if it failed log an error and exit non-zero (so
the container/process fails fast) before reaching the final `exec` that starts
Sidekiq.
In `@README.md`:
- Line 142: Fix the typo and punctuation in the README sentence that currently
reads "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)";
change "oficial" to "official", remove the awkward comma after "Variables" and
rephrase for clarity (e.g., "To see the full list of Decidim environment
variables that you can add to your generated `.env` file, see the official
[documentation](https://docs.decidim.org/en/develop/configure/environment_variables)").
Make the same correction for the other identical occurrence elsewhere in the
document.
- Line 107: Change the phrase "production ready" to the hyphenated form
"production-ready" in the README text (the sentence starting "We've been working
on a script that you can use to have a fully functional, production ready
decidim instance.") so the compound adjective is correctly hyphenated as
"production-ready".
- Around line 109-111: The fenced code block containing the curl command is
missing a language tag; update the block delimiter from ``` to ```bash so the
snippet is marked as a Bash code block (locate the triple-backtick fence around
the curl example in README.md and replace it with ```bash).
- Line 119: Fix the README typo: replace the incorrect environment variable name
REPOSITOIRY_PATH with the correct REPOSITORY_PATH in the sentence mentioning the
default host directory (/opt/decidim). Update any other occurrences in README.md
to match the codebase's REPOSITORY_PATH used in install/install.sh,
install/up.sh, and install/dependencies/build_env.sh so documentation and
scripts are consistent.
🧹 Nitpick comments (3)
install/dependencies/open_ports.sh (1)
3-23: Avoid SSH lockout when enabling UFW.The script always allows port 22 before enabling UFW. If SSH is configured on a different port, this can lock the user out. Consider prompting for the SSH port (default 22) or detecting it from sshd config.
💡 Suggested adjustment
open_ports() { echo echo "To handle the SSL certificate we will have to open the port 80 and the port 443" echo + + read -r -p "SSH port to keep open [22]: " SSH_PORT </dev/tty + SSH_PORT=${SSH_PORT:-22} 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 "$SSH_PORT" sudo ufw allow 80 sudo ufw allow 443 sudo ufw --force enable }install/up.sh (1)
6-20: Consider making REPOSITORY_PATH and compose file path explicit for robustness.While
up.shworks correctly when sourced frominstall.sh(whereREPOSITORY_PATHis set and the current directory is already the repository root), the script could be more resilient if run independently or from different contexts. Adding a safe default forREPOSITORY_PATHand explicitly passing the compose file path with-fwould improve robustness without changing behavior in the intended use case.🔧 Suggested improvements
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPOSITORY_PATH="${REPOSITORY_PATH:-"$(cd "$SCRIPT_DIR/.." && pwd)"}" ENV_FILE="${REPOSITORY_PATH}/.env" +COMPOSE_FILE="${REPOSITORY_PATH}/docker-compose.yml" ... -docker compose --env-file "$ENV_FILE" up -d +docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d ... -docker compose logs --tail=30 +docker compose -f "$COMPOSE_FILE" logs --tail=30install/dependencies/build_env.sh (1)
105-106: Mask secret inputs in interactive prompts.Passwords/secret keys are currently echoed to the terminal. Use silent reads to reduce accidental exposure.
🔐 Suggested prompt hardening
- read -r -p "Database password: " DATABASE_PASSWORD </dev/tty + read -r -s -p "Database password: " DATABASE_PASSWORD </dev/tty + echo @@ -read -r -p "SMTP_PASSWORD: " SMTP_PASSWORD </dev/tty +read -r -s -p "SMTP_PASSWORD: " SMTP_PASSWORD </dev/tty +echo @@ - read -r -p "Secret Access Key: " AWS_SECRET_ACCESS_KEY </dev/tty + read -r -s -p "Secret Access Key: " AWS_SECRET_ACCESS_KEY </dev/tty + echoAlso applies to: 135-136, 158-158
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| workflow_dispatch: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/build_install_folder.ymlRepository: decidim/docker
Length of output: 172
🌐 Web query:
softprops/action-gh-release requirements tag ref behavior
💡 Result:
Summary of softprops/action-gh-release tag/ref behavior and requirements
- tag_name input: defaults to github.ref (the workflow ref). Use the tag name you want with with.tag_name. Documentation shows tag_name defaults to github.ref. [1]
- Expectation: the action is intended to run for tag pushes (refs/tags/*). README recommends gating the step or event to tag pushes (e.g., if: startsWith(github.ref, 'refs/tags/')). [1][2]
- Practical requirement: the tag you reference must exist in the repository (a push of a tag or an explicit tag object). If you pass a tag_name that does not exist (or run the action on a branch ref), the release API call can fail (examples/issues show 403/failed release when using tag_name like "latest" without an actual tag). [2]
- If you need to create a release for a branch commit, create a tag first (or ensure tag_name points to an existing tag/sha) before invoking the action. Alternatively, gate the action to tag pushes so github.ref will be a tag ref. [1][2]
Sources:
[1] softprops/action-gh-release README (usage, tag_name default and tag-gating).
[2] softprops/action-gh-release GitHub issue reporting failures when using non-existing tag_name (example "latest").
🏁 Script executed:
git ls-files | grep -E "\.github/workflows"Repository: decidim/docker
Length of output: 132
Release step will fail on branch pushes without proper tag handling.
softprops/action-gh-release defaults tag_name to github.ref and requires an actual tag ref. Since this workflow triggers on push: branches: [main], the release step at lines 21-24 will fail with a failed release API call when invoked on branch pushes. Gate the release step with if: startsWith(github.ref, 'refs/tags/') or restrict the trigger to tag pushes only (e.g., on: push: tags: ['v*']).
🔧 Proposed fix (tag-only release)
-on:
- push:
- branches:
- - main
+on:
+ push:
+ tags:
+ - 'v*'
workflow_dispatch:Or add a conditional gate to the release step:
- name: Release
+ if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2🤖 Prompt for AI Agents
In @.github/workflows/build_install_folder.yml around lines 3 - 7, The release
step using softprops/action-gh-release is vulnerable because tag_name defaults
to github.ref and the workflow is triggered on branch pushes; either restrict
the workflow trigger to tag pushes (e.g., change on: push to push: tags: ['v*'])
or add a conditional on the release job/step (use if: startsWith(github.ref,
'refs/tags/')) so the softprops/action-gh-release step (the step invoking
softprops/action-gh-release and setting tag_name) only runs for tag refs.
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
Co-authored-by: Tom Greenwood <101816158+greenwoodt@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@install/dependencies/build_env.sh`:
- Around line 168-175: The script branches to call get_storage_keys when the
user chooses S3 but never sets the STORAGE variable, causing failures under set
-u; update the code so STORAGE is set to a valid value when S3 is chosen (e.g.,
set STORAGE="s3")—either inside get_storage_keys or immediately after calling
get_storage_keys in the case for [Yy]*—and ensure any required export or default
fallback remains for other branches; reference the STORAGE variable and the
get_storage_keys call to locate where to add the assignment.
- Around line 263-271: The heredoc writing to BUILD_ENV_PATH currently includes
leading spaces before each AWS_* line (inside the STORAGE conditional), which
will be emitted literally into the .env; update the heredoc in build_env.sh so
the variable lines (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_BUCKET,
AWS_REGION, AWS_ENDPOINT) have no leading whitespace (or switch to an
unindented/left-aligned EOF marker) so the resulting file contains lines like
AWS_ACCESS_KEY_ID="..." with no leading spaces.
- Around line 6-11: The BUILD_ENV_PATH assignment uses an unsafe expansion of
REPOSITORY_PATH which under set -u will cause a crash before the subsequent
validation runs; fix by validating REPOSITORY_PATH exists before using it (move
the if [ -z "${REPOSITORY_PATH:-}" ] check above the BUILD_ENV_PATH assignment)
or change the assignment to use safe expansion (e.g.,
BUILD_ENV_PATH="${REPOSITORY_PATH:-}/.env") so the script does not error out
when REPOSITORY_PATH is unset.
In `@install/scripts/entrypoint.sh`:
- Around line 27-34: The script prints "✅ Migrations are all up" unconditionally
even when SKIP_MIGRATIONS is set; update the logic so the success message is
only echoed after running bundle exec rails db:migrate (when SKIP_MIGRATIONS is
unset), and emit a clear different message when SKIP_MIGRATIONS is set (or
remove the unconditional echo). Locate the SKIP_MIGRATIONS conditional and move
or conditionally guard the echo "✅ Migrations are all up" so it only runs after
the bundle exec rails db:migrate branch, leaving the existing echo "⚠️ Skipping
migrations!" in the else branch.
♻️ Duplicate comments (4)
install/scripts/entrypoint.sh (1)
1-14: Add fail-fast behavior for robustness.The script lacks
set -e, so failures inbundle install,rake, orrails db:migratewon't halt execution, potentially starting the container in a broken state. This was flagged in a previous review.install/dependencies/generate_vapid_keys.sh (1)
21-26: Add validation for extracted VAPID keys.If
grepreturns no matches (e.g., the Rails task output format changes or fails silently), empty keys are exported and the installer proceeds with invalid configuration. This will cause push notification failures at runtime.Proposed fix
VAPID_PUBLIC_KEY=$(echo "$output" | grep 'VAPID_PUBLIC_KEY' | cut -d'=' -f2) VAPID_PRIVATE_KEY=$(echo "$output" | grep 'VAPID_PRIVATE_KEY' | cut -d'=' -f2) +if [ -z "$VAPID_PUBLIC_KEY" ] || [ -z "$VAPID_PRIVATE_KEY" ]; then + echo "❌ Failed to extract VAPID keys from generator output" + exit 1 +fi + # Export the keys for use by calling script export VAPID_PUBLIC_KEY export VAPID_PRIVATE_KEYinstall/dependencies/build_env.sh (2)
114-125: InitializeCOMPOSE_PROFILESbefore the case statement to prevent crash.
COMPOSE_PROFILESis only set inbuild_local_database(line 68). When the user chooses external database, line 259 expands an unset variable underset -u, crashing the script.Proposed fix
+COMPOSE_PROFILES="" + case $yn in [Yy]*) EXTERNAL_DATABASE=true build_external_database ;; [Nn]*) EXTERNAL_DATABASE=false build_local_database ;; esac
191-192: Fix typo in variable name:MAPS_API_PROIVDER→MAPS_API_PROVIDER.The misspelled variable reference means any pre-existing
MAPS_API_PROVIDERvalue is ignored, always defaulting to "here".Proposed fix
read -r -p "HERE API KEY: " MAPS_API_KEY </dev/tty -MAPS_API_PROVIDER=${MAPS_API_PROIVDER=-here} +MAPS_API_PROVIDER=${MAPS_API_PROVIDER:-here}
🧹 Nitpick comments (1)
install/dependencies/build_env.sh (1)
104-109: Consider hiding password input withread -rs.Database password is visible as the user types. The same applies to SMTP_PASSWORD (line 136) and AWS_SECRET_ACCESS_KEY (line 158). Using
-ssuppresses echo for sensitive fields.Example fix for this block
while [ -z "${DATABASE_PASSWORD:-}" ]; do - read -r -p "Database password: " DATABASE_PASSWORD </dev/tty + read -rs -p "Database password: " DATABASE_PASSWORD </dev/tty + echo # newline after hidden input if [ -z "$DATABASE_PASSWORD" ]; then echo "❌ Database password cannot be empty" fi done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@install/install.sh`:
- Around line 39-42: The script currently sets REPOSITORY_PATH using only
DECIDIM_PATH, ignoring a user-set REPOSITORY_PATH; update the assignment for the
REPOSITORY_PATH variable so it first uses the environment-provided
REPOSITORY_PATH if present, then falls back to DECIDIM_PATH, and finally to the
default "/opt/decidim". Modify the REPOSITORY_PATH assignment (the
REPOSITORY_PATH variable near the top of the script) to evaluate in that
priority order and keep REPOSITORY_URL and REPOSITORY_BRANCH unchanged.
In `@install/up.sh`:
- Around line 6-12: The script assumes REPOSITORY_PATH is set and fails under
set -u; before defining ENV_FILE add a safe default for REPOSITORY_PATH (e.g.,
use shell parameter expansion to fall back to a sensible path such as the
repository root or the script's parent directory) so
ENV_FILE="${REPOSITORY_PATH}/.env" works when up.sh is run standalone; update
install/up.sh to set REPOSITORY_PATH if unset (affecting the ENV_FILE assignment
and subsequent checks) using the parameter expansion pattern so no runtime error
occurs when REPOSITORY_PATH is missing.
♻️ Duplicate comments (3)
install/dependencies/build_env.sh (1)
194-195: Fix map provider default assignment (-heretypo).
Line 195 setsMAPS_API_PROVIDERto-herewhen unset, which is likely invalid and inconsistent with Line 252’s default. Use the standard:-heredefault.🛠️ Proposed fix
-MAPS_API_PROVIDER=${MAPS_API_PROVIDER=-here} +MAPS_API_PROVIDER=${MAPS_API_PROVIDER:-here}If you want to confirm how the variable is consumed across scripts and compose files:
#!/bin/bash rg -n "MAPS_(API_)?PROVIDER" -g '*.sh' -g '*.yml' -g '*.yaml'install/install.sh (1)
67-75: Add integrity verification for deploy.zip before unzip.
Lines 67‑75 fetch and extract a remote archive that is later sourced. Without checksum/signature verification, a compromised release becomes RCE.🔒 Suggested checksum verification
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" + +curl -fsSL \ + -o "$TMP/deploy.zip.sha256" \ + "$REPOSITORY_URL/releases/download/latest/deploy.zip.sha256" +(cd "$TMP" && sha256sum -c deploy.zip.sha256)If you want to confirm whether the release workflow already publishes checksums:
#!/bin/bash rg -n "sha256|checksum" .github/workflowsREADME.md (1)
169-169: Add period after “etc.”
Line 169 should use “etc.).” for correct punctuation.✏️ Suggested edit
-| **MAPS_PROVIDER** | `here` | app | Selects map provider (here, mapbox, google, etc). | +| **MAPS_PROVIDER** | `here` | app | Selects map provider (here, mapbox, google, etc.). |
🧹 Nitpick comments (1)
install/dependencies/build_env.sh (1)
137-141: Hide secret inputs in prompts.
Lines 138 and 160 echo secrets to the terminal. Usingread -sprevents shoulder‑surfing and keeps sensitive values out of scrollback.🔒 Proposed update
-read -r -p "SMTP_PASSWORD: " SMTP_PASSWORD </dev/tty +read -r -s -p "SMTP_PASSWORD: " SMTP_PASSWORD </dev/tty +echo @@ -read -r -p "Secret Access Key: " AWS_SECRET_ACCESS_KEY </dev/tty +read -r -s -p "Secret Access Key: " AWS_SECRET_ACCESS_KEY </dev/tty +echoPlease verify the prompt flow still renders clearly in your target terminals after masking input.
Also applies to: 159-161
| REPOSITORY_PATH=${DECIDIM_PATH:-/opt/decidim} | ||
| REPOSITORY_URL="https://github.com/decidim/docker" | ||
| REPOSITORY_BRANCH="feat/decidim_install" | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, check the full context of install/install.sh around lines 39-42
head -n 60 install/install.sh | tail -n +1Repository: decidim/docker
Length of output: 2855
🏁 Script executed:
#!/bin/bash
# Search for usage of REPOSITORY_PATH and DECIDIM_PATH across the repo
rg -n "DECIDIM_PATH|REPOSITORY_PATH" -g '*.sh' -g '*.md' -B 2 -A 2Repository: decidim/docker
Length of output: 2819
Respect the documented REPOSITORY_PATH environment variable override.
The script ignores any user-provided REPOSITORY_PATH and only reads DECIDIM_PATH, contradicting the documented behavior in README.md which states users can change the installation directory with the REPOSITORY_PATH environment variable.
Proposed fix
-REPOSITORY_PATH=${DECIDIM_PATH:-/opt/decidim}
+REPOSITORY_PATH=${REPOSITORY_PATH:-${DECIDIM_PATH:-/opt/decidim}}This ensures the priority is: user-provided REPOSITORY_PATH > DECIDIM_PATH fallback > /opt/decidim default.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| REPOSITORY_PATH=${DECIDIM_PATH:-/opt/decidim} | |
| REPOSITORY_URL="https://github.com/decidim/docker" | |
| REPOSITORY_BRANCH="feat/decidim_install" | |
| REPOSITORY_PATH=${REPOSITORY_PATH:-${DECIDIM_PATH:-/opt/decidim}} | |
| REPOSITORY_URL="https://github.com/decidim/docker" | |
| REPOSITORY_BRANCH="feat/decidim_install" | |
🤖 Prompt for AI Agents
In `@install/install.sh` around lines 39 - 42, The script currently sets
REPOSITORY_PATH using only DECIDIM_PATH, ignoring a user-set REPOSITORY_PATH;
update the assignment for the REPOSITORY_PATH variable so it first uses the
environment-provided REPOSITORY_PATH if present, then falls back to
DECIDIM_PATH, and finally to the default "/opt/decidim". Modify the
REPOSITORY_PATH assignment (the REPOSITORY_PATH variable near the top of the
script) to evaluate in that priority order and keep REPOSITORY_URL and
REPOSITORY_BRANCH unchanged.
| 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." | ||
| exit 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Read the full install/up.sh file
cat -n install/up.shRepository: decidim/docker
Length of output: 172
🏁 Script executed:
# Search for references to up.sh to understand invocation patterns
rg -n "up\.sh" --type sh --type md -A 2 -B 2Repository: decidim/docker
Length of output: 276
🏁 Script executed:
# Check if there's a parent installation script that might set REPOSITORY_PATH
fd -e sh -path "*/install/*" | head -20Repository: decidim/docker
Length of output: 226
🏁 Script executed:
# Read the full install/up.sh file
wc -l install/up.shRepository: decidim/docker
Length of output: 74
🏁 Script executed:
# Read install/up.sh
cat -n install/up.shRepository: decidim/docker
Length of output: 769
🏁 Script executed:
# Read install/install.sh around the source line to see REPOSITORY_PATH setup
sed -n '1,130p' install/install.sh | tail -50Repository: decidim/docker
Length of output: 1349
🏁 Script executed:
# Check where REPOSITORY_PATH is set in install/install.sh
sed -n '1,130p' install/install.sh | head -100Repository: decidim/docker
Length of output: 3854
🏁 Script executed:
# Get more context from the beginning of install/install.sh
head -50 install/install.shRepository: decidim/docker
Length of output: 2539
🏁 Script executed:
# Check if REPOSITORY_PATH is exported in install/install.sh
grep -n "export REPOSITORY_PATH" install/install.shRepository: decidim/docker
Length of output: 40
🏁 Script executed:
# Get the full context around REPOSITORY_PATH and its export
sed -n '40,50p' install/install.shRepository: decidim/docker
Length of output: 396
Add default for REPOSITORY_PATH to support standalone execution of up.sh.
While up.sh is normally sourced from install/install.sh (where REPOSITORY_PATH is set), the script would fail under set -u if invoked directly. Adding a default improves robustness:
Suggested fix
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+REPOSITORY_PATH="${REPOSITORY_PATH:-$SCRIPT_DIR}"
ENV_FILE="${REPOSITORY_PATH}/.env"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 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." | |
| exit 1 | |
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
| REPOSITORY_PATH="${REPOSITORY_PATH:-$SCRIPT_DIR}" | |
| 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." | |
| exit 1 |
🤖 Prompt for AI Agents
In `@install/up.sh` around lines 6 - 12, The script assumes REPOSITORY_PATH is set
and fails under set -u; before defining ENV_FILE add a safe default for
REPOSITORY_PATH (e.g., use shell parameter expansion to fall back to a sensible
path such as the repository root or the script's parent directory) so
ENV_FILE="${REPOSITORY_PATH}/.env" works when up.sh is run standalone; update
install/up.sh to set REPOSITORY_PATH if unset (affecting the ENV_FILE assignment
and subsequent checks) using the parameter expansion pattern so no runtime error
occurs when REPOSITORY_PATH is missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🤖 Fix all issues with AI agents
In `@install/docker-compose.yml`:
- Line 87: The Traefik dashboard is exposed without authentication via the
command flag --entrypoints.traefik.address=:8080; either disable the dashboard
by removing/enforcing --api=false in the Traefik service command or add
authentication middleware and attach it to the traefik router: create a basic
auth middleware (htpasswd) and reference it from the router that serves the
dashboard (the router named/labelled "traefik"), or add the auth via a
static/dynamic provider referenced by the service; update the docker-compose
Traefik service command/labels and the router configuration to ensure the
dashboard endpoint is protected.
- Around line 63-69: The worker service's environment omits a value for
BUNDLE_GEMFILE while the app service sets BUNDLE_GEMFILE=Gemfile.wrapper,
causing inconsistent Gemfile usage; update the worker service environment to
explicitly set BUNDLE_GEMFILE=Gemfile.wrapper so both services use the same
Gemfile (look for the worker environment block and the app service
BUNDLE_GEMFILE setting to ensure they match).
- Around line 19-25: The traefik label traefik.http.routers.app.rule currently
uses Host(`$DECIDIM_DOMAIN`) which Docker Compose will interpolate at compose
time and produce malformed labels; update the label to escape the dollar sign so
the runtime container receives the literal variable (use $$DECIDIM_DOMAIN) so
Traefik can resolve it at runtime. Locate the labels block containing
traefik.http.routers.app.rule and replace the single-dollar variable with a
double-dollar escape to prevent compose interpolation.
In `@install/README.md`:
- Line 249: The README has duplicate and incorrect section numbers: the heading
"6.3 Email Domain Authentication" should be renumbered to follow the prior
subsection (e.g., change the second "6.3" to "6.4" or the appropriate next
number), and the "Step 7" subsection references that currently use 6.1, 6.2, 6.3
must be updated to 7.1, 7.2, 7.3 respectively; locate the headings and the "Step
7" block in install/README.md (search for the literal headings "6.3 Email Domain
Authentication" and "Step 7") and update the numeric prefixes so numbering is
sequential and consistent across the file.
- Around line 294-297: The restart command in the README targets a non-existent
Docker service name ("sidekiq"); update the command to use the actual service
name defined in docker-compose.yml (replace "sidekiq" with "worker"), or
alternatively rename the service in docker-compose.yml to "sidekiq" if that
naming is preferred—ensure the README's "Restart Sidekiq if needed" section and
the docker-compose service names (worker) match.
- Around line 327-332: The README's update steps reference running "git pull"
but the installer delivers a zip (no git repo); remove or replace the git pull
step in the sequence shown and instead document the correct update flow: show
running "docker compose pull" then "docker compose up -d" to refresh images, and
add a short note telling users that to update installer scripts or configuration
they must re-run the installer or download the latest release (link to the
releases page); update the block in install/README.md that contains the commands
and add the clarifying note suggested in the review.
- Around line 421-430: The log command example uses the container name "decidim"
but docker compose logs expects a service name; update the example line "docker
compose logs -f decidim" to use the service name "app" instead (leave the "db"
example as-is), and add a brief note or comment clarifying that docker compose
logs accepts service names while docker logs uses container names so readers use
"app" for compose commands.
- Around line 69-73: The displayed ssh-keygen command is truncated ("ssh-keygen
-t rsa -b 4096 -C \"") causing a syntax error; update the snippet so the command
includes a placeholder email and the closing quote (e.g., replace the truncated
string with ssh-keygen -t rsa -b 4096 -C "your_email@example.com") and ensure
the fenced code block is properly closed; target the README snippet containing
the ssh-keygen command.
- Around line 7-14: The table of contents links are broken because the actual
headings differ: the heading for server creation contains the parenthetical
"(Hetzner Example)" so its auto-generated anchor is
"#step-1-create-a-server-hetzner-example" (not "#step-1-create-a-server"), and
the final setup heading is numbered "Step 7: Complete Setup" while the TOC
points to "#step-6-complete-setup"; update the TOC entry 2 to use
"#step-1-create-a-server-hetzner-example" (or remove the parenthetical from the
heading) and update TOC entry 7 (the "Step 6/7" entry) so the link matches the
heading by either renaming the heading to "Step 6: Complete Setup" or changing
the TOC link to "#step-7-complete-setup".
🧹 Nitpick comments (5)
install/docker-compose.yml (4)
76-77: Replace deprecatedlinkswithdepends_on.The
linksdirective is deprecated in modern Docker Compose. Service discovery via container names works automatically on the default network. Usedepends_onif you need startup ordering.♻️ Proposed fix
- links: - - cache + depends_on: + - cache
84-84: Consider reducing Traefik log level for production.
DEBUGlevel logging is verbose and may expose sensitive request/response details. For a production deployment guide,INFOorWARNwould be more appropriate defaults.♻️ Proposed fix
- - --log.level=DEBUG + - --log.level=INFO
46-52: Inconsistentpull_policybetween app and worker services.The worker service has
pull_policy: always(line 51) but the app service doesn't. For consistency and to ensure both services use the same image version, consider adding the same policy to the app service.♻️ Proposed fix for app service
app: container_name: decidim image: ${DECIDIM_IMAGE:-decidim/decidim:latest} + pull_policy: always command: ["bin/rails", "server", "-b", "0.0.0.0"]
116-121: Consider adding health checks for Redis cache service.The PR objectives mention adding container health checks as a planned improvement. Adding a health check to Redis would allow dependent services to wait for Redis to be ready.
♻️ Example health check
cache: image: redis:8-alpine container_name: decidim_cache volumes: - cache_data:/data restart: always + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 3install/README.md (1)
182-188: Use proper headings instead of bold emphasis for option categories.Lines 182 and 185 use bold text (
**Free Options**,**Paid Options**) as pseudo-headings. This affects document structure and accessibility. Consider using proper heading levels.📝 Proposed fix
-**Free Options** +#### Free Options - [Gmail SMTP](https://support.google.com/a/answer/176600) (500 emails/day limit) -**Paid Options** +#### Paid Options - [Scaleway](https://www.scaleway.com/en/transactional-email-tem/)
| labels: | ||
| - "traefik.enable=true" | ||
| - "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" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Find all references to DECIDIM_DOMAIN in the codebase
rg "DECIDIM_DOMAIN" -t yml -t yaml -t env -t shRepository: decidim/docker
Length of output: 85
🏁 Script executed:
# Look for .env template files
fd -t f "\.(env|example)" install/ || fd -t f "\.env" . | head -20Repository: decidim/docker
Length of output: 40
🏁 Script executed:
# Examine the full docker-compose.yml to understand context
cat -n install/docker-compose.yml | head -40Repository: decidim/docker
Length of output: 1712
🏁 Script executed:
# Search for DECIDIM_DOMAIN in all file types
rg "DECIDIM_DOMAIN" --type-list | head -5Repository: decidim/docker
Length of output: 447
🏁 Script executed:
# Try broader search for DECIDIM_DOMAIN
rg "DECIDIM_DOMAIN"Repository: decidim/docker
Length of output: 898
🏁 Script executed:
# Check if there's a .env.example or similar in the install directory
ls -la install/ | grep -E "env|example"Repository: decidim/docker
Length of output: 40
🏁 Script executed:
# Look at more of the docker-compose.yml for context
cat -n install/docker-compose.ymlRepository: decidim/docker
Length of output: 5071
🏁 Script executed:
# Check if there's a .env file or .env.example in the repository
fd -t f "\.env" --max-one-result install/Repository: decidim/docker
Length of output: 291
🏁 Script executed:
# Look at how other labels use variables in the same file
grep -n "traefik\." install/docker-compose.yml | head -10Repository: decidim/docker
Length of output: 544
🏁 Script executed:
# Check how DECIDIM_DOMAIN is handled in the build script
cat -n install/dependencies/build_env.sh | grep -A 2 -B 2 "DECIDIM_DOMAIN"Repository: decidim/docker
Length of output: 1061
🏁 Script executed:
# Check if there's a .env file or .env.example
find install -name ".env*" -o -name "env.example"Repository: decidim/docker
Length of output: 40
🏁 Script executed:
# Look at the actual syntax patterns used in docker-compose.yml more broadly
grep -E "\$\{|\$[A-Z_]+" install/docker-compose.yml | head -15Repository: decidim/docker
Length of output: 40
🏁 Script executed:
# Check the actual docker-compose interpolation behavior by looking for documentation or comments
grep -r "interpolat\|expand\|\${\|\$[A-Z]" install/ --include="*.md" --include="*.sh" | head -10Repository: decidim/docker
Length of output: 790
🏁 Script executed:
# Check how the .env is actually created and what values it contains
cat install/dependencies/build_env.sh | tail -50Repository: decidim/docker
Length of output: 1393
Use $$DECIDIM_DOMAIN to prevent Docker Compose from interpolating the variable.
Docker Compose will interpolate $DECIDIM_DOMAIN using the value from .env, which is written with quotes (DECIDIM_DOMAIN="example.com"). This causes the label to become malformed: Host(\"example.com"`). Use $$` to escape the dollar sign so Docker Compose passes it literally to the container, allowing Traefik to resolve the variable from the runtime environment.
🤖 Prompt for AI Agents
In `@install/docker-compose.yml` around lines 19 - 25, The traefik label
traefik.http.routers.app.rule currently uses Host(`$DECIDIM_DOMAIN`) which
Docker Compose will interpolate at compose time and produce malformed labels;
update the label to escape the dollar sign so the runtime container receives the
literal variable (use $$DECIDIM_DOMAIN) so Traefik can resolve it at runtime.
Locate the labels block containing traefik.http.routers.app.rule and replace the
single-dollar variable with a double-dollar escape to prevent compose
interpolation.
| environment: | ||
| - BUNDLE_GEMFILE | ||
| - DATABASE_URL | ||
| - SECRET_KEY_BASE | ||
| - DECIDIM_FORCE_SSL=false | ||
| - QUEUE_ADAPTER=sidekiq | ||
| - REDIS_URL=${REDIS_URL:-redis://decidim_cache:6379/0} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worker service has inconsistent BUNDLE_GEMFILE configuration.
Line 64 declares BUNDLE_GEMFILE without a value, meaning it will be empty unless set in .env. However, the app service explicitly sets BUNDLE_GEMFILE=Gemfile.wrapper (line 29). This inconsistency may cause the worker to use a different Gemfile than the app, leading to gem version mismatches or missing dependencies.
🛠️ Proposed fix
environment:
- - BUNDLE_GEMFILE
+ - BUNDLE_GEMFILE=Gemfile.wrapper
- DATABASE_URL📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| environment: | |
| - BUNDLE_GEMFILE | |
| - DATABASE_URL | |
| - SECRET_KEY_BASE | |
| - DECIDIM_FORCE_SSL=false | |
| - QUEUE_ADAPTER=sidekiq | |
| - REDIS_URL=${REDIS_URL:-redis://decidim_cache:6379/0} | |
| environment: | |
| - BUNDLE_GEMFILE=Gemfile.wrapper | |
| - DATABASE_URL | |
| - SECRET_KEY_BASE | |
| - DECIDIM_FORCE_SSL=false | |
| - QUEUE_ADAPTER=sidekiq | |
| - REDIS_URL=${REDIS_URL:-redis://decidim_cache:6379/0} |
🤖 Prompt for AI Agents
In `@install/docker-compose.yml` around lines 63 - 69, The worker service's
environment omits a value for BUNDLE_GEMFILE while the app service sets
BUNDLE_GEMFILE=Gemfile.wrapper, causing inconsistent Gemfile usage; update the
worker service environment to explicitly set BUNDLE_GEMFILE=Gemfile.wrapper so
both services use the same Gemfile (look for the worker environment block and
the app service BUNDLE_GEMFILE setting to ensure they match).
| - --log.level=DEBUG | ||
| - --entrypoints.web.address=:80 | ||
| - --entrypoints.websecure.address=:443 | ||
| - --entrypoints.traefik.address=:8080 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Traefik dashboard is exposed without authentication.
The Traefik API/dashboard is enabled on port 8080 and routed via the traefik router, but no authentication middleware is configured. While port 8080 isn't published to the host, the dashboard is still accessible if someone accesses the container directly or if the routing exposes it. Consider either disabling the dashboard (--api=false) or adding basic auth middleware.
🔒 Option 1: Disable the dashboard
command:
- - --api
+ - --api.dashboard=false🔒 Option 2: Add authentication (requires generating htpasswd)
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.service=api@internal"
+ - "traefik.http.routers.traefik.middlewares=auth"
+ - "traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_DASHBOARD_AUTH}"Also applies to: 101-103
🤖 Prompt for AI Agents
In `@install/docker-compose.yml` at line 87, The Traefik dashboard is exposed
without authentication via the command flag --entrypoints.traefik.address=:8080;
either disable the dashboard by removing/enforcing --api=false in the Traefik
service command or add authentication middleware and attach it to the traefik
router: create a basic auth middleware (htpasswd) and reference it from the
router that serves the dashboard (the router named/labelled "traefik"), or add
the auth via a static/dynamic provider referenced by the service; update the
docker-compose Traefik service command/labels and the router configuration to
ensure the dashboard endpoint is protected.
| 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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n install/README.md | head -30Repository: decidim/docker
Length of output: 1309
🏁 Script executed:
grep -n "^#" install/README.mdRepository: decidim/docker
Length of output: 1927
Fix invalid table of contents anchor links due to heading mismatches.
Two issues prevent the TOC links from working:
- Line 39 heading includes "(Hetzner Example)" — the auto-generated anchor will be
#step-1-create-a-server-hetzner-example, not#step-1-create-a-server - Line 257 heading is "Step 7: Complete Setup" but TOC entry references
#step-6-complete-setup— the document numbering is inconsistent (shows Step 7, not Step 6)
Update the TOC anchor for item 2 to include the extra text, or simplify the heading. For item 7, either renumber the heading to "Step 6" or update the TOC link to #step-7-complete-setup.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
7-7: Link fragments should be valid
(MD051, link-fragments)
8-8: Link fragments should be valid
(MD051, link-fragments)
9-9: Link fragments should be valid
(MD051, link-fragments)
10-10: Link fragments should be valid
(MD051, link-fragments)
11-11: Link fragments should be valid
(MD051, link-fragments)
12-12: Link fragments should be valid
(MD051, link-fragments)
13-13: Link fragments should be valid
(MD051, link-fragments)
14-14: Link fragments should be valid
(MD051, link-fragments)
🤖 Prompt for AI Agents
In `@install/README.md` around lines 7 - 14, The table of contents links are
broken because the actual headings differ: the heading for server creation
contains the parenthetical "(Hetzner Example)" so its auto-generated anchor is
"#step-1-create-a-server-hetzner-example" (not "#step-1-create-a-server"), and
the final setup heading is numbered "Step 7: Complete Setup" while the TOC
points to "#step-6-complete-setup"; update the TOC entry 2 to use
"#step-1-create-a-server-hetzner-example" (or remove the parenthetical from the
heading) and update TOC entry 7 (the "Step 6/7" entry) so the link matches the
heading by either renaming the heading to "Step 6: Complete Setup" or changing
the TOC link to "#step-7-complete-setup".
| ```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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete ssh-keygen command will confuse users.
The command is truncated and missing the email address placeholder and closing quote. This will cause a syntax error or leave users stuck.
📝 Proposed fix
- ```bash
- ssh-keygen -t rsa -b 4096 -C "
- ```
+ ```bash
+ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
+ ```📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ```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. |
🤖 Prompt for AI Agents
In `@install/README.md` around lines 69 - 73, The displayed ssh-keygen command is
truncated ("ssh-keygen -t rsa -b 4096 -C \"") causing a syntax error; update the
snippet so the command includes a placeholder email and the closing quote (e.g.,
replace the truncated string with ssh-keygen -t rsa -b 4096 -C
"your_email@example.com") and ensure the fenced code block is properly closed;
target the README snippet containing the ssh-keygen command.
| 4. **Monitor logs**: Check for suspicious activity | ||
| 5. **Backup regularly**: Database and configuration files | ||
| ### 6.3 Email Domain Authentication |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Section numbering is inconsistent.
There are two sections numbered "6.3" (lines 239 and 249), and "Step 7" (line 257) uses subsection numbers 6.1, 6.2, 6.3 instead of 7.1, 7.2, 7.3.
📝 Proposed fix
-### 6.3 Email Domain Authentication
+### 6.4 Email Domain Authentication
...
## ✅ Step 7: Complete Setup
-### 6.1 Create System Administrator
+### 7.1 Create System Administrator
...
-### 6.2 Access Your Decidim Instance
+### 7.2 Access Your Decidim Instance
...
-### 6.3 Configure Your Organization
+### 7.3 Configure Your Organization
...
-### 6.4 Background Jobs & Maintenance
+### 7.4 Background Jobs & MaintenanceAlso applies to: 257-259
🤖 Prompt for AI Agents
In `@install/README.md` at line 249, The README has duplicate and incorrect
section numbers: the heading "6.3 Email Domain Authentication" should be
renumbered to follow the prior subsection (e.g., change the second "6.3" to
"6.4" or the appropriate next number), and the "Step 7" subsection references
that currently use 6.1, 6.2, 6.3 must be updated to 7.1, 7.2, 7.3 respectively;
locate the headings and the "Step 7" block in install/README.md (search for the
literal headings "6.3 Email Domain Authentication" and "Step 7") and update the
numeric prefixes so numbering is sequential and consistent across the file.
| # Restart Sidekiq if needed | ||
| docker compose restart sidekiq | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect service name in restart command.
The command references sidekiq but the service is named worker in docker-compose.yml.
📝 Proposed fix
# Restart Sidekiq if needed
-docker compose restart sidekiq
+docker compose restart worker📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Restart Sidekiq if needed | |
| docker compose restart sidekiq | |
| ``` | |
| # Restart Sidekiq if needed | |
| docker compose restart worker |
🤖 Prompt for AI Agents
In `@install/README.md` around lines 294 - 297, The restart command in the README
targets a non-existent Docker service name ("sidekiq"); update the command to
use the actual service name defined in docker-compose.yml (replace "sidekiq"
with "worker"), or alternatively rename the service in docker-compose.yml to
"sidekiq" if that naming is preferred—ensure the README's "Restart Sidekiq if
needed" section and the docker-compose service names (worker) match.
| ```bash | ||
| cd /opt/decidim | ||
| git pull | ||
| docker compose pull | ||
| docker compose up -d | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update instructions reference git pull but installation uses zip download.
The installation is done via curl | bash which downloads a zip file, not a git clone. Users won't have a git repository to pull from. Consider providing alternative update instructions or clarifying the intended update workflow.
📝 Suggested alternative
### Updating Decidim
```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+> Note: For script and configuration updates, re-run the installer or check the releases page for the latest install package.
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
In @install/README.md around lines 327 - 332, The README's update steps
reference running "git pull" but the installer delivers a zip (no git repo);
remove or replace the git pull step in the sequence shown and instead document
the correct update flow: show running "docker compose pull" then "docker compose
up -d" to refresh images, and add a short note telling users that to update
installer scripts or configuration they must re-run the installer or download
the latest release (link to the releases page); update the block in
install/README.md that contains the commands and add the clarifying note
suggested in the review.
</details>
<!-- fingerprinting:phantom:poseidon:ocelot -->
<!-- This is an auto-generated comment by CodeRabbit -->
| ```bash | ||
| # Application logs | ||
| docker compose logs -f decidim | ||
| # Database logs | ||
| docker compose logs -f db | ||
| # All services | ||
| docker compose logs -f | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Service name mismatch in log command example.
The command uses decidim which is the container name, but docker compose logs expects the service name app. While container names work with docker logs, they don't work with docker compose logs.
📝 Proposed fix
# Application logs
-docker compose logs -f decidim
+docker compose logs -f app
# Database logs
docker compose logs -f db🤖 Prompt for AI Agents
In `@install/README.md` around lines 421 - 430, The log command example uses the
container name "decidim" but docker compose logs expects a service name; update
the example line "docker compose logs -f decidim" to use the service name "app"
instead (leave the "db" example as-is), and add a brief note or comment
clarifying that docker compose logs accepts service names while docker logs uses
container names so readers use "app" for compose commands.
This PR closes #113 .
We are adding a script that enables the creation of a Decidim instance based on the docker images built in this repository. The user will be guided through some questions on how to properly configure the instance, and the script itself will take care of the necessary dependencies (such as the database, where the storage is going to be located, etc).
Some improvements:
This will generate extra-security on the download of the shell script and the files it uses, giving the final user more security.
What we still need
How to test
Using the released zip.
sudo curl -s https://raw.githubusercontent.com/decidim/docker/refs/heads/feat/decidim_install/install/install.sh | bashWhile developing we might not have access to the released zip, the way to test it is to zip ourselfs the script folder and push it to the server.
Later on, we need the deploy.zip to be under the
/tmp/decidim-docker-files/deploy.zip. It's a bit messy right now.Also, if you want to try it locally you can use
multipassSummary by CodeRabbit
New Features
Documentation
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.