# Hybrid method 3: Custom Docker image

## Bundle the nodegen-server and Wasm modules into a new Docker image

Alternatively, you can bundle the  [`nodegen-server`](https://github.com/orgs/Coherent-Partners/packages/container/package/nodegen-server)  and Wasm modules into a new Docker image. This approach is useful if you want to create a custom Docker image with your own configuration.

1. Complete the instructions in [Hybrid method 2: Manual Wasm mount](/hybrid-runner/setup-the-hybrid-runner/hybrid-method-2-manual-wasm-mount.md#export-the-wasm-modules-from-spark).
2. Navigate to your desired working directory and move the exported ZIP to this location. In this example the name of the file is `runner_example.zip`.
3. Create a [Dockerfile](https://docs.docker.com/engine/reference/builder/) with the following content:

   ```docker
   FROM alpine:latest AS unzipper

   # Set extract model name
   ARG MODEL_PATH=./runner_example.zip

   # Add unzip package
   RUN apk add unzip
   RUN mkdir /models && mkdir /model_zip

   # Copy extracted model model zip to temp folder
   COPY $MODEL_PATH ./model_zip

   # Unzip the extracted zip file
   RUN find ./model_zip -depth -name "*.zip" -exec sh -c 'f="{}"; unzip -- "$f" -d ./models' \; && rm -rf ./model_zip;

   # Set nodegen-server image
   FROM ghcr.io/coherent-partners/nodegen-server:latest

   # Create models folder
   RUN mkdir /models

   # Copy unzipped models to previously created folder
   COPY --from=unzipper /models/ /models

   # Set MODEL_LOCATION variable to models folder
   ENV MODEL_LOCATION=/models

   # Set the hybrid runner mode
   ENV USE_SAAS=false

   # Default application will listen on port 3000; you can set different to port by set PORT variable
   ENV PORT=8080

   # Start the application by script npm start
   CMD ["npm", "start"]
   ```
4. [`build`](https://docs.docker.com/engine/reference/commandline/build/) the Docker image.

   ```sh
   docker build -t nodegen_server_custom .
   ```
5. [`run`](https://docs.docker.com/engine/reference/commandline/run/) the service and create a container called `wasm-server`. This example binds `8080` of the container to the port `8080` of the host.

   ```bash
   docker run --name wasm-server -p 8080:8080 nodegen_server_custom
   ```
6. Make API calls to the `healthcheck` and `execute` endpoints similar to above to `localhost:8080`.

## Configure `HTTPS` with nginx

By default [`nodegen-server`](https://github.com/orgs/Coherent-Partners/packages/container/package/nodegen-server) only supports `HTTP`. `HTTPS` support can be configured by including [nginx server](https://nginx.org/en/) in the Docker image. Read more on how to configure `HTTPS` servers in the [nginx documentation](https://nginx.org/en/docs/http/configuring_https_servers.html).

1. Navigate to your desired working directory and move the exported ZIP to this location. In this example the name of the file is `runner_example.zip`.
2. Prepare your ssl certificate in the working directory saved as `ssl`.
3. Create your [nginx configuration file](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/) in the working directory, saved as `nginx.conf`. Here is an example that could be used.

   ```nginx
   events {
     worker_connections 1024;
   }
   http {
     upstream backend {
         server localhost:8080;
     }

     server {
       listen 443 ssl http2 default_server;
       listen [::]:443 ssl http2 default_server;

       server_name localhost;

       ssl_certificate /etc/ssl/nginx-selfsigned.crt;
       ssl_certificate_key /etc/ssl/nginx-selfsigned.key;

       location / {
         proxy_http_version 1.1;
         proxy_cache_bypass $http_upgrade;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection 'upgrade';
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
         proxy_pass http://backend;
       }
     }
   }
   ```
4. Create a [Dockerfile](https://docs.docker.com/engine/reference/builder/) with the following content:

   ```docker
   FROM alpine:latest AS unzipper

   # Set extract model name
   ARG MODEL_PATH=./runner_example.zip

   # Add unzip package
   RUN apk add unzip
   RUN mkdir /models && mkdir /model_zip

   # Copy extracted model model zip to temp folder
   COPY $MODEL_PATH ./model_zip

   # Unzip the extracted zip file
   RUN find ./model_zip -depth -name "*.zip" -exec sh -c 'f="{}"; unzip -- "$f" -d ./models' \; && rm -rf ./model_zip;

   # Set nodegen-server image
   FROM ghcr.io/coherent-partners/nodegen-server:latest

   # Create models folder
   RUN mkdir /models

   # Copy unzipped models to previously created folder
   COPY --from=unzipper /models/ /models

   # Set MODEL_LOCATION variable to models folder
   ENV MODEL_LOCATION=/models

   # Set the hybrid runner mode
   ENV USE_SAAS=false

   # Default application will listen on port 3000; you can set different to port by set PORT variable
   ENV PORT=8080

   # ADDED: Proxy app through nginx
   RUN apk update && apk add nginx
   COPY nginx.conf /etc/nginx/nginx.conf

   # ADDED: Copy ssl certificate
   COPY ssl /etc/ssl
   EXPOSE 443

   # MODIFIED: Start the application by script npm start
   CMD nginx; npm start;
   ```
5. Make API calls to the `healthcheck` and `execute` endpoints similar [Hybrid method 2: Manual Wasm mount](/hybrid-runner/setup-the-hybrid-runner/hybrid-method-2-manual-wasm-mount.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.coherent.global/hybrid-runner/setup-the-hybrid-runner/hybrid-method-3-custom-docker-image.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
