diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..9f286acdf3601710178a3d16efd83436f3c56a58 --- /dev/null +++ b/.env.example @@ -0,0 +1,28 @@ +# docker compose +COMPOSE_BAKE=true + +# Server +DOMAIN=localhost + +# mail +SMTP_NAME=username +SMTP_PASSWORD=123456 +SMTP_HOST=smtp.domain.com +MAIL_FROM_ADDRESS=no-reply +MAIL_DOMAIN=domain.com + +# database +DB_HOST=db +DB_USER=nextcloud +DB_PASSWORD=123456 +DB_NAME=nextcloud + +# redis +REDIS_HOST=redis +REDIS_HOST_PASSWORD=12456 + +# nextcloud +NEXTCLOUD_DOCKERFILE=slim.Dockerfile +NEXTCLOUD_DOCKER_IMG=registry.gitlab.e.foundation/e/infra/ecloud/nextcloud/slim +NEXTCLOUD_ADMIN_USER=admin +NEXTCLOUD_ADMIN_PASSWORD=@dm1n diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0a4370578ab23da720843e6c5803310c6426511e..2e5cfe2c4cb315755fd38eef8d8867ba065a2902 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,58 +1,49 @@ -# When using dind, it's wise to use the overlayfs driver for -# improved performance. -variables: - DOCKER_DRIVER: overlay2 - DOCKER_TLS_CERTDIR: "/certs" - -default: - image: docker:24.0.6 - +.docker: + image: docker:28.0 services: - - docker:24.0.6-dind + - docker:28.0-dind before_script: - - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY + - echo $CI_JOB_TOKEN | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY tags: - generic_privileged -.build-docker: +.build: + extends: .docker + stage: build script: - - echo "TARGET $TARGET, BRANCH $CI_COMMIT_BRANCH, COMMIT_REF_SLUG $CI_COMMIT_REF_SLUG, COMMIT_TAG $CI_COMMIT_TAG" - - docker build --target $TARGET --pull -t "$CI_REGISTRY_IMAGE$SUBPATH:$CI_COMMIT_REF_SLUG" . - - docker push "$CI_REGISTRY_IMAGE$SUBPATH:$CI_COMMIT_REF_SLUG" + - docker build -t $CI_REGISTRY_IMAGE$REGISTRY_SUBPATH:$CI_COMMIT_REF_SLUG $DOCKER_BUILD_ARGS . + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' -build-branch: - stage: build +.deploy: + extends: .docker + stage: deploy + script: + - docker build -t $CI_REGISTRY_IMAGE$REGISTRY_SUBPATH:${CI_COMMIT_TAG/v/} $DOCKER_BUILD_ARGS . + - docker push $CI_REGISTRY_IMAGE$REGISTRY_SUBPATH:${CI_COMMIT_TAG/v/} + rules: + - if: '$CI_COMMIT_TAG' + +build-workspace: + extends: .build variables: - TARGET: ecloud - SUBPATH: '' - only: - - branches - extends: .build-docker + DOCKER_BUILD_ARGS: "--target ecloud" + REGISTRY_SUBPATH: "" -build-branch-selfhost: - stage: build +build-slim-workspace: + extends: .build variables: - TARGET: selfhost - SUBPATH: '/selfhost' - only: - - branches - when: manual - extends: .build-docker + DOCKER_BUILD_ARGS: "-f slim.Dockerfile" + REGISTRY_SUBPATH: "/slim" -build-tag: - stage: build +publish-workspace: + extends: .deploy variables: - TARGET: ecloud - SUBPATH: '' - only: - - tags - extends: .build-docker + DOCKER_BUILD_ARGS: "--target ecloud" + REGISTRY_SUBPATH: "" -build-tag-selfhost: - stage: build +publish-slim-workspace: + extends: .deploy variables: - TARGET: selfhost - SUBPATH: '/selfhost' - only: - - tags - extends: .build-docker + DOCKER_BUILD_ARGS: "-f slim.Dockerfile" + REGISTRY_SUBPATH: "/slim" diff --git a/COPYING-README b/COPYING-README deleted file mode 100644 index 606eb798b3794b4974054d53f1f3e66b6369c688..0000000000000000000000000000000000000000 --- a/COPYING-README +++ /dev/null @@ -1,16 +0,0 @@ -Files in Nextcloud are licensed under the Affero General Public License version 3, -the text of which can be found in LICENSE, or any later version of the AGPL, -unless otherwise noted. - -Licensing of components: -* jQuery: MIT / GPL -* HTTP: 3 clause BSD -* MDB2: BSD style custom -* User: AGPL -* XML/RPC: MIT / PHP -* Elementary filetype icons: GPL v3+ -* Material UI icons: APACHE LICENSE, VERSION 2.0 -All unmodified files from these and other sources retain their original copyright -and license notices: see the relevant individual files. - -Attribution information for Nextcloud is contained in the AUTHORS file: https://raw.githubusercontent.com/nextcloud/server/master/AUTHORS diff --git a/README.md b/README.md index 3e43770e0702e9c53d1656c37ad2d8ac627111f6..642bf397916e42129c8e530833c278c77da18242 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,18 @@ -# Custom nextcloud image for eCloud +# Murena Workspace -This project builds a custom docker image from the official Nextcloud one, applying workarounds or specific behaviour of interest only for a shared, private-by-default installation such as ecloud.global. +This project builds a custom docker image from the official [Nextcloud](https://nextcloud.com), applying patches to make Murena Workspace. -## Building +2 images are available the `default` and the `slim` ones. -Simply build as a standard docker image. Check `gitlab-ci.ym` for the commands we use. +## Getting started -## Using +You can configure default values from the `.env` file. See [.env.example](./.env.example). +By default, the `slim` Murena Workspace is configured. -We suggest you use our [ecloud-selfhosting](https://gitlab.e.foundation/e/infra/ecloud-selfhosting) project instead of this one directly. But if you wish to do so, then check our [releases page](https://gitlab.e.foundation/e/infra/ecloud/nextcloud/-/releases) and pull the latest tag from the container registry. +`slim` Murena Workspace +``` +cp .env.example .env +docker compose up --build -d +``` -### To run ecloud locally(Tested on Ubuntu and Manjaro, should work on most linux distributions) - -- Install [docker](https://docs.docker.com/engine/install/ubuntu/)(link is for Ubuntu) -- Install [docker-compose](https://docs.docker.com/compose/install/) -- Create a copy of the `ecloud_dev_example` directory locally where you want to install an `ecloud` development environment -- Use `cd` or file manager to enter the above directory -- Add a `.env` file with chosen attributes(example [.env](./ecloud_dev_example/.dev.env) file here, you can rename to `.env` to use same defaults) -- Set correct permissions to volumes: - - `chown -R '33':'33' volumes/nextcloud/{html,data,log}` -- Pull the images and up the containers - - `docker-compose pull` - - `docker-compose up -d` - -### Things to do on first installation locally - -- Set config values, disable integrity check and refresh theme cache: - - - `docker exec -u www-data ecloud /var/www/html/occ config:system:set theme --value='eCloud'` - - `docker exec -u www-data ecloud /var/www/html/occ config:system:set logfile --value='/var/www/log/nextcloud.log'` - - `docker exec -u www-data ecloud /var/www/html/occ config:system:set loglevel --value='2' --type=integer` - - `docker exec -u www-data ecloud /var/www/html/occ config:system:set integrity.check.disabled --value='true' --type=boolean` - - `docker exec -u www-data ecloud /var/www/html/occ maintenance:theme:update` - -- Disable apps: - - - `docker exec -u www-data ecloud /var/www/html/occ app:disable firstrunwizard` - - `docker exec -u www-data ecloud /var/www/html/occ app:disable theming` - - `docker exec -u www-data ecloud /var/www/html/occ app:disable files_external` - -- Enable\Install apps: - - - `docker exec -u www-data ecloud /var/www/html/occ app:enable murena_launcher` - - `docker exec -u www-data ecloud /var/www/html/occ app:enable ecloud-theme-helper` - - `docker exec -u www-data ecloud /var/www/html/occ app:enable notes` - - `docker exec -u www-data ecloud /var/www/html/occ app:enable news` - - `docker exec -u www-data ecloud /var/www/html/occ app:enable quota_warning` - - `docker exec -u www-data ecloud /var/www/html/occ app:enable contacts` - - `docker exec -u www-data ecloud /var/www/html/occ app:enable calendar` - - `docker exec -u www-data ecloud /var/www/html/occ app:enable email-recovery` - - `docker exec -u www-data ecloud /var/www/html/occ app:enable ecloud-accounts` - - `docker exec -u www-data ecloud /var/www/html/occ app:enable integration_google` - - To install more apps, use `docker exec -u www-data ecloud /var/www/html/occ app:install $app` where `$app` is the name of the app - -- To make the `html` folder editable to current user(`$USER`)(run commands with `sudo` if required): - - `usermod -a -G '33' $USER` - - `chmod -R g+w volumes/nextcloud/html` - - Log out and log back into your system - -## Contributing - -Anyone can fork a project on our GitLab instance, but to prevent abuse it's disabled by default. Get in touch with us [by e-mail](mailto:dev@murena.com) or through our support channels and we will let you create a fork and submit MRs. +Go to http://localhost:8000 then use admin credentials provided into `.env` file. diff --git a/config/nginx/templates/default.conf.template b/config/nginx/templates/default.conf.template new file mode 100644 index 0000000000000000000000000000000000000000..300416c992d2eafb40014ea2b1e66271f5af3174 --- /dev/null +++ b/config/nginx/templates/default.conf.template @@ -0,0 +1,183 @@ +# Set the `immutable` cache control options only for assets with a cache busting `v` argument +map $arg_v $asset_immutable { + "" ""; + default ", immutable"; +} + +upstream php-handler { + server nextcloud:9000; +} + +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + + # Path to the root of your installation + root /var/www/html; + + # Prevent nginx HTTP Server Detection + server_tokens off; + + # HSTS settings + # WARNING: Only add the preload option once you read about + # the consequences in https://hstspreload.org/. This option + # will add the domain to a hardcoded list that is shipped + # in all major browsers and getting removed from this list + # could take several months. + #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always; + + # set max upload size and increase upload timeout: + client_max_body_size 512M; + client_body_timeout 300s; + fastcgi_buffers 64 4K; + + # Enable gzip but do not remove ETag headers + gzip on; + gzip_vary on; + gzip_comp_level 4; + gzip_min_length 256; + gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; + gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; + + # Pagespeed is not supported by Nextcloud, so if your server is built + # with the `ngx_pagespeed` module, uncomment this line to disable it. + #pagespeed off; + + # The settings allows you to optimize the HTTP2 bandwidth. + # See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/ + # for tuning hints + client_body_buffer_size 512k; + + # HTTP response headers borrowed from Nextcloud `.htaccess` + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Robots-Tag "noindex, nofollow" always; + add_header X-XSS-Protection "1; mode=block" always; + + # Remove X-Powered-By, which is an information leak + fastcgi_hide_header X-Powered-By; + + # Set .mjs and .wasm MIME types + # Either include it in the default mime.types list + # and include that list explicitly or add the file extension + # only for Nextcloud like below: + include mime.types; + types { + text/javascript mjs; + application/wasm wasm; + } + + # Specify how to handle directories -- specifying `/index.php$request_uri` + # here as the fallback means that Nginx always exhibits the desired behaviour + # when a client requests a path that corresponds to a directory that exists + # on the server. In particular, if that directory contains an index.php file, + # that file is correctly served; if it doesn't, then the request is passed to + # the front-end controller. This consistent behaviour means that we don't need + # to specify custom rules for certain paths (e.g. images and other assets, + # `/updater`, `/ocs-provider`), and thus + # `try_files $uri $uri/ /index.php$request_uri` + # always provides the desired behaviour. + index index.php index.html /index.php$request_uri; + + # Rule borrowed from `.htaccess` to handle Microsoft DAV clients + location = / { + if ( $http_user_agent ~ ^DavClnt ) { + return 302 /remote.php/webdav/$is_args$args; + } + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + # Make a regex exception for `/.well-known` so that clients can still + # access it despite the existence of the regex rule + # `location ~ /(\.|autotest|...)` which would otherwise handle requests + # for `/.well-known`. + location ^~ /.well-known { + # The rules in this block are an adaptation of the rules + # in `.htaccess` that concern `/.well-known`. + + location = /.well-known/carddav { return 301 /remote.php/dav/; } + location = /.well-known/caldav { return 301 /remote.php/dav/; } + + location /.well-known/acme-challenge { try_files $uri $uri/ =404; } + location /.well-known/pki-validation { try_files $uri $uri/ =404; } + + # Let Nextcloud's API for `/.well-known` URIs handle all other + # requests by passing them to the front-end controller. + return 301 /index.php$request_uri; + } + + # Rules borrowed from `.htaccess` to hide certain paths from clients + location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } + location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } + + # Ensure this block, which passes PHP files to the PHP process, is above the blocks + # which handle static assets (as seen below). If this block is not declared first, + # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` + # to the URI, resulting in a HTTP 500 error response. + location ~ \.php(?:$|/) { + # Required for legacy support + rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri; + + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + set $path_info $fastcgi_path_info; + + try_files $fastcgi_script_name =404; + + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $path_info; + #fastcgi_param HTTPS on; + + fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice + fastcgi_param front_controller_active true; # Enable pretty urls + fastcgi_pass php-handler; + + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + + fastcgi_max_temp_file_size 0; + } + + # Serve static files + location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac)$ { + try_files $uri /index.php$request_uri; + # HTTP response headers borrowed from Nextcloud `.htaccess` + add_header Cache-Control "public, max-age=15778463$asset_immutable"; + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Robots-Tag "noindex, nofollow" always; + add_header X-XSS-Protection "1; mode=block" always; + access_log off; # Optional: Don't log access to assets + } + + location ~ \.(otf|woff2?)$ { + try_files $uri /index.php$request_uri; + expires 7d; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets + } + + # Rule borrowed from `.htaccess` + location /remote { + return 301 /remote.php$request_uri; + } + + location / { + try_files $uri $uri/ /index.php$request_uri; + } + + # For the Rainloop admin message saying "data folder accessible" + # It is a false positive as seen at https://github.com/pierre-alain-b/rainloop-nextcloud/issues/62 + location ^~/apps/rainloop/app/data { + deny all; + } +} diff --git a/config/syslog-ng/syslog-ng.conf b/config/syslog-ng/syslog-ng.conf new file mode 100644 index 0000000000000000000000000000000000000000..3ee176d9d6d839564aabf1deb9077d677a542d32 --- /dev/null +++ b/config/syslog-ng/syslog-ng.conf @@ -0,0 +1,13 @@ +source s_local { + system(); + internal(); +}; + +destination d_remote { + network("${SYSLOG_HOST}" port(514) transport(tcp)); +}; + +log { + source(s_local); + destination(d_remote); +}; diff --git a/custom_entrypoint.sh b/custom_entrypoint.sh old mode 100644 new mode 100755 index 2e385232fa181299d261c5d23dc576507ec0f5d3..384eec4f6affa13cada3afc6843104b169c79606 --- a/custom_entrypoint.sh +++ b/custom_entrypoint.sh @@ -21,28 +21,20 @@ if version_greater "$image_version" "$installed_version"; then rsync $rsync_options --include "/notes/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ rsync $rsync_options --include "/calendar/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ rsync $rsync_options --include "/contacts/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ - rsync $rsync_options --include "/user_backend_sql_raw/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ - rsync $rsync_options --include "/email-recovery/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ - rsync $rsync_options --include "/ecloud-accounts/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ rsync $rsync_options --include "/ecloud-theme-helper/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ rsync $rsync_options --include "/murena_launcher/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ - rsync $rsync_options --include "/integration_google/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ - rsync $rsync_options --include "/ldap_write_support/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ rsync $rsync_options --include "/murena-dashboard/" --exclude '/*' $SRC_DIR/custom_apps/ /$DST_DIR/custom_apps/ rsync $rsync_options --include "/snappymail/" --exclude '/*' $SRC_DIR/custom_apps/ /$DST_DIR/custom_apps/ rsync $rsync_options --include "/eCloud/" --exclude '/*' $SRC_DIR/themes/ $DST_DIR/themes/ rsync $rsync_options --include "/Murena/" --exclude '/*' $SRC_DIR/themes/ $DST_DIR/themes/ rsync $rsync_options --include "/memories/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ - rsync $rsync_options --include "/drop_account/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ - rsync $rsync_options --include "/selfhost-theme-helper/" --exclude '/*' $SRC_DIR/custom_apps/ $DST_DIR/custom_apps/ else echo "Skipping rsync step as version not updated!" fi -if [ "$(id -u)" = 0 ]; then - su -p www-data -s /bin/sh -c "php $DST_DIR/occ config:system:set profile.enabled --value=false --type=boolean" -else - sh -c "php $DST_DIR/occ config:system:set profile.enabled --value=false --type=boolean" -fi +# syslog-ng +sed -i "s|\${SYSLOG_HOST}|${SYSLOG_HOST:-127.0.0.1}|g" /etc/syslog-ng/syslog-ng.conf +syslog-ng --no-caps + /entrypoint.sh "$@" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..2f20afb6b8519b2cbdf9c380627437a57c739948 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,86 @@ +services: + db: + image: postgres:17.4-alpine + restart: unless-stopped + environment: + - POSTGRES_DB=${DB_NAME} + - POSTGRES_USER=${DB_USER} + - POSTGRES_PASSWORD=${DB_PASSWORD} + volumes: + - db:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:7.4-alpine + restart: unless-stopped + healthcheck: + test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ] + interval: 10s + timeout: 5s + retries: 5 + + nextcloud: + image: ${NEXTCLOUD_DOCKER_IMG} + build: + context: . + dockerfile: ${NEXTCLOUD_DOCKERFILE} + restart: unless-stopped + environment: + - POSTGRES_HOST=${DB_HOST} + - POSTGRES_USER=${DB_USER} + - POSTGRES_PASSWORD=${DB_PASSWORD} + - POSTGRES_DB=${DB_NAME} + - REDIS_HOST=${REDIS_HOST} + - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} + - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} + - NEXTCLOUD_TRUSTED_DOMAINS=${DOMAIN} + - SMTP_SECURE=tls + - SMTP_PORT=587 + - SMTP_NAME=${SMTP_NAME} + - SMTP_PASSWORD=${SMTP_PASSWORD} + - SMTP_HOST=${SMTP_HOST} + - MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS} + - MAIL_DOMAIN=${MAIL_DOMAIN} + - SYSLOG_HOST=syslog + volumes: + - nextcloud:/var/www/html + depends_on: + syslog: + condition: service_started + db: + condition: service_healthy + redis: + condition: service_healthy + + syslog: + image: jumanjiman/rsyslog + + nextcloud-cron: + image: ${NEXTCLOUD_DOCKER_IMG} + restart: unless-stopped + entrypoint: /cron.sh + volumes: + - nextcloud:/var/www/html + depends_on: + - nextcloud + + nginx: + image: nginx:stable-alpine + restart: unless-stopped + environment: + DOMAIN: ${DOMAIN} + ports: + - "8000:80" + volumes: + - ${DEPLOYMENT_PATH:-.}/config/nginx/templates:/etc/nginx/templates + - nextcloud:/var/www/html + depends_on: + - nextcloud + +volumes: + db: + nextcloud: diff --git a/ecloud_dev_example/.dev.env b/ecloud_dev_example/.dev.env deleted file mode 100644 index d059435a0f8cc6c01e3390109cee5b09cce2ece7..0000000000000000000000000000000000000000 --- a/ecloud_dev_example/.dev.env +++ /dev/null @@ -1,9 +0,0 @@ -MYSQL_ROOT_PASSWORD=iamroot -MYSQL_PASSWORD=iamnotroot -MYSQL_USER=nextcloud -NEXTCLOUD_ADMIN_USER=admin -NEXTCLOUD_ADMIN_PASSWORD=admin1234 -NEXTCLOUD_EMAIL_RECOVERY_APP_SECRET=abcd1234 -ECLOUD_ACCOUNTS_SECRET=1234abcd - -ECLOUD_IMAGE_TAG=ecloud-21.0.7.18-privacy diff --git a/ecloud_dev_example/config/nginx/nginx.conf b/ecloud_dev_example/config/nginx/nginx.conf deleted file mode 100644 index 19eccabe2554ea656b7491acf945e829c177294f..0000000000000000000000000000000000000000 --- a/ecloud_dev_example/config/nginx/nginx.conf +++ /dev/null @@ -1,169 +0,0 @@ -worker_processes auto; - -error_log /var/log/nginx/error.log warn; -pid /var/run/nginx.pid; - - -events { - worker_connections 1024; -} - - -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /var/log/nginx/access.log main; - - sendfile on; - #tcp_nopush on; - - keepalive_timeout 65; - - #gzip on; - - upstream php-handler { - server nextcloud:9000; - } - - server { - listen 80; - - # Add headers to serve security related headers - # Before enabling Strict-Transport-Security headers please read into this - # topic first. - #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always; - # - # WARNING: Only add the preload option once you read about - # the consequences in https://hstspreload.org/. This option - # will add the domain to a hardcoded list that is shipped - # in all major browsers and getting removed from this list - # could take several months. - add_header Referrer-Policy "no-referrer" always; - add_header X-Content-Type-Options "nosniff" always; - add_header X-Download-Options "noopen" always; - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Permitted-Cross-Domain-Policies "none" always; - add_header X-Robots-Tag "none" always; - add_header X-XSS-Protection "1; mode=block" always; - - # Remove X-Powered-By, which is an information leak - fastcgi_hide_header X-Powered-By; - - # Path to the root of your installation - root /var/www/html; - - location = /robots.txt { - allow all; - log_not_found off; - access_log off; - } - - # The following 2 rules are only needed for the user_webfinger app. - # Uncomment it if you're planning to use this app. - #rewrite ^/.well-known/host-meta /public.php?service=host-meta last; - #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; - - # The following rule is only needed for the Social app. - # Uncomment it if you're planning to use this app. - #rewrite ^/.well-known/webfinger /public.php?service=webfinger last; - - location = /.well-known/carddav { - return 301 $scheme://$host:$server_port/remote.php/dav; - } - - location = /.well-known/caldav { - return 301 $scheme://$host:$server_port/remote.php/dav; - } - - # set max upload size - client_max_body_size 10G; - fastcgi_buffers 64 4K; - - # Enable gzip but do not remove ETag headers - gzip on; - gzip_vary on; - gzip_comp_level 4; - gzip_min_length 256; - gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; - gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; - - # Uncomment if your server is build with the ngx_pagespeed module - # This module is currently not supported. - #pagespeed off; - - location / { - rewrite ^ /index.php; - } - - location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ { - deny all; - } - location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) { - deny all; - } - - location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) { - fastcgi_split_path_info ^(.+?\.php)(\/.*|)$; - set $path_info $fastcgi_path_info; - try_files $fastcgi_script_name =404; - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $path_info; - # fastcgi_param HTTPS on; - - # Avoid sending the security headers twice - fastcgi_param modHeadersAvailable true; - - # Enable pretty urls - fastcgi_param front_controller_active true; - fastcgi_pass php-handler; - fastcgi_intercept_errors on; - fastcgi_request_buffering off; - } - - location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) { - try_files $uri/ =404; - index index.php; - } - - # Adding the cache control header for js, css and map files - # Make sure it is BELOW the PHP block - location ~ \.(?:css|js|woff2?|svg|gif|map)$ { - try_files $uri /index.php$request_uri; - add_header Cache-Control "public, max-age=15778463"; - # Add headers to serve security related headers (It is intended to - # have those duplicated to the ones above) - # Before enabling Strict-Transport-Security headers please read into - # this topic first. - #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always; - # - # WARNING: Only add the preload option once you read about - # the consequences in https://hstspreload.org/. This option - # will add the domain to a hardcoded list that is shipped - # in all major browsers and getting removed from this list - # could take several months. - add_header Referrer-Policy "no-referrer" always; - add_header X-Content-Type-Options "nosniff" always; - add_header X-Download-Options "noopen" always; - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Permitted-Cross-Domain-Policies "none" always; - add_header X-Robots-Tag "none" always; - add_header X-XSS-Protection "1; mode=block" always; - - # Optional: Don't log access to assets - access_log off; - } - - location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ { - try_files $uri /index.php$request_uri; - # Optional: Don't log access to other assets - access_log off; - } - } -} - diff --git a/ecloud_dev_example/docker-compose.yml b/ecloud_dev_example/docker-compose.yml deleted file mode 100644 index 21f736aa29e1b0a35aa2190fef790f02a7bda73f..0000000000000000000000000000000000000000 --- a/ecloud_dev_example/docker-compose.yml +++ /dev/null @@ -1,48 +0,0 @@ -version: "3" - -services: - mariadb: - image: mariadb:10.3 - container_name: mariadb - restart: always - command: --transaction-isolation=READ-COMMITTED --log-bin --binlog-format=ROW - volumes: - - ./volumes/db/data:/var/lib/mysql - environment: - - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - - MYSQL_PASSWORD=${MYSQL_PASSWORD} - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=${MYSQL_USER} - - nextcloud: - image: registry.gitlab.e.foundation:5000/e/infra/ecloud/nextcloud:${ECLOUD_IMAGE_TAG} - container_name: ecloud - restart: always - depends_on: - - mariadb - volumes: - - ./volumes/nextcloud/html:/var/www/html/ - - ./volumes/nextcloud/log:/var/www/log/ - - ./volumes/nextcloud/data:/var/www/data - environment: - - MYSQL_PASSWORD=${MYSQL_PASSWORD} - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=${MYSQL_USER} - - MYSQL_HOST=mariadb - - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} - - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} - - NEXTCLOUD_DATA_DIR=/var/www/data - - NEXTCLOUD_EMAIL_RECOVERY_APP_SECRET=${NEXTCLOUD_EMAIL_RECOVERY_APP_SECRET} - - ECLOUD_ACCOUNTS_SECRET=${ECLOUD_ACCOUNTS_SECRET} - - nginx: - image: nginx:1.20-alpine - container_name: nginx - restart: always - ports: - - 8080:80 - depends_on: - - nextcloud - volumes: - - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - - ./volumes/nextcloud/html:/var/www/html diff --git a/ecloud_dev_example/volumes/db/data/.keep b/ecloud_dev_example/volumes/db/data/.keep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/ecloud_dev_example/volumes/nextcloud/data/.keep b/ecloud_dev_example/volumes/nextcloud/data/.keep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/ecloud_dev_example/volumes/nextcloud/html/.keep b/ecloud_dev_example/volumes/nextcloud/html/.keep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/ecloud_dev_example/volumes/nextcloud/log/.keep b/ecloud_dev_example/volumes/nextcloud/log/.keep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/hooks.d/post-installation/murena-config.json b/hooks.d/post-installation/murena-config.json new file mode 100644 index 0000000000000000000000000000000000000000..e9d0a488e40f9fca3f76b016ccbb326f0e1d6efc --- /dev/null +++ b/hooks.d/post-installation/murena-config.json @@ -0,0 +1,30 @@ +{ + "system": { + "integrity.check.disabled": true, + "profile.enabled": false, + "defaultapp": "murena-dashboard,files", + "theme": "eCloud", + "filelocking.enabled": true, + "log_type": "syslog", + "logfile": "/dev/null", + "loglevel": 2, + "logfilemode": "0644", + "syslog_tag": "nextcloud", + "cron_log": true, + "enabledPreviewProviders": [ + "OC\\Preview\\PNG", + "OC\\Preview\\JPEG", + "OC\\Preview\\GIF", + "OC\\Preview\\BMP", + "OC\\Preview\\XBitmap", + "OC\\Preview\\MP3", + "OC\\Preview\\TXT", + "OC\\Preview\\MarkDown", + "OC\\Preview\\OpenDocument", + "OC\\Preview\\Krita", + "OC\\Preview\\Movie" + ], + "preview_max_x": 1024, + "preview_max_y": 1024 + } +} diff --git a/hooks.d/post-installation/murena-theme.sh b/hooks.d/post-installation/murena-theme.sh new file mode 100755 index 0000000000000000000000000000000000000000..62347b79e3769b9a8836f5dc9356bb82798a3b19 --- /dev/null +++ b/hooks.d/post-installation/murena-theme.sh @@ -0,0 +1,35 @@ +#!/bin/sh -e + +SCRIPT_DIR=$(dirname "$0") +PATH=${PATH}:/var/www/html + +# Apply configuration +sed -e "s|\${NEXTCLOUD_LOGFILE}|${NEXTCLOUD_LOGFILE:-/var/www/html/data/nextcloud.log}|g" \ + "${SCRIPT_DIR}/murena-config.json" | occ config:import + +# Update theme +occ maintenance:theme:update + +echo "Enabling nextcloud apps" +occ app:enable calendar +occ app:enable notes +occ app:enable contacts +occ app:enable ecloud-theme-helper +occ app:enable murena-dashboard +occ app:enable murena_launcher +occ app:enable bruteforcesettings +occ app:enable suspicious_login +occ app:enable twofactor_totp +occ app:disable firstrunwizard +occ app:enable mail +occ app:enable tasks +occ app:enable sentry + +echo "Performing some Nextcloud administrative tasks" +if [ -n "${MYSQL_DATABASE+x}" ]; then + occ db:convert-mysql-charset +fi +occ db:convert-filecache-bigint --no-interaction +occ db:add-missing-indices +# Set background jobs to use system cron +occ background:cron diff --git a/slim.Dockerfile b/slim.Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..dd417cf5fcb901c38d954601698b38d58d973fc5 --- /dev/null +++ b/slim.Dockerfile @@ -0,0 +1,113 @@ +FROM nextcloud:29.0.14-fpm + +ARG BASE_DIR="/usr/src/nextcloud" +ARG TMP_PATCH_DIR="/tmp/build_patches" + +ARG NOTES_VERSION="4.11.0" +ARG CONTACTS_JOB_ID="881946" +ARG CALENDAR_JOB_ID="991372" +ARG THEME_HELPER_JOB_ID="1168069" +ARG THEME_VERSION="28.0.2" +ARG LAUNCHER_JOB_ID="1168135" +ARG DASHBOARD_JOB_ID="1168115" +ARG MAIL_URL="https://github.com/nextcloud-releases/mail/releases/download/v3.7.24/mail-stable3.7.tar.gz" +ARG TASKS_URL="https://github.com/nextcloud/tasks/releases/download/v0.16.1/tasks.tar.gz" +ARG SENTRY_URL="https://github.com/ChristophWurst/nextcloud_sentry/releases/download/v8.15.0/sentry-v8.15.0.tar.gz" + +COPY custom_entrypoint.sh / +COPY hooks.d/post-installation/ /docker-entrypoint-hooks.d/post-installation/ + +RUN sed -i 's/29,0,14,1/29,0,14,2/' ${BASE_DIR}/version.php +RUN rm -rf ${BASE_DIR}/core/skeleton/* \ + && mkdir -p ${BASE_DIR}/core/skeleton/Documents \ + && mkdir -p ${BASE_DIR}/core/skeleton/Images + +# Install unzip for unzipping artifacts +RUN apt-get update && apt-get install -y unzip ffmpeg syslog-ng + +RUN curl -fsSL -o notes.tar.gz \ + "https://github.com/nextcloud-releases/notes/releases/download/v${NOTES_VERSION}/notes-v${NOTES_VERSION}.tar.gz" && \ + tar -xf notes.tar.gz -C ${BASE_DIR}/custom_apps/ && \ + rm notes.tar.gz; + +# custom Contact +RUN curl -fsSL -o contacts.zip \ + "https://gitlab.e.foundation/e/infra/ecloud/nextcloud-apps/contacts/-/jobs/${CONTACTS_JOB_ID}/artifacts/download" && \ + unzip contacts.zip && \ + mv dist/contacts ${BASE_DIR}/custom_apps/ && \ + rm contacts.zip; + +RUN curl -fsSL -o calendar.zip \ + "https://gitlab.e.foundation/e/infra/ecloud/nextcloud-apps/calendar/-/jobs/${CALENDAR_JOB_ID}/artifacts/download" && \ + unzip calendar.zip && \ + mv dist/calendar ${BASE_DIR}/custom_apps/ && \ + rm calendar.zip; + +RUN curl -fsSL -o ecloud-theme-helper.zip \ + "https://gitlab.e.foundation/e/infra/ecloud/nextcloud-apps/ecloud-theme-helper/-/jobs/${THEME_HELPER_JOB_ID}/artifacts/download" && \ + unzip ecloud-theme-helper.zip && \ + mv dist/ecloud-theme-helper ${BASE_DIR}/custom_apps/ && \ + rm ecloud-theme-helper.zip; + +# Custom theme +RUN rm -rf ${BASE_DIR}/themes/eCloud && \ + curl -fsSL -o eCloud-theme.tar.gz \ + "https://gitlab.e.foundation/e/infra/ecloud/nextcloud-apps/nextcloud-theme/-/archive/${THEME_VERSION}/nextcloud-theme-${THEME_VERSION}.tar.gz" && \ + tar -xf eCloud-theme.tar.gz -C /tmp/ && \ + mv /tmp/nextcloud-theme-${THEME_VERSION}/ ${BASE_DIR}/themes/eCloud && \ + chown -R www-data:www-data ${BASE_DIR}/themes/eCloud/ && \ + rm -rf eCloud-theme.tar.gz ${BASE_DIR}/themes/example/ + +RUN curl -fsSL -o murena_launcher.zip \ + "https://gitlab.e.foundation/e/infra/ecloud/nextcloud-apps/launcher/-/jobs/${LAUNCHER_JOB_ID}/artifacts/download" && \ + unzip murena_launcher.zip && \ + mv dist/murena_launcher ${BASE_DIR}/custom_apps/ && \ + rm murena_launcher.zip; + +RUN curl -fsSL -o ecloud-dashboard.zip \ + "https://gitlab.e.foundation/e/infra/ecloud/nextcloud-apps/murena-dashboard/-/jobs/${DASHBOARD_JOB_ID}/artifacts/download" && \ + unzip ecloud-dashboard.zip && \ + mv dist/murena-dashboard ${BASE_DIR}/custom_apps/ && \ + rm ecloud-dashboard.zip; + +RUN bash -c "curl -sL ${MAIL_URL} | tar xzf - -C ${BASE_DIR}/custom_apps" +RUN bash -c "curl -sL ${TASKS_URL} | tar xzf - -C ${BASE_DIR}/custom_apps" +RUN bash -c "curl -sL ${SENTRY_URL} | tar xzf - -C ${BASE_DIR}/custom_apps" + + +# Patches +COPY patches/ ${TMP_PATCH_DIR}/ +RUN cd ${BASE_DIR} \ + && patch -p0 < ${TMP_PATCH_DIR}/002-login-without-domain.patch \ + && patch -u ${BASE_DIR}/apps/settings/lib/Settings/Personal/ServerDevNotice.php -i ${TMP_PATCH_DIR}/007-remove-dev-notice.patch \ + && patch -p1 < ${TMP_PATCH_DIR}/009-help-links.patch \ + && patch -u ${BASE_DIR}/lib/private/Updater.php -i ${TMP_PATCH_DIR}/010-disable-app-store-upgrade.patch \ + && patch -p0 < ${TMP_PATCH_DIR}/011-privacy-settings.patch \ + && patch -u ${BASE_DIR}/lib/private/Authentication/Token/PublicKeyTokenProvider.php -i ${TMP_PATCH_DIR}/013-revert-token-password-update.patch \ + && patch -p0 < ${TMP_PATCH_DIR}/015-email-mail-template.patch \ + && patch -u ${BASE_DIR}/core/Command/User/Setting.php -i ${TMP_PATCH_DIR}/018-occ-user-setting.patch \ + && patch -u ${BASE_DIR}/3rdparty/sabre/vobject/lib/ITip/Broker.php -i ${TMP_PATCH_DIR}/022-significantchange.patch \ + && patch -p0 < ${TMP_PATCH_DIR}/026-primary-color-fix.patch \ + && patch -u ${BASE_DIR}/lib/private/Template/JSResourceLocator.php -i ${TMP_PATCH_DIR}/031-theme-custom-app-translations.patch \ + && patch -u ${BASE_DIR}/lib/private/L10N/Factory.php -i ${TMP_PATCH_DIR}/032-select-lang-from-session.patch \ + && patch -p1 < ${TMP_PATCH_DIR}/036-user-config-change-event.patch \ + && patch -u ${BASE_DIR}/core/templates/layout.user.php -i ${TMP_PATCH_DIR}/003-contact-search-removal.patch \ + && patch -u ${BASE_DIR}/core/Controller/ContactsMenuController.php -i ${TMP_PATCH_DIR}/004-contact-search-controller-removal.patch \ + && patch -p0 < ${TMP_PATCH_DIR}/005-autocomplete-user-leak-core.patch \ + && patch -u ${BASE_DIR}/core/templates/layout.guest.php -i ${TMP_PATCH_DIR}/016-login-screen.patch \ + && patch -u ${BASE_DIR}/lib/private/Notification/Manager.php -i ${TMP_PATCH_DIR}/020-fairuse-notification-fix.patch \ + && patch -u ${BASE_DIR}/lib/private/User/Manager.php -i ${TMP_PATCH_DIR}/025-optimize-get-by-email.patch \ + && patch -u ${BASE_DIR}/apps/dav/lib/Connector/Sabre/Principal.php -i ${TMP_PATCH_DIR}/027-displayname-user-leak-dav.patch \ + && patch -u ${BASE_DIR}/apps/dav/lib/HookManager.php -i ${TMP_PATCH_DIR}/028-default-task-calendar.patch \ + && patch -u ${BASE_DIR}/apps/provisioning_api/lib/Controller/UsersController.php -i ${TMP_PATCH_DIR}/029-restrict-user-to-change-primary-email.patch \ + && patch -u ${BASE_DIR}/lib/private/Security/VerificationToken/VerificationToken.php -i ${TMP_PATCH_DIR}/033-verification-token-private.patch \ + && patch -u ${BASE_DIR}/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php -i ${TMP_PATCH_DIR}/034-oidc-bearer-token-auth.patch \ + && rm -rf ${TMP_PATCH_DIR} + + +COPY config/syslog-ng/syslog-ng.conf /etc/syslog-ng/syslog-ng.conf + +ENTRYPOINT ["/custom_entrypoint.sh"] +CMD ["php-fpm"] +# only for dev purpose +STOPSIGNAL SIGKILL