docker-compose.yml 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. # uploads and .UOJSetupDone -- must persist across recreates
  57. - ./uoj_data/web/data:/var/uoj_data
  58. # submissions / pastes / tmp / judge_client.zip
  59. - ./uoj_data/web/storage:/opt/uoj/web/app/storage
  60. # generated on first boot from the environment below; kept on the host so
  61. # that rebuilding the image does not lose it
  62. - type: bind
  63. source: ./.config.local.php
  64. target: /opt/uoj/web/app/.config.php
  65. ports:
  66. - "80:80"
  67. # 3690 was published by the original file but nothing listens on it.
  68. # - "3690:3690"
  69. environment:
  70. - DATABASE_HOST=uoj-db
  71. - DATABASE_NAME=app_uoj233
  72. - DATABASE_USER=root
  73. - DATABASE_PASSWORD=root
  74. - JUDGER_SOCKET_PORT=2333
  75. - JUDGER_SOCKET_PASSWORD=_judger_socket_password_
  76. - SALT_0=_salt_0_
  77. - SALT_1=_salt_1_
  78. - SALT_2=_salt_2_
  79. - SALT_3=_salt_3_
  80. - UOJ_PROTOCOL=http
  81. uoj-judger:
  82. image: uoj-judger:latest
  83. build:
  84. context: ./judger/
  85. dockerfile: Dockerfile
  86. container_name: uoj-judger
  87. restart: always
  88. depends_on:
  89. - uoj-web
  90. # run_program.cpp drives the sandbox with ptrace(); without SYS_PTRACE the
  91. # first submission fails with "Judgement Failed". If the sandbox still
  92. # misbehaves under docker's default seccomp profile, add:
  93. # security_opt: ["seccomp:unconfined"]
  94. cap_add:
  95. - SYS_PTRACE
  96. volumes:
  97. # main_judger reads problem data directly instead of downloading it
  98. # (judge_client skips update_problem_data for judger_name == main_judger),
  99. # so share the web's data directory with it.
  100. - ./uoj_data/web/data:/var/uoj_data_copy:ro
  101. environment:
  102. - UOJ_PROTOCOL=http
  103. - UOJ_HOST=uoj-web
  104. - JUDGER_NAME=main_judger
  105. - JUDGER_PASSWORD=_judger_password_
  106. - JUDGER_SOCKET_PORT=2333
  107. - JUDGER_SOCKET_PASSWORD=_judger_socket_password_
  108. # No ports: the web reaches this container over the compose network via the
  109. # service name (`uoj-judger`), which is also what judger_info.ip must hold.