# documentation: https://docs.opnform.com/introduction # slogan: OpnForm is an open-source form builder that lets you create beautiful forms and share them anywhere. It's super fast, you don't need to know how to code # tags: opnform, form, survey, cloud, open-source, self-hosted, docker, no-code, embeddable # logo: svg/opnform.svg # port: 80 x-shared-env: &shared-api-env APP_NAME: "OpnForm" APP_ENV: production APP_KEY: ${SERVICE_BASE64_APIKEY} APP_DEBUG: ${APP_DEBUG:-false} APP_URL: ${SERVICE_URL_NGINX} LOG_CHANNEL: errorlog LOG_LEVEL: ${LOG_LEVEL:-debug} FILESYSTEM_DRIVER: ${FILESYSTEM_DRIVER:-local} LOCAL_FILESYSTEM_VISIBILITY: public CACHE_DRIVER: redis QUEUE_CONNECTION: redis SESSION_DRIVER: redis SESSION_LIFETIME: 120 MAIL_MAILER: ${MAIL_MAILER:-log} MAIL_HOST: ${MAIL_HOST} MAIL_PORT: ${MAIL_PORT} MAIL_USERNAME: ${MAIL_USERNAME:-your@email.com} MAIL_PASSWORD: ${MAIL_PASSWORD} MAIL_ENCRYPTION: ${MAIL_ENCRYPTION} MAIL_FROM_ADDRESS: ${MAIL_FROM_ADDRESS:-your@email.com} MAIL_FROM_NAME: ${MAIL_FROM_NAME:-OpnForm} AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION:-us-east-1} AWS_BUCKET: ${AWS_BUCKET} OPEN_AI_API_KEY: ${OPEN_AI_API_KEY} TELEGRAM_BOT_ID: ${TELEGRAM_BOT_ID} TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN} REDIS_HOST: redis REDIS_PASSWORD: ${SERVICE_PASSWORD_64_REDIS} # Database settings DB_HOST: postgresql DB_DATABASE: ${POSTGRESQL_DATABASE:-opnform} DB_USERNAME: ${SERVICE_USER_POSTGRESQL} DB_PASSWORD: ${SERVICE_PASSWORD_POSTGRESQL} DB_CONNECTION: pgsql # PHP Configuration PHP_MEMORY_LIMIT: "1G" PHP_MAX_EXECUTION_TIME: "600" PHP_UPLOAD_MAX_FILESIZE: "64M" PHP_POST_MAX_SIZE: "64M" services: opnform-api: image: jhumanj/opnform-api:1.12.1 volumes: - api-storage:/usr/share/nginx/html/storage environment: # Use the shared environment variables. <<: *shared-api-env JWT_TTL: ${JWT_TTL:-1440} JWT_SECRET: ${SERVICE_PASSWORD_JWTSECRET} JWT_SKIP_IP_UA_VALIDATION: ${JWT_SKIP_IP_UA_VALIDATION:-true} H_CAPTCHA_SITE_KEY: ${H_CAPTCHA_SITE_KEY} H_CAPTCHA_SECRET_KEY: ${H_CAPTCHA_SECRET_KEY} RE_CAPTCHA_SITE_KEY: ${RE_CAPTCHA_SITE_KEY} RE_CAPTCHA_SECRET_KEY: ${RE_CAPTCHA_SECRET_KEY} SHOW_OFFICIAL_TEMPLATES: ${SHOW_OFFICIAL_TEMPLATES:-true} depends_on: postgresql: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD-SHELL", "php /usr/share/nginx/html/artisan about || exit 1"] interval: 30s timeout: 15s retries: 3 start_period: 60s api-worker: image: jhumanj/opnform-api:1.12.1 volumes: - api-storage:/usr/share/nginx/html/storage environment: # Use the shared environment variables. <<: *shared-api-env command: ["php", "artisan", "queue:work"] depends_on: postgresql: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD-SHELL", "pgrep -f 'php artisan queue:work' > /dev/null || exit 1"] interval: 60s timeout: 10s retries: 3 start_period: 30s api-scheduler: image: jhumanj/opnform-api:1.12.1 volumes: - api-storage:/usr/share/nginx/html/storage environment: # Use the shared environment variables. <<: *shared-api-env command: ["php", "artisan", "schedule:work"] depends_on: postgresql: condition: service_healthy redis: condition: service_healthy healthcheck: test: [ "CMD-SHELL", "php /usr/share/nginx/html/artisan app:scheduler-status --mode=check --max-minutes=3 || exit 1", ] interval: 60s timeout: 30s retries: 3 start_period: 70s # Allow time for first scheduled run and cache write opnform-ui: image: jhumanj/opnform-client:1.12.1 environment: - NUXT_PUBLIC_APP_URL=/ - NUXT_PUBLIC_API_BASE=/api - NUXT_PRIVATE_API_BASE=http://nginx/api - NUXT_PUBLIC_ENV=production - NUXT_PUBLIC_H_CAPTCHA_SITE_KEY=${H_CAPTCHA_SITE_KEY} - NUXT_PUBLIC_RE_CAPTCHA_SITE_KEY=${RE_CAPTCHA_SITE_KEY} healthcheck: test: ["CMD-SHELL", "wget --spider -q http://opnform-ui:3000/login || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 45s depends_on: opnform-api: condition: service_healthy postgresql: image: postgres:16 volumes: - opnform-postgresql-data:/var/lib/postgresql/data environment: - POSTGRES_USER=${SERVICE_USER_POSTGRESQL} - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL} - POSTGRES_DB=${POSTGRESQL_DATABASE:-opnform} healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 20s retries: 10 redis: image: redis:7 environment: - REDIS_PASSWORD=${SERVICE_PASSWORD_64_REDIS} volumes: - redis-data:/data command: ["redis-server", "--requirepass", "${SERVICE_PASSWORD_64_REDIS}"] healthcheck: test: ["CMD", "redis-cli", "-a", "${SERVICE_PASSWORD_64_REDIS}", "PING"] interval: 10s timeout: 30s retries: 3 # The nginx reverse proxy. # used for reverse proxying the API service and Web service. nginx: image: nginx:1.29.2 environment: - SERVICE_URL_NGINX volumes: - type: bind source: ./nginx/nginx.conf target: /etc/nginx/conf.d/default.conf read_only: true content: | map $original_uri $api_uri { ~^/api(/.*$) $1; default $original_uri; } server { listen 80 default_server; root /usr/share/nginx/html/public; access_log /dev/stdout; error_log /dev/stderr error; index index.html index.htm index.php; location / { proxy_http_version 1.1; proxy_pass http://opnform-ui:3000; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } location ~/(api|open|local\/temp|forms\/assets)/ { set $original_uri $uri; try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass opnform-api:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/public/index.php; fastcgi_param REQUEST_URI $api_uri; } } depends_on: - opnform-api - opnform-ui healthcheck: test: ["CMD", "nginx", "-t"] interval: 30s timeout: 10s retries: 3 start_period: 40s