Misskey Docker Rapid Deployment
Distributed social network, alternative to Mastodon, or maybe better

1. Background
Misskey is a distributed social network to post short messages. User's post is called Note. As other distributed social networks, Users can join or create servers. Server is managed by different administrators and in different places.
Although Misskey has official document, you are likely to deploy it with failure if you follow the exact steps. In this article, I will introduce the Misskey docker deployment.
GitHub repo: Misskey GitHub
2. Misskey Configuration
- Essentials
apt -y update
apt -y install curl nginx python3-certbot-nginx
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
- Clone repo
cd /your/path
git clone -b master https://github.com/misskey-dev/misskey.git
cd misskey
git checkout master
- Copy config files
cp .config/example.yml .config/default.yml
cp .config/docker_example.env .config/docker.env
- Edit default.yml
nano .config/default.yml
In short, you have to modify the followings:
url: https://misskey.example.com/ # Your domain
db:
host: db # The host of PostgreSQL should be consistent with the services name in docker-compose.yml
port: 5432
db: misskey # Your PostgreSQL DB name
user: example-misskey-user # Your PostgreSQL username
pass: example-misskey-pass # Your PostgreSQL password
redis:
host: redis # The host of Redis should be consistent with the services name in docker-compose.yml
port: 6379
- Edit docker.env
nano .config/docker.env
# db settings
POSTGRES_PASSWORD=example-misskey-pass # Your PostgreSQL username, matching the one in default.yml
POSTGRES_USER=example-misskey-user # Your PostgreSQL password, matching the one in default.yml
POSTGRES_DB=misskey # Your PostgreSQL DB name, matching the one in default.yml
- Edit docker-compose.yml
nano docker-compose.yml
version: "3.8"
services:
web:
image: misskey/misskey:latest
# build: .
restart: always
links:
- db # Match the value in default.yml
- redis # Match the value in default.yml
# - es
depends_on:
db: # Match the value in default.yml
condition: service_healthy
redis: # Match the value in default.yml
condition: service_healthy
ports:
- "127.0.0.1:3000:3000"
networks:
- internal_network
- external_network
volumes:
- ./files:/misskey/files
- ./.config:/misskey/.config:ro
redis: # Match the value in default.yml
restart: always
image: redis:7-alpine
networks:
- internal_network
volumes:
- ./redis:/data
healthcheck:
test: "redis-cli ping"
interval: 5s
retries: 20
db: # Match the value in default.yml
restart: always
image: postgres:15-alpine
networks:
- internal_network
env_file:
- .config/docker.env
volumes:
- ./db:/var/lib/postgresql/data
healthcheck:
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
interval: 5s
retries: 20
# es:
# restart: always
# image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.2
# environment:
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
# - "TAKE_FILE_OWNERSHIP=111"
# networks:
# - internal_network
# volumes:
# - ./elasticsearch:/usr/share/elasticsearch/data
networks:
internal_network:
internal: true
external_network:
- Bring up the container
docker compose up -d
- Set public folder permission (Important)
chown -R 991:991 files
3. Nginx Configuration
- Configure Nginx reverse proxy. Create a new Nginx configuration
nano /etc/nginx/sites-available/misskey
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name misskey.example.com;
client_max_body_size 0;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_redirect off;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
- Enable new Nginx configuration
ln -s /etc/nginx/sites-available/misskey /etc/nginx/sites-enabled/misskey
- Issue SSL cert
certbot --nginx
- Restart Nginx
nginx -t
systemctl restart nginx
Enjoy!
Copyright statement: Unless otherwise stated, all articles on this blog adopt the CC BY-NC-SA 4.0 license agreement. For non-commercial reprints and citations, please indicate the author: Henry, and original article URL. For commercial reprints, please contact the author for authorization.