Skip to content

Commit

Permalink
docker
Browse files Browse the repository at this point in the history
  • Loading branch information
olzraiti committed Feb 28, 2025
1 parent 9a954e6 commit d8d0578
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
*.log
*.md
.git
47 changes: 47 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This Dockerfile is for running the app in production. It must be connected to
# Redis with docker-compose.yml.

# Use an Oracle Instant Client base image
FROM oraclelinux:8 AS oracle-client

# Install Oracle Instant Client via Oracle's YUM repository
RUN dnf install -y oracle-instantclient-release-el8 && \
dnf install -y oracle-instantclient-basic

# Use the official Node.js image as the base image
FROM node:18

# Set the working directory inside the container
WORKDIR /app

# Install dependencies for OracleDB
RUN apt-get update && apt-get install -y \
libaio1 && \
rm -rf /var/lib/apt/lists/*

# Copy Oracle Instant Client from the previous stage
COPY --from=oracle-client /usr/lib/oracle /usr/lib/oracle
COPY --from=oracle-client /usr/share/oracle /usr/share/oracle

# Set environment variables
ENV LD_LIBRARY_PATH=/usr/lib/oracle/21/client64/lib
ENV TNS_ADMIN=/usr/lib/oracle/21/client64/network/admin
ENV PATH="$PATH:/usr/lib/oracle/21/client64/bin"

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install the application dependencies
RUN npm ci

# Copy the rest of the application files
COPY . .

# Build the NestJS application
RUN npm run build

# Expose the application port
EXPOSE 3004

# Command to run the application
CMD ["node", "dist/main"]
47 changes: 47 additions & 0 deletions Dockerfile.npm-run
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This file is for running any npm commands in docker. It is connected to redis
# with docker-compose.npm-run.yml.

# Use an Oracle Instant Client base image
FROM oraclelinux:8 AS oracle-client

# Install Oracle Instant Client via Oracle's YUM repository
RUN dnf install -y oracle-instantclient-release-el8 && \
dnf install -y oracle-instantclient-basic

# Use the official Node.js image as the base image
FROM node:18

# Set the working directory inside the container
WORKDIR /app

# Install dependencies for OracleDB
RUN apt-get update && apt-get install -y \
libaio1 && \
rm -rf /var/lib/apt/lists/*

# Copy Oracle Instant Client from the previous stage
COPY --from=oracle-client /usr/lib/oracle /usr/lib/oracle
COPY --from=oracle-client /usr/share/oracle /usr/share/oracle

# Set environment variables
ENV LD_LIBRARY_PATH=/usr/lib/oracle/21/client64/lib
ENV TNS_ADMIN=/usr/lib/oracle/21/client64/network/admin
ENV PATH="$PATH:/usr/lib/oracle/21/client64/bin"

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install the application dependencies
RUN npm ci

# Copy the rest of the application files
COPY . .

# Build the NestJS application
RUN npm run build

# Expose the application port
EXPOSE 3004

# Command to run the application
ENTRYPOINT ["npm"]
57 changes: 48 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,64 @@ Check the [wiki](https://github.com/luomus/laji-api/wiki) for a more technically

[Nest](https://github.com/nestjs/nest)

### Installation
### Installation & running

Fill in `.env` file, using `.env.example` as a template.

The app can be ran inside a docker, or directly on the host machine.

#### Docker (recommended)

Use `docker` to build & start the app:

```bash
$ npm ci
npm run docker
```

Fill in `.env` file, using `.env.example` as as template.
*Hint:* The docker container runs any npm script, `start:dev` being the default. You can run other scripts like so:

```bash
npm run docker -- test:e2e-old
```

#### Without Docker

Install the dependencies:

```bash
$ npm ci
```

#### Other requirements
Install the following:

* [Redis](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/) >= 5
* [Oracle Instantclient](https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html#instzip)
* [Oracle Instant Client](https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html#instzip)

### Run

Start Redis, and then run:
##### Running

1. Start Redis
2. Make sure the Oracle Instant Client is installed at `/opt/oracle/instantclient` or adjust the next step accordingly:
3.
```bash
$ LD_LIBRARY_PATH=/opt/oracle/instantclient npm run start:dev
```

### Test

Hint: The npm command works also with the aforementioned Docker container. These examples run `npm` directly for simplicity.

#### Unit tests

Unit tests coverage so far only some core logic. They act also as documentation for how they are supposed to work.
Unit tests cover so far only some core logic. They act also as documentation for how they are supposed to work.

With Docker:

```bash
npm run docker -- test
```

Without Docker:

```bash
npm test
Expand All @@ -47,10 +79,17 @@ npm test

Currently we rely on the e2e tests from the old api. Fill in `integration-test/config.json` and then you can run the tests:

With Docker:

```bash
$ LD_LIBRARY_PATH=/opt/oracle/instantclient npm run test:e2e-old
$ npm run docker -- test:e2e-old
```

Without Docker:

```bash
$ LD_LIBRARY_PATH=/opt/oracle/instantclient npm run test:e2e-old
```

## Contact

Expand Down
34 changes: 34 additions & 0 deletions docker-compose.npm-run.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This file is for running any npm commands in docker.

version: "3.8"

services:
npm-run:
build:
context: .
dockerfile: Dockerfile.npm-run
ports:
- "3004:3004" # Default to 3004 if PORT is not set
#- "${PORT:-3004}:3004" # Default to 3004 if PORT is not set
environment:
- REDIS_URL=redis://redis:6379
volumes:
- .:/usr/src/app
networks:
- backend
depends_on:
- redis
entrypoint: ["npm", "run"] # Always run `npm run` by default
command: ["start:dev"] # Default argument (overridden if custom command given)

redis:
image: redis:latest
restart: always
ports:
- "6379:6379"
networks:
- backend

networks:
backend:
driver: bridge
27 changes: 27 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# This file is for running the app in production
version: "3.8"

services:
laji-api:
build: .
ports:
- "0.0.0.0:${PORT:-3004}:3004" # Default to 3004 if PORT is not set
#- "0.0.0.0:3004:3004" # Default to 3004 if PORT is not set
environment:
- REDIS_URL=redis://redis:6379
depends_on:
- redis
networks:
- backend

redis:
image: redis:latest
restart: always
ports:
- "6379:6379"
networks:
- backend

networks:
backend:
driver: bridge
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json",
"test:e2e-old": "mocha --timeout 6000 --require integration-test/setup.js ./integration-test/{form-permission,forms,collection,person,notifications,api-user,audio,image,warehouse,named-place,trait,document,annotation,area,information}/tests.js ./integration-test/document/validate-tests.js ./integration-test/document/batch-tests.js --exit",
"test:e2e-old:ci": "npm run test:e2e-old -- -R xunit --grep @no-ci --invert"
"test:e2e-old:ci": "npm run test:e2e-old -- -R xunit --grep @no-ci --invert",
"docker": "docker-compose -f docker-compose.npm-run.yml run npm-run"
},
"dependencies": {
"@luomus/laji-schema": "^2.0.101",
Expand Down
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export async function bootstrap() {
.setTitle("Laji API")
.setDescription(description)
.setVersion("0")
.addServer(configService.get("SWAGGER_SERVER") as string)
.addApiKey({ type: "apiKey", name: "access_token", in: "query" }, "access_token")
.build()
);
Expand Down
7 changes: 6 additions & 1 deletion src/redis-cache/redis-cache.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Injectable, Logger, OnApplicationShutdown, OnModuleInit } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { createClient } from "redis";

@Injectable()
Expand All @@ -7,8 +8,12 @@ export class RedisCacheService implements OnModuleInit, OnApplicationShutdown {
private client: ReturnType<typeof createClient>;
private logger = new Logger(RedisCacheService.name);

constructor(private config: ConfigService) {}

async onModuleInit() {
this.client = await createClient()
this.client = await createClient({
url: this.config.get("REDIS_URL"), // Defaults to localhost on port 6379.
})
.on("error", err => {
this.logger.error("Connecting to redis failed!");
throw new Error("Connecting to redis failed with message: " + err);
Expand Down

0 comments on commit d8d0578

Please sign in to comment.