> For the complete documentation index, see [llms.txt](https://docs.coherent.global/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coherent.global/hybrid-runner/setup-the-hybrid-runner/hybrid-method-3-custom-docker-image.md).

# 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).
