Preface#
Deploying Mastodon is no longer a rare occurrence, but I still want to share my deployment method, which may be more suitable for beginners. This tutorial is also applicable without 1Panel.
Regarding the deployment of Mastodon, this guide does not set up the original version of Mastodon, but rather a Fork based on Glitch—Chuckya, which has more configurable items compared to the original version and generally requires no modification of the source code.
Why Use 1Panel#
Just like everyone used Baota back then, I use 1Panel because of its visual file management, built-in SSH, convenient certificate configuration, and easy backup settings, making it very suitable for beginners.
Using 1Panel naturally means deploying with Docker, which is also one of the most convenient methods.
Preparations#
- Choose a server. If you want to set up Mastodon, I recommend at least a 2C4G server; 4C8G would be better. Please do not use domestic servers!
- Choose a domain name.
- Install 1Panel. (There is no need to install Docker separately; it is installed together with 1Panel.)
Official Installation#
Choose a Directory to Store Your Mastodon#
I placed it in /opt/Mastodon.
Using 1Panel, you can create a folder here, or enter the terminal and type:
mkdir /opt/mastodon
Pull the Configuration Files for Mastodon from the Repository and Modify Them#
Repository Address (Chuckya Fork)
https://github.com/TheEssem/mastodon
We need to pull two files: docker-compose.yml and .env.production.sample. Using 1Panel, you can download and then upload, or enter the terminal and type:
cd Mastodon
wget https://gcore.jsdelivr.net/gh/TheEssem/mastodon@refs/heads/main/docker-compose.yml
wget https://gcore.jsdelivr.net/gh/TheEssem/mastodon@refs/heads/main/.env.production.sample
cp ./.env.production.sample .env.production
Modify docker-compose.yml#
If you want to use the Glitch branch or the original version, you only need to modify the image.
I commented out the db and redis sections; to clearly demonstrate, I have removed these two parts from the code below. Installing Elasticsearch with 1Panel has become cumbersome, so I installed it directly together.
Parts that need modification: Replace all networks with 1panel-network and add the external attribute at the end.
(The format may contain errors; please directly pull the files from the repository for modification.)
services:
web:
image: ghcr.io/theessem/mastodon:nightly # Change according to your needs
restart: always
env_file: .env.production
command: bundle exec puma -C config/puma.rb
networks: # Needs modification
- 1panel-network
healthcheck:
# prettier-ignore
test: ['CMD-SHELL',"curl -s --noproxy localhost localhost:3000/health | grep -q 'OK' || exit 1"]
ports:
- '127.0.0.1:3000:3000' # Change according to your needs
volumes:
- ./public/system:/mastodon/public/system
es:
restart: always
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.4
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true"
- "xpack.license.self_generated.type=basic"
- "xpack.security.enabled=false"
- "xpack.watcher.enabled=false"
- "xpack.graph.enabled=false"
- "xpack.ml.enabled=false"
- "bootstrap.memory_lock=true"
- "cluster.name=es-mastodon"
- "discovery.type=single-node"
- "thread_pool.write.queue_size=1000"
networks:
- 1panel-network
healthcheck:
test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
volumes:
- ./elasticsearch:/usr/share/elasticsearch/data
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
ports:
- '127.0.0.1:9200:9200'
streaming:
image: ghcr.io/theessem/mastodon-streaming:nightly # Change according to your needs
restart: always
env_file: .env.production
command: node ./streaming/index.js
networks: # Needs modification
- 1panel-network
healthcheck:
# prettier-ignore
test: ['CMD-SHELL', "curl -s --noproxy localhost localhost:4000/api/v1/streaming/health | grep -q 'OK' || exit 1"]
ports:
- '127.0.0.1:4000:4000' # Change according to your needs
sidekiq:
image: ghcr.io/theessem/mastodon:nightly # Change according to your needs
restart: always
env_file: .env.production
command: bundle exec sidekiq
networks: # Needs modification
- 1panel-network
volumes:
- ./public/system:/mastodon/public/system
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
# Parts that need modification:
networks:
1panel-network:
external: true
Currently, the default web service for Mastodon is set to port 3000, and streaming is set to port 4000.
Install PostgreSQL and Redis from the 1Panel App Store#
One-click installation is sufficient; you can choose the version of PostgreSQL yourself.
Create a Database#
- After installation, go to Database from the left navigation bar.
- Select PostgreSQL.
-
Click to create a database, customize your database name, username, and password.
-
Check your PostgreSQL and Redis connection information:
PostgreSQL:
Click to enter; there will be a container connection address here:
Redis: Similarly
You will also need the password from here.
Execute Installation#
cd /opt/Mastodon
docker-compose run --rm web bundle exec rake mastodon:setup
Domain name: your domain name
Single user mode disables registrations and redirects the landing page to your public profile.
Do you want to enable single user mode? N
Are you using Docker to run Mastodon? Y
PostgreSQL host: # The container connection address from earlier
PostgreSQL port: 5432
Name of PostgreSQL database: mastodon
Name of PostgreSQL user: mastodon
Password of PostgreSQL user: (enter the database password you set for mastodon above)
Database configuration works! 🎆
Redis host: # The container connection address from earlier
Redis port: 6379
Redis password: # The password from earlier
Redis configuration works! 🎆
Do you want to store uploaded files on the cloud? N # Change according to your needs; I stored them locally.
Do you want to send e-mails from localhost? N # Set your SMTP server
SMTP server:
SMTP port: 587
SMTP username:
SMTP password:
SMTP authentication: plain
SMTP OpenSSL verify mode: none
E-mail address to send e-mails “from”:
Send a test e-mail with this configuration right now? Y
This configuration will be written to .env.production
Save configuration? Yes
After running, a string of configuration information will be generated, which you need to fill into your .env.production.
Continue to Generate Admin Account#
As of the current version, generating the admin account no longer has bugs.
Modifiable Content in .env.production#
I used AI for translation, which can be referenced. The Glitch version allows for more customization of Mastodon (such as character count, maximum number of tags, number of pins, etc.; Chuckya can set the maximum number of attachments allowed for upload and display).
# This is a sample configuration file. You can use the interactive setup wizard `bundle exec rails mastodon:setup` to generate your configuration, but if you want to further customize settings, you may need to edit manually. This example does not show all available configuration options. Please refer to https://docs.joinmastodon.org/admin/config/ for complete documentation.
# Note that the syntax accepted by this file varies slightly depending on whether you are using `docker-compose`. In particular, if you are using `docker-compose`, the values of each declared variable will be taken directly, including quotes.
# Reference: https://github.com/mastodon/mastodon/issues/16895
# Federation settings
# ----------
# This identifies your server and cannot be safely changed later
# ----------
LOCAL_DOMAIN=example.com
# Use this option only if you need to run Mastodon on a domain different from the one used for federation.
# You can read more about this option here: https://docs.joinmastodon.org/admin/config/#web-domain
# DO *NOT* USE THIS UNLESS YOU KNOW *EXACTLY* WHAT YOU ARE DOING.
# WEB_DOMAIN=mastodon.example.com
# If you want to have multiple aliases [email protected]
# [email protected], etc., for the same user. LOCAL_DOMAIN should not be included. Separate with commas.
# ALTERNATE_DOMAINS=example1.com,example2.com
# HTTP proxy for outbound requests (optional)
# http_proxy=http://gateway.local:8118
# Access control for hidden services.
# ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
# Authorized fetch mode (optional)
# Requires remote servers to authenticate when fetching tweets, see
# https://docs.joinmastodon.org/admin/config/#authorized_fetch
# AUTHORIZED_FETCH=true
# Limited federation mode (optional)
# Only allows federation with specific domains, see
# https://docs.joinmastodon.org/admin/config/#whitelist_mode
# LIMITED_FEDERATION_MODE=true
# Redis
# -----
REDIS_HOST=localhost
REDIS_PORT=6379
# PostgreSQL
# ----------
DB_HOST=/var/run/postgresql
DB_USER=mastodon
DB_NAME=mastodon_production
DB_PASS=
DB_PORT=5432
# Elasticsearch (optional)
# ------------------------
#ES_ENABLED=true
#ES_HOST=localhost
#ES_PORT=9200
# Elasticsearch authentication (optional)
#ES_USER=elastic
#ES_PASS=password
# Secrets
# -------
# Use the task `RAILS_ENV=production bundle exec rails secret` to generate each key (if using docker compose, use `docker-compose run --rm web bundle exec rails secret`)
# -------
SECRET_KEY_BASE=
OTP_SECRET=
# Encryption keys
# ------------------
# Must be available and have the same value across all server processes
# These are private/secret values; do not share outside of the hosting environment
# Use `bin/rails db:encryption:init` to generate new keys
# Do not change these keys, or it will lead to data loss and other issues
# ------------------
# ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=
# ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=
# ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=
# Web Push
# --------
# Use `bundle exec rails mastodon:webpush:generate_vapid_key` to generate (the first is the private key, the second is the public key)
# You should only generate this once for the instance. If you later decide to change it, all push subscriptions will
# be invalidated, and users will need to revisit the site to resubscribe.
# --------
VAPID_PRIVATE_KEY=
VAPID_PUBLIC_KEY=
# Registration
# -------------
# Single user mode disables registrations and redirects the homepage to the first user profile
# SINGLE_USER_MODE=true
# Prevent registration using the following email domains
# EMAIL_DOMAIN_DENYLIST=example1.com|example2.de|etc
# Only allow registration using the following email domains
# EMAIL_DOMAIN_ALLOWLIST=example1.com|example2.de|etc
#TODO Move this
# Optionally change the default language
# DEFAULT_LOCALE=de
# Send emails
# ------------
SMTP_SERVER=
SMTP_PORT=587
SMTP_LOGIN=
SMTP_PASSWORD=
SMTP_FROM_ADDRESS[email protected]
# File storage (optional)
# -----------------------
# The attachment host must allow cross-origin requests from WEB_DOMAIN or
# if WEB_DOMAIN is not set, from LOCAL_DOMAIN. For example, the server may have the following header fields:
# Access-Control-Allow-Origin: https://192.168.1.123:9000/
# -----------------------
#S3_ENABLED=true
#S3_BUCKET=files.example.com
#AWS_ACCESS_KEY_ID=
#AWS_SECRET_ACCESS_KEY=
#S3_ALIAS_HOST=files.example.com
# Swift (optional)
# The attachment host must allow cross-origin requests - see the description above.
# SWIFT_ENABLED=true
#SWIFT_USERNAME=
# For Keystone V3, the value of SWIFT_TENANT should be the project name
# SWIFT_TENANT=
# SWIFT_PASSWORD=
# Some OpenStack V3 providers may require setting PROJECT_ID during high load (optional)
# SWIFT_PROJECT_ID=
# Supports both Keystone V2 and V3 URLs. It is recommended to use V3 URLs to avoid token rate limiting issues.
# SWIFT_AUTH_URL=
# SWIFT_CONTAINER=
# SWIFT_OBJECT_URL=
# SWIFT_REGION=
# Defaults to 'default'
# SWIFT_DOMAIN_NAME=
# Defaults to 60 seconds. Set to 0 to disable
# SWIFT_CACHE_TTL=
# Optional asset host in multi-server setups
# The asset host must allow cross-origin requests from WEB_DOMAIN or LOCAL_DOMAIN
# For example, the server may have the following header fields:
# Access-Control-Allow-Origin: https://example.com/
# CDN_HOST=https://assets.example.com
# Optional list of hosts allowed to serve media for your instance
# This is useful if you include external media in custom CSS or about pages,
# or if your data storage provider uses redirects to other domains.
# EXTRA_DATA_HOSTS=https://data.example1.com|https://data.example2.com
# Optional S3 alias (e.g., to provide files using a custom domain, possibly using Cloudfront or Cloudflare)
# S3_ALIAS_HOST=
# Streaming API integration
# STREAMING_API_BASE_URL=
# External authentication (optional)
# ----------------------------------
# LDAP authentication (optional)
# LDAP_ENABLED=true
# LDAP_HOST=localhost
# LDAP_PORT=389
# LDAP_METHOD=simple_tls
# LDAP_BASE=
# LDAP_BIND_DN=
# LDAP_PASSWORD=
# LDAP_UID=cn
# LDAP_MAIL=mail
# LDAP_SEARCH_FILTER=(|(%{uid}=%{email})(%{mail}=%{email}))
# LDAP_UID_CONVERSION_ENABLED=true
# LDAP_UID_CONVERSION_SEARCH=., -
# LDAP_UID_CONVERSION_REPLACE=_
# PAM authentication (optional)
# PAM authentication uses the "email" PAM variable to generate the email,
# and optionally uses PAM_DEFAULT_SUFFIX as a fallback
# The "email" pam environment variable is provided by:
# https://github.com/devkral/pam_email_extractor
# PAM_ENABLED=true
# Fallback email domain for email address generation (defaults to LOCAL_DOMAIN)
# PAM_EMAIL_DOMAIN=example.com
# Name of the PAM service (evaluates the "auth" part of pam)
# PAM_DEFAULT_SERVICE=rpam
# PAM service name for checking if a user can register (defaults to nil (disabled))
# PAM_CONTROLLED_SERVICE=rpam
# Global OAuth settings (optional):
# If you only have one policy, you may want to enable this
# OAUTH_REDIRECT_AT_SIGN_IN=true
# Optional CAS authentication (see omniauth-cas):
# CAS_ENABLED=true
# CAS_URL=https://sso.myserver.com/
# CAS_HOST=sso.myserver.com/
# CAS_PORT=443
# CAS_SSL=true
# CAS_VALIDATE_URL=
# CAS_CALLBACK_URL=
# CAS_LOGOUT_URL=
# CAS_LOGIN_URL=
# CAS_UID_FIELD='user'
# CAS_CA_PATH=
# CAS_DISABLE_SSL_VERIFICATION=false
# CAS_UID_KEY='user'
# CAS_NAME_KEY='name'
# CAS_EMAIL_KEY='email'
# CAS_NICKNAME_KEY='nickname'
# CAS_FIRST_NAME_KEY='firstname'
# CAS_LAST_NAME_KEY='lastname'
# CAS_LOCATION_KEY='location'
# CAS_IMAGE_KEY='image'
# CAS_PHONE_KEY='phone'
# Optional SAML authentication (see omniauth-saml)
# SAML_ENABLED=true
# SAML_ACS_URL=http://localhost:3000/auth/auth/saml/callback
# SAML_ISSUER=https://example.com
# SAML_IDP_SSO_TARGET_URL=https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO
# SAML_IDP_CERT=
# SAML_IDP_CERT_FINGERPRINT=
# SAML_NAME_IDENTIFIER_FORMAT=
# SAML_CERT=
# SAML_PRIVATE_KEY=
# SAML_SECURITY_WANT_ASSERTION_SIGNED=true
# SAML_SECURITY_WANT_ASSERTION_ENCRYPTED=true
# SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true
# SAML_ATTRIBUTES_STATEMENTS_UID="urn:oid:0.9.2342.19200300.100.1.1"
# SAML_ATTRIBUTES_STATEMENTS_EMAIL="urn:oid:1.3.6.1.4.1.5923.1.1.1.6"
# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.16.840.1.113730.3.1.241"
# SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME="urn:oid:2.5.4.42"
# SAML_ATTRIBUTES_STATEMENTS_LAST_NAME="urn:oid:2.5.4.4"
# SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1"
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED=
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL=
# Custom settings
# ---------------
# Customize the behavior of Mastodon in various ways
# ---------------
# Maximum allowed character count
MAX_TOOT_CHARS=500
# Maximum number of hashtags allowed in the subscription column
# Note that setting this value higher may lead to significant
# database load
MAX_FEED_HASHTAGS=4
# Maximum number of pinned posts
MAX_PINNED_TOOTS=5
# Maximum allowed character count for bios
MAX_BIO_CHARS=500
# Maximum number of profile fields
MAX_PROFILE_FIELDS=4
# Maximum allowed character count for display names
MAX_DISPLAY_NAME_CHARS=30
# Maximum number of voting options allowed
MAX_POLL_OPTIONS=5
# Maximum allowed character count for voting options
MAX_POLL_OPTION_CHARS=100
# Maximum number of emoji reactions per toot and user (minimum of 1)
MAX_REACTIONS=1
# Maximum number of attachments allowed for upload and display
# MAX_MEDIA_ATTACHMENTS=4
# MAX_REMOTE_MEDIA_ATTACHMENTS=16
# Maximum upload size for images and videos/audios
# Units in bytes
# 1048576 bytes equals 1 megabyte
# MAX_IMAGE_SIZE=8388608
# MAX_VIDEO_SIZE=41943040
# Maximum number of search results
# Relevant only when Elasticsearch is installed
# MAX_SEARCH_RESULTS=20
# Maximum number of trending hashtags
# Customize the number of hashtags displayed in 'Explore'
# MAX_TRENDING_TAGS=10
# Maximum size for custom emoji files
# If not defined or less than MAX_EMOJI_SIZE, the value of
# MAX_EMOJI_SIZE will be used as MAX_REMOTE_EMOJI_SIZE
# Units in bytes
# MAX_EMOJI_SIZE=262144
# MAX_REMOTE_EMOJI_SIZE=262144
# Optional hCaptcha support
# HCAPTCHA_SECRET_KEY=
# HCAPTCHA_SITE_KEY=
# IP and session retention
# -----------------------
# Ensure to modify the ip_cleanup_scheduler in config/sidekiq.yml
# If IP_RETENTION_PERIOD is set to less than two days (172800), the scheduler should be less than daily.
# -----------------------
IP_RETENTION_PERIOD=31556952
SESSION_RETENTION_PERIOD=31556952
Fill in the previously generated information and make some custom modifications.
Install Plugins for Elasticsearch to Optimize Chinese Search#
- Enter Containers from the left navigation bar.
- Select the container name that includes Elasticsearch, and choose Terminal in the operations column to enter and connect:
- Open https://release.infinilabs.com/ and enter; we need to install analysis-ik and analysis-stconvert, selecting the version you want to install. Back in the terminal, enter the following code (using the version 7.17.4 from the docker-compose.yml file above as an example):
yes | elasticsearch-plugin install https://release.infinilabs.com/analysis-ik/stable/elasticsearch-analysis-ik-7.17.14.zip
elasticsearch-plugin install https://release.infinilabs.com/analysis-stconvert/stable/elasticsearch-analysis-stconvert-7.17.4.zip
After completion, restart Elasticsearch and fill in your Elasticsearch connection information in .env.production.
Then you need to grant permissions to the elasticsearch folder in the Mastodon folder.
chown 1000:1000 -R elasticsearch
Start#
docker-compose up -d
After starting, you need to grant permissions to the public folder; otherwise, the service will continue to report errors:
chown 991:991 -R ./public
At this point, your service has successfully run.
Set Up DNS Account, Acme Account, and Apply for Certificate#
I use Cloudflare; if you are like me, you can continue reading:
- Obtain API Token, create a token - use the template (edit DNS), select all zones:
- In 1Panel, select the website, install OpenResty as required, then go to Certificates - DNS Account.
- Create a DNS account, select Cloudflare, and enter your Cloudflare account email and Token:
- Create an Acme account, enter an email (this email can be chosen freely):
- Click to apply for a certificate, filling in the URL for which you need to apply for a certificate.
Create a Website#
-
From the left navigation bar, go to Websites - Websites, click to create a website - Reverse Proxy, fill in your web address as the proxy address, default is 127.0.0.1:3000.
-
Click on the website name or enter configuration from the right operations, click HTTPs, select enable, and choose the certificate you just applied for.
-
Add a record in Cloudflare, pointing your website name to your server IP.
-
At this point, you can access your server.
Configure Nginx#
After successfully running the service, we also need to configure Nginx. You can pull the official Nginx configuration file from Mastodon for reference:
wget https://gcore.jsdelivr.net/gh/TheEssem/mastodon@refs/heads/main/dist/nginx.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream backend {
server 127.0.0.1:3000 fail_timeout=0;
}
upstream streaming {
# Instruct nginx to send connections to the server with the least number of connections
# to ensure load is distributed evenly.
least_conn;
server 127.0.0.1:4000 fail_timeout=0;
# Uncomment these lines for load-balancing multiple instances of streaming for scaling,
# this assumes your running the streaming server on ports 4000, 4001, and 4002:
# server 127.0.0.1:4001 fail_timeout=0;
# server 127.0.0.1:4002 fail_timeout=0;
}
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 example.com;
root /home/mastodon/live/public;
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_protocols TLSv1.2 TLSv1.3;
# You can use https://ssl-config.mozilla.org/ to generate your cipher set.
# We recommend their "Intermediate" level.
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:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Uncomment these lines once you acquire a certificate:
# ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
keepalive_timeout 70;
sendfile on;
client_max_body_size 99m;
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 image/svg+xml image/x-icon;
gzip_static on;
location / {
try_files $uri @proxy;
}
# If Docker is used for deployment and Rails serves static files,
# then needed must replace line `try_files $uri =404;` with `try_files $uri @proxy;`.
location = /sw.js {
add_header Cache-Control "public, max-age=604800, must-revalidate";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
try_files $uri =404;
}
location ~ ^/assets/ {
add_header Cache-Control "public, max-age=2419200, must-revalidate";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
try_files $uri =404;
}
location ~ ^/avatars/ {
add_header Cache-Control "public, max-age=2419200, must-revalidate";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
try_files $uri =404;
}
location ~ ^/emoji/ {
add_header Cache-Control "public, max-age=2419200, must-revalidate";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
try_files $uri =404;
}
location ~ ^/headers/ {
add_header Cache-Control "public, max-age=2419200, must-revalidate";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
try_files $uri =404;
}
location ~ ^/packs/ {
add_header Cache-Control "public, max-age=2419200, must-revalidate";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
try_files $uri =404;
}
location ~ ^/shortcuts/ {
add_header Cache-Control "public, max-age=2419200, must-revalidate";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
try_files $uri =404;
}
location ~ ^/sounds/ {
add_header Cache-Control "public, max-age=2419200, must-revalidate";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
try_files $uri =404;
}
location ~ ^/system/ {
add_header Cache-Control "public, max-age=2419200, immutable";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "default-src 'none'; form-action 'none'";
try_files $uri =404;
}
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 $scheme;
proxy_set_header Proxy "";
proxy_pass http://streaming;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
tcp_nodelay on;
}
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 $scheme;
proxy_set_header Proxy "";
proxy_pass_header Server;
proxy_pass http://backend;
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;
tcp_nodelay on;
}
error_page 404 500 501 502 503 504 /500.html;
}
Add this to your OpenResty.
Summary#
This article provides a perspective aimed at friends with little to no coding background who prefer a graphical interface. It will be further improved in the future, and I will update the tutorial on using 1Panel for file backups. This first update ends here.