Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: image resizing server and image table with migrations #53

Merged
merged 12 commits into from
Aug 16, 2023
Merged
18 changes: 18 additions & 0 deletions apps/image-server/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
37 changes: 37 additions & 0 deletions apps/image-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
FROM node:20.2-alpine3.18 as unteris-node


RUN npm i -g [email protected] && \
apk add --no-cache \
dumb-init=1.2.5-r2

FROM unteris-node AS unteris-common

WORKDIR /src
RUN apk add --no-cache \
python3 \
make \
gcc \
g++
COPY package.json \
tsconfig* \
nx.json \
pnpm-lock.yaml \
./
ENV CYPRESS_INSTALL_BINARY=0
RUN pnpm i

FROM unteris-common AS image-server-build
COPY apps/image-server ./apps/image-server/
COPY libs/server ./libs/server/
COPY libs/shared ./libs/shared/
RUN pnpm nx run image-server:build:production

FROM unteris-node AS image-server-prod
LABEL description="The image processing serve code for the Unteris website. It runs a NestJS server and connects to a redis and postgres database"
USER node
WORKDIR /src
COPY --from=image-server-build --chown=node:node /src/dist/apps/image-server ./
ENV NODE_ENV=production
RUN pnpm i
CMD ["dumb-init", "node", "main.js"]
72 changes: 72 additions & 0 deletions apps/image-server/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"name": "image-server",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/image-server/src",
"projectType": "application",
"targets": {
"build": {
"executor": "@nx/webpack:webpack",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"target": "node",
"compiler": "tsc",
"outputPath": "dist/apps/image-server",
"main": "apps/image-server/src/main.ts",
"tsConfig": "apps/image-server/tsconfig.app.json",
"assets": ["apps/image-server/src/assets"],
"isolatedConfig": true,
"webpackConfig": "apps/image-server/webpack.config.js"
},
"configurations": {
"production": {
"optimization": true,
"extractLicenses": true,
"inspect": false,
"generatePackageJson": true,
"buildLibsFromSrc": true,
"fileReplacements": [
{
"replace": "apps/image-server/src/environments/environment.ts",
"with": "apps/image-server/src/environments/environment.prod.ts"
}
]
}
}
},
"serve": {
"executor": "@nx/js:node",
"defaultConfiguration": "development",
"options": {
"inspect": false,
"buildTarget": "image-server:build"
},
"configurations": {
"development": {
"buildTarget": "image-server:build:development"
},
"production": {
"buildTarget": "image-server:build:production"
}
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/image-server/**/*.ts"]
}
},
"package": {
"executor": "@unteris/plugin/docker:build",
"outputs": ["{workspaceRoot}/docker/cache/server"],
"options": {},
"configurations": {
"ci": {
"publish": true
}
}
}
},
"tags": []
}
Empty file.
27 changes: 27 additions & 0 deletions apps/image-server/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { OgmaService } from '@ogma/nestjs-module';

import { ImageRootModule } from '@unteris/server/image-root';

async function bootstrap() {
const app = await NestFactory.createMicroservice(ImageRootModule, {
bufferLogs: true,
transport: Transport.RMQ,
options: {
urls: [
`amqp://${process.env.RABBIT_USER}:${process.env.RABBIT_PASSWORD}@${process.env.RABBIT_HOST}:${process.env.RABBIT_PORT}`,
],
queue: '',
queueOptions: {
durable: true,
},
},
});
app.useLogger(app.get(OgmaService));
await app.listen();
Logger.log(`🚀 Image Processing Server up and running!`);
}

bootstrap();
18 changes: 18 additions & 0 deletions apps/image-server/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["node"],
"emitDecoratorMetadata": true,
"target": "es2021",
"strictNullChecks": true,
"noImplicitAny": true,
"strictBindCallApply": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"esModuleInterop": true
},
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
"include": ["src/**/*.ts"]
}
13 changes: 13 additions & 0 deletions apps/image-server/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
}
],
"compilerOptions": {
"esModuleInterop": true
}
}
8 changes: 8 additions & 0 deletions apps/image-server/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const { composePlugins, withNx } = require('@nx/webpack');

// Nx plugins for webpack.
module.exports = composePlugins(withNx(), (config) => {
// Update the webpack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
return config;
});
2 changes: 1 addition & 1 deletion apps/kysely-cli/src/app/seed.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class SeedCommand extends CommandRunner {
}
await this.db
.insertInto('deity')
.values([{ ...data, category: category.id }])
.values([{ ...data, categoryId: category.id }])
.executeTakeFirstOrThrow();
}

Expand Down
10 changes: 10 additions & 0 deletions apps/server/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,18 @@
},
"serve": {
"executor": "@nx/js:node",
"defaultConfiguration": "development",
"options": {
"inspect": false,
"buildTarget": "server:build"
},
"configurations": {
"development": {
"buildTarget": "server:build:development"
},
"production": {
"buildTarget": "server:build:production"
}
}
},
"lint": {
Expand Down
22 changes: 22 additions & 0 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@ services:
- '3333:3333'
depends_on:
- postgres
- redis
- rabbit
labels:
- 'com.centurylinklabs.watchtower.enable=true'
image-server:
image: jmcdo29/unteris-image-server
logging:
driver: local
env_file: .env
environment:
DATABASE_HOST: postgres
volumes:
- './images:/src/images'
depends_on:
- postgres
- rabbit
labels:
- 'com.centurylinklabs.watchtower.enable=true'
migrations:
Expand Down Expand Up @@ -57,3 +73,9 @@ services:
volumes:
- './redis.conf:/usr/local/etc/redis/redis.conf'
command: redis-server /usr/local/etc/redis/redis.conf
rabbitmq:
image: rabbitmq
ports:
- '5672:5672'
volumes:
- './rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf'
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,10 @@ services:
image: redis
ports:
- '6379:6379'
rabbitmq:
image: rabbitmq
ports:
- '5672:5672'
environment:
RABBITMQ_DEFAULT_USER: rabbit
RABBITMQ_DEFAULT_PASS: rabbit
18 changes: 14 additions & 4 deletions libs/db/migrations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ erDiagram
User_Account ||--|{ User_Permission : "should have"
Verification_Token ||--|| User_Account : "relates to"
Role ||--|{ User_Permission : "relates_to"
User_Account ||--|| : "has an avatar"
Deity ||--|| Image : "has a portrait"
DeityCategory {
string name
ulid id
Expand All @@ -26,9 +28,9 @@ erDiagram
string name
ulid id
string description
string image_url
string category
string location
string image_id
string category_id
string location_id
}
Domain {
string name
Expand Down Expand Up @@ -67,7 +69,7 @@ erDiagram
string name
string email
boolean isVerified
string photo_url
string image_id
}
User_Permission {
ulid id
Expand Down Expand Up @@ -96,5 +98,13 @@ erDiagram
ulid user_id
string type
}
Image {
ulid id
string type
string original_url
string small_url
string medium_url
string large_url
}

```
18 changes: 14 additions & 4 deletions libs/db/migrations/diagram.mmd
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ erDiagram
User_Account ||--|{ User_Permission : "should have"
Verification_Token ||--|| User_Account : "relates to"
Role ||--|{ User_Permission : "relates_to"
User_Account ||--|| : "has an avatar"
Deity ||--|| Image : "has a portrait"
DeityCategory {
string name
ulid id
Expand All @@ -17,9 +19,9 @@ erDiagram
string name
ulid id
string description
string image_url
string category
string location
string image_id
string category_id
string location_id
}
Domain {
string name
Expand Down Expand Up @@ -58,7 +60,7 @@ erDiagram
string name
string email
boolean isVerified
string photo_url
string image_id
}
User_Permission {
ulid id
Expand Down Expand Up @@ -87,3 +89,11 @@ erDiagram
ulid user_id
string type
}
Image {
ulid id
string type
string original_url
string small_url
string medium_url
string large_url
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@ import {
Kysely,
sql,
} from 'kysely';
import { kyselyUlid } from './ulid.sql';

const convertToUlid = (
column: string
): [string, AlterColumnBuilderCallback] => [
column,
(col: AlterColumnBuilder) =>
col.setDataType(sql`ulid USING (${column}::ulid)`),
col.setDataType(sql`ulid USING (${sql.ref(column)}::ulid)`),
];

const setUlidDefault = (
column: string
): [string, AlterColumnBuilderCallback] => [
column,
(col: AlterColumnBuilder) => col.setDefault(sql`gen_ulid()`),
(col: AlterColumnBuilder) => col.setDefault(kyselyUlid()),
];

const migrateTableColumnToUlid = async (
Expand All @@ -28,6 +29,7 @@ const migrateTableColumnToUlid = async (
): Promise<void> => {
let command = db.schema
.alterTable(table)
.alterColumn(column, (col) => col.dropDefault())
.alterColumn(...convertToUlid(column));
if (setDefault) {
command = command.alterColumn(...setUlidDefault(column));
Expand Down
Loading
Loading