docker-compose.yml 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # WyOJ -- one-command deployment.
  2. #
  3. # docker compose up -d --build # fresh install (creates ./uoj_data)
  4. # ./judger/register-judger.sh # register the judger in judger_info
  5. # docker compose -f docker-compose.yml -f docker-compose.seed.yml up -d
  6. # # ... and seed the bundled production dump
  7. # docker compose logs -f uoj-web # apache + install output
  8. # docker compose logs -f uoj-judger # judge_client output
  9. # docker exec -it uoj-web bash # shell inside the web container
  10. #
  11. # Layout:
  12. # ./db/ uoj-db image: MySQL 5.7 + the current schema (app_uoj233.sql)
  13. # ./web/ uoj-web image: apache + php 7.4 + the WyOJ sources (+ judger tree)
  14. # ./judger/ uoj-judger image: python judge_client + the C++ sandbox
  15. # ./uoj_data/ runtime state (mysql datadir, /var/uoj_data, app/storage)
  16. #
  17. # `version` is kept so this still parses with the legacy python docker-compose;
  18. # service readiness is handled by install.sh's own wait loop, not by
  19. # depends_on conditions, for the same reason.
  20. #
  21. # SECURITY: the three secrets below are placeholders that are published in this
  22. # repository. Change JUDGER_PASSWORD / JUDGER_SOCKET_PASSWORD / the database
  23. # password together (and re-run ./judger/register-judger.sh) before putting this
  24. # anywhere public.
  25. version: '3'
  26. services:
  27. uoj-db:
  28. image: uoj-db:latest
  29. build:
  30. context: ./db/
  31. dockerfile: Dockerfile
  32. container_name: uoj-db
  33. restart: always
  34. volumes:
  35. - ./uoj_data/db/mysql:/var/lib/mysql
  36. environment:
  37. - MYSQL_DATABASE=app_uoj233
  38. - MYSQL_ROOT_PASSWORD=root
  39. healthcheck:
  40. test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-proot"]
  41. interval: 10s
  42. timeout: 5s
  43. retries: 12
  44. start_period: 30s
  45. uoj-web:
  46. image: uoj-web:latest
  47. build:
  48. # root context: the web image also needs ./judger (see web/Dockerfile)
  49. context: ./
  50. dockerfile: web/Dockerfile
  51. container_name: uoj-web
  52. restart: always
  53. depends_on:
  54. - uoj-db
  55. volumes:
  56. # DEV: mount the sources so edits take effect per-request instead of
  57. # requiring an image rebuild. Remove this line for a production deploy.
  58. - ./web:/opt/uoj/web
  59. # uploads and .UOJSetupDone -- must persist across recreates
  60. - ./uoj_data/web/data:/var/uoj_data
  61. # submissions / pastes / tmp / judge_client.zip
  62. - ./uoj_data/web/storage:/opt/uoj/web/app/storage
  63. # generated on first boot from the environment below; kept on the host so
  64. # that rebuilding the image does not lose it
  65. - type: bind
  66. source: ./.config.local.php
  67. target: /opt/uoj/web/app/.config.php
  68. ports:
  69. - "80:80"
  70. # 3690 was published by the original file but nothing listens on it.
  71. # - "3690:3690"
  72. environment:
  73. - DATABASE_HOST=uoj-db
  74. - DATABASE_NAME=app_uoj233
  75. - DATABASE_USER=root
  76. - DATABASE_PASSWORD=root
  77. - JUDGER_SOCKET_PORT=2333
  78. - JUDGER_SOCKET_PASSWORD=_judger_socket_password_
  79. - SALT_0=_salt_0_
  80. - SALT_1=_salt_1_
  81. - SALT_2=_salt_2_
  82. - SALT_3=_salt_3_
  83. - UOJ_PROTOCOL=http
  84. uoj-judger:
  85. image: uoj-judger:latest
  86. build:
  87. context: ./judger/
  88. dockerfile: Dockerfile
  89. container_name: uoj-judger
  90. restart: always
  91. depends_on:
  92. - uoj-web
  93. # run_program.cpp drives the sandbox with ptrace(); without SYS_PTRACE the
  94. # first submission fails with "Judgement Failed". If the sandbox still
  95. # misbehaves under docker's default seccomp profile, add:
  96. # security_opt: ["seccomp:unconfined"]
  97. cap_add:
  98. - SYS_PTRACE
  99. volumes:
  100. # main_judger reads problem data directly instead of downloading it
  101. # (judge_client skips update_problem_data for judger_name == main_judger),
  102. # so share the web's data directory with it.
  103. - ./uoj_data/web/data:/var/uoj_data_copy:ro
  104. environment:
  105. - UOJ_PROTOCOL=http
  106. - UOJ_HOST=uoj-web
  107. - JUDGER_NAME=main_judger
  108. - JUDGER_PASSWORD=_judger_password_
  109. - JUDGER_SOCKET_PORT=2333
  110. - JUDGER_SOCKET_PASSWORD=_judger_socket_password_
  111. # No ports: the web reaches this container over the compose network via the
  112. # service name (`uoj-judger`), which is also what judger_info.ip must hold.