Initial commit

This commit is contained in:
2026-07-26 12:29:43 +09:00
parent 5f290dc465
commit 50bfaeafdf
2253 changed files with 318636 additions and 196 deletions
+5
View File
@@ -0,0 +1,5 @@
# API Documentation
You can find interactive API documentation at any Iceshrimp instance. https://iceshrimp.social/api-doc
You can also find auto-generated documentation for iceshrimp-sdk [here](../packages/iceshrimp-sdk/markdown/iceshrimp-sdk.md).
+81
View File
@@ -0,0 +1,81 @@
# Installing Iceshrimp with Docker
This guide is based on `docker compose`/Docker Compose v2, but `docker-compose`/Docker Compose v1 should work as well. Docker 20.10+ is required for building your own images because of BuildKit usage, and Docker 20.10 users need to [enable BuildKit first](https://docs.docker.com/build/buildkit/#getting-started), or [upgrade to latest Docker](https://docs.docker.com/engine/install/#server).
## Preparations
### Getting needed files
If you want to use the prebuilt images:
```sh
GIT_LFS_SKIP_SMUDGE=1 git clone https://iceshrimp.dev/iceshrimp/iceshrimp.git --depth=1
```
If you want to build your own images (make sure to install `git-lfs` and to run `git lfs install` before running the command):
```sh
git clone https://iceshrimp.dev/iceshrimp/iceshrimp.git
```
### docker-compose.yml
First, run `cp docs/examples/docker-compose.yml docker-compose.yml`, and edit `docker-compose.yml` if you want to build the image yourself or choose a [different tag](https://iceshrimp.dev/iceshrimp/-/packages/container/iceshrimp/versions)
### .config
Run `cp .config/docker_example.env .config/docker.env`, and edit `.config/docker.env` and fill it with the database credentials you want.
Run `cp .config/example-docker.yml .config/default.yml`, and edit `.config/default.yml`
- Replace example database credentials with the ones you entered in `.config/docker.env`
- Change other configuration
If you are running Iceshrimp on a system with more than one CPU thread, you might want to set the `clusterLimit` config option to about half of your thread count, depending on your system configuration. Please note that each worker requires around 10 PostgreSQL connections, so be sure to set `max_connections` appropriately. To do this with docker-compose, add `args: ["-c", "max_connections=n"]` to the `db:` section of `docker-compose.yml`, with `n` being `(10 * no_workers) + 10`.
## Installation and first start
Choose a method, whether you chose to build the image yourself or not.
Note: Ctrl-C will shut down Iceshrimp gracefully.
### Pulling the image
```sh
docker compose pull
docker compose up
```
### Building the image
Depending on your machine specs, this can take well over 30 minutes
```sh
docker compose build
docker compose up
```
## Starting Iceshrimp automatically
Run `docker compose up -d` and Iceshrimp will start automatically on boot.
## Updating Iceshrimp
### Pulling the image
```sh
docker compose pull
docker compose down
docker compose up -d
```
### Building the image
```sh
## Run git stash commands only if you have uncommitted changes
git stash
git pull
git stash pop
docker compose build
docker compose down
docker compose up -d
```
## Post-install
See [post-install](post-install.md).
+48
View File
@@ -0,0 +1,48 @@
# 🐳 Running a Iceshrimp server with Docker
## Pre-built docker container
[iceshrimp/iceshrimp](iceshrimp.dev/iceshrimp/iceshrimp)
## `docker-compose`
There is a `docker-compose.yml` in the root of the project that you can use to build the container from source
- .config/docker.env (**db config settings**)
- .config/default.yml (**Iceshrimp server settings**)
## Configuring
Rename the files:
`cp .config/example.yml .config/default.yml`
`cp .config/example.env .config/docker.env`
then edit them according to your environment.
You can configure `docker.env` with anything you like, but you will have to pay attention to the `default.yml` file:
- `url` should be set to the URL you will be hosting the web interface for the server at.
- `host`, `db`, `user`, `pass` will have to be configured in the `PostgreSQL configuration` section - `host` is the name of the postgres container (eg: *iceshrimp_db_1*), and the others should match your `docker.env`.
- `host`will need to be configured in the *Redis configuration* section - it is the name of the redis container (eg: *iceshrimp_redis_1*)
- `auth` will need to be configured in the *Sonic* section - cannot be the default `SecretPassword`
Everything else can be left as-is.
## Running docker-compose
The [prebuilt container for iceshrimp](https://iceshrimp.dev/iceshrimp/-/packages/container/iceshrimp/latest) is fairly large, and may take a few minutes to download and extract using docker.
Copy `docker-compose.yml` and the `config/` to a directory, then run the **docker-compose** command:
`docker-compose up -d`.
NOTE: This will take some time to come fully online, even after download and extracting the container images, and it may emit some error messages before completing successfully. Specifically, the `db` container needs to initialize and so isn't available to the `web` container right away. Only once the `db` container comes online does the `web` container start building and initializing the Iceshrimp tables.
Once the server is up you can use a web browser to access the web interface at `http://serverip:3000` (where `serverip` is the IP of the server you are running the Iceshrimp server on).
## Docker for development
```sh
cd dev/
docker-compose build
docker-compose run --rm web pnpm run init
docker-compose up -d
```
@@ -0,0 +1,14 @@
[Unit]
Description=Iceshrimp PostgreSQL container
[Container]
Image=docker.io/postgres:15-alpine
ContainerName=iceshrimp_db
HostName=db
Network=iceshrimp.network
EnvironmentFile=%h/services/iceshrimp/.config/docker.env
Volume=%h/services/iceshrimp/db:/var/lib/postgresql/data:Z
[Service]
Restart=on-failure
TimeoutStartSec=900
[Install]
WantedBy=iceshrimp-web.service
@@ -0,0 +1,14 @@
[Unit]
Description=Iceshrimp Redis container
[Container]
Image=docker.io/redis:7.0-alpine
ContainerName=iceshrimp_redis
HostName=redis
Network=iceshrimp.network
Volume=%h/services/iceshrimp/redis:/data:Z
[Service]
Restart=on-failure
TimeoutStartSec=900
[Install]
WantedBy=iceshrimp-web.service
@@ -0,0 +1,16 @@
[Unit]
Description=Iceshrimp container
[Container]
Image=iceshrimp.dev/iceshrimp/iceshrimp:latest
ContainerName=iceshrimp_web
HostName=web
PublishPort=3000:3000
Network=iceshrimp.network
Environment=NODE_ENV=production
Volume=%h/services/iceshrimp/files:/iceshrimp/files:z
Volume=%h/services/iceshrimp/.config:/iceshrimp/.config:ro,z
[Service]
Restart=on-failure
TimeoutStartSec=900
[Install]
WantedBy=multi-user.target default.target
@@ -0,0 +1 @@
[Network]
@@ -0,0 +1,24 @@
#!/bin/bash
if [ -d $HOME/.config/containers/systemd ]; then
mkdir -pv $(grep -F "Volume=" $HOME/.config/containers/systemd/iceshrimp-*.container | sed "s|%h|$HOME|g" | cut -d= -f2 | cut -d: -f1);
db_env=$(grep -F "EnvironmentFile=" $HOME/.config/containers/systemd/iceshrimp-db.container | sed "s|%h|$HOME|g" | cut -d= -f2)
config_dir=$(grep -F ":/iceshrimp/.config" $HOME/.config/containers/systemd/iceshrimp-web.container | sed "s|%h|$HOME|g" | cut -d= -f2 | cut -d: -f1)
if [ ! -f $config_dir/docker_example.env ]; then
wget -O $db_env \
https://iceshrimp.dev/iceshrimp/iceshrimp/raw/branch/dev/.config/docker_example.env;
else
cp -v $config_dir/docker_example.env $db_env;
fi
if [ ! -f $config_dir/example-docker.yml ]; then
wget -O $config_dir/default.yml \
https://iceshrimp.dev/iceshrimp/iceshrimp/raw/branch/dev/.config/example-docker.yml;
else
cp $config_dir/example-docker.yml $config_dir/default.yml
fi
else
echo "No $HOME/.config/containers/systemd found"
exit 1
fi
+53
View File
@@ -0,0 +1,53 @@
version: "3"
services:
web:
image: iceshrimp.dev/iceshrimp/iceshrimp:dev
### If you want to build the image locally
# build: .
### If you want to build the image locally AND use Docker 20.10
# build:
# context: .
# args:
# DOCKER_BUILDKIT: 1
container_name: iceshrimp_web
restart: unless-stopped
depends_on:
- db
- redis
ports:
- "3000:3000"
networks:
- ishnet
# - web
environment:
NODE_ENV: production
volumes:
- ./files:/iceshrimp/files
- ./.config:/iceshrimp/.config:ro
redis:
restart: unless-stopped
image: docker.io/valkey/valkey:7-alpine
container_name: iceshrimp_redis
networks:
- ishnet
volumes:
- ./redis:/data
db:
restart: unless-stopped
image: docker.io/postgres:16-alpine
container_name: iceshrimp_db
networks:
- ishnet
env_file:
- .config/docker.env
volumes:
- ./db:/var/lib/postgresql/data
networks:
ishnet:
# web:
# external:
# name: web
+13
View File
@@ -0,0 +1,13 @@
# Replace example.com with your domain
<VirtualHost *:80>
ServerName example.com
# For WebSocket
ProxyPass "/streaming" "ws://127.0.0.1:3000/streaming/"
# Proxy to Node
ProxyPass "/" "http://127.0.0.1:3000/"
ProxyPassReverse "/" "http://127.0.0.1:3000/"
ProxyPreserveHost On
# For files proxy
AllowEncodedSlashes On
</VirtualHost>
+78
View File
@@ -0,0 +1,78 @@
# Replace example.com with your domain
# For WebSocket
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache1:16m max_size=1g inactive=720m use_temp_path=off;
server {
listen 80;
listen [::]:80;
server_name example.com;
# For SSL domain validation
root /var/www/html;
location /.well-known/acme-challenge/ { allow all; }
location /.well-known/pki-validation/ { allow all; }
location / { return 301 https://$server_name$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_session_timeout 1d;
ssl_session_cache shared:ssl_session_cache:10m;
ssl_session_tickets off;
# To use Let's Encrypt certificate
ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem;
# To use Debian/Ubuntu's self-signed certificate (For testing or before issuing a certificate)
#ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
#ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
# SSL protocol settings
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;
ssl_stapling on;
ssl_stapling_verify on;
# Change to your upload limit
client_max_body_size 80m;
# Gzip compression
gzip on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/activity+json application/atom+xml;
# Proxy to Node
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_redirect off;
# If it's behind another reverse proxy or CDN, remove the following.
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;
# For WebSocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Cache settings
proxy_cache cache1;
proxy_cache_lock on;
proxy_cache_use_stale updating;
add_header X-Cache $upstream_cache_status;
}
}
+15
View File
@@ -0,0 +1,15 @@
[Unit]
Description=Iceshrimp daemon
[Service]
Type=simple
User=iceshrimp
ExecStart=/usr/bin/yarn start
WorkingDirectory=/home/iceshrimp/iceshrimp
Environment="NODE_ENV=production"
TimeoutSec=60
SyslogIdentifier=iceshrimp
Restart=always
[Install]
WantedBy=multi-user.target
+41
View File
@@ -0,0 +1,41 @@
diff --git a/packages/backend/built/services/chart/core.js b/packages/backend/built/services/chart/core.js
index 000b2f7..33d4031 100644
--- a/packages/backend/built/services/chart/core.js
+++ b/packages/backend/built/services/chart/core.js
@@ -3,7 +3,6 @@
*
* Tests located in test/chart
*/ import { db } from "../../db/postgre.js";
-import { getChartInsertLock } from "../../misc/app-lock.js";
import { addTime, dateUTC, isTimeBefore, isTimeSame, subtractTime } from "../../prelude/time.js";
import * as nestedProperty from "nested-property";
import promiseLimit from "promise-limit";
@@ -224,6 +223,7 @@ export function getJsonSchema(schema) {
}
const date = Chart.dateToTimestamp(current);
const lockKey = group ? `${this.name}:${date}:${span}:${group}` : `${this.name}:${date}:${span}`;
+ const { getChartInsertLock } = await import("../../misc/app-lock.js");
const lock = await getChartInsertLock(lockKey);
try {
// ロック内でもう1回チェックする
diff --git a/packages/backend/built/db/postgre.js b/packages/backend/built/db/postgre.js
index 81d6238..a133c02 100644
--- a/packages/backend/built/db/postgre.js
+++ b/packages/backend/built/db/postgre.js
@@ -71,7 +71,6 @@ import { User } from "../models/entities/user.js";
import { Webhook } from "../models/entities/webhook.js";
import { entities as charts } from "../services/chart/entities.js";
import { dbLogger } from "./logger.js";
-import { redisClient } from "./redis.js";
// TODO?: should we avoid importing things from built directory?
import { nativeInitDatabase } from "native-utils/built/index.js";
const sqlLogger = dbLogger.createSubLogger("sql", "gray", false);
@@ -221,6 +220,8 @@ export async function initDb(force = false) {
}
export async function resetDb() {
const reset = async ()=>{
+ const { redisClient } = await import("./redis.js");
+
await redisClient.flushdb();
const tables = await db.query(`SELECT relname AS "table"
FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
+41
View File
@@ -0,0 +1,41 @@
diff --git a/packages/backend/migration/1661376843000-remove-mentioned-remote-users-column.js b/packages/backend/migration/1661376843000-remove-mentioned-remote-users-column.js
index 42d79b5b5..1fd5e0f10 100644
--- a/packages/backend/migration/1661376843000-remove-mentioned-remote-users-column.js
+++ b/packages/backend/migration/1661376843000-remove-mentioned-remote-users-column.js
@@ -7,6 +7,22 @@ export class removeMentionedRemoteUsersColumn1661376843000 {
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "note" ADD "mentionedRemoteUsers" TEXT NOT NULL DEFAULT '[]'::text`);
- await queryRunner.query(`UPDATE "note" SET "mentionedRemoteUsers" = (SELECT COALESCE(json_agg(row_to_json("data"))::text, '[]') FROM (SELECT "url", "uri", "username", "host" FROM "user" JOIN "user_profile" ON "user"."id" = "user_profile". "userId" WHERE "user"."host" IS NOT NULL AND "user"."id" = ANY("note"."mentions")) AS "data")`);
+ await queryRunner.query(`
+ CREATE TEMP TABLE IF NOT EXISTS "temp_mentions" AS
+ SELECT "id", "url", "uri", "username", "host"
+ FROM "user"
+ JOIN "user_profile" ON "user"."id" = "user_profile"."userId" WHERE "user"."host" IS NOT NULL
+ `);
+
+ await queryRunner.query(`
+ CREATE UNIQUE INDEX "temp_mentions_id" ON "temp_mentions"("id")
+ `);
+
+ await queryRunner.query(`
+ UPDATE "note" SET "mentionedRemoteUsers" = (
+ SELECT COALESCE(json_agg(row_to_json("data")::jsonb - 'id')::text, '[]') FROM "temp_mentions" AS "data"
+ WHERE "data"."id" = ANY("note"."mentions")
+ )
+ `);
}
}
diff --git a/packages/backend/migration/1663399074403-resize-comments-drive-file.js b/packages/backend/migration/1663399074403-resize-comments-drive-file.js
index a037f1655..0873aec9b 100644
--- a/packages/backend/migration/1663399074403-resize-comments-drive-file.js
+++ b/packages/backend/migration/1663399074403-resize-comments-drive-file.js
@@ -9,6 +9,6 @@ export class resizeCommentsDriveFile1663399074403 {
}
async down(queryRunner) {
- await queryRunner.query(`ALTER TABLE "drive_file" ALTER COLUMN "comment" TYPE character varying(512)`);
- }
+ console.log('This migration cannot be reverted, skipping...');
+ }
}
+175
View File
@@ -0,0 +1,175 @@
# Installing Iceshrimp
This document will guide you through manual installation of Iceshrimp. We also provide prebuilt [packages](/iceshrimp/packaging) for various platforms, should you prefer those over a manual install.
## Dependencies
### Build
- C/C++ compiler like **GCC** or **Clang**
- Build tools like **make**
- **Python 3**
### Required
- [**Node.js**](https://nodejs.org) v18.16.0+ (v20 recommended)
- [**PostgreSQL**](https://www.postgresql.org/) 12+ (including modules, usually packaged as postgresql-contrib)
- [**Valkey**](https://valkey.io/) (or any other Redis 6 compatible fork)
- [**libvips**](https://www.libvips.org/)
- **Web proxy**
- nginx
- Caddy
### Optional
- [**FFmpeg**](https://ffmpeg.org/) for video transcoding
## Preparations
### Download repository
Make sure you have `git-lfs` installed and have run `git lfs install` before cloning the repo, as we are using Git LFS for efficient storage of binary blobs.
```sh
git clone https://iceshrimp.dev/iceshrimp/iceshrimp.git
```
If you don't want to run the latest development version, pick a version from [here](https://iceshrimp.dev/iceshrimp/iceshrimp/releases) and run `git checkout <version>` before continuing.
### Creating a new user
In case you want to run Iceshrimp as a different user, run `adduser --disabled-password --disabled-login iceshrimp`
Following steps will require you to run them as the user you have made, so use `su - iceshrimp`, or `sudo -iu iceshrimp`, or whatever else method in order to temporarily log in as that user.
### Configuration
- Copy `.config/example.yml` to `.config/default.yml`
- Edit `.config/default.yml` with text editor
- Make sure to set PostgreSQL and Redis section correctly
## Installing project dependencies
This project uses corepack to manage yarn versions, please make sure you don't have a globally installed non-corepack yarn binary (e.g. by having run `npm install -g yarn` in the past, or via your operating system's package manager)
```sh
corepack enable
corepack prepare --activate
yarn
```
Note: If you get a lot of `The remote archive doesn't match the expected checksum` errors, please make sure you installed `git-lfs` and ran `git lfs install && git lfs pull`.
## Building Iceshrimp
```sh
yarn build
```
## Database
### Creating database
This will create a postgres user with your password and database, while also granting that user all privileges on database.
Using `psql` prompt:
```sh
sudo -u postgres psql
```
```postgresql
create database iceshrimp with encoding = 'UTF8';
create user iceshrimp with encrypted password '{YOUR_PASSWORD}';
grant all privileges on database iceshrimp to iceshrimp;
alter database iceshrimp owner to iceshrimp;
\q
```
### First migration
In order for Iceshrimp to work properly, you need to initialise the database using
```bash
yarn run init
```
### Optimizing performance
If you are running Iceshrimp on a system with more than one CPU thread, you might want to set the `clusterLimit` config option to about half of your thread count, depending on your system configuration. Please note that each worker requires around 10 PostgreSQL connections, so be sure to set `max_connections` appropriately (aim for `(10 * no_workers) + 10`, if you have no other applications accessing the PostgreSQL database).
For optimal database performance, it's highly recommended to configure PostgreSQL with [PGTune](https://pgtune.leopard.in.ua/) using the "Mixed type of application" profile. This is especially important should your database server use HDD instead of SATA or NVMe SSD storage.
## Setting up Webproxy
### Nginx
- Run `sudo cp docs/examples/iceshrimp.nginx.conf /etc/nginx/sites-available/ && cd /etc/nginx/sites-available/`
- Edit `iceshrimp.nginx.conf` to reflect your server properly
- Run `sudo ln -s ./iceshrimp.nginx.conf ../sites-enabled/iceshrimp.nginx.conf`
- Run `sudo nginx -t` to check that the config is valid, then restart the nginx service.
### Caddy
- Add the following to your Caddyfile, and replace `example.com` with your domain
```
example.com {
reverse_proxy localhost:3000
}
```
## Running Iceshrimp
### Running manually
- Start Iceshrimp by running `NODE_ENV=production yarn run start`.
If this is your first run, after Iceshrimp has started successfully, you'll be able to go to the URL you have specified in `.config/default.yml` and create first user.
- To stop the server, use `Ctrl-C`.
### Running using systemd
- Run `sudo cp docs/examples/iceshrimp.service /etc/systemd/system/`
- Edit `/etc/systemd/system/iceshrimp.service` with text editor, and change `User`, `WorkingDir`, `ExecStart` if necessary.
- Run `sudo systemctl daemon-reload`
- Run `sudo systemctl enable --now iceshrimp` in order to enable and start Iceshrimp.
- (Optional) Check if instance is running using `sudo systemctl status iceshrimp`
### Environment variables
- `ICESHRIMP_CONFIG` (default: `.config/default.yml`) to change where the the config file is located
- `ICESHRIMP_SECRETS` (default: unset) if you want to keep your secrets in a separate config file
- `ICESHRIMP_MEDIA_DIR` (default: `files`) to change where internally stored files are located
- `ICESHRIMP_CUSTOM_DIR` (default: `custom`) to change where custom assets and locales are located (caution: assets are copied at build time or when running `yarn gulp`, not during startup!)
Make sure you are specifying absolute paths when setting environment variables.
### Updating Iceshrimp
Before you start, if you cloned the iceshrimp repository before the Git LFS migration, please follow [these instructions](https://iceshrimp.dev/iceshrimp/iceshrimp/wiki/Git-LFS#fixing-up-a-preexisting-cloned-repo) to get your repository back in sync.
First, stop the Iceshrimp service and then run the following commands:
```sh
## Run git stash commands only if you have uncommitted changes
git stash
```
If you were previously running a tagged release and/or want to upgrade to one, run:
```sh
git fetch --tags
git checkout <new-version>
```
If you were previously running a development version, and want to continue doing so or switch to the latest commit, run:
```sh
git switch dev
git pull
```
Regardless of which of the above you picked, run:
```sh
git stash pop
yarn
yarn build && yarn migrate
```
Note: If you get a lot of `The remote archive doesn't match the expected checksum` errors, please make sure you installed `git-lfs` and ran `git lfs install && git lfs pull`.
Now restart the Iceshrimp service and everything should be up to date.
## Post-install
See [post-install](post-install.md).
+45
View File
@@ -0,0 +1,45 @@
# Running a iceshrimp server with Kubernetes and Helm
This is a [Helm](https://helm.sh/) chart directory in the root of the project
that you can use to deploy iceshrimp to a Kubernetes cluster
## Deployment
1. Copy the example helm values and make your changes:
```shell
cp .config/helm_values_example.yml .config/helm_values.yml
```
2. Update helm dependencies:
```shell
cd chart
helm dependency list $dir 2> /dev/null | tail +2 | head -n -1 | awk '{ print "helm repo add " $1 " " $3 }' | while read cmd; do $cmd; done;
cd ../
```
3. Create the iceshrimp helm release (also used to update existing deployment):
```shell
helm upgrade \
--install \
--namespace iceshrimp \
--create-namespace \
iceshrimp chart/ \
-f .config/helm_values.yml
```
4. Watch your iceshrimp server spin up:
```shell
kubectl -n iceshrimp get po -w
```
5. Initial the admin user and managed config:
```shell
export iceshrimp_USERNAME="my_desired_admin_handle" && \
export iceshrimp_PASSWORD="myDesiredInitialPassword" && \
export iceshrimp_HOST="iceshrimp.example.com" && \
export iceshrimp_TOKEN=$(curl -X POST https://$iceshrimp_HOST/api/admin/accounts/create -H "Content-Type: application/json" -d "{ \"username\":\"$iceshrimp_USERNAME\", \"password\":\"$iceshrimp_PASSWORD\" }" | jq -r '.token') && \
echo "Save this token: ${iceshrimp_TOKEN}" && \
curl -X POST -H "Authorization: Bearer $iceshrimp_TOKEN" https://$iceshrimp_HOST/api/admin/accounts/hosted
```
6. Enjoy!
+66
View File
@@ -0,0 +1,66 @@
# 🚚 Migrating from Firefish to Iceshrimp
> **Warning**
> Before proceeding, please **ensure you have an *up-to-date* backup of the database.**
## Preparations
First, follow Firefish's [downgrade guide](https://codeberg.org/firefish/firefish/src/branch/develop/docs/downgrade.md) to get back to v1.0.5-rc. When prompted to switch the docker image/git tag, make sure to pick `v1.0.5-rc`, and not `v20240206`. This is to make sure that the migration patch applies correctly.
### Docker
First, stop the container by running `docker compose down`.
Now, run `docker-compose run --rm --entrypoint '/bin/bash' web` to get a shell in the main container.
### Bare metal
First, stop the service. If using systemd, run `sudo systemctl stop firefish.service`.
Now, `cd` into the root of your firefish repository.
## Applying the migrations patch
To make sure migrations revert correctly, run `curl -s https://iceshrimp.dev/iceshrimp/iceshrimp/raw/branch/dev/docs/firefish-redis.patch | git apply --ignore-whitespace`. This will patch two built JS files related to redis. The patch is ephemeral, once you complete the migration process it will no longer apply. Iceshrimp-JS has the patch built in.
## Reverting the migrations
To begin, run `cd packages/backend` to switch to the backend workspace.
Now, revert all of the typeorm migrations. reverted. To do this, run the command `pnpm run revertmigration:typeorm` until the output confirms that the migration `FirefishRepo1689957674000` has been reverted successfully.
If migration `IncreaseHostCharLimit1692374635734` failed to revert, please run `DELETE FROM "migrations" WHERE "name" = 'IncreaseHostCharLimit1692374635734';` in the database shell.
If you get any other errors here please ask for support in the [chat room](https://chat.iceshrimp.dev).
Finally, revert all the cargo migrations, by running `pnpm run revertmigration:cargo` until `m20230806_170616_fix_antenna_stream_ids` has been reverted. Again, if you get any errors, please ask for support in the [chat room](https://chat.iceshrimp.dev).
## Switching to Iceshrimp
### Docker
First, run `docker compose down` to shut down firefish.
Now, switch out image for the `web` container with `iceshrimp.dev/iceshrimp/iceshrimp:latest`.
Furthermore, for every volume/mount that's mapped to /firefish, switch it out for /iceshrimp (leaving any trailing text intact).
Finally, run `docker compose up`, and make sure that it starts up correctly. If everything works, press CTRL+C and run `docker compoe up -d` to start it in the background.
If you get any errors on startup, please ask for support in the [chat room](https://chat.iceshrimp.dev).
### Bare metal
Before you begin, make sure `git-lfs` is installed on the system, and that the firefish service is stopped.
Then, switch back to the repository root directory and run `git remote set-url origin https://iceshrimp.dev/iceshrimp/iceshrimp.git`, as well as `git lfs install`.
Now, run `git fetch --all` to fetch the new commits.
If you get an error like `couldn't find remote ref` here, run `git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"`, followed by `git remote prune origin` and `git fetch --all`. If you still get any errors, please ask for support in the [chat room](https://chat.iceshrimp.dev).
Then, run `git checkout dev` to switch to the `dev` branch, or `git checkout <tag>` to switch to a versioned tag. Make sure to run `git lfs pull` as well, to get all the dependencies.
Now, run `yarn && yarn build && yarn migrate` to install dependencies, build the project & run all pending migrations.
Finally, to clean up now-unnecessary files, run `rm -rf packages/backend/native-utils packages/megalodon`.
You should now be able to start the service back up.
If you get any errors during this process, please ask for support in the [chat room](https://chat.iceshrimp.dev).
## Closing notes
Please check out the [example configuration file](https://iceshrimp.dev/iceshrimp/iceshrimp/src/branch/dev/.config/example.yml), as it's changed quite a bit since Firefish and you may want to make use of the new features.
If you need further assistance for any reason, please ask for help in the [chat room](https://chat.iceshrimp.dev), we will assist you with the migration.
+45
View File
@@ -0,0 +1,45 @@
diff --git a/packages/backend/migration/1672704017999-remove-lastCommunicatedAt.js b/packages/backend/migration/1672704017999-remove-lastCommunicatedAt.js
index 38a676985..c4ae690e0 100644
--- a/packages/backend/migration/1672704017999-remove-lastCommunicatedAt.js
+++ b/packages/backend/migration/1672704017999-remove-lastCommunicatedAt.js
@@ -6,6 +6,8 @@ export class removeLastCommunicatedAt1672704017999 {
}
async down(queryRunner) {
- await queryRunner.query(`ALTER TABLE "instance" ADD "lastCommunicatedAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
+ await queryRunner.query(`ALTER TABLE "instance" ADD "lastCommunicatedAt" TIMESTAMP WITH TIME ZONE`);
+ await queryRunner.query(`UPDATE "instance" SET "lastCommunicatedAt" = COALESCE("infoUpdatedAt", "caughtAt")`);
+ await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "lastCommunicatedAt" SET NOT NULL`);
}
}
diff --git a/packages/backend/migration/1673336077243-PollChoiceLength.js b/packages/backend/migration/1673336077243-PollChoiceLength.js
index 810c626e0..5809528cb 100644
--- a/packages/backend/migration/1673336077243-PollChoiceLength.js
+++ b/packages/backend/migration/1673336077243-PollChoiceLength.js
@@ -6,6 +6,6 @@ export class PollChoiceLength1673336077243 {
}
async down(queryRunner) {
- await queryRunner.query(`ALTER TABLE "poll" ALTER COLUMN "choices" TYPE character varying(128) array`);
+ //await queryRunner.query(`ALTER TABLE "poll" ALTER COLUMN "choices" TYPE character varying(128) array`);
}
}
diff --git a/packages/backend/migration/1674118260469-achievement.js b/packages/backend/migration/1674118260469-achievement.js
index 131ab96f8..57a922f83 100644
--- a/packages/backend/migration/1674118260469-achievement.js
+++ b/packages/backend/migration/1674118260469-achievement.js
@@ -18,12 +18,13 @@ export class achievement1674118260469 {
async down(queryRunner) {
await queryRunner.query(`CREATE TYPE "public"."user_profile_mutingnotificationtypes_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app', 'pollEnded')`);
+ await queryRunner.query(`CREATE TYPE "public"."notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" DROP DEFAULT`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" TYPE "public"."user_profile_mutingnotificationtypes_enum_old"[] USING "mutingNotificationTypes"::"text"::"public"."user_profile_mutingnotificationtypes_enum_old"[]`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" SET DEFAULT '{}'`);
await queryRunner.query(`DROP TYPE "public"."user_profile_mutingnotificationtypes_enum"`);
await queryRunner.query(`ALTER TYPE "public"."user_profile_mutingnotificationtypes_enum_old" RENAME TO "user_profile_mutingnotificationtypes_enum"`);
- await queryRunner.query(`CREATE TYPE "public"."notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`);
+ await queryRunner.query(`DELETE FROM "public"."notification" WHERE "type" = 'achievementEarned'`);
await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "public"."notification_type_enum_old" USING "type"::"text"::"public"."notification_type_enum_old"`);
await queryRunner.query(`DROP TYPE "public"."notification_type_enum"`);
await queryRunner.query(`ALTER TYPE "public"."notification_type_enum_old" RENAME TO "notification_type_enum"`);
+127
View File
@@ -0,0 +1,127 @@
diff --git a/packages/backend/migration/1680491187535-cleanup.js b/packages/backend/migration/1680491187535-cleanup.js
index 1e609ca06..0e6accf3e 100644
--- a/packages/backend/migration/1680491187535-cleanup.js
+++ b/packages/backend/migration/1680491187535-cleanup.js
@@ -1,10 +1,40 @@
export class cleanup1680491187535 {
- name = 'cleanup1680491187535'
+ name = "cleanup1680491187535";
- async up(queryRunner) {
- await queryRunner.query(`DROP TABLE "antenna_note" `);
- }
+ async up(queryRunner) {
+ await queryRunner.query(`DROP TABLE "antenna_note" `);
+ }
- async down(queryRunner) {
- }
+ async down(queryRunner) {
+ await queryRunner.query(
+ `CREATE TABLE antenna_note ( id character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "antennaId" character varying(32) NOT NULL, read boolean DEFAULT false NOT NULL)`,
+ );
+ await queryRunner.query(
+ `COMMENT ON COLUMN antenna_note."noteId" IS 'The note ID.'`,
+ );
+ await queryRunner.query(
+ `COMMENT ON COLUMN antenna_note."antennaId" IS 'The antenna ID.'`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE ONLY antenna_note ADD CONSTRAINT "PK_fb28d94d0989a3872df19fd6ef8" PRIMARY KEY (id)`,
+ );
+ await queryRunner.query(
+ `CREATE INDEX "IDX_0d775946662d2575dfd2068a5f" ON antenna_note USING btree ("antennaId")`,
+ );
+ await queryRunner.query(
+ `CREATE UNIQUE INDEX "IDX_335a0bf3f904406f9ef3dd51c2" ON antenna_note USING btree ("noteId", "antennaId")`,
+ );
+ await queryRunner.query(
+ `CREATE INDEX "IDX_9937ea48d7ae97ffb4f3f063a4" ON antenna_note USING btree (read)`,
+ );
+ await queryRunner.query(
+ `CREATE INDEX "IDX_bd0397be22147e17210940e125" ON antenna_note USING btree ("noteId")`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE ONLY antenna_note ADD CONSTRAINT "FK_0d775946662d2575dfd2068a5f5" FOREIGN KEY ("antennaId") REFERENCES antenna(id) ON DELETE CASCADE`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE ONLY antenna_note ADD CONSTRAINT "FK_bd0397be22147e17210940e125b" FOREIGN KEY ("noteId") REFERENCES note(id) ON DELETE CASCADE`,
+ );
+ }
}
diff --git a/packages/backend/migration/1680582195041-cleanup.js b/packages/backend/migration/1680582195041-cleanup.js
index c587e456a..a91d6ff3c 100644
--- a/packages/backend/migration/1680582195041-cleanup.js
+++ b/packages/backend/migration/1680582195041-cleanup.js
@@ -1,11 +1,64 @@
export class cleanup1680582195041 {
- name = 'cleanup1680582195041'
+ name = "cleanup1680582195041";
- async up(queryRunner) {
- await queryRunner.query(`DROP TABLE "notification" `);
- }
+ async up(queryRunner) {
+ await queryRunner.query(`DROP TABLE "notification"`);
+ }
- async down(queryRunner) {
-
- }
+ async down(queryRunner) {
+ await queryRunner.query(
+ `CREATE TABLE notification ( id character varying(32) NOT NULL, "createdAt" timestamp with time zone NOT NULL, "notifieeId" character varying(32) NOT NULL, "notifierId" character varying(32), "isRead" boolean DEFAULT false NOT NULL, "noteId" character varying(32), reaction character varying(128), choice integer, "followRequestId" character varying(32), type notification_type_enum NOT NULL, "customBody" character varying(2048), "customHeader" character varying(256), "customIcon" character varying(1024), "appAccessTokenId" character varying(32), achievement character varying(128))`,
+ );
+ await queryRunner.query(
+ `COMMENT ON COLUMN notification."createdAt" IS 'The created date of the Notification.'`,
+ );
+ await queryRunner.query(
+ `COMMENT ON COLUMN notification."notifieeId" IS 'The ID of recipient user of the Notification.'`,
+ );
+ await queryRunner.query(
+ `COMMENT ON COLUMN notification."notifierId" IS 'The ID of sender user of the Notification.'`,
+ );
+ await queryRunner.query(
+ `COMMENT ON COLUMN notification."isRead" IS 'Whether the Notification is read.'`,
+ );
+ await queryRunner.query(
+ `COMMENT ON COLUMN notification.type IS 'The type of the Notification.'`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE ONLY notification ADD CONSTRAINT "PK_705b6c7cdf9b2c2ff7ac7872cb7" PRIMARY KEY (id)`,
+ );
+ await queryRunner.query(
+ `CREATE INDEX "IDX_080ab397c379af09b9d2169e5b" ON notification USING btree ("isRead")`,
+ );
+ await queryRunner.query(
+ `CREATE INDEX "IDX_33f33cc8ef29d805a97ff4628b" ON notification USING btree (type)`,
+ );
+ await queryRunner.query(
+ `CREATE INDEX "IDX_3b4e96eec8d36a8bbb9d02aa71" ON notification USING btree ("notifierId")`,
+ );
+ await queryRunner.query(
+ `CREATE INDEX "IDX_3c601b70a1066d2c8b517094cb" ON notification USING btree ("notifieeId")`,
+ );
+ await queryRunner.query(
+ `CREATE INDEX "IDX_b11a5e627c41d4dc3170f1d370" ON notification USING btree ("createdAt")`,
+ );
+ await queryRunner.query(
+ `CREATE INDEX "IDX_e22bf6bda77b6adc1fd9e75c8c" ON notification USING btree ("appAccessTokenId")`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE ONLY notification ADD CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710" FOREIGN KEY ("notifierId") REFERENCES "user"(id) ON DELETE CASCADE`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE ONLY notification ADD CONSTRAINT "FK_3c601b70a1066d2c8b517094cb9" FOREIGN KEY ("notifieeId") REFERENCES "user"(id) ON DELETE CASCADE`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE ONLY notification ADD CONSTRAINT "FK_769cb6b73a1efe22ddf733ac453" FOREIGN KEY ("noteId") REFERENCES note(id) ON DELETE CASCADE`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE ONLY notification ADD CONSTRAINT "FK_bd7fab507621e635b32cd31892c" FOREIGN KEY ("followRequestId") REFERENCES follow_request(id) ON DELETE CASCADE`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE ONLY notification ADD CONSTRAINT "FK_e22bf6bda77b6adc1fd9e75c8c9" FOREIGN KEY ("appAccessTokenId") REFERENCES access_token(id) ON DELETE CASCADE`,
+ );
+ }
}
+42
View File
@@ -0,0 +1,42 @@
# 🌎 Iceshrimp Developer Docs
## Nix Dev Environment
The Iceshrimp repo comes with a Nix-based shell environment to help make development as easy as possible!
Please note, however, that this environment will not work on Windows outside of a WSL2 environment.
### Prerequisites
- Installed the [Nix Package Manager](https://nixos.org/download.html) (use the comman on their website)
- Installed [direnv](https://direnv.net/docs/installation.html) and added its hook to your shell. (package manager)
- Ensured all dependencies are pulled with `git-lfs`, which also needs to be installed.
Once the repo is cloned to your computer, follow these next few steps inside the Iceshrimp folder:
- Run `direnv allow`. This will build the environment and install all needed tools.
- Run `install-deps`, then `prepare-config`, to install the node dependencies and prepare the needed config files.
- In a second terminal, run `devenv up`. This will spawn a **Redis** server, a **Postgres** server, and the **Iceshrimp** server in dev mode.
- Once you see the Iceshrimp banner printed in your second terminal, run `migrate` in the first.
- Once migrations finish, open http://localhost:3000 in your web browser.
- You should now see the admin user creation screen!
Note: When you want to restart a dev server, all you need to do is run `devenv up`, no other steps are necessary.
### Windows Subsystem for Linux
if `devenv up` terminates because of wrong folder permissions,
create the file `/etc/wsl.conf` in your distro and add
```shell
[automount]
options = "metadata"
```
this allows `chmod` calls to actually have an effect.
the build scripts DO actually set the permissions, it just needs to work in wsl.
### Problems with the environment
We don't anticipate any problems with the environment, as it is kept stable and does not require much maintainence.
Nevertheless, if you do encounter nix-specific problems and are unable to solve these problems yourself, please join the [Matrix support Channel](https://matrix.to/#/%23iceshrimp-dev:161.rocks)
and ping @Pyrox with the specific error message you encounter.
+92
View File
@@ -0,0 +1,92 @@
# Installing Iceshrimp using Podman and Quadlet
Quadlet is a feature of Podman that is kind of like Docker Compose, but is better integrated with systemd, just like whole Podman.
## Requirements
- Podman 4.4+ with aardvark
- Git with LFS installed (if building your own images)
## Preparations
### Getting needed files
If you want to use prebuilt images:
```sh
GIT_LFS_SKIP_SMUDGE=1 git clone https://iceshrimp.dev/iceshrimp/iceshrimp.git --depth=1
mkdir -p $HOME/.config/containers/systemd
cp "iceshrimp/docs/examples/Podman (quadlet)"/* $HOME/.config/containers/systemd
```
Tweak quadlet files and change the image tag in `$HOME/.config/containers/systemd/iceshrimp-web.container` from `latest` to `dev` or `pre` if desired, and run `docs/examples/Podman\ \(quadlet\)/volume-dir-creation.sh`.
If you want to build your own images:
```sh
git lfs install
git clone https://iceshrimp.dev/iceshrimp/iceshrimp.git
mkdir -p $HOME/.config/containers/systemd
cp "iceshrimp/docs/examples/Podman (quadlet)"/* $HOME/.config/containers/systemd
```
Tweak quadlet files if needed, change content of `Image:` line in `$HOME/.config/containers/systemd/iceshrimp-web.container` to `Image: localhost/iceshrimp/iceshrimp:latest`, and run `docs/examples/Podman\ \(quadlet\)/volume-dir-creation.sh`.
### .config
Edit `.config/docker.env` and fill it with the database credentials you want.
Edit `.config/default.yml` and:
- Replace example database credentials with the ones you entered in `.config/docker.env`
- Change other configuration
## Installation and first start
Choose a method, whether you chose to build the image yourself or not.
### Pulling the image
```sh
podman pull $(grep -F "Image=" $HOME/.config/containers/systemd/iceshrimp-web.container | cut -d= -f2)
systemctl --user daemon-reload
systemctl --user start iceshrimp-web.service
```
### Building the image
Enter Iceshrimp repo and run:
```sh
podman build . -t $(grep -F "Image=" $HOME/.config/containers/systemd/iceshrimp-web.container | cut -d= -f2) --ulimit nofile=16384:16384
systemctl --user daemon-reload
systemctl --user start iceshrimp-web.service
```
## Starting Iceshrimp automatically
Run `sudo loginctl enable-linger [user]` and Iceshrimp will start automatically on boot. You don't need to, and in fact [cannot enable Podman-generated systemd services](https://man.archlinux.org/man/extra/podman/podman-systemd.unit.5.en#Enabling_unit_files).
## Updating Iceshrimp
### Pulling the image
```sh
podman pull $(grep -F "Image=" $HOME/.config/containers/systemd/iceshrimp-web.container | cut -d= -f2)
systemctl --user restart iceshrimp-web.service
```
### Building the image
```sh
## Run git stash commands only if you have uncommitted changes
git stash
git pull
git stash pop
podman build . -t $(grep -F "Image=" $HOME/.config/containers/systemd/iceshrimp-web.container | cut -d= -f2) --ulimit nofile=16384:16384
systemctl --user restart iceshrimp-web.service
```
## Post-install
If you are running Iceshrimp on a system with more than one CPU thread, you might want to set the `clusterLimit` config option to about half of your thread count, depending on your system configuration. Please note that each worker requires around 10 PostgreSQL connections, so be sure to set `max_connections` appropriately. To do this, change `max_connections=n` line in `db/postgresql.conf`, with `n` being `(10 * no_workers) + 10`, and run `systemctl --user restart iceshrimp-db iceshrimp-web`.
See also [post-install](post-install.md).
+48
View File
@@ -0,0 +1,48 @@
# Post-install
This document describes things you can do after successfully installing Iceshrimp.
## Automatic translation
### DeepL
- Create a Free or Pro API account on [DeepL's website](https://www.deepl.com/pro#developer)
- Copy the API key to Control Panel > General > DeepL Translation
- Check the "Pro account" switch if you registered for paid account
### LibreTranslate
- Install [LibreTranslate](https://libretranslate.com/)
- Get an API URL and API key, copy and paste them into Control Panel > General > Libre Translate
## Object Storage (S3)
Recommended if using Docker
- Set up a bucket on provider's website (for example: AWS, Backblaze B2, Wasabi, minio or Google Cloud)
- Go to Control Panel > Object Storage and follow instructions
## Customising assets, locale
- To add custom CSS for all users, edit `custom/assets/instance.css`.
- To add static assets (such as images for the splash screen), place them in the `custom/assets/` directory. They'll then be available on https://example.com/static-assets/filename.ext.
- To add custom locales, place them in the `custom/locales/` directory. If you name your custom locale the same as an existing locale, it will overwrite it. If you give it a unique name, it will be added to the list. Also make sure that the first part of the filename matches the locale you're basing it on. (Example: en-FOO.yml)
- To add custom error images, place them in the `custom/assets/badges` directory, replacing the files already there.
- To add custom sounds, place only mp3 files in the `custom/assets/sounds` directory.
- To update custom assets without rebuilding, just run `yarn run gulp`.
## Another admin account
- Go to desired user's page, click 3 dots in upper right corner > About > Moderation, turn on "Moderator"
- Go back to Overview and copy their ID
- Run `psql -d iceshrimp`, replace `iceshrimp` with a name of your database if needed
- If instance is ran by a different system user: Prepend that command with `sudo -U iceshrimp`, replace `iceshrimp` with a name of that user if needed
- Docker Compose users: `docker compose exec db psql -d iceshrimp -U iceshrimp`, replace both `iceshrimp` with name of your db, and username owning that db respectively, if needed
- Run `UPDATE "user" SET "isAdmin" = true WHERE id='999999';`, where `999999` is the copied ID of that user
- Restart your Iceshrimp server
### Removing admin privileges
- Get ID of the user
- Run `psql` the same way when adding admin
- Run `UPDATE "user" SET "isAdmin" = false WHERE id='999999';`, where `999999` is the copied ID of that user
- Restart your Iceshrimp server
- Remove moderator privileges of the user
+23
View File
@@ -0,0 +1,23 @@
diff --git a/packages/backend/migration/1665091090561-add-renote-muting.js b/packages/backend/migration/1665091090561-add-renote-muting.js
index 2c76aaff5..f8541c818 100644
--- a/packages/backend/migration/1665091090561-add-renote-muting.js
+++ b/packages/backend/migration/1665091090561-add-renote-muting.js
@@ -4,18 +4,6 @@ export class addRenoteMuting1665091090561 {
}
async up(queryRunner) {
- await queryRunner.query(
- `CREATE TABLE "renote_muting" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "muteeId" character varying(32) NOT NULL, "muterId" character varying(32) NOT NULL, CONSTRAINT "PK_renoteMuting_id" PRIMARY KEY ("id"))`,
- );
- await queryRunner.query(
- `CREATE INDEX "IDX_renote_muting_createdAt" ON "muting" ("createdAt") `,
- );
- await queryRunner.query(
- `CREATE INDEX "IDX_renote_muting_muteeId" ON "muting" ("muteeId") `,
- );
- await queryRunner.query(
- `CREATE INDEX "IDX_renote_muting_muterId" ON "muting" ("muterId") `,
- );
}
async down(queryRunner) {}