diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07e6e47 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/node_modules diff --git a/Dockerfile b/Dockerfile index 1479184..59f4b26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,4 +35,8 @@ COPY . . EXPOSE 3630 # Run the application. +# Run the application. +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:3630/api/watchlist || exit 1 + CMD npm start diff --git a/compose.yaml b/compose.yaml index a4417e8..b472317 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,50 +1,16 @@ -# Comments are provided throughout this file to help you get started. -# If you need more help, visit the Docker Compose reference guide at -# https://docs.docker.com/go/compose-spec-reference/ - -# Here the instructions define your application as a service called "server". -# This service is built from the Dockerfile in the current directory. -# You can add other services your application may depend on here, such as a -# database or a cache. For examples, see the Awesome Compose repository: -# https://github.com/docker/awesome-compose services: what-to-watch: build: context: . environment: + # Pass environment variables to the container NODE_ENV: production + PORT: 3630 + DB_HOST: ${DB_HOST:-db} + DB_PORT: ${DB_PORT:-3306} + DB_USER: ${DB_USER:-whattowatch} + DB_PASSWORD: ${DB_PASSWORD:-whattowatch} + DB_NAME: ${DB_NAME:-whattowatch} + TMDB_API_KEY: ${TMDB_API_KEY} ports: - 3630:3630 - -# The commented out section below is an example of how to define a PostgreSQL -# database that your application can use. `depends_on` tells Docker Compose to -# start the database before your application. The `db-data` volume persists the -# database data between container restarts. The `db-password` secret is used -# to set the database password. You must create `db/password.txt` and add -# a password of your choosing to it before running `docker-compose up`. -# depends_on: -# db: -# condition: service_healthy -# db: -# image: postgres -# restart: always -# user: postgres -# secrets: -# - db-password -# volumes: -# - db-data:/var/lib/postgresql/data -# environment: -# - POSTGRES_DB=example -# - POSTGRES_PASSWORD_FILE=/run/secrets/db-password -# expose: -# - 5432 -# healthcheck: -# test: [ "CMD", "pg_isready" ] -# interval: 10s -# timeout: 5s -# retries: 5 -# volumes: -# db-data: -# secrets: -# db-password: -# file: db/password.txt diff --git a/package-lock.json b/package-lock.json index 782833e..4e02a3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "whattowatch", "version": "1.0.0", "dependencies": { - "axios": "^1.13.3", + "axios": "^1.13.5", "dotenv": "^16.3.1", "express": "^4.18.2", "mysql2": "^3.3.3" @@ -66,13 +66,13 @@ } }, "node_modules/axios": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.3.tgz", - "integrity": "sha512-ERT8kdX7DZjtUm7IitEyV7InTHAF42iJuMArIiDIV5YtPanJkgw4hw5Dyg9fh0mihdWNn1GKaeIWErfe56UQ1g==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, diff --git a/package.json b/package.json index 8df9916..1bb40aa 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,12 @@ "dev": "nodemon server.js" }, "dependencies": { + "axios": "^1.13.5", + "dotenv": "^16.3.1", "express": "^4.18.2", - "mysql2": "^3.3.3", - "dotenv": "^16.3.1" + "mysql2": "^3.3.3" }, "devDependencies": { "nodemon": "^2.0.22" } -} \ No newline at end of file +} diff --git a/test-endpoints.js b/test-endpoints.js new file mode 100644 index 0000000..019d980 --- /dev/null +++ b/test-endpoints.js @@ -0,0 +1,34 @@ +const axios = require('axios'); + +const BASE = 'http://localhost:3630/api/watchlist'; + +async function test() { + try { + console.log('1. Getting watchlist...'); + const res1 = await axios.get(BASE); + console.log(` Success. Items: ${res1.data.length}`); + + console.log('2. Adding "Inception"...'); + const res2 = await axios.post(BASE, { title: 'Inception', type: 'movie' }); + console.log(` Success. ID: ${res2.data.id}`); + const newId = res2.data.id; + + console.log('3. Toggling watched status...'); + const res3 = await axios.put(`${BASE}/${newId}/toggle`); + console.log(` Success. Watched: ${res3.data.watched}`); + + console.log('4. Deleting item...'); + const res4 = await axios.delete(`${BASE}/${newId}`); + console.log(` Success.`); + + console.log('All tests passed!'); + } catch (err) { + console.error('Test failed:', err.message); + if (err.response) { + console.error('Data:', err.response.data); + console.error('Status:', err.response.status); + } + } +} + +test();