Published on

Deploying Secure Docs on Oracle Cloud VM

Authors

Deploying a simple yet secure documentation site on Oracle Cloud's always-free tier, protected by GitHub OAuth, can be straightforward. This post walks you through setting up an Oracle Cloud VM, installing essential tools, configuring OAuth2 Proxy, and deploying a Nextra-based documentation site.

Project Overview

In this post, I’ll walk through the steps to create a virtual machine (VM) on Oracle Cloud and deploy a protected documentation site. The setup includes:

  • A Nextra documentation platform for managing my projects.
  • An OAuth2 Proxy, used to protect the application using a GitHub login.

The final result is a secure, GitHub OAuth-protected documentation page, accessible at https://projects.andreluciani.dev/docs

Why I Chose Oracle Cloud

I took on this project to:

  1. Explore Oracle Cloud’s always-free resources.
  2. Centralize the documentation of my projects for easier management.

Step-by-Step Deployment Process

1. Creating the Oracle Cloud VM

After signing up for Oracle Cloud, creating a VM was simple. I navigated to Compute -> Instances -> Create Instance from the main menu.

Oracle Cloud Instance Creation

On the creation page, it is possible to choose different OS images, shapes (CPU/Memory/Architecture), volumes, and other configurations. I've selected the Ubuntu 22.04 Minimal image and left the rest with default values (using the "Always-free eligible" options).

One important thing to do during VM creation is to save the SSH keys:

Oracle Cloud Instance SSH Keys

After the instance was created, I just had to wait until it was ready, with the status RUNNING

Oracle Cloud Instance Running

2. Connecting via SSH

After the VM was ready, I accessed it through SSH using the saved private key:

sudo chmod 400 <path-to-private-key>
ssh -i <path-to-private-key> <username>@<public-ip-address>

The username and public-ip-address values are available at the Oracle Cloud instance page:

Oracle Cloud Instance Access

3. Installing Git, Docker and GitHub CLI

Once connected, I installed git and Docker to manage deployments:

sudo apt update
sudo apt install git
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

I've also installed GitHub CLI.

These tools will make the whole process easier.

4. Setting up GitHub Actions

I created a GitHub repository to store configurations for tools running on the VM. This GitHub Action workflow automates deployments:

build.yaml
name: Build & Deploy to Oracle Cloud VM

on:
  push:
    paths-ignore:
      - .gitignore
      - README.md
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup SSH agent
        uses: webfactory/ssh-agent@v0.9.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Deploy to VM
        run: |
          ssh -o StrictHostKeyChecking=no ubuntu@${{ vars.VM_PUBLIC_IP }} "
            echo 'Deploying to Oracle Cloud VM'
          "

This was just the base for the final workflow.

5. Configuring OAuth2 Proxy with GitHub

For secure access, I created a GitHub OAuth2 app on the developers page. Here's the configuration used:

GitHub OAuth2 App Creation

Also, I copied the client ID and client secret and stored them as repository secrets to allow easy upgrades using the GitHub Action workflow created before.

6. Configuring DNS, SSL, and Nginx

To map the VM’s public IP and enable HTTPS, I followed these steps:

  1. Created a DNS Zone on Oracle Cloud: projects.andreluciani.dev
  2. Mapped the subdomain to the VM's public IP.
  3. Added NS records to my domain registrar (Vercel).
  4. Configured firewall rules to allow traffic on ports 80 (HTTP) and 443 (HTTPS).
  5. Installed Nginx for reverse proxy and SSL using Certbot.
  6. Nginx was configured to forward HTTPS requests to OAuth2 Proxy, running on port 4180, which protects access to the documentation.

The whole process was not as straightforward as it seems in the steps above, though. Since it was the first time using Oracle Cloud and OAuth2 Proxy, I have iterated the settings a few times until everything worked smoothly.

After that, I had everything needed to spin up the proxy. To do that, I updated the build.yaml file:

build.yaml
name: Build & Deploy to Oracle Cloud VM

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  oauth2-proxy:
    name: OAuth2 Proxy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup SSH agent
        uses: webfactory/ssh-agent@v0.9.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Build image & Start Docker container
        env:
          VM_PUBLIC_IP: ${{ secrets.VM_PUBLIC_IP }}
          OAUTH2_PROXY_COOKIE_SECRET: ${{ secrets.OAUTH2_PROXY_COOKIE_SECRET }}
        run: |
          ssh -o StrictHostKeyChecking=no ubuntu@${{ vars.VM_PUBLIC_IP }} "
            sudo docker rm -f $(sudo docker ps -a -q --filter ancestor=quay.io/oauth2-proxy/oauth2-proxy:latest) 2>/dev/null || true && \
            sudo docker run -d --net="host" -p 4180:4180 quay.io/oauth2-proxy/oauth2-proxy:latest \
              --provider=github \
              --cookie-secret=${{ secrets.OAUTH2_PROXY_COOKIE_SECRET }} \
              --client-id=${{ secrets.OAUTH2_PROXY_CLIENT_ID }} \
              --client-secret=${{ secrets.OAUTH2_PROXY_CLIENT_SECRET }} \
              --github-user=andreluciani \
              --email-domain=* \
              --reverse-proxy=true \
              --http-address=0.0.0.0:4180 \
              --upstream=http://127.0.0.1:3000/docs
          "

7. Deploying Nextra Docs

I've created a Nextra project with the default configurations for a documentation project. Besides the default configuration, I've changed:

  • The base path to : /docs
  • App port to: 3000
  • Created a Dockerfile based on the Next.js docs.

I used this GitHub Actions workflow to build and run the Nextra app:

build.yaml
name: Build & Deploy to Oracle Cloud VM

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  deploy:
    name: Docs
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup SSH agent
        uses: webfactory/ssh-agent@v0.9.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Create docs directory & Clone repository
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          ssh -o StrictHostKeyChecking=no ubuntu@${{ vars.VM_PUBLIC_IP }} "
            if [ ! -d /home/ubuntu/docs ]; then
                cd /home/ubuntu
                gh auth login --with-token <<< $GH_TOKEN
                gh repo clone andreluciani/andrelucianidev-docs
                mv andrelucianidev-docs docs
            fi
            cd /home/ubuntu/docs && git pull
          "

      - name: Build image & Start Docker container
        run: |
          ssh -o StrictHostKeyChecking=no ubuntu@${{ vars.VM_PUBLIC_IP }} "
            cd /home/ubuntu/docs
            sudo docker build -t docs . &&
            sudo docker run -d -p 3000:3000 --name docs-container docs:latest
          "

8. Testing the Setup

The expected behavior of the deployed system was as follows:

  • Accessing any path other than /docs (e.g., /) returns 404: Not Found.
  • Accessing /docs triggers GitHub OAuth login. Upon successful login, the documentation becomes available.
  • Unauthorized users receive a 403: Forbidden error.

Conclusion

Deploying this project gave me valuable hands-on experience with Oracle Cloud’s always-free tier. It helped solidify my understanding of VM management, GitHub Actions, Docker, and OAuth2 Proxy. I intend to refine this setup as I deploy more tools to the VM.