diff --git a/.gitignore b/.gitignore index a1e8c19..eae59bb 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ public/sw.js* # Ignore Tailwind configuration tailwind.config.js yarn-error.log +minio_data diff --git a/Dockerfile b/Dockerfile index ddc7ce2..69edf4a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,19 +7,19 @@ ENV RAILS_ENV=production \ WORKDIR /opt/decidim RUN apt-get update && apt-get install -y --no-install-recommends \ - libpq-dev curl git libicu-dev build-essential openssl \ - && curl -fsSL https://deb.nodesource.com/setup_18.x | bash \ + libpq-dev curl git libicu-dev build-essential \ + && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ && npm install --global yarn \ && gem install bundler:2.5.22 \ && apt-get clean && rm -rf /var/lib/apt/lists/* COPY Gemfile Gemfile.lock ./ + RUN bundle install --jobs="$(nproc)" --retry=3 COPY . . -RUN yarn add axe-core RUN bundle exec rake decidim:webpacker:install && \ bundle exec rake assets:precompile && \ bundle exec rails shakapacker:compile diff --git a/Gemfile b/Gemfile index affed65..e895887 100644 --- a/Gemfile +++ b/Gemfile @@ -25,6 +25,7 @@ gem "decidim-verifications", github: "decidim/decidim", tag: "v0.29.1" gem "bootsnap", "~> 1.4" gem "puma", ">= 6.3.1" +gem "aws-sdk-s3" gem "dalli" gem "dotenv-rails", "~> 2.7" gem "letter_opener_web", "~> 2.0" diff --git a/Gemfile.lock b/Gemfile.lock index c860de6..4bc13f4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -254,6 +254,22 @@ GEM addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) + aws-eventstream (1.3.0) + aws-partitions (1.894.0) + aws-sdk-core (3.191.3) + aws-eventstream (~> 1, >= 1.3.0) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.8) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.77.0) + aws-sdk-core (~> 3, >= 3.191.0) + aws-sigv4 (~> 1.1) + aws-sdk-s3 (1.143.0) + aws-sdk-core (~> 3, >= 3.191.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.8) + aws-sigv4 (1.8.0) + aws-eventstream (~> 1, >= 1.0.2) base64 (0.2.0) batch-loader (1.5.0) bcrypt (3.1.20) @@ -285,6 +301,14 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) + carrierwave (2.2.6) + activemodel (>= 5.0.0) + activesupport (>= 5.0.0) + addressable (~> 2.6) + image_processing (~> 1.1) + marcel (~> 1.0.0) + mini_mime (>= 0.1.3) + ssrf_filter (~> 1.0) cells (4.1.8) declarative-builder (~> 0.2.0) declarative-option (< 0.2.0) @@ -385,13 +409,23 @@ GEM activemodel (>= 3.2) mime-types (>= 1.0) flamegraph (0.9.5) + fog-aws (3.21.0) + fog-core (~> 2.1) + fog-json (~> 1.1) + fog-xml (~> 0.1) fog-core (2.6.0) builder excon (~> 1.0) formatador (>= 0.2, < 2.0) mime-types + fog-json (1.2.0) + fog-core + multi_json (~> 1.10) fog-local (0.8.0) fog-core (>= 1.27, < 3.0) + fog-xml (0.1.4) + fog-core + nokogiri (>= 1.5.11, < 2.0.0) formatador (1.1.0) foundation_rails_helper (4.0.1) actionpack (>= 4.1, < 7.1) @@ -447,6 +481,7 @@ GEM invisible_captcha (0.13.0) rails (>= 3.2.0) io-console (0.7.2) + jmespath (1.6.2) json (2.8.2) jwt (2.9.3) base64 @@ -497,6 +532,7 @@ GEM mini_mime (1.1.5) minitest (5.25.1) msgpack (1.7.5) + multi_json (1.15.0) multi_xml (0.7.1) bigdecimal (~> 3.1) net-http (0.5.0) @@ -777,6 +813,7 @@ GEM spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) spring (>= 4) + ssrf_filter (1.1.2) stackprof (0.2.26) stringio (3.1.2) temple (0.10.3) @@ -850,10 +887,12 @@ PLATFORMS DEPENDENCIES activejob-uniqueness + aws-sdk-s3 bootsnap (~> 1.4) brakeman (~> 6.1) bullet byebug (~> 11.0) + carrierwave dalli decidim-accountability! decidim-admin! @@ -875,6 +914,7 @@ DEPENDENCIES decidim-verifications! dotenv-rails (~> 2.7) flamegraph + fog-aws letter_opener_web (~> 2.0) listen (~> 3.1) memory_profiler diff --git a/Makefile b/Makefile index 3cd738c..083108a 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ rebuild: docker volume rm decidim-app_shared-volume || true @make up -tls-certificate: +tls-cert: mkdir -p $(HOME)/.decidim/tls-certificate openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ -subj "/C=FR/ST=France/L=Paris/O=decidim/CN=decidim.eu" \ diff --git a/README.md b/README.md index 33b7fbf..a543593 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,7 @@ Here's the revised and improved formatting of the table: | decidim-templates | v0.29.1 | Module for using templates within the Decidim platform. ## 🚀 Getting started -- [Coming soon] - +- Local development setup with Docker can be found [here](./docs/DOCKER.md) ## 👋 Contributing - See our [contributing guide](./docs/CONTRIBUTING.md) diff --git a/config/environments/production.rb b/config/environments/production.rb index 4368420..1fd287c 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -39,7 +39,7 @@ # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX # Store uploaded files on the local file system (see config/storage.yml for options). - config.active_storage.service = Rails.application.secrets.dig(:storage, :provider) || :local + config.active_storage.service = Rails.application.secrets.dig(:storage, :provider)&.to_sym || :local config.active_storage.service_urls_expire_in = if Rails.application.secrets.dig(:storage, :s3, :access_key_id).blank? "120000" diff --git a/config/initializers/decidim.rb b/config/initializers/decidim.rb index 31427ed..1a90b5b 100644 --- a/config/initializers/decidim.rb +++ b/config/initializers/decidim.rb @@ -388,7 +388,10 @@ # Defines additional content security policies following the structure # Read more: https://docs.decidim.org/en/develop/configure/initializer#_content_security_policy - config.content_security_policies_extra = {} + config.content_security_policies_extra = { + "connect-src" => %w(http://minio:9000 http://minio http://localhost:9000), + "img-src" => %w(http://minio:9000 http://minio http://localhost:9000) + } # Admin admin password configurations Rails.application.secrets.dig(:decidim, :admin_password, :strong).tap do |strong_pw| diff --git a/config/storage.yml b/config/storage.yml index 8f18353..49ec24a 100644 --- a/config/storage.yml +++ b/config/storage.yml @@ -11,8 +11,9 @@ s3: access_key_id: <%= Rails.application.secrets.dig(:storage, :s3, :access_key_id) %> secret_access_key: <%= Rails.application.secrets.dig(:storage, :s3, :secret_access_key) %> bucket: <%= Rails.application.secrets.dig(:storage, :s3, :bucket) %> + endpoint: <%= Rails.application.secrets.dig(:storage, :s3, :bucket) == "mybucket" ? "http" : "https" %>://<%= Rails.application.secrets.dig(:storage, :s3, :endpoint) %> + force_path_style: true <%= "region: #{Rails.application.secrets.dig(:storage, :s3, :region)}" if Rails.application.secrets.dig(:storage, :s3, :region) %> - <%= "endpoint: #{Rails.application.secrets.dig(:storage, :s3, :endpoint)}" if Rails.application.secrets.dig(:storage, :s3, :endpoint) %> azure: service: AzureStorage diff --git a/docker-compose.yml b/docker-compose.yml index 38b98b4..0a14f73 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,33 @@ services: + minio: - container_name: minio - image: "bitnami/minio:latest" + image: minio/minio ports: - "9000:9000" - "9001:9001" environment: - - MINIO_DEFAULT_BUCKETS=localhost - - MINIO_ROOT_USER=minioadmin - - MINIO_ROOT_PASSWORD=minioadmin - networks: - - minio_network + MINIO_ROOT_USER: minioadmin + MINIO_ROOT_PASSWORD: minioadmin + MINIO_DEFAULT_BUCKETS: mybucket volumes: - - 'minio:/bitnami/minio/data' + - ./minio_data:/data + command: server /data --console-address ":9001" + restart: always + + minio_mc: + image: minio/mc + depends_on: + - minio + entrypoint: > + /bin/sh -c " + /usr/bin/mc alias set local http://minio:9000 minioadmin minioadmin && + /usr/bin/mc mb --ignore-existing local/mybucket && + /usr/bin/mc anonymous set public local/mybucket && + /usr/bin/mc admin config set local/ cors="*" && + /usr/bin/mc admin service restart local && + echo 'Bucket mybucket created and set to public!'; + exit 0; + " database: image: postgres @@ -20,22 +35,19 @@ services: - pg-data:/var/lib/postgresql/data environment: - POSTGRES_HOST_AUTH_METHOD=trust - networks: - - minio_network + memcached: image: memcached ports: - "11211:11211" - networks: - - minio_network + redis: image: redis ports: - "6379:6379" volumes: - redis-data:/var/lib/redis/data - networks: - - minio_network + sidekiq: image: decidim-lite:1.0.0 command: [ "bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml" ] @@ -60,11 +72,14 @@ services: - PUMA_WORKERS=4 - PUMA_PRELOAD_APP=true - RAILS_SESSION_STORE=active_record - - OBJECTSTORE_S3_HOST=minio:9000 - - SCALEWAY_BUCKET_NAME=localhost - - SCALEWAY_ID=minioadmin - - SCALEWAY_TOKEN=minioadmin + - STORAGE_PROVIDER=s3 + - AWS_REGION=fr-par-1 + - AWS_ENDPOINT=minio:9000 + - AWS_BUCKET=mybucket + - AWS_ACCESS_KEY_ID=minioadmin + - AWS_SECRET_ACCESS_KEY=minioadmin depends_on: + - minio_mc - app volumes: - ./app:/decidim/app @@ -74,8 +89,7 @@ services: links: - database - redis - networks: - - minio_network + app: image: decidim-lite:1.0.0 command: [ "bundle", "exec", "rails", "server", "-b", "ssl://0.0.0.0:3000?key=/decidim/tls-certificate/key.pem&cert=/decidim/tls-certificate/cert.pem" ] @@ -100,10 +114,12 @@ services: - PUMA_WORKERS=4 - PUMA_PRELOAD_APP=true - RAILS_SESSION_STORE=active_record - - OBJECTSTORE_S3_HOST=minio:9000 - - SCALEWAY_BUCKET_NAME=localhost - - SCALEWAY_ID=minioadmin - - SCALEWAY_TOKEN=minioadmin + - STORAGE_PROVIDER=s3 + - AWS_REGION=fr-par-1 + - AWS_ENDPOINT=minio:9000 # Should be localhost:9000 to make the AJAX requests work without CORS issues + - AWS_BUCKET=mybucket + - AWS_ACCESS_KEY_ID=minioadmin + - AWS_SECRET_ACCESS_KEY=minioadmin volumes: - ./app:/decidim/app - ./config:/decidim/config @@ -112,19 +128,14 @@ services: ports: - 3000:3000 depends_on: + - minio_mc - database - redis - memcached - networks: - - minio_network - -networks: - minio_network: - driver: bridge volumes: shared-volume: { } pg-data: { } redis-data: { } - minio: - driver: local \ No newline at end of file + minio_data: { } + minio_config: { } \ No newline at end of file diff --git a/docs/DOCKER.md b/docs/DOCKER.md new file mode 100644 index 0000000..285f938 --- /dev/null +++ b/docs/DOCKER.md @@ -0,0 +1,40 @@ +# Getting started with Docker + +This guide will help you to get started with the Decidim-app using Docker. The current Docker compose configuration is not production ready and should be used for development purposes only. + +## Prerequisites + +* Docker +* Docker Compose +* Git + +## Installation + +1. Generate a self-signed certificate for HTTPS. You can use the following command to generate a self-signed certificate: + +```bash +make tls-cert +``` +_You should have a two new files at `$(HOME)/.decidim/tls-certificate/` named `key.pem` and `cert.pem`_ + +2. Run application using Docker Compose: + +```bash +make run +``` +_Seeds takes around 10 minutes to be generated, however you can start navigating while seeds are running_ + +3. If not already done, add MinIO as known host +```bash +echo '127.0.0.1 minio' >> /etc/hosts +``` + +4. Open your browser and navigate to `https://localhost:3000` +5. MinIO S3 bucket is reachable at ``http://localhost:9000`` with access key `minioadmin` and secret key `minioadmin` + +## Known issues + +* Direct upload fails and throws an error when uploading an image. + * Solution: Add `minio` as a host in your `/etc/hosts` file. +* Browser always ask to trust the self-signed certificate + * Solution: Add permanent trust exception to your browser. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e81c5f1..e9dd330 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@decidim/browserslist-config": "file:packages/browserslist-config", "@decidim/core": "file:packages/core", "@decidim/webpacker": "file:packages/webpacker", + "axe-core": "^4.10.2", "graphql": "^16.9.0", "graphql-ws": "^5.16.0" }, @@ -5919,7 +5920,6 @@ "version": "4.10.2", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", - "dev": true, "engines": { "node": ">=4" } diff --git a/package.json b/package.json index 4e5f08d..16f6bdc 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "@decidim/browserslist-config": "file:packages/browserslist-config", "@decidim/core": "file:packages/core", "@decidim/webpacker": "file:packages/webpacker", + "axe-core": "^4.10.2", "graphql": "^16.9.0", "graphql-ws": "^5.16.0" },