diff --git a/README.md b/README.md new file mode 100644 index 0000000..62631a0 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Gitea-Docker-Compose +Nitter Docker-Compose + +1. Update `docker-compose.yml` +2. Configure `nitter.conf` +3. Update the hostname in `swag/nginx/proxy-confs/nitter.subdomain.conf` approprieately. +3. Run `docker-compose up` and make sure nothing errors out. You can use `docker-compose up -d` to start it in the background if you want. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..bfd0a5b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,79 @@ +version: "3" + +services: + + nitter: + image: zedeus/nitter:latest + container_name: nitter + restart: unless-stopped + volumes: + - ./nitter.conf:/src/nitter.conf:Z + networks: + - nitter + - redis + depends_on: + - redis + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:8080/Jack/status/20 || exit 1 + interval: 30s + timeout: 5s + retries: 2 + user: "998:998" + read_only: true + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + + redis: + image: redis:alpine + container_name: redis + restart: unless-stopped + command: redis-server --save 60 1 --loglevel warning + volumes: + - redis:/data + networks: + - redis + healthcheck: + test: redis-cli ping + interval: 30s + timeout: 5s + retries: 2 + user: "999:1000" + read_only: true + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + + swag: + image: ghcr.io/linuxserver/swag + container_name: swag + restart: unless-stopped + cap_add: + - NET_ADMIN + environment: + - PUID=1000 + - PGID=1000 + - URL=arcticfoxes.net + - SUBDOMAINS=nitter + - VALIDATION=http + - EMAIL=contact@tommytran.io + - ONLY_SUBDOMAINS=true + volumes: + - ./swag:/config:Z + - /etc/localtime:/etc/localtime:ro + ports: + - 443:443 + - 80:80 + networks: + - nitter + security_opt: + - no-new-privileges:true + +networks: + nitter: + redis: + +volumes: + redis: \ No newline at end of file diff --git a/nitter.conf b/nitter.conf new file mode 100644 index 0000000..5823432 --- /dev/null +++ b/nitter.conf @@ -0,0 +1,45 @@ +[Server] +address = "0.0.0.0" +port = 8080 +https = false # disable to enable cookies when not using https +httpMaxConnections = 100 +staticDir = "./public" +title = "nitter" +hostname = "nitter.net" + +[Cache] +listMinutes = 240 # how long to cache list info (not the tweets, so keep it high) +rssMinutes = 10 # how long to cache rss queries +redisHost = "redis" # Change to "nitter-redis" if using docker-compose +redisPort = 6379 +redisPassword = "" +redisConnections = 20 # connection pool size +redisMaxConnections = 30 +# max, new connections are opened when none are available, but if the pool size +# goes above this, they're closed when released. don't worry about this unless +# you receive tons of requests per second + +[Config] +hmacKey = "secretkey" # random key for cryptographic signing of video urls +base64Media = false # use base64 encoding for proxied media urls +enableRSS = true # set this to false to disable RSS feeds +enableDebug = false # enable request logs and debug endpoints +proxy = "" # http/https url, SOCKS proxies are not supported +proxyAuth = "" +tokenCount = 10 +# minimum amount of usable tokens. tokens are used to authorize API requests, +# but they expire after ~1 hour, and have a limit of 187 requests. +# the limit gets reset every 15 minutes, and the pool is filled up so there's +# always at least $tokenCount usable tokens. again, only increase this if +# you receive major bursts all the time + +# Change default preferences here, see src/prefs_impl.nim for a complete list +[Preferences] +theme = "Nitter" +replaceTwitter = "nitter.net" +replaceYouTube = "piped.video" +replaceReddit = "teddit.net" +replaceInstagram = "" +proxyVideos = true +hlsPlayback = false +infiniteScroll = false \ No newline at end of file diff --git a/swag/nginx/proxy-confs/nitter.subdomain.conf b/swag/nginx/proxy-confs/nitter.subdomain.conf new file mode 100644 index 0000000..1ea9845 --- /dev/null +++ b/swag/nginx/proxy-confs/nitter.subdomain.conf @@ -0,0 +1,31 @@ +## Version 2022/09/08 + +server { + listen 443 ssl; + listen [::]:443 ssl; + + server_name nitter.*; + + include /config/nginx/ssl.conf; + + client_max_body_size 0; + + location / { + # enable the next two lines for http auth + #auth_basic "Restricted"; + #auth_basic_user_file /config/nginx/.htpasswd; + + # enable for ldap auth (requires ldap-server.conf in the server block) + #include /config/nginx/ldap-location.conf; + + # enable for Authelia (requires authelia-server.conf in the server block) + #include /config/nginx/authelia-location.conf; + + include /config/nginx/proxy.conf; + include /config/nginx/resolver.conf; + set $upstream_app nitter; + set $upstream_port 8080; + set $upstream_proto http; + proxy_pass $upstream_proto://$upstream_app:$upstream_port; + } +} \ No newline at end of file diff --git a/swag/nginx/ssl.conf b/swag/nginx/ssl.conf new file mode 100644 index 0000000..2ec3cd4 --- /dev/null +++ b/swag/nginx/ssl.conf @@ -0,0 +1,41 @@ +## Version 2022/08/20 - Changelog: https://github.com/linuxserver/docker-baseimage-alpine-nginx/commits/master/root/defaults/nginx/ssl.conf.sample + +### Mozilla Recommendations +# generated 2022-08-05, Mozilla Guideline v5.6, nginx 1.17.7, OpenSSL 1.1.1k, intermediate configuration +# https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=intermediate&openssl=1.1.1k&guideline=5.6 + +ssl_certificate /config/keys/cert.crt; +ssl_certificate_key /config/keys/cert.key; +ssl_session_timeout 1d; +ssl_session_cache shared:MozSSL:10m; # about 40000 sessions +ssl_session_tickets off; + +# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam +ssl_dhparam /config/nginx/dhparams.pem; + +# intermediate configuration +ssl_protocols TLSv1.2 TLSv1.3; +ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; +ssl_prefer_server_ciphers off; + +# HSTS (ngx_http_headers_module is required) (63072000 seconds) +add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; + +# OCSP stapling +ssl_stapling on; +ssl_stapling_verify on; + +# verify chain of trust of OCSP response using Root CA and Intermediate certs +ssl_trusted_certificate /config/keys/cert.crt; + +# Optional additional headers +add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; font-src 'self'; img-src 'self'; manifest-src 'self'; media-src blob:; script-src 'self' 'unsafe-inline' blob:; style-src 'self' 'unsafe-inline'; block-all-mixed-content; base-uri 'none'"; +add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), clipboard-read=(), clipboard-write=(), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), screen-wake-lock=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; +add_header Referrer-Policy "same-origin" always; +add_header X-Content-Type-Options "nosniff" always; +#add_header X-UA-Compatible "IE=Edge" always; +add_header X-XSS-Protection "0" always; +add_header Cross-Origin-Resource-Policy same-origin; +add_header Cross-Origin-Embedder-Policy require-corp; +add_header Cross-Origin-Opener-Policy same-origin; +add_header Expect-CT "enforce, max-age=63072000"; \ No newline at end of file