banner
 Aeris

Aerisの小宇宙

Deploy Mastodon with 1Panel and Configure Chinese Search

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#

  1. 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!
  2. Choose a domain name.
  3. 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.

Pasted image 20250109190722.png

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#

Pasted image 20250109192932.png
Pasted image 20250109192952.png

One-click installation is sufficient; you can choose the version of PostgreSQL yourself.

Create a Database#

  1. After installation, go to Database from the left navigation bar.

Pasted image 20250109194446.png

  1. Select PostgreSQL.

Pasted image 20250109194517.png

  1. Click to create a database, customize your database name, username, and password.

  2. Check your PostgreSQL and Redis connection information:

PostgreSQL:

Pasted image 20250109195123.png

Click to enter; there will be a container connection address here:

Pasted image 20250109195224.png

Redis: Similarly

Pasted image 20250109195336.png

You will also need the password from here.

Pasted image 20250109195427.png

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.

  1. Enter Containers from the left navigation bar.

Pasted image 20250109200629.png

  1. Select the container name that includes Elasticsearch, and choose Terminal in the operations column to enter and connect:

Pasted image 20250109200751.png

  1. 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:

  1. Obtain API Token, create a token - use the template (edit DNS), select all zones:

Pasted image 20250109202334.png

Pasted image 20250109202424.png

  1. In 1Panel, select the website, install OpenResty as required, then go to Certificates - DNS Account.

Pasted image 20250109202526.png

Pasted image 20250109192039.png

  1. Create a DNS account, select Cloudflare, and enter your Cloudflare account email and Token:

Pasted image 20250109202647.png

  1. Create an Acme account, enter an email (this email can be chosen freely):

Pasted image 20250109202755.png

  1. Click to apply for a certificate, filling in the URL for which you need to apply for a certificate.

Create a Website#

  1. 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.

  2. Click on the website name or enter configuration from the right operations, click HTTPs, select enable, and choose the certificate you just applied for.

  3. Add a record in Cloudflare, pointing your website name to your server IP.

  4. 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.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.