Developer documentation

Deploying your app
on Dadisiweb.

Everything you need to get any app — Python, Node.js, PHP, Go, Rust — deployed and running on the Dadisiweb platform. Read this before you push.

Platform docs · Doc 2 of 2 · v1.0

Section 1

How deployment works

When you trigger a deploy — from a Git push or a ZIP upload — the platform executes these eight steps in sequence. Understanding this pipeline explains most deployment behaviour and error messages.

01
Clone / extract
Git repo or ZIP
02
Allocate port
Stable across deploys
03
Generate .env
User + platform vars
04
Build image
Alpine · BUILD_COMMANDS
05
Start container
RUN_COMMAND executed
06
Configure Nginx
Reverse proxy entry
07
Issue SSL
Auto certificate
08
Health check
Ping → deployed ✓
#StepDetail
01Clone / extractGit repo or ZIP
02Allocate portStable across deploys
03Generate .envUser + platform vars
04Build imageAlpine · BUILD_COMMANDS
05Start containerRUN_COMMAND executed
06Configure NginxReverse proxy entry
07Issue SSLAuto certificate
08Health checkPing → deployed ✓
Port binding is the #1 deploy failure. Your app must listen on 0.0.0.0:$APP_PORT — not localhost, not a hard-coded port. The platform allocates the port; you read it from the environment.

Section 2

Platform environment variables

These variables are injected into every container automatically. You do not need to set them — just read them. They are available at build time and runtime.

VariableExample valueWhat it is
APP_DOMAINmyapp.on.dadisiweb.comYour app's public subdomain
APP_URLhttps://myapp.on.dadisiweb.comFull HTTPS URL
APP_IDproj_abc123Your project's unique ID
APP_PORT8000Port your app must listen on
HOST_PORT10042Host-side mapped port (informational)
APP_STORAGE/app/storagePersistent storage directory
APP_ENVproductionEnvironment name
APP_DEBUGfalseAlways false in production
PORT8000Alias for APP_PORT (Node.js convenience)
PORT is provided as a convenience alias for APP_PORT because many Node.js frameworks read process.env.PORT by convention. Both point to the same value.

Section 3

Framework recipes

Copy-paste configuration for the most common frameworks. Every recipe assumes your app reads APP_PORT and APP_DOMAIN from environment variables.

Django (Python)

settings.pypython
import os

APP_DOMAIN = os.environ.get('APP_DOMAIN', 'localhost')

ALLOWED_HOSTS = ['localhost', '127.0.0.1', APP_DOMAIN]

CSRF_TRUSTED_ORIGINS = [
    f'https://{APP_DOMAIN}',
    f'http://{APP_DOMAIN}',
]

CORS_ALLOWED_ORIGINS = [
    f'https://{APP_DOMAIN}',
]

# Static & media
STATIC_ROOT = BASE_DIR / 'staticfiles'
MEDIA_ROOT  = os.environ.get('APP_STORAGE', BASE_DIR / 'media')
MEDIA_URL   = '/media/'

Build & run commands

Dashboard → Build commandsbash
# BUILD_COMMANDS
pip install -r requirements.txt && python manage.py collectstatic --noinput

# RUN_COMMAND
python manage.py migrate && gunicorn core.wsgi:application --bind 0.0.0.0:8000
SECRET_KEY must be set in your user env vars. Never commit it to your repository. Django will raise an error if it is absent or left as the default.

FastAPI / Flask (Python)

main.pypython
import os
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()
APP_DOMAIN = os.environ.get('APP_DOMAIN', 'localhost')

app.add_middleware(
    CORSMiddleware,
    allow_origins=[f'https://{APP_DOMAIN}'],
    allow_credentials=True,
    allow_methods=['*'],
    allow_headers=['*'],
)
Dashboard → Run commandbash
uvicorn main:app --host 0.0.0.0 --port 8000

Express / Node.js

server.jsjavascript
const express = require('express');
const cors    = require('cors');
const app     = express();

const PORT = process.env.PORT || process.env.APP_PORT || 3000;

app.use(cors({
  origin: [
    `https://${process.env.APP_DOMAIN}`,
    'http://localhost:3000',
  ]
}));

app.listen(PORT, '0.0.0.0', () => {
  console.log(`Listening on ${PORT}`);
});
Dashboard → Commandsbash
# BUILD_COMMANDS
npm install && npm run build

# RUN_COMMAND
node server.js
# or: npm start

Next.js

next.config.jsjavascript
module.exports = {
  output: 'standalone',
};
Dashboard → Commandsbash
# BUILD_COMMANDS
npm install && npm run build

# RUN_COMMAND
npm start
If you're using NextAuth, set NEXTAUTH_URL=https://$APP_DOMAIN in your user env vars before the first deploy. The platform does not inject this automatically.

Laravel (PHP)

config/filesystems.phpphp
'local' => [
    'driver' => 'local',
    'root'   => env('APP_STORAGE', storage_path('app')),
],
Dashboard → Commandsbash
# BUILD_COMMANDS
composer install --no-dev          \
  && php artisan key:generate       \
  && php artisan migrate --force    \
  && php artisan storage:link

# RUN_COMMAND
php artisan serve --host=0.0.0.0 --port=8000
APP_KEY must be generated before first deploy. Run php artisan key:generate --show locally and paste the result into your user env vars. Laravel crashes immediately at startup without it.

Go

main.gogo
import (
    "net/http"
    "os"
)

func main() {
    port := os.Getenv("APP_PORT")
    if port == "" {
        port = "8000"
    }
    http.ListenAndServe("0.0.0.0:" + port, router)
}
Dashboard → Commandsbash
# BUILD_COMMANDS
go mod download && go build -o app .

# RUN_COMMAND
./app

Section 4

Persistent file storage

The container filesystem is ephemeral. Any file written outside /app/storage is deleted on every redeployment, container restart, or image rebuild.

The platform mounts a persistent volume at /app/storage. This path survives everything — use it for any file that must outlive a deploy.

/app/storage/uploads/ # uploaded files — persists
/app/storage/generated/ # PDFs, exports — persists
/app/uploads/ # wiped on redeploy
/tmp/ # wiped on restart
BASE_DIR/media/ # wiped on rebuild
Never write to paths inside your code directory. When the platform rebuilds your image, the entire code tree is replaced. Only /app/storage (exposed as APP_STORAGE) survives.

Read the storage path from the environment so your code works identically in local development and production:

python
import os
UPLOAD_DIR = os.environ.get('APP_STORAGE', '/tmp/storage')
javascript
const UPLOAD_DIR = process.env.APP_STORAGE ?? '/tmp/storage';

Section 5

WebSockets & real-time

WebSocket connections are fully supported. The platform Nginx configuration includes the required Upgrade and Connection headers automatically. Your app just needs to listen on APP_PORT.

Works out of the box

  • Socket.io (Node.js)
  • Django Channels (Python) — use Daphne or Uvicorn, not Gunicorn
  • Phoenix Channels (Elixir)
  • Gorilla WebSocket (Go)
Django Channels: use Daphne, not Gunicorn. Gunicorn is a synchronous WSGI server and cannot handle WebSocket connections. Use Daphne as your RUN_COMMAND:
bash
daphne -b 0.0.0.0 -p 8000 core.asgi:application

Section 6

Limits & constraints

These limits apply per project instance. Background workers and custom domains require Pro or above.

ConstraintStartProEnterprise
Memory512 MB1 GB2 GB
CPU0.5 core1 core2 cores
Max upload size50 MB50 MB50 MB
Request timeout120s120s120s
Persistent storage1 GB5 GB20 GB
Custom domains
Background workers
The 50 MB max upload size is enforced at the Nginx layer. For files larger than this, upload directly to an external storage provider (S3-compatible) and store only the reference URL in your database.

Section 7

Common deployment errors

If your deploy isn't behaving as expected, check this table first. Most issues fall into one of these nine categories.

Error / symptomLikely causeFix
502 Bad GatewayApp not listening on APP_PORTBind to 0.0.0.0:$APP_PORT
CSRF verification failedCSRF_TRUSTED_ORIGINS not setAdd APP_DOMAIN to CSRF config (§ Frameworks)
413 Request Entity Too LargeFile > 50 MBCompress or use external storage
App crashed on startMissing SECRET_KEY / APP_KEYSet it in user env vars before deploy
Files missing after redeployWriting outside /app/storageUse APP_STORAGE path (§ Storage)
Static files 404collectstatic not in build commandAdd collectstatic to BUILD_COMMANDS
DB migration failedmigrate not in run commandRun migrate before gunicorn starts
WebSocket disconnectsProxy timeoutHandled by platform — contact support
Port already in usePrevious container not cleanedPlatform handles this — redeploy
Still stuck? Open your project in the dashboard and check the real-time logs tab — the container's stdout/stderr output is streamed live and usually shows the exact error within the first few lines of startup.

Need more help?

If you've checked the logs and the error isn't listed here, reach out to support. Include your project ID (APP_ID) and the first 20 lines of your startup log.

Contact support Service status