Setup
Install, configure and connect the API, the admin panel and the site template locally.
On this page you'll learn how to install the three parts of Journey AI on your own machine, how to configure each one and how to connect them.
| Part | Repository | Technology | Local address |
|---|---|---|---|
| API | sameup-cms | .NET 10, EF Core, SQL Server | http://localhost:5235 |
| Admin panel | journey-v2 | React 19, Vite, npm | http://localhost:5173 |
| Site template | Cms-Landing-Core | Next.js 16, pnpm | http://localhost:3000 |
The order matters: API first, then the panel, then the site. The panel and the site read from the API; neither opens without it.
Prerequisites
| Tool | Version | For |
|---|---|---|
| .NET SDK | 10.0.400 or later (global.json) | API |
| SQL Server | Any SQL Server you can reach | API |
| Docker | Current version | The API's helper services (file storage, optional Redis) |
| Node.js | 24 or later | Panel |
| Node.js | 22 or later | Site template |
| pnpm | Current version | Site template (npm and yarn are blocked) |
You provide SQL Server
The Docker files in the repositories have no SQL Server service. Install a local SQL Server or run one in a container; the API only needs the connection string.
1. API
Clone and build
git clone <sameup-cms> && cd sameup-cms
dotnet buildThe solution file is sameup-cms.slnx. The project you run is SameUp.CMS.API; the database layer is SameUp.CMS.Data.
Start the helper services
The API keeps files in an object store. Locally, use the MinIO service in docker-compose.local.yml:
export MINIO_ACCESS_KEY=<access-key> MINIO_SECRET_KEY=<secret-key>
docker compose -f docker-compose.local.yml up -d minio redis| Service | Port | Required |
|---|---|---|
minio | 9000, console 9001 | Yes (or AWS S3 / Azure Blob) |
redis | 6379 | No; without it the API uses an in-memory cache |
kafka, kafka-ui | 9092, 8081 | No; only for shipping logs |
Create the bucket the API will use in the MinIO console (http://localhost:9001).
Configure
The API reads its settings from SameUp.CMS.API/appsettings.json and from environment variables. In environment variables, use __ as the section separator: ConnectionStrings:SqlConnection → ConnectionStrings__SqlConnection.
Required settings:
| Key | Purpose |
|---|---|
ConnectionStrings:SqlConnection | SQL Server connection string. The database is created on first start if it doesn't exist. |
Documents:ActiveFileServer | File storage: MinIO, AWS or AzureBlobStorage. Any other value stops the API from starting. |
Documents:FileServers:MinIO:* | Settings for the storage you chose: AccessKey, SecretKey, BucketName, Host, UseSSL, CDNUrl and so on. AWS and Azure have their own blocks under the same path. |
Jwt:Key | Secret key that signs session tokens. Give every installation its own long, random value. Set Jwt:Issuer and Jwt:Audience for the installation too. |
Origins | Addresses allowed to call the API from a browser (CORS), such as the panel: Origins__0=http://localhost:5173. If empty, the panel can't connect to the API. |
Operational:Token | Secret key for the maintenance endpoints. Needed to create the first admin user; if empty, these endpoints are off. |
Common optional settings:
| Key | Purpose |
|---|---|
Redis:Enabled, Redis:ConnectionString | Redis cache. |
Kafka:LoggingEnabled | Ships logs to Kafka. Set it to false if you don't run Kafka locally. |
Auth:LocalLoginEnabled | Sign-in with e-mail and password (on by default). |
Auth:Sso:* | Corporate SSO sign-in. If local sign-in is off, SSO must be configured or the API won't start. |
Admin:Cookie:* | Domain, Secure and SameSiteMode for the panel's session cookie. |
UseSwagger | Swagger UI. Always on in the development environment. |
DisableAutoMigration | If true, database migrations don't run on start. |
Don't use the repository's development settings as they are
appsettings.Development.json holds values for a specific environment. Pass your own connection string, keys and addresses through environment variables, and don't commit secrets.
Run
dotnet run --project SameUp.CMS.API --urls "http://localhost:5235"On first start, the API runs the database migrations itself and adds the default application parameters. If the database isn't ready yet, it keeps retrying for five minutes.
To check:
GET http://localhost:5235/health: health status.http://localhost:5235/: Swagger UI in the development environment.
Create the first admin user
An empty database has no user who can sign in to the panel. A script in the repository creates the default roles (SuperAdmin, Admin, Editor) and the first admin:
export Operational__Token=<value-from-the-api-settings>
export ADMIN_EMAIL=[email protected] ADMIN_PASSWORD=<a-strong-password>
SEED_ROLES=1 ./scripts/dev-admin.sh- The script assumes the API runs at
http://localhost:5235; change it withAPI_URLif not. - For safety, it only runs against a local database.
SEED_ROLES=1deletes and recreates the existing roles; only use it on an empty database.
2. Admin panel
Clone and install
git clone <journey-v2> && cd journey-v2
npm installPoint it at the API
Create a .env.local file in the repository root:
VITE_API_URL=http://localhost:5235
VITE_API_BASE_PATH=/api/v1| Variable | Purpose |
|---|---|
VITE_API_URL | The API's root address. Required. |
VITE_API_BASE_PATH | API path prefix. Default /api/v1. |
VITE_API_PROXY | Development only: proxies /api requests to this address. Use it if you'd rather not set up CORS. |
VITE_ALLOWED_HOSTS | Allowed addresses (comma-separated) if you open the panel on a host other than localhost. |
VITE_DEV_LOGIN_EMAIL, VITE_DEV_LOGIN_PASSWORD | Prefill the sign-in form, in local development only. |
The site addresses aren't environment variables in the panel; they're read from the API's application parameters (see Connect the parts).
Run
npm run dev # http://localhost:5173
npm run check # types, lint and other checksSign in with the first admin user.
In the Docker image, the VITE_* variables aren't fixed at build time. When the container starts, APP_API_URL (required), APP_API_BASE_PATH and APP_GOOGLE_OAUTH_CLIENT_ID are written to config.js and take precedence over the VITE_* values. The panel is served on port 5173 in the container.
3. Site template
git clone <Cms-Landing-Core> my-site && cd my-site
cp .env.example .env.local
pnpm install
pnpm dev # http://localhost:3000For a local setup, set at least these in .env.local:
NEXT_PUBLIC_API_URL=http://localhost:5235
NEXT_PUBLIC_SITE_URL=http://localhost:3000
REVALIDATE_ALLOWED_ORIGINS=http://localhost:5173NEXT_PUBLIC_API_URLis the API's root address; don't add/api/v1. If it isn't set or the API can't be reached, you see a setup screen in development.REVALIDATE_ALLOWED_ORIGINSis the panel's address; with it, the panel refreshes the site's cache after saving.- The preview site is a second copy of the same template running with
PREVIEW_MODE=true.
For all variables, the project structure and component mapping, see Site template.
4. Connect the parts
For the three parts to find each other, these settings must match:
| Who | Finds | Setting |
|---|---|---|
| Panel | API | VITE_API_URL in the panel; the panel's address in the API's Origins. |
| Site | API | NEXT_PUBLIC_API_URL in the site. |
| Panel | Site | In the panel, Settings › Connections › Live site address and Preview site address; the panel's address in the site's REVALIDATE_ALLOWED_ORIGINS. |
In a local setup, sign in to the panel and set both site addresses to http://localhost:3000 on the Settings › Connections screen. If these addresses are empty or point to another environment, the preview in the component editor and the Refresh cache button go to the wrong site. For details, see Settings.
Common situations
Documents:ActiveFileServer is empty or not one of MinIO, AWS, AzureBlobStorage. Check the value and the settings block of the storage you chose.
Auth:LocalLoginEnabled is off and Auth:Sso:* isn't configured. At least one sign-in method must be on.
The API's Origins list doesn't contain the panel's full address (http://localhost:5173). Add it and restart the API, or use VITE_API_PROXY in the panel.
Check the site addresses on the panel's Connections screen and the site's REVALIDATE_ALLOWED_ORIGINS value. The refresh request goes from the browser, from the panel's address.
Related pages
Site template
How the Next.js site template that publishes Journey AI content is structured, configured, and turns a request into a page.
Settings
Manage e-mail, captcha, AI, file limits and site addresses from one screen.
Delivery API
The public, unauthenticated API that sites use to read content and submit forms.