1
0
Fork 0
mirror of https://github.com/docker/awesome-compose.git synced 2025-04-19 15:28:06 +02:00
This commit is contained in:
Max Proske 2024-06-11 15:10:44 +00:00 committed by GitHub
commit 65e12fd30b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 213 additions and 0 deletions

View file

@ -0,0 +1,36 @@
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.next
**/.cache
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
**/compose.y*ml
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
**/build
**/dist
LICENSE
README.md
*.js

View file

@ -0,0 +1 @@
REDIS_URL=

3
testcontainers/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.env
node_modules/
*.js

38
testcontainers/Dockerfile Normal file
View file

@ -0,0 +1,38 @@
# syntax=docker/dockerfile:1
# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/
# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7
ARG NODE_VERSION=20.13.1
FROM node:${NODE_VERSION}-alpine
# Use production node environment by default.
ENV NODE_ENV production
WORKDIR /usr/src/app
# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /root/.npm to speed up subsequent builds.
# Leverage a bind mounts to package.json and package-lock.json to avoid having to copy them into
# into this layer.
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci --omit=dev
# Run the application as a non-root user.
USER node
# Copy the rest of the source files into the image.
COPY . .
# Expose the port that the application listens on.
EXPOSE 3000
# Run the application.
CMD node index.js

19
testcontainers/README.md Normal file
View file

@ -0,0 +1,19 @@
# Docker Compose Testcontainers
## Why Testcontainers?
Testcontainers is a tool for creating lightweight, throwaway instances of common databases or anything that can run in a Docker container. In addition to testing, you can leverage the Testcontainers [Docker Compose Feature](https://node.testcontainers.org/features/compose/) to perform **local development** in scenarios where you cannot install the Docker engine or need **cloud workloads** to offload resource-intensive tasks.
This example demonstrates how to use Testcontainers for a Node.js environment. With Testcontainers Desktop, you can develop against [Testcontainers Cloud](https://testcontainers.com/cloud/) or the [Testcontainers embedded runtime](https://newsletter.testcontainers.com/announcements/adopt-testcontainers-desktop-as-your-container-runtime-early-access) to see Testcontainers capabilities.
## Prerequisites
- [Node.js](https://nodejs.org/en/download/)
- [Docker](https://docs.docker.com/get-docker/)
- [Testcontainers Desktop](https://testcontainers.com/desktop/)
## Running the app
The app checks if the `REDIS_URL` environment variable is set. If so, it connects to the specified Redis instance. If `REDIS_URL` is not set, it uses testcontainers to create a Redis instance using the Docker Compose file `redis.yaml`. Simply run `npm run dev` to start the app.
Additionally you can also start this example without Testcontainers by setting the `REDIS_URL` environment variable to a Redis instance. This is already prepared in the `compose.yaml` file, so you can just run `docker compose up` to try it out.

View file

@ -0,0 +1,15 @@
include:
- path: redis.yaml
services:
server:
build:
context: .
init: true
environment:
NODE_ENV: production
REDIS_URL: ${REDIS_URL}
ports:
- 3000:3000
depends_on:
- redis

22
testcontainers/index.ts Normal file
View file

@ -0,0 +1,22 @@
import express from "express"
import { setupRedis } from "./setupRedis.js"
const app = express()
app.use(express.json())
const client = await setupRedis()
app.get("/", async (req, res) => {
try {
const newVisitorCount = await client.incr("visitorCount")
res.send(`You are visitor number ${newVisitorCount}`)
} catch (error) {
console.error("Error accessing Redis:", error)
res.status(500).send("Server error")
}
})
const PORT = 3000
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`)
})

View file

@ -0,0 +1,24 @@
{
"name": "testcontainers-js-compose",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"dev": "nodemon --exec node --loader ts-node/esm index.ts"
},
"keywords": [],
"license": "ISC",
"description": "",
"dependencies": {
"express": "^4.19.2",
"redis": "^4.6.14"
},
"devDependencies": {
"@testcontainers/redis": "^10.9.0",
"@types/express": "^4.17.21",
"nodemon": "^3.1.3",
"testcontainers": "^10.9.0",
"ts-node": "^10.9.2",
"typescript": "^4.9.4"
}
}

11
testcontainers/redis.yaml Normal file
View file

@ -0,0 +1,11 @@
services:
redis:
container_name: redis
image: redis:latest
ports:
- "6379:6379"
volumes:
- redis-data:/data
volumes:
redis-data:

View file

@ -0,0 +1,34 @@
import redis, { type RedisClientType } from "redis"
type RedisClient = RedisClientType<any, any>
export async function setupRedis(): Promise<RedisClient> {
if (process.env.REDIS_URL) {
return connectToRedis(process.env.REDIS_URL)
}
const testcontainers = await import("testcontainers")
const environment = await new testcontainers.DockerComposeEnvironment(".", "redis.yaml")
.withWaitStrategy("redis", testcontainers.Wait.forLogMessage("Ready to accept connections"))
.withNoRecreate()
.up()
const redisPort = environment.getContainer("redis").getMappedPort(6379)
const redisConnectionString = `redis://localhost:${redisPort}`
const client = await connectToRedis(redisConnectionString)
process.on("SIGINT", async () => {
await client.quit()
process.exit()
})
return client
}
async function connectToRedis(url: string): Promise<RedisClient> {
const client = redis.createClient({ url }) as RedisClient
client.on("error", (err) => console.log("Redis Client Error", err))
await client.connect()
return client
}

View file

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"strict": true
}
}