Cordium documentation · Latest

Full-Stack Development

This example sets up a complete, ready-to-code development environment for a full-stack application: a Go API and a React frontend built with Vite in the same repository, backed by the team's staging PostgreSQL database. Every developer gets their own persistent Workspace in which both dev servers are already running when it starts, the frontend and the API are available over HTTPS in the browser, and the staging database is accessible without any password.

The Template

The Template uses the official Go image and adds Node.js via a devcontainer feature. The repository is cloned with each developer's own GitHub account via the github GitProvider of the storefront Space (read more here):

spec: image: registry: url: golang:1.26-bookworm repository: url: https://github.com/acme-corp/storefront gitProvider: github.storefront.cordium runtime: devcontainers: features: - reference: ghcr.io/devcontainers/features/node:1 options: - key: version value: "24" - reference: ghcr.io/devcontainers/features/github-cli:1 envVars: - key: DATABASE_URL value: postgres://pg-staging.payments:5432/storefront - key: VITE_API_URL value: http://localhost:8080 tasks: - name: dependencies type: ON_CREATE workingDir: /workspace/repo onFailure: ON_FAILURE_ABORT run: | (cd api && go mod download) (cd web && npm ci) - name: api type: POST_START workingDir: /workspace/repo/api isBackground: true run: | timeout 120 sh -c 'until getent hosts pg-staging.payments > /dev/null; do sleep 2; done' go run ./cmd/server - name: web type: POST_START workingDir: /workspace/repo/web isBackground: true run: npm run dev -- --host 0.0.0.0 --port 5173 limit: cpu: millicores: 4000 memory: megabytes: 8192 storage: megabytes: 30000

Here are a few notes about this Template:

  • The api task waits until the name of the pg-staging.payments Octelium Service resolves, since the Workspace connects to the Cluster at the beginning of the POST_START phase (read more here). The database password is injected by Octelium, which is why DATABASE_URL contains none (read more here).

  • Both dev servers run as background tasks, which means that the Workspace becomes RUNNING without waiting for them, and that they keep running for as long as the Workspace runs. Their output is available in the Workspace's logs.

  • The dev servers listen on 0.0.0.0 so that they can be reached through the portal (read more here).

Since the repository is cloned with each developer's own account, this Template is not pre-built. Instead, each developer's Workspace is persistent, which means that the dependencies are only installed on its first run.

cordium create template fullstack.storefront.cordium --file fullstack.yaml

Creating a Workspace

Applications are specific to each Workspace. Create a persistent Workspace with the frontend as its default application and the API as a named one:

cordium create ws --template fullstack.storefront.cordium \ --port web:5173:default \ --port api:8080

Then, open the Workspace's page in the web portal, click Sign in to Git provider to authorize GitHub, and start it. Once it is running, the frontend is available at https://<WORKSPACE>.cordium.<DOMAIN> and the API at https://api_<WORKSPACE>.cordium.<DOMAIN>, both authenticated with your Octelium identity.

Developing

You can work from a browser terminal, or connect VS Code, Cursor, Zed or a JetBrains IDE over SSH (read more here):

octelium connect -d cordium code <WORKSPACE>

Since Vite's dev server reloads on file changes, your edits are immediately visible in the browser. git pull and git push use your GitHub account through the GitProvider, while the gh CLI, which is installed by its devcontainer feature, can be authenticated separately via gh auth login.

Sharing a Preview

When your branch is ready for review, share the frontend with the other Members of the storefront Space from the Applications panel of the Workspace's page in the web portal, or via the SDKs. Your teammates can then open https://web_<WORKSPACE>.cordium.<DOMAIN> with their own identities while your Workspace is running (read more here):

if err := ws.SharePort(ctx, "web", cordium.ShareWithMembers); err != nil { return err }

To share a preview with people who are not Users of your Cluster, such as a customer or a designer, serve it as a public Octelium Service instead (read more here).