services: web: restart: unless-stopped container_name: ${CONTAINER_WEB} networks: - default - shared build: context: ./ dockerfile: aether_nginx.Dockerfile env_file: - ./.env environment: - PUID=1000 - PGID=1000 - TZ=US/Eastern - NGINX_SERVER_NAMES="flask_gunicorn.localhost demo.localhost dev.localhost dev.oneskyit.com dev-app.oneskyit.com dev-connect.oneskyit.com dev-demo.oneskyit.com dev-aacc.oneskyit.com dev-aapor.oneskyit.com dev-ascm.oneskyit.com dev-businessgroup.oneskyt.com dev-chow.oneskyit.com dev-cmsc.oneskyit.com dev-idaa.oneskyit.com dev-ishlt.oneskyit.com dev-lci.oneskyit.com dev-ncsd.oneskyit.com dev-npa.oneskyit.com dev-rli.oneskyit.com test-app.oneskyit.com test-api.oneskyit.com test-demo.oneskyit.com test-lci.oneskyit.com test-idaa.oneskyit.com scott.oneskyit.com dgr.oneskyit.com" ports: - "${OSIT_WEB_HTTP_PORT}:80" # LAN HTTP (local access without SSL) # - "${OSIT_WEB_HTTPS_PORT}:443" # HTTPS — not needed internally; terminate SSL at home server - "${AE_API_GATEWAY_PORT}:80" # API gateway: home nginx → workstation:5060 → ae_api replicas - "${AE_APP_GATEWAY_PORT}:80" # App gateway: home nginx → workstation:3001 → ae_app replicas volumes: - ./srv/html_php:/srv/html_php - ./srv/oneskyit_site:/srv/oneskyit_site - ${HOSTED_FILES_SRC}:/srv/hosted_files - ${HOSTED_TMP_SRC}:/srv/hosted_tmp - ./conf/nginx/options-ssl-nginx.conf:/etc/nginx/options-ssl-nginx.conf - ./conf/nginx/site.conf:/etc/nginx/conf.d/0_site.conf - ./conf/nginx/site-enabled_aether_fastapi_gunicorn.conf:/etc/nginx/templates/site-enabled_aether_fastapi_gunicorn.conf.template - ./conf/nginx/site-enabled_aether_app_svelte_node.conf:/etc/nginx/templates/site-enabled_aether_app_svelte_node.conf.template # - ./conf/nginx/site-enabled_aether_flask_gunicorn.conf:/etc/nginx/templates/site-enabled_aether_flask_gunicorn.conf.template - ./conf/certs/oneskyit_wild_fullchain.pem:/etc/certs/fullchain_wild.pem - ./conf/certs/oneskyit_wild_privkey.pem:/etc/certs/privkey_wild.pem - ./conf/certs/oneskyit.com_fullchain.pem:/etc/certs/fullchain.pem - ./conf/certs/oneskyit.com_privkey.pem:/etc/certs/privkey.pem - ./conf/certs/ssl-dhparams.pem:/etc/certs/ssl-dhparams.pem - ./logs/web:/logs depends_on: - ae_api - ae_app # - aether_app_gunicorn logging: driver: "json-file" options: max-size: "10m" max-file: "3" redis: restart: always container_name: ${CONTAINER_REDIS} image: redis networks: - default - shared command: redis-server --save "" --loglevel warning logging: driver: "json-file" options: max-size: "10m" max-file: "3" mariadb: restart: always image: mariadb:10.11 container_name: ae_mariadb_dev profiles: ["database"] networks: - shared command: [ "mysqld", "--max-connections=${MARIADB_MAX_CONNECTIONS}", "--innodb-buffer-pool-size=${MARIADB_INNODB_BUFFER_POOL_SIZE}", "--query-cache-size=${MARIADB_QUERY_CACHE_SIZE}", "--tmp-table-size=${MARIADB_TMP_TABLE_SIZE}", "--max-heap-table-size=${MARIADB_TMP_TABLE_SIZE}", "--table-open-cache=${MARIADB_TABLE_OPEN_CACHE}" ] environment: MYSQL_ROOT_PASSWORD: ${AE_DB_PASSWORD} MYSQL_DATABASE: ${AE_DB_NAME} MYSQL_USER: ${AE_DB_USERNAME} MYSQL_PASSWORD: ${AE_DB_PASSWORD} ports: - "${AE_DB_EXTERNAL_PORT}:3306" volumes: - ./srv/mariadb:/var/lib/mysql - ./conf/mariadb/server.cnf:/etc/mysql/conf.d/server.cnf logging: driver: "json-file" options: max-size: "10m" max-file: "3" phpmyadmin: restart: always image: phpmyadmin/phpmyadmin container_name: ae_pma_dev profiles: ["database"] networks: - shared environment: PMA_HOST: mariadb UPLOAD_LIMIT: 64M ports: - "${AE_PMA_PORT}:80" depends_on: - mariadb logging: driver: "json-file" options: max-size: "10m" max-file: "3" ae_api: restart: always build: context: ${AE_API_SRC} dockerfile: Dockerfile scale: ${AE_API_REPLICAS} networks: - default - shared healthcheck: test: ["CMD", "curl", "-f", "http://localhost:5005/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s env_file: - ./.env extra_hosts: dev.oneskyit.com: "192.168.32.7" dev-app.oneskyit.com: "192.168.32.7" dev-api.oneskyit.com: "192.168.32.7" test-api.oneskyit.com: "104.237.143.4" vpn-db.oneskyit.com: "192.168.64.5" linode.oneskyit.com: "104.237.143.4" volumes: - ./conf/aether_fastapi_gunicorn_conf.py:/conf/gunicorn_fastapi_conf.py - ./logs/ae_api:/logs - ${AE_API_SRC}:/srv/aether_api - ${HOSTED_FILES_SRC}:/srv/hosted_files - ${HOSTED_TMP_SRC}:/srv/hosted_tmp - ./temp/ae_api:/temp depends_on: - redis stdin_open: true tty: true logging: driver: "json-file" options: max-size: "10m" max-file: "3" ae_app: restart: always build: context: ${AE_APP_SRC} dockerfile: Dockerfile target: deploy-node args: BUILD_MODE: ${AE_APP_BUILD_MODE:-staging} scale: ${AE_APP_REPLICAS:-1} networks: - default - shared env_file: - ./.env # No host ports — ae_web_dev proxies to ae_app:3000 via Docker DNS, # round-robining across all replicas. Scale freely with AE_APP_REPLICAS. extra_hosts: srv-nyx.oneskyit.com: "104.237.143.4" dev-app.oneskyit.com: "104.237.143.4" api.oneskyit.com: "104.237.143.4" bak-api.oneskyit.com: "104.237.143.4" test-api.oneskyit.com: "104.237.143.4" dev-api.oneskyit.com: "192.168.32.7" home.oneskyit.com: "71.126.159.102" static.oneskyit.com: "104.237.143.4" dev.oneskyit.com: "192.168.32.7" # volumes: # # In production, the build happens INSIDE the container. # # Mounting the host source here would override the internal build. # # - ${AE_APP_SRC}:/app depends_on: - ae_api - redis logging: driver: "json-file" options: max-size: "10m" max-file: "3" # *Legacy* Aether Flask Application served with Gunicorn # *NOTE:* This legacy frontend using Flask is being replaced by the new one using SvelteKit. # aether_app_gunicorn: # # ... (same as before) ... # restart: always # container_name: ${CONTAINER_AE_APP} # build: # context: ./ # dockerfile: aether_flask_gunicorn.Dockerfile # env_file: # - ./.env # ports: # - "${AE_APP_GUNICORN_PORT}:5005" # extra_hosts: # - "${DOCKER_AE_SERVER_EXTRA_HOST}" # - "${DOCKER_AE_API_SERVER_EXTRA_HOST}" # - "${DOCKER_AE_API_BAK_SERVER_EXTRA_HOST}" # volumes: # - ./conf/aether_flask_gunicorn_conf.py:/conf/gunicorn_flask_conf.py # - ./conf/aether_flask_requirements_current.txt:/requirements_current.txt # - ./conf/aether_app_config.py:/srv/aether_app/flask_config_v2.py # - ./logs/ae_app:/logs # - ${AE_APP_SRC}:/srv/aether_app # - ${HOSTED_FILES_SRC}:/srv/hosted_files # - ${HOSTED_TMP_SRC}:/srv/hosted_tmp # - ./tmp/ae_app:/tmp # depends_on: # - ae_api # stdin_open: true # tty: true # logging: # driver: "json-file" # options: # max-size: "10m" # max-file: "3" dozzle: container_name: ${CONTAINER_DOZZLE:-ae_dozzle_dev} image: amir20/dozzle:latest volumes: - /var/run/docker.sock:/var/run/docker.sock ports: - "${AE_DOZZLE_PORT:-8881}:8080" restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" ae_ops: # ... (same as before) ... container_name: ae_ops_dev image: alpine:latest restart: always profiles: ["database"] networks: - shared env_file: - ./.env volumes: - /var/run/docker.sock:/var/run/docker.sock - ./backups:/backups - ./scripts:/scripts - ./logs:/logs - ./conf/crontab:/etc/crontabs/root command: sh -c "apk add --no-cache docker-cli bash && crond -f -l 2" depends_on: - mariadb logging: driver: "json-file" options: max-size: "10m" max-file: "3" networks: default: name: ${AE_NETWORK_NAME:-ae_dev_net} shared: name: aether_shared_net external: true