<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Backend Server Archives - Nerd Corner</title>
	<atom:link href="https://nerd-corner.com/tag/backend-server-en/feed/" rel="self" type="application/rss+xml" />
	<link>https://nerd-corner.com/tag/backend-server-en/</link>
	<description>Craft your dreams!</description>
	<lastBuildDate>Sun, 16 Mar 2025 18:38:01 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.2</generator>

<image>
	<url>https://nerd-corner.com/wp-content/uploads/2019/10/cropped-LogoNerdCorner-2-32x32.png</url>
	<title>Backend Server Archives - Nerd Corner</title>
	<link>https://nerd-corner.com/tag/backend-server-en/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Create Docker images and upload them to Docker Hub</title>
		<link>https://nerd-corner.com/create-docker-images-and-upload-them-to-docker-hub/</link>
					<comments>https://nerd-corner.com/create-docker-images-and-upload-them-to-docker-hub/#respond</comments>
		
		<dc:creator><![CDATA[Nerds]]></dc:creator>
		<pubDate>Thu, 16 Jan 2025 18:16:16 +0000</pubDate>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[angular]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Backend Server]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Docker Hub]]></category>
		<category><![CDATA[Docker Images]]></category>
		<category><![CDATA[Docker Repository]]></category>
		<category><![CDATA[frontend]]></category>
		<category><![CDATA[google cloud mysql]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[Images]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[mySql]]></category>
		<category><![CDATA[Nest]]></category>
		<category><![CDATA[Nest.js]]></category>
		<category><![CDATA[Redis]]></category>
		<category><![CDATA[redis session management]]></category>
		<category><![CDATA[redis session management nest.js]]></category>
		<category><![CDATA[Repository]]></category>
		<category><![CDATA[Step by step guide]]></category>
		<guid isPermaLink="false">https://nerd-corner.com/de/?p=1691</guid>

					<description><![CDATA[<p>In this article, I will show you how to create production-ready Docker images for a web application with Angular, NestJS, MySQL and Redis and then &#8230; </p>
<p>The post <a href="https://nerd-corner.com/create-docker-images-and-upload-them-to-docker-hub/">Create Docker images and upload them to Docker Hub</a> appeared first on <a href="https://nerd-corner.com">Nerd Corner</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this article, I will show you how to create production-ready Docker images for a web application with Angular, NestJS, MySQL and Redis and then publish them on Docker Hub. The prerequisite is an installed Docker environment.</p>
<p><em><strong>You might also be interested in this: </strong><a href="https://nerd-corner.com/lessons-learned-hosting-nestjs-app-on-vercel/">Hosting NestJS on Vercel</a></em></p>
<h2>Creation of the Docker Compose Yml</h2>
<p>With Docker Compose, all components of an application can be defined via a single configuration file and built or started together.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">version: '3.8'

services:
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend

  backend:
    build: ./backend
    ports:
      - "3000:3000"
    depends_on:
      - mysql
      - redis
    environment:
      - DATABASE_URL=mysql://user:password@mysql:3306/db
      - SESSION_STORE=redis://redis:6379

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: db
    ports:
      - "3306:3306"

  redis:
    image: redis:latest
    ports:
      - "6379:6379"</pre>
<h2>Creating the env file</h2>
<p>To manage environment variables centrally, we create an .env file:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">DATABASE_URL=mysql://user:password@mysql:3306/db 
SESSION_STORE=redis://redis:6379</pre>
<p>Important: All ENV variables used in the code must also appear in docker-compose.yml!</p>
<h2>Docker image for the frontend</h2>
<p>The Angular frontend must be built for production. Here is an example Dockerfile:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">FROM node:20 AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build --prod

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf</pre>
<p>Since we are dependent on nginx for the build, we also need a corresponding config file:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">server {
  listen 80;
  server_name _;

  location / {
    root /usr/share/nginx/html;
    index index.html;
    try_files $uri $uri/ /index.html;
  }
}</pre>
<h2>Docker image for the backend</h2>
<p>The NestJS backend also needs to be built. Here is an optimized Dockerfile.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic"># Build stage
FROM node:20 AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build

# Production stage
FROM node:20-alpine
WORKDIR /app

COPY --from=build /app/dist ./dist
COPY package.json package-lock.json ./
RUN npm install --only=production
CMD ["node", "dist/main.js"]</pre>
<h2>Building the app with Docker Compose</h2>
<p>Once all the Dockerfiles have been configured, the images can now be built. The whole thing is really easy with Docker compose.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">docker compose up -d --build</pre>
<p>The images are then ready, the containers are built and the app can be tested locally! The last step is to upload the images to DockerHub so that they can be used more easily later for deployment on a server.</p>
<h2>Uploading to Docker Hub</h2>
<p>Uploading is explained step by step below:</p>
<ol>
<li>Create an account on <a href="https://www.docker.com/products/docker-hub/">Dockerhub</a></li>
<li>Create a repository for the frontend and backend (1 private repo is currently free)</li>
<li>Build the images and tag them:
<pre class="EnlighterJSRAW" data-enlighter-language="generic">docker tag &lt;image-id&gt; dockerAccountName/frontend:latest
docker tag &lt;image-id&gt; dockerAccountName/backend:latest</pre>
</li>
<li>Sign up and push the images:
<pre class="EnlighterJSRAW" data-enlighter-language="generic">docker login
docker push dockerAccountName/frontend:latest
docker push dockerAccountName/backend:latest</pre>
</li>
</ol>
<h2>Outlook: Deployment with Kubernetes</h2>
<p>Now that the images are on Docker Hub, nothing stands in the way of deployment. I have opted for a Kubernetes cluster on a Hetzner VPS. <a href="https://nerd-corner.com/deployment-of-a-webapp-with-kubernetes-and-caddy/">More information here</a>.</p>
<p>The post <a href="https://nerd-corner.com/create-docker-images-and-upload-them-to-docker-hub/">Create Docker images and upload them to Docker Hub</a> appeared first on <a href="https://nerd-corner.com">Nerd Corner</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nerd-corner.com/create-docker-images-and-upload-them-to-docker-hub/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Import Swagger in Node TypeScript Project</title>
		<link>https://nerd-corner.com/import-swagger-in-node-typescript-project/</link>
					<comments>https://nerd-corner.com/import-swagger-in-node-typescript-project/#comments</comments>
		
		<dc:creator><![CDATA[Nerds]]></dc:creator>
		<pubDate>Wed, 26 Oct 2022 17:10:41 +0000</pubDate>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[angular]]></category>
		<category><![CDATA[Api]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Backend Server]]></category>
		<category><![CDATA[Backend with Swagger]]></category>
		<category><![CDATA[CRUD]]></category>
		<category><![CDATA[Endpoints]]></category>
		<category><![CDATA[express.js]]></category>
		<category><![CDATA[Github]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Node]]></category>
		<category><![CDATA[Node with Swagger and Typescript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[Step by step guide]]></category>
		<category><![CDATA[Swagger]]></category>
		<category><![CDATA[swagger documentation]]></category>
		<category><![CDATA[Swagger express]]></category>
		<category><![CDATA[Swagger.json]]></category>
		<category><![CDATA[typescript]]></category>
		<guid isPermaLink="false">https://nerd-corner.com/de/?p=1287</guid>

					<description><![CDATA[<p>I recently coded a Node server with express.js in Typescript. This is a typical combination for backend development. It is especially beneficial if you already &#8230; </p>
<p>The post <a href="https://nerd-corner.com/import-swagger-in-node-typescript-project/">Import Swagger in Node TypeScript Project</a> appeared first on <a href="https://nerd-corner.com">Nerd Corner</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I recently coded a Node server with express.js in Typescript. This is a typical combination for backend development. It is especially beneficial if you already have experience with frontend development in Typescript. In general I strongly recommend to use Typescript instead of Javascript for frontend as well as backend development. Typescript uses Javascript but is type based and therefore not as error prone!</p>
<p>Also, the focus should always be on clean code and it should be properly documented. Especially when a project gets bigger, proper documented work pays off. For example, to document REST endpoints it is recommended to use Swagger. The Swagger API documentation provides an overview of all endpoints and even the possibility to interact with them.</p>
<p><strong><em>This might also be interesting for you: </em></strong><a href="https://nerd-corner.com/how-to-build-a-custom-angular-reactive-svg-form-with-clickable-elements/" target="_blank" rel="noopener"><em>Angular Form with clickable SVG</em></a></p>
<h2>List of components</h2>
<ul>
<li>IDE (for example VS Code)</li>
<li>Node.js</li>
</ul>
<h2>Documentation with swagger</h2>
<p>Although Swagger is quite well known, I could not find a detailed implementation guide. Therefore I would like to explain 2 ways to implement Swagger in an existing node server. The first way is to add Swagger parameters directly to each endpoint. This is probably the faster variant, but can get messy depending on the number of endpoints. The second option is to create a &#8220;swagger.json&#8221; file that summarizes the parameters of the endpoints.</p>
<p>To use Swagger the following library and its type extension will be needed:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">npm install --save  swagger-ui-express
npm install --save-dev @types/swagger-ui-express</pre>
<p>Swagger creates documentation of the endpoints:</p>
<p><img fetchpriority="high" decoding="async" class="zoooom aligncenter wp-image-1271" src="https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerDocu.jpg" alt="Example Swagger Docu" width="1647" height="853" srcset="https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerDocu.jpg 1847w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerDocu-300x155.jpg 300w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerDocu-1024x531.jpg 1024w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerDocu-768x398.jpg 768w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerDocu-1536x796.jpg 1536w" sizes="(max-width: 1647px) 100vw, 1647px" /></p>
<p>These can be opened and you can see an example request and an example response:</p>
<p><img decoding="async" class="aligncenter wp-image-1273 zoooom" style="font-size: 1.125rem;" src="https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint.jpg" alt="Example Swagger Endpoint 1" width="1657" height="840" srcset="https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint.jpg 1757w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint-300x152.jpg 300w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint-1024x519.jpg 1024w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint-768x389.jpg 768w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint-1536x779.jpg 1536w" sizes="(max-width: 1657px) 100vw, 1657px" /><img decoding="async" class="aligncenter wp-image-1272 zoooom" src="https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint2.png" alt="Example Swagger Endpoint 2" width="1657" height="803" srcset="https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint2.png 1757w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint2-300x145.png 300w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint2-1024x496.png 1024w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint2-768x372.png 768w, https://nerd-corner.com/wp-content/uploads/2022/10/exampleSwaggerEndpoint2-1536x744.png 1536w" sizes="(max-width: 1657px) 100vw, 1657px" /></p>
<p>The &#8220;Try it out&#8221; button can be used to interact directly with the endpoint.</p>
<h2>Swagger API documentation with params</h2>
<p>This variant is more recommended for smaller projects. First, these two Swagger libraries must be integrated into the project:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">npm install --save-dev @types/swagger-jsdoc 
npm install --save swagger-jsdoc</pre>
<p>The libraries are configured in app.ts or for non Typescript users app.js. Due to the configuration set here, the documentation is located in &#8220;/api-docs&#8221;:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="typescript" data-enlighter-title="app.ts">import express from "express";
import bodyParser from "body-parser";
import exampleRoutes from "./routes/example-route";
import swaggerJSDoc from "swagger-jsdoc";
import swaggerUi from "swagger-ui-express";

const app = express();

const options = {
  definition: {
    openapi: "3.0.1",
    info: {
      title: "REST API for Swagger Documentation",
      version: "1.0.0",
    },
    schemes: ["http", "https"],
    servers: [{ url: "http://localhost:3000/" }],
  },
  apis: [
    `${__dirname}/routes/example-route.ts`,
    "./dist/routes/example-route.js",
  ],
};

const swaggerSpec = swaggerJSDoc(options);

app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec));
app.use(bodyParser.json());
app.use(exampleRoutes);

app.listen(3000);</pre>
<p>The endpoint is described with the parameters as follows:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="typescript" data-enlighter-title="example-route.ts">import { Router } from "express";
import { exampleFunction } from "../controller/example";

const router = Router();

/**
 * @swagger
 * /example:
 *      post:
 *          summary: Send the text to the server
 *          tags:
 *              - ExampleEndpoints
 *          description: Send a message to the server and get a response added to the original text.
 *          requestBody:
 *              required: true
 *              content:
 *                  application/json:
 *                      schema:
 *                          type: object
 *                          properties:
 *                              responseText:
 *                                  type: string
 *                                  example: This is some example string! This is an endpoint
 *          responses:
 *              201:
 *                  description: Success
 *                  content:
 *                      application/json:
 *                          schema:
 *                              type: object
 *                              properties:
 *                                  text:
 *                                      type: string
 *                                      example: This is some example string!
 *              404:
 *                  description: Not found
 *              500:
 *                  description: Internal server error
 */
router.post("/example", exampleFunction);

export default router;
</pre>
<h2>Swagger API documentation with swagger.json</h2>
<p>To have a better overview and not to mix the documentation with the actual code, it is recommended to use one, or even more json files. When using TypeScript, the Swagger.json file must be placed in the rootDirectory:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-1276 zoooom" src="https://nerd-corner.com/wp-content/uploads/2022/10/foulderStructureOfSwaggerJson.jpg" alt="Foulder Structure with Swagger.json" width="170" height="344" srcset="https://nerd-corner.com/wp-content/uploads/2022/10/foulderStructureOfSwaggerJson.jpg 199w, https://nerd-corner.com/wp-content/uploads/2022/10/foulderStructureOfSwaggerJson-148x300.jpg 148w" sizes="auto, (max-width: 170px) 100vw, 170px" /></p>
<p>Again, the configuration is first defined in app.ts or, for non-Typescript users, in app.js. The domain path &#8220;/api-docs&#8221; is also selected here for the documentation:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="typescript" data-enlighter-title="app.ts">import express from "express";
import bodyParser from "body-parser";
import exampleRoutes from "./routes/example-route";
import swaggerUi from "swagger-ui-express";

import * as swaggerDocument from "./swagger.json";

const app = express();

app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument));

app.use(bodyParser.json());

app.use(exampleRoutes);

app.listen(3000);</pre>
<p>Important note: To import JSON files into a Typescript project this must be allowed in tsconfig.json. Also, the JSON file must be located in the root directory.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="json" data-enlighter-title="tsconfig.json">{
  "compilerOptions": {
    "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
    "module": "commonjs" /* Specify what module code is generated. */,
    "rootDir": "./src" /* Specify the root folder within your source files. */,
    "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
    "resolveJsonModule": true /* Enable importing .json files. */,
    "outDir": "./dist" /* Specify an output folder for all emitted files. */,
    "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
    "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
    "strict": true /* Enable all strict type-checking options. */,
    "skipLibCheck": true /* Skip type checking all .d.ts files. */
  }
}</pre>
<p>The previous Swagger documentation with parameters would thus look like this in swagger.json:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
  "openapi": "3.0.1",
  "info": {
    "title": "REST API for Swagger Documentation",
    "version": "1.0.0"
  },
  "schemes": ["http"],
  "servers": [{ "url": "http://localhost:3000/" }],
  "paths": {
    "/example": {
      "post": {
        "tags": ["ExampleEndpoints"],
        "summary": "Send a text to the server",
        "description": "Send a message to the server and get a response added to the original text.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExampleSchemaHeader"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExampleSchemaBody"
                }
              }
            }
          },
          "404": { "description": "Not found" },
          "500": { "description": "Internal server error" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ExampleSchemaBody": {
        "properties": {
          "responseText": {
            "type": "string",
            "example": "This is some example string! This is an endpoint"
          }
        }
      },
      "ExampleSchemaHeader": {
        "required": ["text"],
        "properties": {
          "text": {
            "type": "string",
            "example": "This is some example string!"
          }
        }
      }
    }
  }
}
</pre>
<h2>Download files</h2>
<ul>
<li><a href="https://github.com/hanneslim/Node-with-swagger-params" target="_blank" rel="noopener">Github example projcet for swagger params</a></li>
<li><a href="https://github.com/hanneslim/node-with-swagger-json" target="_blank" rel="noopener">Github example project for swagger.json</a></li>
</ul>
<p>The post <a href="https://nerd-corner.com/import-swagger-in-node-typescript-project/">Import Swagger in Node TypeScript Project</a> appeared first on <a href="https://nerd-corner.com">Nerd Corner</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nerd-corner.com/import-swagger-in-node-typescript-project/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
