commit e9fc6f58a32b0ab4a2bf4a763f71301efb931850 Author: Aleksandr Bogdanov Date: Tue Oct 30 16:46:13 2018 +0100 Initial commit diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f618e9b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.git +.gitignore +.dockerignore +node_modules +mastodon +.idea diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..481bf12 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +mastodon +.idea diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..3206be8 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,2 @@ +[2.5.2] +* Initial Cloudron packaging diff --git a/CloudronManifest.json b/CloudronManifest.json new file mode 100644 index 0000000..ec9f332 --- /dev/null +++ b/CloudronManifest.json @@ -0,0 +1,30 @@ +{ + "id": "org.joinmastodon.cloudronapp", + "title": "Mastodon", + "author": "Matodon Authors", + "description": "file://DESCRIPTION.md", + "changelog": "file://CHANGELOG", + "tagline": "A federated microblogging network that is decentralized between independently operated servers", + "version": "2.5.2", + "healthCheckPath": "/about", + "httpPort": 8000, + "memoryLimit": 536870912, + "addons": { + "localstorage": {}, + "postgresql": {}, + "redis": {}, + "sendmail": {} + }, + "minBoxVersion": "1.8.1", + "manifestVersion": 1, + "website": "https://joinmastodon.org/", + "contactEmail": "syn+cloudron@syn.im", + "icon": "logo.png", + "tags": [ + "social", + "forum" + ], + "mediaLinks": [ + "https://upload.wikimedia.org/wikipedia/commons/0/0b/Mastodon_desktop_web_screenshot.png" + ] +} diff --git a/DESCRIPTION.md b/DESCRIPTION.md new file mode 100644 index 0000000..4043383 --- /dev/null +++ b/DESCRIPTION.md @@ -0,0 +1,15 @@ +Social networking, back in your hands +===== +Follow friends and discover new ones. Publish anything you want: links, pictures, text, video. All on a platform that is community-owned and ad-free. + +Find your perfect community +===== +Mastodon isn’t just a website, it is a federation—think Star Trek. Thousands of independent communities running Mastodon form a coherent network, where while every planet is different, being part of one is being part of the whole. + +Safer social media experience +===== +Mastodon comes with effective anti-abuse tools to help protect yourself. Thanks to the network's spread out and independent nature there are more moderators who you can approach for personal help, and servers with strict codes of conduct. + +Sharing your thoughts has never been more convenient +===== +You have 500 characters. You can adjust the thumbnails of your pictures with focal points. You can use custom emojis, hide things behind spoiler warnings and choose who sees a given post. Messed it up? You can delete & redraft for quick corrections. \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..78e79ca --- /dev/null +++ b/Dockerfile @@ -0,0 +1,48 @@ +FROM cloudron/base:1.0.0 + +RUN mkdir -p /app/code +WORKDIR /app/code + +RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list + +# the following does apt-get update +RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - + +RUN apt-get install -y \ + imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core \ + g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf \ + bison build-essential libssl-dev libyaml-dev libreadline6-dev \ + zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev \ + nginx redis-server redis-tools postgresql postgresql-contrib \ + certbot yarn libidn11-dev libicu-dev libjemalloc-dev \ + ruby2.5 + +RUN gem install bundler --no-ri --no-rdoc + +RUN rm -r /etc/nginx/sites-enabled/default /var/lib/nginx /var/log/nginx +RUN mkdir -p /run/nginx && ln -fs /run/nginx /var/lib/nginx && ln -fs /run/nginx/log /var/log/nginx + +RUN git init && \ + git remote add origin https://github.com/tootsuite/mastodon.git && \ + git fetch --depth=1 origin $(git ls-remote --tags | grep refs/tags | grep -v 'rc[0-9]*$' | cut -f2 | sort -V | tail -n 1 | cut -d '/' -f3-) && \ + git checkout FETCH_HEAD + +RUN bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test && \ + yarn install --pure-lockfile + +ENV GEM_PATH=/app/code/vendor/bundle/ruby/2.5.0/gems/ RAILS_ENV=production NODE_ENV=production + +# secret keys are not built into assets, so precompiling is safe to do here +# (these variables are required by rake though) +RUN SECRET_KEY_BASE=insecure.secret_key_base OTP_SECRET=insecure.otp_secret \ + bundle exec rake assets:precompile + +RUN ln -fs /app/data/.env.production /app/code/.env.production +RUN ln -fs /app/data/bullet.log /app/code/log/bullet.log +RUN ln -fs /app/data/system /app/code/public/system +CMD /app/code/start.sh + +COPY nginx.conf /etc/nginx/sites-enabled/mastodon +COPY mastodon.env.template /app/code +COPY start.sh /app/code diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4f51400 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +version: '2.4' + +services: + mastodon: + build: . + ports: + - 3000 + - 4000 + - 80:8000 + environment: + - LOCAL_DOMAIN=localhost + - LOCAL_HTTPS=false + - POSTGRESQL_HOST=postgres + - POSTGRESQL_DATABASE=postgres + - POSTGRESQL_USERNAME=postgres + - POSTGRESQL_PASSWORD=postgres + - REDIS_HOST=redis + volumes: + - data:/app/data + tmpfs: + - /run + - /tmp + postgres: + image: postgres + environment: + - POSTGRES_PASSWORD=postgres + + redis: + image: redis + +volumes: + data: \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..d0dfdd6 Binary files /dev/null and b/logo.png differ diff --git a/mastodon.env.template b/mastodon.env.template new file mode 100644 index 0000000..004527a --- /dev/null +++ b/mastodon.env.template @@ -0,0 +1,41 @@ +#!/bin/bash + +cat <"}" +SMTP_AUTH_METHOD=plain +SMTP_LOGIN=${MAIL_SMTP_USERNAME} +SMTP_PASSWORD=${MAIL_SMTP_PASSWORD} +SMTP_OPENSSL_VERIFY_MODE=none + +LDAP_ENABLED=$([ -z "$LDAP_SERVER" ] && echo "false" || echo "true") +LDAP_HOST=${LDAP_SERVER} +LDAP_PORT=${LDAP_PORT} +LDAP_BASE=${LDAP_USERS_BASE_DN} +LDAP_BIND_DN=${LDAP_BIND_DN} +LDAP_PASSWORD=${LDAP_BIND_PASSWORD} +LDAP_UID=mail + +# the following is generated by start.sh +END + +#SECRET_KEY_BASE= +#OTP_SECRET= +#VAPID_PRIVATE_KEY= +#VAPID_PUBLIC_KEY= \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..7adb57b --- /dev/null +++ b/nginx.conf @@ -0,0 +1,96 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +proxy_cache_path /run/nginx/cache levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g; + +error_log /dev/stdout info; +access_log /dev/stdout; +client_body_temp_path /run/nginx/body 1 2; + +server { + listen 8000; + listen [::]:8000; + + keepalive_timeout 70; + sendfile on; + client_max_body_size 80m; + + root /app/code/public; + + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + add_header Strict-Transport-Security "max-age=31536000"; + + location / { + try_files $uri @proxy; + } + + location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) { + add_header Cache-Control "public, max-age=31536000, immutable"; + add_header Strict-Transport-Security "max-age=31536000"; + try_files $uri @proxy; + } + + location /sw.js { + add_header Cache-Control "public, max-age=0"; + add_header Strict-Transport-Security "max-age=31536000"; + try_files $uri @proxy; + } + + location @proxy { + # forwarding cloudron's nginx proxy-proto headers + proxy_set_header Host $host; + proxy_set_header X-Real-IP $http_x_real_ip; + proxy_set_header X-Forwarded-For $http_x_forwarded_for,$remote_addr; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + proxy_set_header X-Forwarded-Host $http_x_forwarded_host; + proxy_set_header X-Forwarded-Port $http_x_forwarded_port; + proxy_set_header X-Forwarded-Server $http_x_forwarded_server; + + proxy_set_header Proxy ""; + proxy_pass_header Server; + + proxy_pass http://127.0.0.1:3000; + proxy_buffering on; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_cache CACHE; + proxy_cache_valid 200 7d; + proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; + add_header X-Cached $upstream_cache_status; + add_header Strict-Transport-Security "max-age=31536000"; + + tcp_nodelay on; + } + + location /api/v1/streaming { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header Proxy ""; + + proxy_pass http://127.0.0.1:4000; + proxy_buffering off; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + tcp_nodelay on; + } + + error_page 500 501 502 503 504 /500.html; +} diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..93ad60c --- /dev/null +++ b/start.sh @@ -0,0 +1,28 @@ +#!/bin/bash -eu +echo "=>Configuring mastodon<=" +bash /app/code/mastodon.env.template > /app/data/.env.production + +if ! [ -f /app/data/.keys.env ]; then + echo "=>First run, generating keys and setting up the DB<=" + export RANDFILE=/app/data/.rnd + echo -e "SECRET_KEY_BASE=$(openssl rand -hex 64)\nOTP_SECRET=$(openssl rand -hex 64)" > /app/data/.keys.env + + source /app/data/.keys.env + HOME=/app/data bundle exec rake mastodon:webpush:generate_vapid_key >> /app/data/.keys.env + SAFETY_ASSURED=1 HOME=/app/data bundle exec rails db:schema:load db:seed + + # the app writes to the following dirs: + mkdir -p /app/data/system && chown cloudron:cloudron /app/data/system +fi + +cat /app/data/.keys.env >> /app/data/.env.production + +echo "=>Starting mastodon<=" + +SUDO='sudo -u cloudron -H -E' +PORT=3000 $SUDO bundle exec puma -C config/puma.rb & +PORT=4000 STREAMING_CLUSTER_NUM=1 $SUDO npm run start & +DB_POOL=25 MALLOC_ARENA_MAX=2 $SUDO bundle exec sidekiq -c 25 & + +mkdir -p /run/nginx/log /run/nginx/body /run/nginx/cache +nginx -g 'daemon off;'