# Deploy and Secure Access to Next.js/Vite App

> Octelium documentation. Canonical page: <https://octelium.com/docs/octelium/latest/management/guide/service/http/nextjs-vite>.

## Overview

Octelium enables you to seamlessly easily deploy, scale and secure access as well as public anonymous access to your Next.js/Vite.js/Astro web containerized/dockerized applications, effectively making Octelium operate as a PaaS-like deployment platform. Octelium simply provides the following:

- A scalable infrastructure to provide clientless deployment and access to all your containerized/dockerized applications that can be hosted by public container registries or even private registries that require authentication (read more about managed containers [here](https://octelium.com/docs/octelium/latest/management/core/service/managed-containers.md)).
- Secure clientless BeyondCorp access for human *Users* via Octelium's OpenID Connect and SAML 2.0 *IdentityProviders* (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers.md)) as well as for your workload *Users* via OAuth2 client credentials (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential.md#oauth2-client-credentials)) and bearer access tokens (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential.md#access-tokens)).
- Anonymous public access to your websites, APIs and webhooks (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/anonymous-access.md)).
- Dynamic identity-based, context-aware, L7 aware, on a per-request basis, centralized access control via policy-as-code with CEL and OPA (read more about *Policies* and access control [here](https://octelium.com/docs/octelium/latest/management/core/policy.md)).
- Dynamic L7-aware routing to upstreams and advanced request/response header and body manipulation.
- OpenTelemetry-native, identity-based, L7 aware visibility and auditing (read more [here](https://octelium.com/docs/octelium/latest/management/core/visibility.md)).
- Zero-config private client-based access from anywhere by humans as well as workloads via the `octelium` clients and containers (read more about connecting to *Clusters* [here](https://octelium.com/docs/octelium/latest/user/cli/connect.md)).
- GitOps-friendly declarative, programmable management (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview.md)).

## A Simple Example

In this guide, we're going to assume that your web app is built as a Docker image that is served by a private container registry (e.g. `ghcr.io`). We first need to obtain the user and password/token needed to authenticate to the private container registry. For example, the GitHub container registry (i.e. `ghcr.io`), you can read more [here](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry).

Now we store the obtained token as a *Secret* as follows:

```bash
octeliumctl create secret reg-password
```

Now we create the *Service* for our web application as follows:

```yaml
kind: Service
metadata:
  name: dashboard
spec:
  mode: WEB
  isPublic: true
  config:
    upstream:
      container:
        # This is the container port used by the "npm run start" command
        port: 3000
        image: ghcr.io/<ORG>/<IMAGE>:<TAG>
        command:
        - npm
        args:
        - run
        - start
        # Set the number of container replicas, by default it is set to 1
        replicas: 3
        credentials:
          usernamePassword:
            username: <USERNAME>
            password:
              fromSecret: reg-password
```

You can control the *Service* container even more by setting some resource limits, environment variables, etc... as follows:

```yaml
kind: Service
metadata:
  name: dashboard
spec:
  mode: WEB
  isPublic: true
  config:
    upstream:
      container:
        port: 3000
        image: ghcr.io/<ORG>/<IMAGE>:<TAG>
        command:
        - npm
        args:
        - run
        - start
        replicas: 3
        credentials:
          usernamePassword:
            username: <USERNAME>
            password:
              fromSecret: reg-password
        resourceLimit:
          cpu:
            millicores: 2000
          memory:
            megabytes: 4000
        env:
        - name: KEY1
          value: VALUE1
        - name: KEY2
          value: VALUE2
        securityContext:
          runAsUser: 1000
```

You can now apply the *Service* as follows (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview.md)):

```bash
octeliumctl apply /PATH/TO/SERVICE.YAML
```

Now you can access the *Service* publicly via the clientless/BeyondCorp using your browser at the address `https://dashboard.<DOMAIN>`. You can read more about publicly exposed BeyondCorp *Services* [here](https://octelium.com/docs/octelium/latest/management/core/service/clientless.md).

And to provide public anonymous access, you only need to enable the `isAnonymous` field as follows:

```yaml
kind: Service
metadata:
  name: dashboard
spec:
  mode: WEB
  isPublic: true
  #!mark
  isAnonymous: true
  config:
  # The rest of your config
```

## Dynamic Configuration

You can also dynamically route to multiple containers (e.g. multiple container image versions) based on identity or/and context (read more about dynamic configuration [here](https://octelium.com/docs/octelium/latest/management/core/service/dynamic-config.md)). Here is an example:

```yaml
kind: Service
metadata:
  name: my-web-app
spec:
  mode: WEB
  dynamicConfig:
    configs:
    - name: c1
      upstream:
        container:
          port: 80
          image: ghcr.io/org/image:v1
    - name: c2
      upstream:
        container:
          port: 80
          image: ghcr.io/org/image:v2
    rules:
    - condition:
        match: ctx.request.http.path.startsWith("/v1")
      configName: c1
    - condition:
        match: ctx.request.http.path.startsWith("/v2")
      configName: c2
```

## Access Control

When it comes to access control, Octelium provides a rich layer-7 aware, identity-based, context-aware ABAC access control on a per-request basis where you can control access based on the HTTP request's path, method, and even serialized JSON body content using policy-as-code with CEL and Open Policy Agent (OPA) (You can read more in detail about *Policies* and access control [here](https://octelium.com/docs/octelium/latest/management/core/policy.md)). Here is a generic example:

```yaml
kind: Service
metadata:
  name: my-nginx
spec:
  mode: HTTP
  config:
    upstream:
      container:
        image: nginx
        port: 80
        replicas: 3
  authorization:
    inlinePolicies:
      - spec:
          rules:
            - effect: ALLOW
              condition:
                all:
                  of:
                    - match: ctx.user.spec.groups.hasAll("dev", "ops")
                    - match: ctx.request.http.method in ["POST", "PUT"]
                    - match: ctx.request.http.path.startsWith("/users")
                    - match: ctx.request.http.headers["x-custom-header"] == "this-value"
                    # bodyMap contains the serialized JSON body content
                    - match: ctx.request.http.bodyMap.age > 18 && ctx.request.http.bodyMap.email.endsWith("@example.com")
```

## Visibility

Octelium also provides OpenTelemetry-ready, application-layer L7 aware visibility and access logging in real time (see an example for HTTP [here](https://octelium.com/docs/octelium/latest/management/core/service/http.md#visibility)). You can read more about visibility [here](https://octelium.com/docs/octelium/latest/management/core/visibility.md).

This was a very short guide to show you how to use Octelium to deploy, scale, route and provide secure access as well as anonymous public access to any webapp containers. Here are a few more related features that you might be interested in:

- Routing not just by request paths, but also by header keys and values, request body content including JSON (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/http.md#json-request-body)).
- Request/response header manipulation (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/http.md#header-manipulation)).
- Cross-Origin Resource Sharing (CORS) (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/http.md#cross-origin-resource-sharing-cors)).
- gRPC mode (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/http.md#grpc-mode)).
- Secretless access to upstreams and injecting bearer, basic, or custom authentication header credentials (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/http.md#secretless-access)).
- Application layer-aware ABAC access control via policy-as-code using CEL and Open Policy Agent (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy.md)).
- OpenTelemetry-ready, application-layer L7 aware auditing and visibility (read more [here](https://octelium.com/docs/octelium/latest/management/core/visibility.md)).
