Skip to content

Instantly share code, notes, and snippets.

@rkbhochalya
Last active February 18, 2023 23:53
Show Gist options
  • Select an option

  • Save rkbhochalya/ad633c30a01764af40d3f5cf16a59f1f to your computer and use it in GitHub Desktop.

Select an option

Save rkbhochalya/ad633c30a01764af40d3f5cf16a59f1f to your computer and use it in GitHub Desktop.
Mastodon & Shlink setup on a single server using Docker
# Based on https://github.com/tootsuite/mastodon/blob/master/docker-compose.yml
version: "3.7"
services:
db:
restart: always
image: postgres:9.6-alpine
networks:
- internal_network
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
volumes:
- ./postgres:/var/lib/postgresql/data
redis:
restart: always
image: redis:5.0-alpine
networks:
- internal_network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
volumes:
- ./redis:/data
# es:
# restart: always
# image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.3
# environment:
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
# networks:
# - internal_network
# healthcheck:
# test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
# volumes:
# - ./elasticsearch:/usr/share/elasticsearch/data
web:
image: tootsuite/mastodon:v2.9.3
restart: always
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
networks:
- internal_network
- external_network # allow mastodon to talk to the internet
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --header 'x-forwarded-proto: https' --proxy=off localhost:3000/api/v1/instance || exit 1"]
ports:
- "127.0.0.1:3000:3000"
depends_on:
- db
- redis
# - es
volumes:
- ./public/system:/mastodon/public/system
- ./.env.production:/mastodon/.env.production:rw
streaming:
image: tootsuite/mastodon:v2.9.3
restart: always
env_file: .env.production
command: node ./streaming
networks:
- internal_network
- external_network
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --header 'x-forwarded-proto: https' --proxy=off localhost:4000/api/v1/streaming/health || exit 1"]
ports:
- "127.0.0.1:4000:4000"
depends_on:
- db
- redis
sidekiq:
image: tootsuite/mastodon:v2.9.3
restart: always
env_file: .env.production
command: bundle exec sidekiq
depends_on:
- db
- redis
networks:
- internal_network
volumes:
- ./public/system:/mastodon/public/system
## Uncomment to enable federation with tor instances along with adding the following ENV variables
## http_proxy=http://privoxy:8118
## ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
# tor:
# image: sirboops/tor
# networks:
# - internal_network
#
# privoxy:
# image: sirboops/privoxy
# volumes:
# - ./priv-config:/opt/config
# networks:
# - internal_network
nginx:
image: nginx:latest
expose:
- 80
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./public/:/home/mastodon/live/public
- /usr/share/nginx/html:/usr/share/nginx/html
restart: always
environment:
VIRTUAL_HOST: mastodon.ethical.net
LETSENCRYPT_HOST: mastodon.ethical.net
depends_on:
- web
- streaming
networks:
- external_network
- internal_network
networks:
external_network:
external: true
name: nginx-proxy
internal_network:
internal: true
# Based on https://github.com/tootsuite/mastodon/blob/master/dist/nginx.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
server {
listen 80;
listen [::]:80;
server_name mastodon.ethical.net;
keepalive_timeout 70;
sendfile on;
client_max_body_size 80m;
root /home/mastodon/live/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 {
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_header Server;
proxy_pass http://web: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_valid 410 24h;
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://streaming: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;
}
# Based on https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/blob/master/docs/Docker-Compose.md
# and https://blog.ssdnodes.com/blog/host-multiple-ssl-websites-docker-nginx/
version: '3'
services:
nginx:
image: nginx:alpine
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- conf:/etc/nginx/conf.d
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- certs:/etc/nginx/certs
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
dockergen:
image: jwilder/docker-gen
container_name: nginx-proxy-gen
depends_on:
- nginx
command: -notify-sighup nginx-proxy -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
volumes:
- conf:/etc/nginx/conf.d
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- certs:/etc/nginx/certs
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: nginx-proxy-le
depends_on:
- nginx
- dockergen
environment:
NGINX_PROXY_CONTAINER: nginx-proxy
NGINX_DOCKER_GEN_CONTAINER: nginx-proxy-gen
DEFAULT_EMAIL: rajendrabhochalya@gmail.com
volumes:
- conf:/etc/nginx/conf.d
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- certs:/etc/nginx/certs
- /var/run/docker.sock:/var/run/docker.sock:ro
volumes:
conf:
vhost:
html:
certs:
networks:
default:
external:
name: nginx-proxy
@czorzini
Copy link
Copy Markdown

czorzini commented Oct 2, 2019

great work Raj!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment