+43
.containerignore
+43
.containerignore
···
1
+
# Containerignore for Podman (also works as .dockerignore for Docker compatibility)
2
+
3
+
# Dependencies
4
+
node_modules/
5
+
6
+
# Build outputs
7
+
dist/
8
+
coverage/
9
+
doc/
10
+
11
+
# Development files
12
+
*.log
13
+
.eslintcache
14
+
.tsbuildinfo
15
+
16
+
# Git
17
+
.git/
18
+
.gitignore
19
+
20
+
# IDE
21
+
.vscode/
22
+
.idea/
23
+
24
+
# Test files
25
+
**/*.spec.ts
26
+
**/*.spec.tsx
27
+
__mocks__/
28
+
29
+
# Documentation
30
+
*.md
31
+
typedoc.json
32
+
33
+
# Nix
34
+
flake.nix
35
+
flake.lock
36
+
result
37
+
38
+
# Local data
39
+
data/
40
+
41
+
# Environment files (compose will mount these)
42
+
.env
43
+
.env.*
+1
.dockerignore
+1
.dockerignore
···
1
+
.containerignore
+57
Containerfile
+57
Containerfile
···
1
+
# Build stage - install deps and build frontend
2
+
FROM node:22-slim AS builder
3
+
4
+
WORKDIR /app
5
+
6
+
# Install pnpm
7
+
RUN corepack enable && corepack prepare pnpm@latest --activate
8
+
9
+
# Copy package files first for better layer caching
10
+
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
11
+
12
+
# Install all dependencies (including dev for build)
13
+
RUN pnpm install --frozen-lockfile
14
+
15
+
# Copy source code
16
+
COPY tsconfig.json vite.config.js ./
17
+
COPY src ./src
18
+
19
+
# Build the frontend
20
+
RUN pnpm run build
21
+
22
+
# Production stage - minimal runtime image
23
+
FROM node:22-slim AS runtime
24
+
25
+
WORKDIR /app
26
+
27
+
# Install pnpm
28
+
RUN corepack enable && corepack prepare pnpm@latest --activate
29
+
30
+
# Copy package files
31
+
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
32
+
33
+
# Install production dependencies only
34
+
RUN pnpm install --frozen-lockfile --prod
35
+
36
+
# Copy built frontend from builder
37
+
COPY --from=builder /app/dist ./dist
38
+
39
+
# Copy server source (runs with tsx)
40
+
COPY tsconfig.json ./
41
+
COPY src/feedline ./src/feedline
42
+
COPY src/realm ./src/realm
43
+
COPY src/lib ./src/lib
44
+
45
+
# Create data directory for realm storage
46
+
RUN mkdir -p /data/realms
47
+
48
+
# Environment variables
49
+
ENV NODE_ENV=production
50
+
ENV PORT=4001
51
+
ENV HOST=0.0.0.0
52
+
ENV REALM_STORAGE_DIR=/data/realms
53
+
54
+
EXPOSE 4001
55
+
56
+
# Run the server
57
+
CMD ["pnpm", "exec", "tsx", "src/feedline/main.ts"]
+35
compose.yaml
+35
compose.yaml
···
1
+
# Usage: podman-compose up -d
2
+
# Or: podman compose up -d (with compose plugin)
3
+
4
+
services:
5
+
feedline:
6
+
build:
7
+
context: .
8
+
dockerfile: Containerfile
9
+
restart: unless-stopped
10
+
ports:
11
+
- '${PORT:-4001}:4001'
12
+
environment:
13
+
- NODE_ENV=production
14
+
- REALM_STORAGE_DIR=/data/realms
15
+
- PORT=4001
16
+
# Public hostname for the service (used for WebSocket URLs, etc.)
17
+
- FEEDLINE_HOST=${FEEDLINE_HOST:-localhost}
18
+
volumes:
19
+
# Persist realm data
20
+
- feedline-data:/data/realms
21
+
healthcheck:
22
+
test:
23
+
[
24
+
'CMD',
25
+
'node',
26
+
'-e',
27
+
"fetch('http://localhost:4001/').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))",
28
+
]
29
+
interval: 30s
30
+
timeout: 10s
31
+
retries: 3
32
+
start_period: 10s
33
+
34
+
volumes:
35
+
feedline-data: