On-premise Deployments

AppMaster applications can be deployed on-premise with a number of infrastructure steps.

Recommended on-premise infrastructure:

  • Server with Linux on Intel/AMD x64 CPU (Ubuntu LTS or any other modern). Additionally apps can be built for Windows and macOS , for arm or x32 for legacy systems.
  • PostgreSQL Database 14+, managed like AWS RDS recommended
  • S3-compatible storage (AWS recommended). Local files folder can be used as an alternative for test deployments, but not recommended.
  • nginx as reverse proxy to terminate TLS and route requests

NOTE. On-premise is available starting from Business subscription tier. Automatic provisioning, automated deploy and some specific options are available with Enterprise subscription only.

General Steps

  1. Decide how you will host backend applications: by downloading binaries or using docker images (recommended).
  • If you prefer binaries, you can download them from Artifacts page and run them via systemd or supervisord.
  • To get access to the docker image registry reach our to our support team to get credentials.
  1. Install docker to your server (Install Docker Engine | Docker Docs or just sudo apt install docker-ce for the most debian-based distros)

  2. Install nginx, for the most of debian-based distros:
    sudo apt install nginx

  3. Authorize docker to the AppMaster Docker registry:
    docker login registry.appmaster.io

  4. Go to the web UI of the registry https://registry.appmaster.io and get pull command for the build you need. Execute pull on your server, it should look like this:
    docker pull registry.appmaster.io/app_426371/app_426371@sha256:8b5a7d08c4077e88ad1688bafa52e970bfe09f0c50f9a887a05f977b4c7a3352

  5. Prepare configuration file for your backend by adjusting template from the attachment with your DB/S3 credentials and ports if needed.

  6. Run docker container:
    docker run -d -p 127.0.0.1:9895:9895-v /<your-folder/config.yaml:/app/config.yaml --restart unless-stopped <image>

  7. Check that container is successfully started and running:
    docker ps -a
    In a case of any issues try to check logs
    docker logs <container-name>

  8. Download web application artifact from the Studio and unpack to the folder

  9. Use nginx configuration sample from the attachment to adjust for your needs.

Important Moments

  • To serve web applications you must have HTTPS connection and any SSL certificate (even self-signed for testing).
  • To serve mobile applications you must have HTTPS and valid SSL certificate
  • Enable gzip, br, zstd in your nginx if supported for the optimal performance
  • Use CDN to cache static resources and protect application with WAF
  • For advanced users docker compose can be a preferred solution to manage containers
1 Like

Sample nginx config

server {
  listen *:443 ssl;
  server_name <your-domain-name>;

# SSL configuration
ssl_certificate     /<fullpath-to-your-ssl-cert>.crt;
ssl_certificate_key /<fullpath-to-your-ssl-key>.key;

# Set HSTS to 365 days
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload' always;

client_max_body_size 128M;
 
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;

# Backend routes
location /api/ {
          proxy_pass http://127.0.0.1:9895;
}

# Web v4
location /<prefix/ {
        alias /<path-to-web-app-folder>/;
        index index.html;
        try_files $uri $uri/ index.html /index.html =404;
}

# Mobile apps v3
location /api/v3/mobile/ {
  alias /<path-to-mob-app-folder>/;
}

# Mobile apps v4
location /api/v4/mobile/ {
  alias /<path-to-mob-app-folder>/;

}
1 Like

Sample app config

env: dev
enable_workers: true
instance_id: 9sMWy5NGR
app:
    id: 0
    project_id: 0
    app_id: ""
    token: 
    build: 1
    built_at: 0001-01-01T00:00:00Z
    send_critical_errors: false
    send_critical_error_addr: 
    push_notifications_addr: 
    job_id:
server:
    port: "9895"
    api_base_path: api
    api_addr: 
db:
    network: tcp
    host: <db-server-addr>
    port: "5432"
    name: <db-name>
    user: <db-username>
    password: <db-password>
    log_queries: true
    pool_size: 100
    per_page_max: 0

log:
    level: debug
    folder: logs
    format: simple
    log_to_file: false
swagger:
    path: api/_swagger
cache:
    cleanup_interval: 0
    fs_size_cache_period: 0
    db_record_count_cache_period: 0
    db_size_cache_period: 0
metrics:
    enable: false
    server_addr: 
    send_interval: 60
    auth_token: 
    cache_period: 0
    second_to_start: 17
    sql:
        enable: false
        cache_period: 0
storage:
    driver: s3
    fs:
        path: /files
    s3:
        endpoint: <your-creds>
        key: <your-creds>
        secret: <your-creds>
        bucket: <your-creds>
        prefix: <your-creds>
        region: <your-creds>

scheduler_off: false
modules_settings:
    auth_v1:
        auth_cookie_name: ""
        confirmation_code_expiration: "30"
        confirmation_code_max_attempts: "5"
        confirmation_required: "false"
        failed_login_delay: "0"
        force_session_signature: "false"
        recovery_code_expiration: "30"
        recovery_code_max_attempts: "5"
        request_replay_protection: "true"
        session_duration: "60"
        timestamp_max_skew: "15"
        token_options: "1"
        verify_host_schema: "false"

allow_cli_bp: false
1 Like

Couple of questions:

  1. point 6 if local file system will be used, should i simply remove S3 from config?

Change driver to fs

1 Like

Where exactly should they be located and in what form?

I’ve tried several hypotheses and every time after deployment I get 404 on all web fronts at the same time mobile application works with api successfully, so the server works and the problem is with the front.

I described in detail everything I tried, and attached screens in a file, because when trying to send here I got an error that I can not upload more than 1 media:

A couple of questions for you:

  • What version of the web application do you use? v3 and not v4?
  • According to your screenshots you try to pack everything to the docker container. What are you trying to get? All web and mobile applications need to be served via http server like nginx/apache etc.
  • In your screenshot you have at lease 1 file from web v3 - appv3.json that your app tries to load from root location. If thats as intended try to add another location like /appv3.json and point alias to the exact location of the file to serve it.
  • Not really sure, probably V3.

  • Yes I tried to upload all the necessary files through docker. Seems I realized that might be the problem. I’ll try to upload the files directly to the server today.

  • So I need to specify a path like this in the config?

location /teacher {
        alias /storage/web-app-16916_1430/appv3.json;
        index index.html;
        try_files $uri $uri/ index.html /index.html =404;
location /admin {
        alias /storage/web-app-16915_1430/appv3.json;
        index index.html;
        try_files $uri $uri/ index.html /index.html =404;

Or like that?

location /teacher {
        alias /storage/webapp-v3/web-app-16916_1430/appv3.json;
        index index.html;
        try_files $uri $uri/ index.html /index.html =404;
location /admin {
        alias /storage/webapp-v3/web-app-16915_1430/appv3.json;
        index index.html;
        try_files $uri $uri/ index.html /index.html =404;

Initially from the example I thought that the path to the whole web folder was needed.

Here is nginx example with web v3 configuration for your case and project

server {
    listen *:443 ssl;
    server_name <your-domain-name>;

    # SSL configuration
    ssl_certificate     /<fullpath-to-your-ssl-cert>.crt;
    ssl_certificate_key /<fullpath-to-your-ssl-key>.key;

    # Set HSTS to 365 days
    add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload' always;

    client_max_body_size 128M;
     
    proxy_set_header HOST $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;

    # Backend routes
    location /api/ {
              proxy_pass http://127.0.0.1:9895; # <-- MAKE SURE the same port is in your backend app config
    }

    # Web v3

    location /static/ {
        alias /storage/myapps/static/;
    }
    location /webapp-static/ {
        alias /storage/myapps/webbundle-v3/; # <-- Place your web app v3 bundle here
    }

    location = /admin {
        return 301 $scheme://$host/admin/;
    }
    location /admin/ {
        alias /storage/myapps/webbundle-v3/
        index index.html;
        try_files $uri $uri/ index.html /index.html =404;
    }
    location ~ ^/admin/(.+\.json)$ {
        alias /storage/myapps/admin/$1;
    }
    location = /teacher {
        return 301 $scheme://$host/teacher/;
    }
    location /teacher/ {
        alias /storage/myapps/webbundle-v3/
        index index.html;
        try_files $uri $uri/ index.html /index.html =404;
    }
    location ~ ^/teacher/(.+\.json)$ {
        alias /storage/myapps/teacher/$1;
    }
    location = /student {
        return 301 $scheme://$host/student/;
    }
    location /student/ {
        alias /storage/myapps/webbundle-v3/
        index index.html;
        try_files $uri $uri/ index.html /index.html =404;
    }
    location ~ ^/student/(.+\.json)$ {
        alias /storage/myapps/student/$1;
    }


    # Mobile Apps v3
    location /api/v3/mobile/ {
        alias /storage/myapps/mobile/;
    }
    location /__mob/v3/ {
        alias /storage/myapps/mobile/;
    }

    # Mobile Apps v4
    location /api/v4/mobile/ {
        alias /storage/myapps/mobile/;
    }
    location /__mob/v4/ {
        alias /storage/myapps/mobile/;
    }

    
    location /robots.txt {
        alias /storage/myapps/tools/robots.txt;
    }

    location /.well-known/assetlinks.json {
        alias /storage/myapps/tools/assetlinks.json;
    }
    location /.well-known/apple-app-site-association {
        alias /storage/myapps/tools/apple-app-site-association;
    }

}

backend не видел бакет s3, пока не прописали в
server:
api_addr:
адрес https:// сайта