画像をMiniOサーバにアップロードするアプリを作成してビルド後自鯖にデプロイしてみたところ、Server Actionsの1MB制限に引っかかってしまいアップロードできない事態に見舞われました。開発環境だと問題なく上げられたのでちょっと困りました。

Next.js13以下ではnext.config.tsに下記を追加することで回避できたようですが、Next.js15 App Routerでは使用できません。

next.config.ts
// Next.js13以前の設定
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  // これを追記
  experimental: {
    serverActions: {
      bodySizeLimit: '500mb',
    },
  },
};

export default nextConfig;

Next.js15ではスタンドアロンモード(最小限の構成でビルド)でデプロイすることでExpressのserver.js側でアップロード上限を設定できるようなのでやってみました。next.config.tsに下記を追記します。

next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  // スタンドアロンモードで出力
  output: "standalone",
};

export default nextConfig;

設定系は/myapp/.env.productionに書いています。

ディレクトリ構成が下記になっているので適宜変更してください。

/
├─ myapp/ (Next.jsアプリ)
│  ├─ app/
│  │  └─ page.tsx
│  ├─ .env.production
│  ├─ next.config.ts
│  ├─ package.json
│  ├─ package.lock.json
│  ├─ server.js
│  └─ tsconfig.json
└─ docker-compose.yml

自前でserver.jsを用意します

server.js
/* eslint-disable @typescript-eslint/no-require-imports */

// server.js
const express = require("express");
const next = require("next");
const path = require("path");

const port = parseInt(process.env.PORT || "3000", 10);
const dev = process.env.NODE_ENV !== "production";

const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = express();

  // 最大アップロードサイズを設定
  server.use(express.json({ limit: "500mb" }));
  server.use(express.urlencoded({ extended: true, limit: "500mb" }));
  
  server.use(
    "/_next/static",
    express.static(path.join(__dirname, ".next/static"))
  );

  server.all("*", (req, res) => {
    return handle(req, res);
  });

  server.listen(port, () => {
    console.log(`> Ready on http://localhost:${port}`);
  });
});
Dockerfile
# Dockerfile

FROM node:20-alpine AS base
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=base /app/node_modules ./node_modules
COPY . .
RUN npm run build

# 本番用
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production

COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /server.js ./server.js

# Next standalone実行に必要
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

EXPOSE 3000
CMD ["node", "server.js"]
docker-compose.yml
services:
  app:
    build:
      context: ./myapp
      dockerfile: Dockerfile
    container_name: myapp-app
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
    env_file:
      - ./myapp/.env.production
    depends_on:
      - db

volumes:
  postgres_data:

あとはNginx側でもclient_max_body_sizeを設定してあげます。

Nginx
server {
    listen 32222 ssl;
    ssl_certificate /home/owner/system/pem/server_cert.pem;
    ssl_certificate_key /home/owner/system/pem/server_key.pem;
    client_max_body_size 500m; # ここで上限設定
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Blueskyも登録してみました。

フィードが便利なのですが、フィードの作れるskyfeedは7日保存だったりたまに重くなるので自鯖に立ててみました。Bluesky公式のfeed-generatorとDockerを使用します。

参考サイト:

Github – ATProto Feed Generator

feed-generatorを使ってBlueskyのCustomFeedを作る

カスタムフィードを作ってみる?

feed-generatorはリアルタイムで全ての投稿が流れてくる中から自鯖のDBにデータを選んで保存し、そのDBからフィードを作成してフィードのjsonを返します。

AT protocolの思想にcraving indexerがBluesky鯖の外部に作成されて分散型でも鯖を跨いでデータを収集し検索や統計に使用されるという要素が有り、フィード作成はその思想の一端を担っている印象です。(現時点まだ鯖間の連合はできないですが…)

続きを読む

MisskeyやFirefishの個人鯖立ててみたいけどいきなりweb上でやるの怖い!そうだ!宅内鯖に入れて宅内だけで通信しよう!!

イメージ図(??)

サーバーを立てる所からの個人的メモです~

続きを読む

なんか…欲しくなっちゃってェ…

Misskey鯖かFirefish鯖を自分で立てたかったのですが、VPSのプランを大きくするとお金が掛かる&後からダウングレードが出来ず再契約なのとか、宅内だけで動かしてみたかったので宅内鯖用にベアボーンを買っちゃいました。

目標はdockerとかでMisskeyとか色々突っ込んでオレオレ証明書で宅内https通信したりして遊ぶことです。

最初はRaspberry Pie4+SDカードあたりでも良いかな…と思ったのですが、飽きたら後でリビング用のPCにも転用できるし…とIntelのNUC Kit NUC11ATKC4を購入しました。やっぱりSoCのベンチマークが全然違うので…。

あとは動かすのに必要な適当なメモリ8GBx2とM.2 SSD 500GB、19V/65W電源ケーブルを購入。

ちっちゃいね。

左側にM.2 SSD(Type2280)、右側にSODIMM DDR4(PC4-19200)2枚を取り付けたところ…

長尾製作所さんのSSD用ヒートシンクカバーSS-M2S-HS02(左)はばっちりケースと干渉してしまいました。2mm厚でも駄目でした…。別のPC作るときに使い回したいです。(;o;)オヨー

最小構成()で起動を確認後、F2キーでBIOSを起動してセキュアブートをオフ&USB First Bootを選んでUSBブートを有効に。

Memtest86+でメモリチェックを何度か回して特にエラーも出なかったため、Ubuntu Server 22.04LTSをインストールしました。

ここでちょっと問題が発生して、宅内LANをまだ引いていなかったためWi-Fiでアプデして設定しようとしたものの/etc/netplan/をいくら弄ってもip aコマンド結果が

 wlp0s2013: <NO-CARRIER, BROADCAST, MULTICAST, UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
 link/ether (WifiアダプタのMACアドレス) brd ff:ff:ff:ff:ff:ff

という表示が出て繋がらず…。仕方が無いのでベアボーンとWindowsマシンを有線LANで直接繋ぎ、ネットワーク共有をしてsudo apt updateを噛ませてようやく無線LANでも繋がるようになりました。宅内鯖なので最終的にはルータと有線で繋ぐのですけども…。早く宅内LAN通したいね…(業者に頼むと高いので自力で引くつもり/最近のおうちは最初からCD管通してて良いですね)

/etc/netplan/内の.yamlファイルを変更して固定IPに、ルータ側でもMACアドレスを静的ルーティングで固定します。

あとは仮想マシンでやったのと同じようにファイヤーウォールを入れたりSSHサーバーを立てて、Windows機からもリモート操作できるようにしました。パスワードを拒否して公開鍵認証のみにしたり…WinSCPも使えるようにしたり…。

SSHの暗号はed25519を使うことにしたのでメモ

ssh-keygen -t ed25519
cd /home/{User}/.ssh/
sudo cat id_ed25519.pub >> authorized_keys
sudo chmod 600 authorized_keys
sudo vi /etc/ssh/sshd_config

VimでPasswordAuthentication no, PubkeyAuthentication yesにして保存、秘密鍵をWinマシンの/.sshに保存して同様にconfig弄ってssh ubuntuとかでアクセスできるように

とりあえずサーバーとして動かせたので何か備忘録があればまたメモしていきます。わあい。