環境 VMware
CentOS 7.6
[root@warship ~]# docker version
Client:
Version: 18.09.0
API version: 1.39
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:48:22 2018
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:19:08 2018
OS/Arch: linux/amd64
Experimental: false
安裝github官方文檔
[root@warship live]# git clone https://github.com/tootsuite/mastodon.git live
[root@warship live]# cd ~/live
[root@warship live]# git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)
[root@warship live]# vim docker-compose.yml
註釋所有build .
[root@warship live]# cat docker-compose.yml
version: '3'
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:
#build: .
image: tootsuite/mastodon
restart: always
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
networks:
- external_network
- internal_network
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
streaming:
#build: .
image: tootsuite/mastodon
restart: always
env_file: .env.production
command: node ./streaming
networks:
- external_network
- internal_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:
#build: .
image: tootsuite/mastodon
restart: always
env_file: .env.production
command: bundle exec sidekiq
depends_on:
- db
- redis
networks:
- external_network
- 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:
# - external_network
# - internal_network
#
# privoxy:
# image: sirboops/privoxy
# volumes:
# - ./priv-config:/opt/config
# networks:
# - external_network
# - internal_network
networks:
external_network:
internal_network:
internal: true
[root@warship live]# cp .env.production.sample .env.production
[root@warship live]# chown -R 991:991 public
[root@warship live]# docker-compose run --rm web bundle exec rake mastodon:setup
Starting live_redis_1 ... done
Starting live_db_1 ... done
Your instance is identified by its domain name. Changing it afterward will break things.
Domain name: mymedia.com
Single user mode disables registrations and redirects the landing page to your public profile.
Do you want to enable single user mode? No
Are you using Docker to run Mastodon? Yes
PostgreSQL host: db
PostgreSQL port: 5432
Name of PostgreSQL database: postgres
Name of PostgreSQL user: 1
Password of PostgreSQL user: Aborting. Bye!
[root@warship live]# docker-compose run --rm web bundle exec rake mastodon:setup
Starting live_redis_1 ... done
Starting live_db_1 ... done
Your instance is identified by its domain name. Changing it afterward will break things.
Domain name: mymedia.com
Single user mode disables registrations and redirects the landing page to your public profile.
Do you want to enable single user mode? No
Are you using Docker to run Mastodon? Yes
PostgreSQL host: db
PostgreSQL port: 5432
Name of PostgreSQL database: postgres
Name of PostgreSQL user: postgres
Password of PostgreSQL user:
Database configuration works! 🎆
Redis host: redis
Redis port: 6379
Redis password:
Redis configuration works! 🎆
Do you want to store uploaded files on the cloud? No
Do you want to send e-mails from localhost? No
SMTP server: smtp.qq.com
SMTP port: 587
SMTP username:你的qq號@qq.com
SMTP password:由網頁郵箱配置頁面生成的
SMTP authentication: plain
SMTP OpenSSL verify mode: none 必須選這個
E-mail address to send e-mails "from": 你的qq號@qq.com(必須寫這個 默認的不能用)
Send a test e-mail with this configuration right now? Yes
Send test e-mail to: 測試郵件的接收郵箱
This configuration will be written to .env.production
Save configuration? Yes
Below is your configuration, save it to an .env.production file outside Docker:
把下面內容寫入.env.production 之前以爲是自動寫的,後來發現需要手動寫入文件.env.production
# Generated with mastodon:setup on 2019-09-02 05:36:12 UTC
LOCAL_DOMAIN=mymedia.com
SINGLE_USER_MODE=false
SECRET_KEY_BASE=6a74668b033ec0357052ba5046805e80733dbe565b7d570774490ac978b6b8bd87aaa57471608bdeba955ac499b28c1edb4b291da45630f59086a0062667680d
OTP_SECRET=28431a3559ed5ea84b153c9abc7c12fe524b1cd9e37cf72f62934764eae73e6d1175796f6175fbdf456f6f1d08d02f3b12e0c10b40e89a525b2e62e6f1ef868e
VAPID_PRIVATE_KEY=aY9GGtmNGBrdqbXXz7OrMZP8CqIIx86D71YHC5DQ_tU=
VAPID_PUBLIC_KEY=BBJ6l-N7YAaUVN3ulcnABb-SRWzpuJfEBDb6AdU6gI1TuSUNuAeLAYyTULbnL0ilg0RwlcQPmGZf-nSZjsm0DjQ=
DB_HOST=db
DB_PORT=5432
DB_NAME=postgres
DB_USER=postgres
DB_PASS=
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=
SMTP_SERVER=smtp.qq.com
SMTP_PORT=587
SMTP_LOGIN=你的qq號@qq.com
SMTP_PASSWORD=由網頁郵箱配置頁面生成的
SMTP_AUTH_METHOD=plain
SMTP_OPENSSL_VERIFY_MODE=none
SMTP_FROM_ADDRESS=你的qq號@qq.com
Now that configuration is saved, the database schema must be loaded.
If the database already exists, this will erase its contents.
#令開一個終端寫完.env.production後繼續點擊下一步
Prepare the database now? Yes
Running `RAILS_ENV=production rails db:setup` ...
Database 'postgres' already exists
-- enable_extension("plpgsql")
-> 0.0185s
-- create_table("account_conversations", {:force=>:cascade})
-> 0.0960s
-- create_table("account_domain_blocks", {:force=>:cascade})
-> 0.0086s
-- create_table("account_identity_proofs", {:force=>:cascade})
-> 0.0158s
-- create_table("account_moderation_notes", {:force=>:cascade})
-> 0.0170s
-- create_table("account_pins", {:force=>:cascade})
-> 0.0183s
-- create_table("account_stats", {:force=>:cascade})
-> 0.0139s
-- create_table("account_tag_stats", {:force=>:cascade})
-> 0.0101s
-- create_table("account_warning_presets", {:force=>:cascade})
-> 0.0058s
-- create_table("account_warnings", {:force=>:cascade})
-> 0.0173s
-- create_table("accounts", {:force=>:cascade})
-> 0.0560s
-- create_table("accounts_tags", {:id=>false, :force=>:cascade})
-> 0.0096s
-- create_table("admin_action_logs", {:force=>:cascade})
-> 0.0141s
-- create_table("backups", {:force=>:cascade})
-> 0.0073s
-- create_table("blocks", {:force=>:cascade})
-> 0.0146s
-- create_table("conversation_mutes", {:force=>:cascade})
-> 0.0093s
-- create_table("conversations", {:force=>:cascade})
-> 0.0111s
-- create_table("custom_emojis", {:force=>:cascade})
-> 0.0105s
-- create_table("custom_filters", {:force=>:cascade})
-> 0.0120s
-- create_table("domain_blocks", {:force=>:cascade})
-> 0.0139s
-- create_table("email_domain_blocks", {:force=>:cascade})
-> 0.0101s
-- create_table("favourites", {:force=>:cascade})
-> 0.0190s
-- create_table("featured_tags", {:force=>:cascade})
-> 0.0125s
-- create_table("follow_requests", {:force=>:cascade})
-> 0.0111s
-- create_table("follows", {:force=>:cascade})
-> 0.0195s
-- create_table("identities", {:force=>:cascade})
-> 0.0128s
-- create_table("imports", {:force=>:cascade})
-> 0.0069s
-- create_table("invites", {:force=>:cascade})
-> 0.0157s
-- create_table("list_accounts", {:force=>:cascade})
-> 0.0184s
-- create_table("lists", {:force=>:cascade})
-> 0.0102s
-- create_table("media_attachments", {:force=>:cascade})
-> 0.0274s
-- create_table("mentions", {:force=>:cascade})
-> 0.0170s
-- create_table("mutes", {:force=>:cascade})
-> 0.0184s
-- create_table("notifications", {:force=>:cascade})
-> 0.0285s
-- create_table("oauth_access_grants", {:force=>:cascade})
-> 0.0131s
-- create_table("oauth_access_tokens", {:force=>:cascade})
-> 0.0171s
-- create_table("oauth_applications", {:force=>:cascade})
-> 0.0152s
-- create_table("pghero_space_stats", {:force=>:cascade})
-> 0.0102s
-- create_table("poll_votes", {:force=>:cascade})
-> 0.0170s
-- create_table("polls", {:force=>:cascade})
-> 0.0171s
-- create_table("preview_cards", {:force=>:cascade})
-> 0.0204s
-- create_table("preview_cards_statuses", {:id=>false, :force=>:cascade})
-> 0.0107s
-- create_table("relays", {:force=>:cascade})
-> 0.0087s
-- create_table("report_notes", {:force=>:cascade})
-> 0.0145s
-- create_table("reports", {:force=>:cascade})
-> 0.0150s
-- create_table("scheduled_statuses", {:force=>:cascade})
-> 0.0138s
-- create_table("session_activations", {:force=>:cascade})
-> 0.0194s
-- create_table("settings", {:force=>:cascade})
-> 0.0101s
-- create_table("site_uploads", {:force=>:cascade})
-> 0.0133s
-- create_table("status_pins", {:force=>:cascade})
-> 0.0378s
-- create_table("status_stats", {:force=>:cascade})
-> 0.0209s
-- create_table("statuses", {:id=>:bigint, :default=>#<Proc:0x00007fc1b79f5ad0@/opt/mastodon/db/schema.rb:609 (lambda)>, :force=>:cascade})
-> 0.0279s
-- create_table("statuses_tags", {:id=>false, :force=>:cascade})
-> 0.0099s
-- create_table("stream_entries", {:force=>:cascade})
-> 0.0141s
-- create_table("subscriptions", {:force=>:cascade})
-> 0.0112s
-- create_table("tags", {:force=>:cascade})
-> 0.0143s
-- create_table("tombstones", {:force=>:cascade})
-> 0.0143s
-- create_table("user_invite_requests", {:force=>:cascade})
-> 0.0095s
-- create_table("users", {:force=>:cascade})
-> 0.0354s
-- create_table("web_push_subscriptions", {:force=>:cascade})
-> 0.0144s
-- create_table("web_settings", {:force=>:cascade})
-> 0.0095s
-- add_foreign_key("account_conversations", "accounts", {:on_delete=>:cascade})
-> 0.0102s
-- add_foreign_key("account_conversations", "conversations", {:on_delete=>:cascade})
-> 0.0029s
-- add_foreign_key("account_domain_blocks", "accounts", {:name=>"fk_206c6029bd", :on_delete=>:cascade})
-> 0.0030s
-- add_foreign_key("account_identity_proofs", "accounts", {:on_delete=>:cascade})
-> 0.0043s
-- add_foreign_key("account_moderation_notes", "accounts")
-> 0.0023s
-- add_foreign_key("account_moderation_notes", "accounts", {:column=>"target_account_id"})
-> 0.0030s
-- add_foreign_key("account_pins", "accounts", {:column=>"target_account_id", :on_delete=>:cascade})
-> 0.0033s
-- add_foreign_key("account_pins", "accounts", {:on_delete=>:cascade})
-> 0.0037s
-- add_foreign_key("account_stats", "accounts", {:on_delete=>:cascade})
-> 0.0033s
-- add_foreign_key("account_tag_stats", "tags", {:on_delete=>:cascade})
-> 0.0038s
-- add_foreign_key("account_warnings", "accounts", {:column=>"target_account_id", :on_delete=>:cascade})
-> 0.0050s
-- add_foreign_key("account_warnings", "accounts", {:on_delete=>:nullify})
-> 0.0027s
-- add_foreign_key("accounts", "accounts", {:column=>"moved_to_account_id", :on_delete=>:nullify})
-> 0.0035s
-- add_foreign_key("admin_action_logs", "accounts", {:on_delete=>:cascade})
-> 0.0029s
-- add_foreign_key("backups", "users", {:on_delete=>:nullify})
-> 0.0042s
-- add_foreign_key("blocks", "accounts", {:column=>"target_account_id", :name=>"fk_9571bfabc1", :on_delete=>:cascade})
-> 0.0035s
-- add_foreign_key("blocks", "accounts", {:name=>"fk_4269e03e65", :on_delete=>:cascade})
-> 0.0028s
-- add_foreign_key("conversation_mutes", "accounts", {:name=>"fk_225b4212bb", :on_delete=>:cascade})
-> 0.0031s
-- add_foreign_key("conversation_mutes", "conversations", {:on_delete=>:cascade})
-> 0.0041s
-- add_foreign_key("custom_filters", "accounts", {:on_delete=>:cascade})
-> 0.0045s
-- add_foreign_key("favourites", "accounts", {:name=>"fk_5eb6c2b873", :on_delete=>:cascade})
-> 0.0040s
-- add_foreign_key("favourites", "statuses", {:name=>"fk_b0e856845e", :on_delete=>:cascade})
-> 0.0041s
-- add_foreign_key("featured_tags", "accounts", {:on_delete=>:cascade})
-> 0.0028s
-- add_foreign_key("featured_tags", "tags", {:on_delete=>:cascade})
-> 0.0040s
-- add_foreign_key("follow_requests", "accounts", {:column=>"target_account_id", :name=>"fk_9291ec025d", :on_delete=>:cascade})
-> 0.0023s
-- add_foreign_key("follow_requests", "accounts", {:name=>"fk_76d644b0e7", :on_delete=>:cascade})
-> 0.0028s
-- add_foreign_key("follows", "accounts", {:column=>"target_account_id", :name=>"fk_745ca29eac", :on_delete=>:cascade})
-> 0.0046s
-- add_foreign_key("follows", "accounts", {:name=>"fk_32ed1b5560", :on_delete=>:cascade})
-> 0.0032s
-- add_foreign_key("identities", "users", {:name=>"fk_bea040f377", :on_delete=>:cascade})
-> 0.0038s
-- add_foreign_key("imports", "accounts", {:name=>"fk_6db1b6e408", :on_delete=>:cascade})
-> 0.0034s
-- add_foreign_key("invites", "users", {:on_delete=>:cascade})
-> 0.0023s
-- add_foreign_key("list_accounts", "accounts", {:on_delete=>:cascade})
-> 0.0029s
-- add_foreign_key("list_accounts", "follows", {:on_delete=>:cascade})
-> 0.0029s
-- add_foreign_key("list_accounts", "lists", {:on_delete=>:cascade})
-> 0.0033s
-- add_foreign_key("lists", "accounts", {:on_delete=>:cascade})
-> 0.0032s
-- add_foreign_key("media_attachments", "accounts", {:name=>"fk_96dd81e81b", :on_delete=>:nullify})
-> 0.0026s
-- add_foreign_key("media_attachments", "scheduled_statuses", {:on_delete=>:nullify})
-> 0.0032s
-- add_foreign_key("media_attachments", "statuses", {:on_delete=>:nullify})
-> 0.0037s
-- add_foreign_key("mentions", "accounts", {:name=>"fk_970d43f9d1", :on_delete=>:cascade})
-> 0.0024s
-- add_foreign_key("mentions", "statuses", {:on_delete=>:cascade})
-> 0.0033s
-- add_foreign_key("mutes", "accounts", {:column=>"target_account_id", :name=>"fk_eecff219ea", :on_delete=>:cascade})
-> 0.0032s
-- add_foreign_key("mutes", "accounts", {:name=>"fk_b8d8daf315", :on_delete=>:cascade})
-> 0.0032s
-- add_foreign_key("notifications", "accounts", {:column=>"from_account_id", :name=>"fk_fbd6b0bf9e", :on_delete=>:cascade})
-> 0.0032s
-- add_foreign_key("notifications", "accounts", {:name=>"fk_c141c8ee55", :on_delete=>:cascade})
-> 0.0039s
-- add_foreign_key("oauth_access_grants", "oauth_applications", {:column=>"application_id", :name=>"fk_34d54b0a33", :on_delete=>:cascade})
-> 0.0038s
-- add_foreign_key("oauth_access_grants", "users", {:column=>"resource_owner_id", :name=>"fk_63b044929b", :on_delete=>:cascade})
-> 0.0021s
-- add_foreign_key("oauth_access_tokens", "oauth_applications", {:column=>"application_id", :name=>"fk_f5fc4c1ee3", :on_delete=>:cascade})
-> 0.0032s
-- add_foreign_key("oauth_access_tokens", "users", {:column=>"resource_owner_id", :name=>"fk_e84df68546", :on_delete=>:cascade})
-> 0.0035s
-- add_foreign_key("oauth_applications", "users", {:column=>"owner_id", :name=>"fk_b0988c7c0a", :on_delete=>:cascade})
-> 0.0020s
-- add_foreign_key("poll_votes", "accounts", {:on_delete=>:cascade})
-> 0.0043s
-- add_foreign_key("poll_votes", "polls", {:on_delete=>:cascade})
-> 0.0028s
-- add_foreign_key("polls", "accounts", {:on_delete=>:cascade})
-> 0.0032s
-- add_foreign_key("polls", "statuses", {:on_delete=>:cascade})
-> 0.0027s
-- add_foreign_key("report_notes", "accounts", {:on_delete=>:cascade})
-> 0.0029s
-- add_foreign_key("report_notes", "reports", {:on_delete=>:cascade})
-> 0.0048s
-- add_foreign_key("reports", "accounts", {:column=>"action_taken_by_account_id", :name=>"fk_bca45b75fd", :on_delete=>:nullify})
-> 0.0035s
-- add_foreign_key("reports", "accounts", {:column=>"assigned_account_id", :on_delete=>:nullify})
-> 0.0030s
-- add_foreign_key("reports", "accounts", {:column=>"target_account_id", :name=>"fk_eb37af34f0", :on_delete=>:cascade})
-> 0.0034s
-- add_foreign_key("reports", "accounts", {:name=>"fk_4b81f7522c", :on_delete=>:cascade})
-> 0.0042s
-- add_foreign_key("scheduled_statuses", "accounts", {:on_delete=>:cascade})
-> 0.0040s
-- add_foreign_key("session_activations", "oauth_access_tokens", {:column=>"access_token_id", :name=>"fk_957e5bda89", :on_delete=>:cascade})
-> 0.0030s
-- add_foreign_key("session_activations", "users", {:name=>"fk_e5fda67334", :on_delete=>:cascade})
-> 0.0033s
-- add_foreign_key("status_pins", "accounts", {:name=>"fk_d4cb435b62", :on_delete=>:cascade})
-> 0.0036s
-- add_foreign_key("status_pins", "statuses", {:on_delete=>:cascade})
-> 0.0031s
-- add_foreign_key("status_stats", "statuses", {:on_delete=>:cascade})
-> 0.0032s
-- add_foreign_key("statuses", "accounts", {:column=>"in_reply_to_account_id", :name=>"fk_c7fa917661", :on_delete=>:nullify})
-> 0.0023s
-- add_foreign_key("statuses", "accounts", {:name=>"fk_9bda1543f7", :on_delete=>:cascade})
-> 0.0029s
-- add_foreign_key("statuses", "statuses", {:column=>"in_reply_to_id", :on_delete=>:nullify})
-> 0.0032s
-- add_foreign_key("statuses", "statuses", {:column=>"reblog_of_id", :on_delete=>:cascade})
-> 0.0035s
-- add_foreign_key("statuses_tags", "statuses", {:on_delete=>:cascade})
-> 0.0030s
-- add_foreign_key("statuses_tags", "tags", {:name=>"fk_3081861e21", :on_delete=>:cascade})
-> 0.0025s
-- add_foreign_key("stream_entries", "accounts", {:name=>"fk_5659b17554", :on_delete=>:cascade})
-> 0.0037s
-- add_foreign_key("subscriptions", "accounts", {:name=>"fk_9847d1cbb5", :on_delete=>:cascade})
-> 0.0039s
-- add_foreign_key("tombstones", "accounts", {:on_delete=>:cascade})
-> 0.0046s
-- add_foreign_key("user_invite_requests", "users", {:on_delete=>:cascade})
-> 0.0026s
-- add_foreign_key("users", "accounts", {:name=>"fk_50500f500d", :on_delete=>:cascade})
-> 0.0033s
-- add_foreign_key("users", "invites", {:on_delete=>:nullify})
-> 0.0042s
-- add_foreign_key("users", "oauth_applications", {:column=>"created_by_application_id", :on_delete=>:nullify})
-> 0.0025s
-- add_foreign_key("web_push_subscriptions", "oauth_access_tokens", {:column=>"access_token_id", :on_delete=>:cascade})
-> 0.0037s
-- add_foreign_key("web_push_subscriptions", "users", {:on_delete=>:cascade})
-> 0.0038s
-- add_foreign_key("web_settings", "users", {:name=>"fk_11910667b2", :on_delete=>:cascade})
-> 0.0042s
Done!
The final step is compiling CSS/JS assets.
This may take a while and consume a lot of RAM.
Compile the assets now? Yes
Running `RAILS_ENV=production rails assets:precompile` ...
yarn install v1.17.3
[1/6] Validating package.json...
[2/6] Resolving packages...
success Already up-to-date.
Done in 1.56s.
Done!
All done! You can now power on the Mastodon server 🐘
Do you want to create an admin user straight away? Yes
Username: admin
E-mail: 你的qq郵箱賬號,用來登陸
You can login with the password: 4e2cdb20b425e8dd1eea48b6886cb586
You can change your password once you login.
qq郵箱配置第三方smtp密碼
點擊生成授權碼
上述郵箱和密碼“4e2cdb20b425e8dd1eea48b6886cb586”是用來登陸的。
[root@warship live]# docker-compose up -d啓動容器
[root@warship live]# docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------
live_db_1 docker-entrypoint.sh postgres Up (healthy)
live_redis_1 docker-entrypoint.sh redis ... Up (healthy)
live_sidekiq_1 /tini -- bundle exec sidekiq Up
live_streaming_1 /tini -- node ./streaming Up (healthy) 127.0.0.1:4000->4000/tcp
live_web_1 /tini -- bash -c rm -f /ma ... Up (healthy) 127.0.0.1:3000->3000/tcp
直接訪問報錯
[root@warship nginx]# curl 127.0.0.1:4000
{"error":"Error: Missing access token"}
需要配置nginx yum -y install nginx 或者源碼,源碼安裝需要注意
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_v2_module --with-http_stub_status_module --with-http_sub_module
然後配置https
其它教程上都說用let’s encrypt生成https證書,但虛擬機沒有外網ip,無法申請,所以手動自簽名
[root@warship ~]# cd /tmp/ssl/
[root@warship ssl]# openssl genrsa -des3 -out ca.key 2048
密碼123456
[root@warship ssl]# openssl req -new -x509 -days 7305 -key ca.key -out ca.crt
[root@warship ssl]# openssl genrsa -des3 -out client.key 1024
[root@warship ssl]# openssl req -new -key client.key -out client.csr
[root@warship ssl]# openssl x509 -req -in client.csr -out client.pem -signkey client.key -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
[root@warship ssl]# ls
ca.crt ca.key ca.srl client.csr client.key client.pem
[root@warship ~]# cat /usr/local/nginx/conf/nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
include /usr/local/nginx/conf.d/*.conf;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
# server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate /tmp/ssl/client.pem;
# ssl_certificate_key /tmp/ssl/client.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# location / {
# root html;
# index index.html index.htm;
# }
# }
}
[root@warship ~]# cat /usr/local/nginx/conf.d/mymedia.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name mymedia.com;
root /root/live/public;
# Useful for Let's Encrypt
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 mymedia.com;
ssl_protocols TLSv1.2;
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_certificate /tmp/ssl/client.pem;
ssl_certificate_key /tmp/ssl/client.key;
keepalive_timeout 70;
sendfile on;
client_max_body_size 80m;
root /root/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";
try_files $uri @proxy;
}
location /sw.js {
add_header Cache-Control "public, max-age=0";
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://127.0.0.1:3000;
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;
}
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;
}
啓動nginx,
[root@warship ~]# /usr/local/nginx/sbin/nginx
Enter PEM pass phrase:輸入密碼123456
訪問https://ip
用戶名是qq郵箱,密碼是“4e2cdb20b425e8dd1eea48b6886cb586”
部分配置文件
[root@warship ~]# nginx -V
nginx version: nginx/1.17.3
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_v2_module --with-http_stub_status_module --with-http_sub_module
[root@warship ~]# cat live/.env.production
LOCAL_DOMAIN=mymedia.com
SINGLE_USER_MODE=false
SECRET_KEY_BASE=6a74668b033ec0357052ba5046805e80733dbe565b7d570774490ac978b6b8bd87aaa57471608bdeba955ac499b28c1edb4b291da45630f59086a0062667680d
OTP_SECRET=28431a3559ed5ea84b153c9abc7c12fe524b1cd9e37cf72f62934764eae73e6d1175796f6175fbdf456f6f1d08d02f3b12e0c10b40e89a525b2e62e6f1ef868e
VAPID_PRIVATE_KEY=aY9GGtmNGBrdqbXXz7OrMZP8CqIIx86D71YHC5DQ_tU=
VAPID_PUBLIC_KEY=BBJ6l-N7YAaUVN3ulcnABb-SRWzpuJfEBDb6AdU6gI1TuSUNuAeLAYyTULbnL0ilg0RwlcQPmGZf-nSZjsm0DjQ=
DB_HOST=db
DB_PORT=5432
DB_NAME=postgres
DB_USER=postgres
DB_PASS=
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=
SMTP_SERVER=smtp.qq.com
SMTP_PORT=587
[email protected]
SMTP_PASSWORD=
SMTP_AUTH_METHOD=plain
SMTP_OPENSSL_VERIFY_MODE=none
[email protected]
參考
https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Docker-Guide.md
https://www.cnblogs.com/chjbbs/p/5748369.html