{"id":4286,"date":"2026-04-08T07:00:00","date_gmt":"2026-04-07T22:00:00","guid":{"rendered":"https:\/\/litcoder.com\/?p=4286"},"modified":"2026-04-05T12:08:04","modified_gmt":"2026-04-05T03:08:04","slug":"openproject-docker%eb%a1%9c-%ec%84%a4%ec%b9%98%ed%95%98%ea%b8%b0","status":"publish","type":"post","link":"https:\/\/litcoder.com\/?p=4286","title":{"rendered":"OpenProject\ub97c Docker\ub85c \uc124\uce58"},"content":{"rendered":"\n<p>\ud504\ub85c\uc81d\ud2b8 \uad00\ub9ac \ub3c4\uad6c\ub85c \ub9ce\uc774 \uc0ac\uc6a9\ub418\ub294 Atlassian\uc758 JIRA\ub97c \ub300\uccb4\ud558\uae30 \uc704\ud55c \uc624\ud508\uc18c\uc2a4 \ud504\ub85c\uc81d\ud2b8\ub4e4 \uc911 \uac00\uc7a5 \uc778\uae30\uac00 \uc788\ub2e4\ub294 OpenProject\ub97c \uc124\uce58\ud574\uc11c \uc0ac\uc6a9\ud574 \ubcf4\uae30\ub85c \ud588\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Docker\ub85c \uc124\uce58\ud558\uae30 \uc900\ube44<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Clone<\/h3>\n\n\n\n<p>OpenProject\ub294 <a href=\"https:\/\/github.com\/opf\/openproject-docker-compose\" data-type=\"link\" data-id=\"https:\/\/github.com\/opf\/openproject-docker-compose\">GitHub repo<\/a>\uc5d0\uc11c tag\uac00 \uc544\ub2cc branch\uba85\uc744 stable\/&lt;version> \ud615\uc2dd\uc73c\ub85c \ub9b4\ub9ac\uc988\ud558\uace0 \uc788\ub294 \ub4ef \ud558\ub2e4. 2026\ub144 4\uc6d4 \ud604\uc7ac \uac00\uc7a5 \ucd5c\uc2e0 \ubc84\uc804\uc778 17\ubc84\uc804\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 GitHub\uc5d0\uc11c \uac00\uc838\uc628\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"dracula\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">git clone https:\/\/github.com\/opf\/openproject-docker-compose.git --branch=stable\/17 openproject\ncd openproject<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\ud658\uacbd \uc124\uc815 \ud30c\uc77c \uc218\uc815<\/h3>\n\n\n\n<p>\ub2e4\uc6b4\ub85c\ub4dc \ubc1b\uc740 \uc18c\uc2a4\uc5d0\ub294 \ud658\uacbd \uc124\uc815\ud30c\uc77c \uc608\uc81c\uc778 .env.example \ud30c\uc77c\uc774 \uc788\ub294\ub370, \uc774 \ud30c\uc77c \uc774\ub984\uc744 .env\ub85c \ubcc0\uacbd\ud558\uace0 \ud544\uc694\ud55c \uc0ac\ud56d\uc744 \uc218\uc815\ud574 \uc900\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>SECRETE_KEY_BASE<\/code>\uc5d0 \uac12\uc744 \uc548\ub0b4\ub41c \uba85\ub839\uc5b4 \uacb0\uacfc \uac12\uc73c\ub85c \ubc18\uc601, \ub2e8 64 character\n<ul class=\"wp-block-list\">\n<li><code>head \/dev\/urandom | tr -dc A-Za-z0-9 | head -c 64 ; echo<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>OPENPROJECT_HOST__NAME<\/code> \uac12\uc744 localhost\uc5d0\uc11c IP \ud639\uc740 domain\uc774\ub984\uc73c\ub85c \ubcc0\uacbd<\/li>\n\n\n\n<li><code>PORT<\/code>\uac12\uc744 \ubaa8\ub4e0 \uc811\uc18d\uc744 \ud5c8\uc6a9\ud558\ub3c4\ub85d <code>0.0.0.0:8080<\/code>\uc73c\ub85c \ubcc0\uacbd<\/li>\n\n\n\n<li><code>POSTGRES_VERSION<\/code>\uc744 <code>17<\/code>\uc5d0\uc11c <code>13<\/code>\uc73c\ub85c \ubcc0\uacbd (Ubuntu\uc5d0 \uc124\uce58\ub41c \ubc84\uc804)<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"true\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">##\n# All environment variables defined here will only apply if you pass them\n# to the OpenProject container in docker-compose.yml under x-op-app -> environment.\n# For the examples here this is already the case.\n#\n# Please refer to our documentation to see all possible variables:\n#   https:\/\/www.openproject.org\/docs\/installation-and-operations\/configuration\/environment\/\n#\nTAG=17-slim\nOPENPROJECT_HTTPS=false\n# Please override the SECRET_KEY_BASE\n# Please use a pseudo-random value for this and treat it like a password.\n# If you are on Linux you can generate a scret key with the following command\n# head \/dev\/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo ''\nSECRET_KEY_BASE=&lt;\uba85\ub839 \uc218\ud589 \uacb0\uacfc>\nOPENPROJECT_HOST__NAME=&lt;\uc11c\ubc84 IP>\nPORT=0.0.0.0:8080\nOPENPROJECT_RAILS__RELATIVE__URL__ROOT=\nIMAP_ENABLED=false\nDATABASE_URL=postgres:\/\/postgres:&lt;database \ube44\ubc00\ubc88\ud638>@db\/openproject?pool=20&amp;encoding=unicode&amp;reconnect=true\nRAILS_MIN_THREADS=4\nRAILS_MAX_THREADS=16\nPGDATA=\"\/var\/lib\/postgresql\/data\"\nOPDATA=\"\/var\/openproject\/assets\"\nCOLLABORATIVE_SERVER_URL=ws:\/\/localhost:8080\/hocuspocus\nCOLLABORATIVE_SERVER_SECRET=secret12345\nPOSTGRES_VERSION=13\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Docker \uc2e4\ud589<\/h3>\n\n\n\n<p>\ud658\uacbd \uc124\uc815\uc774 \ub05d\ub098\uba74 docker \uba85\ub839\uc5b4\ub85c \uc2e4\ud589 \uc2dc\ucf1c\uc900\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"dracula\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker compose up -d\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\uc811\uc18d\ud655\uc778<\/h3>\n\n\n\n<p>\uc774\uc81c \uc6f9\ube0c\ub77c\uc6b0\uc838\uc5d0\uc11c ip\ub098 \ub3c4\uba54\uc778 \uc774\ub984\uc744 \uc785\ub825\ud558\uace0 \uc811\uc18d\ud558\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 \ucc3d\uc774 \ub728\ub294\ub370 \uae30\ubcf8 \ub85c\uadf8\uc778 id \/ password\ub294 admin\/admin\uc774\uace0 \uc811\uc18d\ud558\uba74 \ube44\ubc00\ubc88\ud638\ub97c \uc124\uc815\ud558\ub294 \ud654\uba74\uc73c\ub85c \ub118\uc5b4\uac00\uac8c \ub41c\ub2e4.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"572\" height=\"460\" src=\"https:\/\/litcoder.com\/wp-content\/uploads\/2026\/03\/openproject17_login.png\" alt=\"\" class=\"wp-image-4288\" style=\"width:500px\" srcset=\"https:\/\/litcoder.com\/wp-content\/uploads\/2026\/03\/openproject17_login.png 572w, https:\/\/litcoder.com\/wp-content\/uploads\/2026\/03\/openproject17_login-300x241.png 300w\" sizes=\"auto, (max-width: 572px) 100vw, 572px\" \/><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">HTTPS \uc801\uc6a9<\/h2>\n\n\n\n<p>HTTPS\ub97c \uc704\ud55c \uc720\ub8cc \uc778\uc99d\uc11c\ub97c \uc0ac\uc6a9\ud558\uace0 \uc2f6\uc9c0 \uc54a\ub2e4\uba74 <a href=\"https:\/\/letsencrypt.org\/ko\/\" data-type=\"link\" data-id=\"https:\/\/letsencrypt.org\/ko\/\">Let&#8217;s encrypt<\/a>\ub97c \uace0\ub824\ud560 \ud150\ub370, \uc774 \uc11c\ube44\uc2a4\ub294 public IP\ub97c \uae30\uc900\uc73c\ub85c \uc778\uc99d\uc11c\ub97c \ubc1c\uae09\ud558\ub294\ub370 \uc81c\ud55c\uc744 \ub450\uace0 \uc788\ub2e4. \uc815\ud655\ud788\ub294 2026\ub144 \ucd08\ubd80\ud130 IP\ub97c \ub300\uc0c1\uc73c\ub85c \ubc1c\uae09\ud558\ub294 \uc778\uc99d\uc11c\ub97c \uc81c\uacf5\ud558\ub294\ub370 \uc720\ud6a8\uae30\uac04\uc774 6\uc77c\ub85c \ub9e4\uc6b0 \uc9e7\ub2e4.<\/p>\n\n\n\n<p>Renew script\uc5d0 \uc758\ud574 \uc5c5\ub370\uc774\ud2b8 \ub418\uae30\ub294 \ud558\uaca0\uc9c0\ub9cc, \uc7a5\uae30\uc801\uc73c\ub85c \uc0ac\uc6a9\ud560 \uac83 \uc774\ub77c\uba74 \ub3c4\uba54\uc778\uc744 \uc0ac\uc6a9\ud558\ub294\uac8c \uc5ec\ub7ec\ubaa8\ub85c \ub0ab\ub2e4. \ub300\ubd80\ubd84\uc758 \ub3c4\uba54\uc778 \ub4f1\ub85d \uae30\uad00\uc5d0\uc11c\ub294 \uae30\uc874 \ub3c4\uba54\uc778\uc774 \uc788\ub2e4\uba74 \ucd94\uac00 \ube44\uc6a9 \uc5c6\uc774 \uc11c\ube0c \ub3c4\uba54\uc778 \ub4f1\ub85d\uc774 \uac00\ub2a5\ud558\ub3c4\ub85d \ud558\uace0 \uc788\uc73c\ub2c8 \uc774 \uac83\uc744 \ud65c\uc6a9\ud558\ub294 \uac83\ub3c4 \uc88b\uc744\uac83 \uac19\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">.env \ubcc0\uacbd<\/h3>\n\n\n\n<p>\uc11c\ube0c \ub3c4\uba54\uc778\uacfc IP\ub97c \uc5f0\uacb0\ud55c \ud6c4\uc5d0\ub294 .env \ud30c\uc77c\ub3c4 \uc870\uae08 \ubcc0\uacbd\ud574 \uc8fc\uc5b4\uc57c \ud55c\ub2e4. \ub2e4\ub978 \uc124\uc815\ub4e4\uc744 \uc720\uc9c0\ud558\uace0 \ub2e4\uc74c\uc758 \uc138\uac00\uc9c0 \uc124\uc815\uc744 \ubcc0\uacbd\ud574 \uc900\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">...\nOPENPROJECT_HTTPS=true\n...\nOPENPROJECT_HOST__NAME=&lt;\uc11c\ube0c \ub3c4\uba54\uc778>\nPORT=8080\n...<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>OPENPROJECT_HTTPS\ub97c true\ub85c \uc124\uc815<\/li>\n\n\n\n<li>OPENPROJECT_HOST__NAME\uc744 \uc11c\ube0c\ub3c4\uba54\uc778\uc73c\ub85c \uc124\uc815<\/li>\n\n\n\n<li>PORT\ub97c \ud3ec\ud2b8\ubc88\ud638\ub9cc 8080\uc73c\ub85c \uc124\uc815<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">docker-compose.yml \ubcc0\uacbd<\/h3>\n\n\n\n<p><code>proxy<\/code> section\uc5d0 <code>ports<\/code> \ubd80\ubd84\uc5d0 80\ubc88\uacfc \ud568\uaed8 https\ub97c \uc704\ud55c 443\ubc88\uc744 \ucd94\uac00\ud574 \uc900\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">  proxy:\n    build:\n      context: .\/proxy\n      args:\n        APP_HOST: web\n    image: openproject\/proxy\n    &lt;&lt;: *restart_policy\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n    depends_on:\n      - web\n    networks:\n      - frontend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Caddyfile.template \ubcc0\uacbd<\/h3>\n\n\n\n<p>\uc18c\uc2a4\ucf54\ub4dc\uc640 \ud568\uaed8 \uc624\ub294 <code>Caddyfile.template<\/code>\uc740 \uc608\uc81c \ud30c\uc77c \uc778 \uc904 \uc54c\uace0 \ubcf5\uc0ac\ud574\uc11c <code>Caddyfile<\/code>\ub85c \uc791\uc131\ud588\ub2e4\uac00  \ud55c\ucc38\uc744 \ud574\ub9f8\ub294\ub370 <code>proxy\/Caddyfile.template <\/code>\ud30c\uc77c\uc744 \uc9c1\uc811 \ucc38\uc870\ud558\uae30 \ub54c\ubb38\uc5d0 \ud30c\uc77c\uba85\uc744 \ubcc0\uacbd\ud558\uc9c0 \uc54a\uace0 \uc9c1\uc811 \uc218\uc815\ud574 \uc8fc\uc5b4\uc57c \ud55c\ub2e4. \ub2e4\ub978 \uc124\uc815\uc744\ub2e4 \ub0a0\ub9ac\uace0 \uc544\ub798\uc758 \uc138 \uc904\ub9cc \ub0a8\uacbc\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{$OPENPROJECT_HOST__NAME} {\n    reverse_proxy web:8080\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">proxy docker \uc7ac\ube4c\ub4dc \ubc0f \uc2e4\ud589<\/h3>\n\n\n\n<p>\ubc29\ud654\ubcbd\uc774 80\ubc88\uacfc 443 \ud3ec\ud2b8\ub97c \uc5f4\uc5b4 \uc8fc\ub294\uc9c0 \ub2e4\uc2dc\ud55c\ubc88 \ud655\uc778\ud558\uace0,<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sudo ufw allow 80\/tcp\nsudo ufw allow 443\/tcp\nsudo ufw reload<\/pre>\n\n\n\n<p>proxy docker\ub97c \ub2e4\uc2dc \ube4c\ub4dc \ud558\uace0 \uc2e4\ud589 \ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker compose stop proxy\ndocker compose build --no-cache proxy\ndocker compose up -d proxy\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\uc774\uba54\uc77c \uc124\uc815<\/h2>\n\n\n\n<p>OpenProject\uc5d0\uc11c \ubcc0\uacbd\ub418\ub294 notification\uc744 \uc774\uba54\uc77c\ub85c \uc804\uc1a1\ubc1b\ub3c4\ub85d \ud558\uae30 \uc704\ud574\uc11c\ub294 \uba54\uc77c \uc124\uc815\uc744 \ud574\uc57c \ud558\ub294\ub370, <code>Postfix<\/code>\ub85c \ub85c\uceec\uc5d0 SMTP \uc11c\ubc84 \uc124\uce58\ub97c \uc2dc\ub3c4 \ud588\ub2e4\uac00 \uc0dd\uac01\ubcf4\ub2e4 \ubcf5\uc7a1\ud558\uace0 \ubc88\uac70\ub85c\uc6b4 \uc2a4\ud338 \ud544\ud130 \ud53c\ud558\ub294 \uc808\ucc28\ub4e4 \ub54c\ubb38\uc5d0 \uacb0\uad6d PTR(reverse DNS)\ub97c \uc124\uc815\ud558\ub294 \uc988\uc74c\uc5d0\uc11c \ud3ec\uae30\ud558\uace0 \ub9d0\uc558\ub2e4.<\/p>\n\n\n\n<p><a href=\"https:\/\/aws.amazon.com\/ko\/ses\/\" data-type=\"link\" data-id=\"https:\/\/aws.amazon.com\/ko\/ses\/\">AWS\uc758 SES<\/a>\uac19\uc740 \uba54\uc77c \uc11c\ube44\uc2a4\ub294 \ubcf5\uc7a1\ud55c \uc124\uc815 \uc5c6\uc774\ub3c4 \ub3d9\uc791 \ud560 \uc218 \uc788\uc9c0\ub9cc \uc804\uc1a1\ub7c9\uc744 \uc0dd\uac01\ud574\ubcf4\ub2c8 \ud55c\ub2ec\uc5d0 \ub300\ub7b5 5\ucc9c\uc6d0 \uc815\ub3c4\uac00 \ub098\uc62c\uac83 \uac19\uc558\ub2e4.<\/p>\n\n\n\n<p>\uc774 \ub9c8\uc800\ub3c4 \uc544\ub07c\ub824\uace0 Gmail\uc758 SMTP \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub3c4\ub85d \ub4f1\ub85d\ud574 \uc8fc\uc5c8\ub2e4. \uc778\uc99d\uc744 \uc704\ud574\uc11c\ub294 &#8220;\uc571 \ube44\ubc00\ubc88\ud638&#8221;\ub97c \uc0dd\uc131\ud574\uc11c \ud658\uacbd\uc124\uc815 \ud30c\uc77c\uc5d0 \ub123\uc5b4 \uc8fc\uc5b4\uc57c \ud55c\ub2e4.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"944\" src=\"https:\/\/litcoder.com\/wp-content\/uploads\/2026\/03\/google_account_app_password-1024x944.png\" alt=\"\" class=\"wp-image-4294\" style=\"width:500px\" srcset=\"https:\/\/litcoder.com\/wp-content\/uploads\/2026\/03\/google_account_app_password-1024x944.png 1024w, https:\/\/litcoder.com\/wp-content\/uploads\/2026\/03\/google_account_app_password-300x277.png 300w, https:\/\/litcoder.com\/wp-content\/uploads\/2026\/03\/google_account_app_password-768x708.png 768w, https:\/\/litcoder.com\/wp-content\/uploads\/2026\/03\/google_account_app_password-624x576.png 624w, https:\/\/litcoder.com\/wp-content\/uploads\/2026\/03\/google_account_app_password.png 1494w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<p>\ub2e4\ub9cc \uc774 \ub54c\ub294 \uba54\uc77c\uc744 \uc218\uc2e0\ud558\ub294 \uc218\uc2e0\uc790\uac00 \ud68c\uc0ac \uc2dc\uc2a4\ud15c\uc73c\ub85c \ubd80\ud130\uac00 \uc544\ub2cc Gmail\uc5d0 \ub4f1\ub85d\ub41c \ub0b4 \uac1c\uc778 \uacc4\uc815\uc73c\ub85c \ubd80\ud130 noti\ub97c \ubc1b\uac8c \ub41c\ub2e4\ub294 \uc0ac\uc18c\ud55c \ub2e8\uc810\uc774 \ud558\ub098 \uc788\ub2e4.<\/p>\n\n\n\n<p>\ubfd0\ub9cc \uc544\ub2c8\ub77c \uc77c\uc77c \uc0ac\uc6a9\ub7c9\uc5d0 \uc81c\ud55c\uc774 \uc788\uc73c\ub2c8 \ud504\ub85c\uc81d\ud2b8 \uaddc\ubaa8\uac00 \uce74\uc11c \uc774\uba54\uc77c \uc804\uc1a1\ub7c9\uc774 \ub9ce\uc740 \uacbd\uc6b0\ub77c\uba74 \uc55e\uc11c \ub9d0\ud55c AWS SES \uac19\uc740 \ub2e4\ub978 \uba54\uc77c \uc11c\ube44\uc2a4\ub4e4\uc744 \uace0\ub824\ud574 \ubcf4\ub294\uac8c \uc88b\uaca0\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud504\ub85c\uc81d\ud2b8 \uad00\ub9ac \ub3c4\uad6c\ub85c \ub9ce\uc774 \uc0ac\uc6a9\ub418\ub294 Atlassian\uc758 JIRA\ub97c \ub300\uccb4\ud558\uae30 \uc704\ud55c \uc624\ud508\uc18c\uc2a4 \ud504\ub85c\uc81d\ud2b8\ub4e4 \uc911 \uac00\uc7a5 \uc778\uae30\uac00 \uc788\ub2e4\ub294 OpenProject\ub97c \uc124\uce58\ud574\uc11c \uc0ac\uc6a9\ud574 \ubcf4\uae30\ub85c \ud588\ub2e4. Docker\ub85c \uc124\uce58\ud558\uae30 \uc900\ube44 Clone OpenProject\ub294 GitHub repo\uc5d0\uc11c tag\uac00 \uc544\ub2cc branch\uba85\uc744 stable\/&lt;version> \ud615\uc2dd\uc73c\ub85c \ub9b4\ub9ac\uc988\ud558\uace0 \uc788\ub294 \ub4ef \ud558\ub2e4. 2026\ub144 4\uc6d4 \ud604\uc7ac \uac00\uc7a5 \ucd5c\uc2e0 \ubc84\uc804\uc778 17\ubc84\uc804\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 GitHub\uc5d0\uc11c \uac00\uc838\uc628\ub2e4. \ud658\uacbd \uc124\uc815 \ud30c\uc77c \uc218\uc815 \ub2e4\uc6b4\ub85c\ub4dc \ubc1b\uc740 \uc18c\uc2a4\uc5d0\ub294 \ud658\uacbd [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,6],"tags":[36,426],"class_list":["post-4286","post","type-post","status-publish","format-standard","hentry","category-linux","category-tools","tag-docker","tag-openproject"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/posts\/4286","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/litcoder.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4286"}],"version-history":[{"count":9,"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/posts\/4286\/revisions"}],"predecessor-version":[{"id":4315,"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/posts\/4286\/revisions\/4315"}],"wp:attachment":[{"href":"https:\/\/litcoder.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/litcoder.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/litcoder.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}