{"id":34509,"date":"2023-01-09T03:54:59","date_gmt":"2023-05-25T10:32:24","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/"},"modified":"2024-04-29T09:10:21","modified_gmt":"2024-04-29T01:10:21","slug":"%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/","title":{"rendered":"\u7528Raspberry Pi 4\u7684Docker\u5c06OpenProject\u8fd0\u884c\u8d77\u6765"},"content":{"rendered":"<p>\u4f3c\u4e4e\u9700\u8981\u66f4\u52a0\u52aa\u529b\u624d\u80fd\u652f\u6301\u5efa\u7b51\u4e1a\u754c\u7684\u529f\u80fd\u3002<br \/>\n\u203b\u5982COLLADA2GLTF\u6216IFCconvert\u4e4b\u7c7b\u7684\u5de5\u5177\u3002\u60f3\u8981\u4f7f\u7528\u7684\u4eba\u8bf7\u7ee7\u7eed\u52aa\u529b\u5427&#8230;\u867d\u7136\u6784\u5efa\u662f\u6210\u529f\u7684\u3002\u4e0d\u8fc7\u592a\u957f\u5c31\u4e0d\u5199\u4e86\u3002<\/p>\n<h2>\u80cc\u666f<\/h2>\n<p>\u6700\u8fd1\u6211\u5c1d\u8bd5\u5728Redmine\u4e0a\u4f7f\u7528GTD\uff0c\u5df2\u7ecf\u8fd0\u8425\u4e86\u5927\u7ea6\u4e24\u5468\u3002\u7136\u800c\uff0c\u6211\u53d1\u73b0\u4e3a\u4e86\u8ba9\u5b83\u66f4\u6613\u7528\uff0c\u9700\u8981\u5b89\u88c5\u8fd110\u4e2a\u63d2\u4ef6\uff1b\u800c\u4e14\u6709\u5f88\u591a\u5730\u65b9\u4e0d\u591f\u7075\u6d3b\u3002\u7b80\u5355\u641c\u7d22\u540e\uff0c\u6211\u53d1\u73b0OpenProject\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u62e5\u6709\u6211\u9700\u8981\u7684\u529f\u80fd\u3002\u56e0\u6b64\uff0c\u6211\u51b3\u5b9a\u5c1d\u8bd5\u5728\u5b98\u65b9\u4e0d\u652f\u6301\u7684arm64\u67b6\u6784\u4e0a\u4f7f\u7528Docker\u6765\u8fd0\u884cOpenProject\u3002\u7ed3\u679c\u57fa\u672c\u4e0a\u6210\u529f\u4e86\uff0c\u6240\u4ee5\u6211\u51b3\u5b9a\u4e3a\u4e86\u5168\u4e16\u754c\u7684\u67d0\u4e2a\u4eba\u800c\u53d1\u5e03\u8fd9\u7bc7\u6587\u7ae0\u3002<\/p>\n<h2>\u73af\u5883\u5efa\u8bbe<\/h2>\n<p>\u5927\u81f4\u7684\u6784\u5efa\u65b9\u6cd5\u5982\u4e0b\uff1a<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u516c\u5f0f\u306e Dockerfile \u3092\u5143\u306b arm64 \u3067\u52d5\u304f\u3088\u3046\u306b\u5909\u66f4\u3092\u52a0\u3048\u308b<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">All in One \u30b3\u30f3\u30c6\u30ca\u3067\u306f\u306a\u304f\u3001docker-compose \u3092\u4f7f\u7528\u3059\u308b\u30d0\u30fc\u30b8\u30e7\u30f3\u306e arm64 \u7248\u3092\u76ee\u6307\u3059<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">https \u3092\u6709\u52b9\u306b\u3059\u308b\u305f\u3081\u306b letsencrypt \u3092\u5229\u7528\u3059\u308b\u81ea\u4f5c\u306e proxy \u3092\u7acb\u3066\u308b<\/ul>\n<h3>\u9996\u5148\uff0c\u6211\u4eec\u7684\u76ee\u6807\u662f\u4f7fAll in One\u5bb9\u5668\u8fd0\u884c\u3002<\/h3>\n<h4>\u514b\u9686\u516c\u5f0f\u7684GitHub\u5b58\u50a8\u5e93<\/h4>\n<pre class=\"post-pre\"><code>git clone https:\/\/github.com\/opf\/openproject.git\r\n<span class=\"c\"># \u771f\u9762\u76ee\u306a\u4eba\u306f\u3053\u306e\u5f8c\u3001\u30bf\u30b0\u3092\u30c1\u30a7\u30c3\u30af\u30a2\u30a6\u30c8\u3057\u3066\u306d\u3002\u79c1\u306f\u9762\u5012\u306a\u306e\u3067\u30c7\u30d5\u30a9\u30eb\u30c8\u30d6\u30e9\u30f3\u30c1\u3067\u4f5c\u696d\u3057\u307e\u3059\u3002<\/span>\r\n<\/code><\/pre>\n<h4>\u4fee\u6539docker\/prod\/Dockerfile<\/h4>\n<p>\u5c06gosu\u66f4\u6539\u4e3aarm64\u7248\u672c\u4f7f\u7528\u3002<br \/>\n#\u514b\u9686\u5e76\u4fee\u6539\u6240\u4e0b\u8f7d\u7684\u5185\u5bb9\uff08\u5305\u62ec\u4e2d\u95f4\u7684COPY . .\uff09<br \/>\n#\u5982\u679c\u9700\u8981\u91cd\u65b0\u5f00\u59cb\uff0c\u4e5f\u53ef\u4ee5\u5728\u4e3b\u673a\u4e0a\u4e0b\u8f7d\uff0c\u4f46\u5bb9\u6613\u5fd8\u8bb0\u91cd\u65b0\u6267\u884c\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">FROM<\/span><span class=\"s\"> ruby:2.7.2-buster<\/span>\r\n<span class=\"k\">MAINTAINER<\/span><span class=\"s\"> operations@openproject.com<\/span>\r\n\r\n<span class=\"c\"># Allow platform-specific additions. Valid values are: on-prem,saas,bahn<\/span>\r\n<span class=\"k\">ARG<\/span><span class=\"s\"> PLATFORM=on-prem<\/span>\r\n<span class=\"c\"># Use OAuth token in case private gems need to be fetched<\/span>\r\n<span class=\"k\">ARG<\/span><span class=\"s\"> GITHUB_OAUTH_TOKEN<\/span>\r\n<span class=\"k\">ARG<\/span><span class=\"s\"> DEBIAN_FRONTEND=noninteractive<\/span>\r\n\r\n<span class=\"k\">ARG<\/span><span class=\"s\"> PGLOADER_BINARY_DOWNLOAD_URL=https:\/\/openproject-docker-public.s3-eu-west-1.amazonaws.com\/pgloader\/bin\/pgloader-ccl<\/span>\r\n\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> NODE_VERSION=\"12.18.3\"<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> BUNDLER_VERSION=\"2.1.4\"<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> BUNDLE_PATH__SYSTEM=false<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> APP_USER=app<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> APP_PATH=\/app<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> APP_DATA_PATH=\/var\/openproject\/assets<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> APP_DATA_PATH_LEGACY=\/var\/db\/openproject<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PGDATA=\/var\/openproject\/pgdata<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PGDATA_LEGACY=\/var\/lib\/postgresql\/9.6\/main<\/span>\r\n\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> DATABASE_URL=postgres:\/\/openproject:openproject@127.0.0.1\/openproject<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> RAILS_ENV=production<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> RAILS_CACHE_STORE=memcache<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> RAILS_GROUPS=production<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> RAILS_LOG_TO_STDOUT=1<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> RAILS_SERVE_STATIC_FILES=1<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> OPENPROJECT_INSTALLATION__TYPE=docker<\/span>\r\n<span class=\"c\"># Valid values are: standard,bim<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> OPENPROJECT_EDITION=standard<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> NEW_RELIC_AGENT_ENABLED=false<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> ATTACHMENTS_STORAGE_PATH=$APP_DATA_PATH\/files<\/span>\r\n<span class=\"c\"># Set a default key base, ensure to provide a secure value in production environments!<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> SECRET_KEY_BASE=OVERWRITE_ME<\/span>\r\n\r\n<span class=\"k\">RUN <\/span>curl <span class=\"k\">${<\/span><span class=\"nv\">PGLOADER_BINARY_DOWNLOAD_URL<\/span><span class=\"k\">}<\/span> <span class=\"o\">&gt;<\/span> \/usr\/local\/bin\/pgloader-ccl <span class=\"o\">&amp;&amp;<\/span> <span class=\"nb\">chmod<\/span> +x \/usr\/local\/bin\/pgloader-ccl\r\n\r\n<span class=\"k\">WORKDIR<\/span><span class=\"s\"> $APP_PATH<\/span>\r\n\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> docker\/prod\/setup .\/docker\/prod\/setup<\/span>\r\n<span class=\"k\">RUN <\/span>.\/docker\/prod\/setup\/preinstall.sh\r\n\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> Gemfile .\/Gemfile<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> Gemfile.* .\/<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> modules .\/modules<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> vendor .\/vendor<\/span>\r\n<span class=\"c\"># some gemspec files of plugins require files in there, notably OpenProject::Version<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> lib .\/lib<\/span>\r\n\r\n<span class=\"k\">RUN <\/span>bundle <span class=\"nb\">install<\/span> <span class=\"nt\">--quiet<\/span> <span class=\"nt\">--deployment<\/span> <span class=\"nt\">--path<\/span> vendor\/bundle <span class=\"nt\">--no-cache<\/span> <span class=\"se\">\\\r\n<\/span>  <span class=\"nt\">--with<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"<\/span><span class=\"nv\">$RAILS_GROUPS<\/span><span class=\"s2\">\"<\/span> <span class=\"nt\">--without<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"test development\"<\/span> <span class=\"nt\">--jobs<\/span><span class=\"o\">=<\/span>8 <span class=\"nt\">--retry<\/span><span class=\"o\">=<\/span>3 <span class=\"o\">&amp;&amp;<\/span> <span class=\"se\">\\\r\n<\/span>  <span class=\"nb\">rm<\/span> <span class=\"nt\">-rf<\/span> vendor\/bundle\/ruby\/<span class=\"k\">*<\/span>\/cache <span class=\"o\">&amp;&amp;<\/span> <span class=\"nb\">rm<\/span> <span class=\"nt\">-rf<\/span> vendor\/bundle\/ruby\/<span class=\"k\">*<\/span>\/gems\/<span class=\"k\">*<\/span>\/spec <span class=\"o\">&amp;&amp;<\/span> <span class=\"nb\">rm<\/span> <span class=\"nt\">-rf<\/span> vendor\/bundle\/ruby\/<span class=\"k\">*<\/span>\/gems\/<span class=\"k\">*<\/span>\/test\r\n\r\n<span class=\"c\"># Finally, copy over the whole thing<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> . .<\/span>\r\n\r\n<span class=\"c\"># Replace gosu with gosu-arm64<\/span>\r\n<span class=\"k\">RUN <\/span>wget <span class=\"nt\">-O<\/span> .\/docker\/prod\/gosu https:\/\/github.com\/tianon\/gosu\/releases\/download\/1.12\/gosu-arm64\r\n\r\n<span class=\"k\">RUN <\/span>.\/docker\/prod\/setup\/postinstall.sh\r\n\r\n<span class=\"c\"># Expose ports for apache and postgres<\/span>\r\n<span class=\"k\">EXPOSE<\/span><span class=\"s\"> 8080 5432<\/span>\r\n\r\n<span class=\"c\"># Expose the postgres data directory and OpenProject data directory as volumes<\/span>\r\n<span class=\"k\">VOLUME<\/span><span class=\"s\"> [\"$PGDATA\", \"$APP_DATA_PATH\"]<\/span>\r\n\r\n<span class=\"c\"># Set a custom entrypoint to allow for privilege dropping and one-off commands<\/span>\r\n<span class=\"k\">ENTRYPOINT<\/span><span class=\"s\"> [\".\/docker\/prod\/entrypoint.sh\"]<\/span>\r\n\r\n<span class=\"c\"># Set default command to launch the all-in-one configuration supervised by supervisord<\/span>\r\n<span class=\"k\">CMD<\/span><span class=\"s\"> [\".\/docker\/prod\/supervisord\"]<\/span>\r\n<\/code><\/pre>\n<h4>\u4fee\u6539docker\/prod\/setup\/preinstall-common.sh<\/h4>\n<p>\u5c06\u6307\u5b9ax64\u7248\u672c\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u90e8\u5206\u66f4\u6539\u4e3a\u4f7f\u7528arm64\u7248\u672c\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\">#!\/bin\/bash<\/span>\r\n\r\n<span class=\"nb\">set<\/span> <span class=\"nt\">-e<\/span>\r\n<span class=\"nb\">set<\/span> <span class=\"nt\">-o<\/span> pipefail\r\n\r\n<span class=\"c\"># install node + npm<\/span>\r\ncurl <span class=\"nt\">-s<\/span> https:\/\/nodejs.org\/dist\/v<span class=\"k\">${<\/span><span class=\"nv\">NODE_VERSION<\/span><span class=\"k\">}<\/span>\/node-v<span class=\"k\">${<\/span><span class=\"nv\">NODE_VERSION<\/span><span class=\"k\">}<\/span><span class=\"nt\">-linux-arm64<\/span>.tar.gz | <span class=\"nb\">tar <\/span>xzf - <span class=\"nt\">-C<\/span> \/usr\/local <span class=\"nt\">--strip-components<\/span><span class=\"o\">=<\/span>1\r\n\r\nwget <span class=\"nt\">--quiet<\/span> <span class=\"nt\">-O-<\/span> https:\/\/www.postgresql.org\/media\/keys\/ACCC4CF8.asc | apt-key add -\r\n<span class=\"nb\">echo<\/span> <span class=\"s2\">\"deb http:\/\/apt.postgresql.org\/pub\/repos\/apt buster-pgdg main\"<\/span> <span class=\"o\">&gt;<\/span> \/etc\/apt\/sources.list.d\/pgdg.list\r\n\r\napt-get update <span class=\"nt\">-qq<\/span>\r\napt-get <span class=\"nb\">install<\/span> <span class=\"nt\">-y<\/span> <span class=\"se\">\\<\/span>\r\n    apt-transport-https <span class=\"se\">\\<\/span>\r\n    pandoc <span class=\"se\">\\<\/span>\r\n    poppler-utils <span class=\"se\">\\<\/span>\r\n    unrtf <span class=\"se\">\\<\/span>\r\n    tesseract-ocr <span class=\"se\">\\<\/span>\r\n    catdoc <span class=\"se\">\\<\/span>\r\n    postgresql-9.6 <span class=\"se\">\\<\/span>\r\n    postgresql-client-9.6 <span class=\"se\">\\<\/span>\r\n    imagemagick\r\n\r\n<span class=\"nb\">rm<\/span> <span class=\"nt\">-rf<\/span> <span class=\"s2\">\"<\/span><span class=\"nv\">$PGDATA_LEGACY<\/span><span class=\"s2\">\"<\/span>\r\n\r\n<span class=\"c\"># Specifics for BIM edition<\/span>\r\ncurl <span class=\"nt\">-SL<\/span> <span class=\"nt\">-o<\/span> dotnet.tar.gz https:\/\/dotnetcli.blob.core.windows.net\/dotnet\/Runtime\/master\/dotnet-runtime-latest-linux-arm64.tar.gz\r\n<span class=\"nb\">mkdir<\/span> <span class=\"nt\">-p<\/span> \/usr\/share\/dotnet\r\n<span class=\"nb\">tar<\/span> <span class=\"nt\">-zxf<\/span> dotnet.tar.gz <span class=\"nt\">-C<\/span> \/usr\/share\/dotnet\r\n<span class=\"nb\">ln<\/span> <span class=\"nt\">-s<\/span> \/usr\/share\/dotnet\/dotnet \/usr\/bin\/dotnet\r\n\r\n<span class=\"nv\">tmpdir<\/span><span class=\"o\">=<\/span><span class=\"si\">$(<\/span><span class=\"nb\">mktemp<\/span> <span class=\"nt\">-d<\/span><span class=\"si\">)<\/span>\r\n<span class=\"nb\">cd<\/span> <span class=\"nv\">$tmpdir<\/span>\r\n\r\n<span class=\"c\"># Install XKT converter<\/span>\r\nnpm <span class=\"nb\">install<\/span> @xeokit\/xeokit-gltf-to-xkt@0.0.3 <span class=\"nt\">-g<\/span>\r\n\r\n<span class=\"c\"># Install COLLADA2GLTF<\/span>\r\nwget <span class=\"nt\">--quiet<\/span> https:\/\/github.com\/KhronosGroup\/COLLADA2GLTF\/releases\/download\/v2.1.5\/COLLADA2GLTF-v2.1.5-linux.zip\r\nunzip <span class=\"nt\">-q<\/span> COLLADA2GLTF-v2.1.5-linux.zip\r\n<span class=\"nb\">mv <\/span>COLLADA2GLTF-bin <span class=\"s2\">\"\/usr\/local\/bin\/COLLADA2GLTF\"<\/span>\r\n\r\n<span class=\"c\"># IFCconvert<\/span>\r\nwget <span class=\"nt\">--quiet<\/span> https:\/\/s3.amazonaws.com\/ifcopenshell-builds\/IfcConvert-v0.6.0-9bcd932-linux64.zip\r\nunzip <span class=\"nt\">-q<\/span> IfcConvert-v0.6.0-9bcd932-linux64.zip\r\n<span class=\"nb\">mv <\/span>IfcConvert <span class=\"s2\">\"\/usr\/local\/bin\/IfcConvert\"<\/span>\r\n\r\nwget <span class=\"nt\">--quiet<\/span> https:\/\/github.com\/bimspot\/xeokit-metadata\/releases\/download\/1.0.0\/xeokit-metadata-linux-arm.tar.gz\r\n<span class=\"nb\">tar<\/span> <span class=\"nt\">-zxvf<\/span> xeokit-metadata-linux-arm.tar.gz\r\n<span class=\"nb\">chmod<\/span> +x xeokit-metadata-linux-arm\/xeokit-metadata\r\n<span class=\"nb\">cp<\/span> <span class=\"nt\">-r<\/span> xeokit-metadata-linux-arm\/ <span class=\"s2\">\"\/usr\/lib\/xeokit-metadata\"<\/span>\r\n<span class=\"nb\">ln<\/span> <span class=\"nt\">-s<\/span> \/usr\/lib\/xeokit-metadata\/xeokit-metadata \/usr\/local\/bin\/xeokit-metadata\r\n\r\n<span class=\"nb\">cd<\/span> \/\r\n<span class=\"nb\">rm<\/span> <span class=\"nt\">-rf<\/span> <span class=\"nv\">$tmpdir<\/span>\r\n\r\ngem <span class=\"nb\">install <\/span>bundler <span class=\"nt\">--version<\/span> <span class=\"s2\">\"<\/span><span class=\"nv\">$BUNDLER_VERSION<\/span><span class=\"s2\">\"<\/span> <span class=\"nt\">--no-document<\/span>\r\n\r\nuseradd <span class=\"nt\">-d<\/span> \/home\/<span class=\"nv\">$APP_USER<\/span> <span class=\"nt\">-m<\/span> <span class=\"nv\">$APP_USER<\/span>\r\n\r\n<\/code><\/pre>\n<h4>\u5efa\u8bbe\uff08\u5927\u7ea6\u9700\u898120\u5206\u949f\uff09<\/h4>\n<pre class=\"post-pre\"><code>docker build <span class=\"nt\">-t<\/span> openproject\/community:11-arm64 <span class=\"nt\">-f<\/span> docker\/prod\/Dockerfile .\/\r\n<\/code><\/pre>\n<h4>\u8fdb\u884c\u70df\u96fe\u6d4b\u8bd5<\/h4>\n<pre class=\"post-pre\"><code>docker run <span class=\"nt\">--rm<\/span> <span class=\"nt\">-it<\/span> <span class=\"nt\">-p<\/span> 8080:80 <span class=\"nt\">-e<\/span> <span class=\"nv\">SECRET_KEY_BASE<\/span><span class=\"o\">=<\/span>secret openproject\/community:11-arm64\r\n<\/code><\/pre>\n<h3>\u5728\u4f7f\u7528docker-compose\u8fd0\u884c<\/h3>\n<h4>\u83b7\u53d6\u516c\u5f0f\u7684 docker-compose.yml<\/h4>\n<pre class=\"post-pre\"><code>git clone https:\/\/github.com\/opf\/openproject-deploy <span class=\"nt\">--depth<\/span><span class=\"o\">=<\/span>1 <span class=\"nt\">--branch<\/span><span class=\"o\">=<\/span>stable\/11 openproject\r\n<span class=\"nb\">cd <\/span>openproject\/compose\r\nnano docker-compose.yml\r\n<\/code><\/pre>\n<h4>\u4fee\u6539docker-compose.yml\u6587\u4ef6<\/h4>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u30b3\u30f3\u30c6\u30ca\u30cd\u30fc\u30e0 app \u306e\u30a4\u30e1\u30fc\u30b8\u3092\u81ea\u4f5c\u306e\u30a4\u30e1\u30fc\u30b8\u306b\u5909\u66f4\u3059\u308b<\/ul>\n<\/li>\n<\/ul>\n<p>volumes \u306e\u30db\u30b9\u30c8\u5074\u306e\u30de\u30a6\u30f3\u30c8\u30dd\u30a4\u30f3\u30c8\u3092\u30ab\u30ec\u30f3\u30c8\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u3059\u308b<\/p>\n<pre class=\"post-pre\"><code><span class=\"na\">version<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">3.7\"<\/span>\r\n\r\n<span class=\"na\">networks<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">frontend<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">backend<\/span><span class=\"pi\">:<\/span>\r\n\r\n<span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">pgdata<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">opdata<\/span><span class=\"pi\">:<\/span>\r\n\r\n<span class=\"na\">x-op-restart-policy<\/span><span class=\"pi\">:<\/span> <span class=\"nl\">&amp;restart_policy<\/span>\r\n  <span class=\"na\">restart<\/span><span class=\"pi\">:<\/span> <span class=\"s\">unless-stopped<\/span>\r\n<span class=\"na\">x-op-image<\/span><span class=\"pi\">:<\/span> <span class=\"nl\">&amp;image<\/span>\r\n  <span class=\"na\">image<\/span><span class=\"pi\">:<\/span> <span class=\"s\">openproject\/community:11-arm64<\/span>\r\n<span class=\"na\">x-op-app<\/span><span class=\"pi\">:<\/span> <span class=\"nl\">&amp;app<\/span>\r\n  <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*image<\/span>\r\n  <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*restart_policy<\/span>\r\n  <span class=\"na\">environment<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">RAILS_CACHE_STORE<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">memcache\"<\/span>\r\n    <span class=\"na\">OPENPROJECT_CACHE__MEMCACHE__SERVER<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">cache:11211\"<\/span>\r\n    <span class=\"na\">OPENPROJECT_RAILS__RELATIVE__URL__ROOT<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}\"<\/span>\r\n    <span class=\"na\">DATABASE_URL<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">postgres:\/\/postgres:p4ssw0rd@db\/openproject\"<\/span>\r\n    <span class=\"na\">USE_PUMA<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">true\"<\/span>\r\n    <span class=\"c1\"># set to true to enable the email receiving feature. See .\/docker\/cron for more options<\/span>\r\n    <span class=\"na\">IMAP_ENABLED<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${IMAP_ENABLED:-false}\"<\/span>\r\n  <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">.\/opdata:\/var\/openproject\/assets\"<\/span>\r\n\r\n<span class=\"na\">services<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">db<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">image<\/span><span class=\"pi\">:<\/span> <span class=\"s\">postgres:10<\/span>\r\n    <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*restart_policy<\/span>\r\n    <span class=\"na\">stop_grace_period<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">3s\"<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">.\/pgdata:\/var\/lib\/postgresql\/data\"<\/span>\r\n    <span class=\"na\">environment<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">POSTGRES_PASSWORD<\/span><span class=\"pi\">:<\/span> <span class=\"s\">p4ssw0rd<\/span>\r\n      <span class=\"na\">POSTGRES_DB<\/span><span class=\"pi\">:<\/span> <span class=\"s\">openproject<\/span>\r\n    <span class=\"na\">networks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">backend<\/span>\r\n\r\n  <span class=\"na\">cache<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">image<\/span><span class=\"pi\">:<\/span> <span class=\"s\">memcached<\/span>\r\n    <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*restart_policy<\/span>\r\n    <span class=\"na\">networks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">backend<\/span>\r\n\r\n  <span class=\"na\">proxy<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*image<\/span>\r\n    <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*restart_policy<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">.\/docker\/prod\/proxy\"<\/span>\r\n    <span class=\"na\">ports<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${PORT:-8080}:80\"<\/span>\r\n    <span class=\"na\">environment<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">APP_HOST<\/span><span class=\"pi\">:<\/span> <span class=\"s\">web<\/span>\r\n      <span class=\"na\">OPENPROJECT_RAILS__RELATIVE__URL__ROOT<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}\"<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">web<\/span>\r\n    <span class=\"na\">networks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">frontend<\/span>\r\n\r\n  <span class=\"na\">web<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*app<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">.\/docker\/prod\/web\"<\/span>\r\n    <span class=\"na\">networks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">frontend<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">backend<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">db<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">cache<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">seeder<\/span>\r\n\r\n  <span class=\"na\">worker<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*app<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">.\/docker\/prod\/worker\"<\/span>\r\n    <span class=\"na\">networks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">backend<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">db<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">cache<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">seeder<\/span>\r\n\r\n  <span class=\"na\">cron<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*app<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">.\/docker\/prod\/cron\"<\/span>\r\n    <span class=\"na\">networks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">backend<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">db<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">cache<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">seeder<\/span>\r\n\r\n  <span class=\"na\">seeder<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"s\">&lt;&lt;<\/span><span class=\"pi\">:<\/span> <span class=\"nv\">*app<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">.\/docker\/prod\/seeder\"<\/span>\r\n    <span class=\"na\">restart<\/span><span class=\"pi\">:<\/span> <span class=\"s\">on-failure<\/span>\r\n    <span class=\"na\">networks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">backend<\/span>\r\n<\/code><\/pre>\n<h4>\u6267\u884c\uff08\u70df\u96fe\uff09\u6d4b\u8bd5<\/h4>\n<pre class=\"post-pre\"><code>docker-compose up\r\n<\/code><\/pre>\n<h3>\u542f\u7528HTTPS<\/h3>\n<h4>\u76ee\u5f55\u7ed3\u6784<\/h4>\n<pre class=\"post-pre\"><code>compose\/\r\n\u251c\u2500\u2500 docker-compose.yml #\u5909\u66f4\u3059\u308b\r\n\u2514\u2500\u2500 proxy #\u4f5c\u6210\u3059\u308b\r\n    \u251c\u2500\u2500 Dockerfile #\u4f5c\u6210\u3059\u308b\r\n    \u2514\u2500\u2500 default.conf.template #\u4f5c\u6210\u3059\u308b\r\n<\/code><\/pre>\n<h4>\u5c06\u4ee3\u7406\u66f4\u6539\u4e3a\u81ea\u5236\u7684\u3002<\/h4>\n<pre class=\"post-pre\"><code><span class=\"k\">FROM<\/span><span class=\"s\"> nginx:latest<\/span>\r\n<span class=\"k\">ARG<\/span><span class=\"s\"> CERTBOT_EMAIL=default@default.com<\/span>\r\n<span class=\"k\">ARG<\/span><span class=\"s\"> DOMAIN_LIST<\/span>\r\n\r\n<span class=\"c\"># Expose ports.<\/span>\r\n<span class=\"k\">EXPOSE<\/span><span class=\"s\"> 80<\/span>\r\n<span class=\"k\">EXPOSE<\/span><span class=\"s\"> 443<\/span>\r\n\r\n<span class=\"k\">RUN  <\/span>apt-get update <span class=\"se\">\\\r\n<\/span>      <span class=\"o\">&amp;&amp;<\/span> apt-get <span class=\"nb\">install<\/span> <span class=\"nt\">-y<\/span> cron certbot <span class=\"se\">\\\r\n<\/span>      <span class=\"o\">&amp;&amp;<\/span> certbot certonly <span class=\"nt\">--dry-run<\/span> <span class=\"nt\">--standalone<\/span> <span class=\"nt\">--agree-tos<\/span> <span class=\"nt\">-m<\/span> <span class=\"s2\">\"<\/span><span class=\"k\">${<\/span><span class=\"nv\">CERTBOT_EMAIL<\/span><span class=\"k\">}<\/span><span class=\"s2\">\"<\/span> <span class=\"nt\">-n<\/span> <span class=\"nt\">-d<\/span> <span class=\"k\">${<\/span><span class=\"nv\">DOMAIN_LIST<\/span><span class=\"k\">}<\/span> <span class=\"se\">\\ <\/span>\r\n      &amp;&amp; certbot certonly  --standalone --agree-tos -m \"${CERTBOT_EMAIL}\" -n -d ${DOMAIN_LIST} \\\r\n      &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/* \\\r\n      &amp;&amp; echo \"@monthly \/usr\/bin\/certbot renew --nginx &gt;&gt; \/var\/log\/cron.log 2&gt;&amp;1\" &gt;\/etc\/cron.d\/certbot-renew \\\r\n      &amp;&amp; crontab \/etc\/cron.d\/certbot-renew \r\n<span class=\"k\">VOLUME<\/span><span class=\"s\"> \/etc\/letsencrypt<\/span>\r\n\r\n<span class=\"k\">CMD<\/span><span class=\"s\"> [ \"sh\", \"-c\", \"cron &amp;&amp; .\/docker-entrypoint.sh nginx -g 'daemon off;'\" ]<\/span>\r\n<\/code><\/pre>\n<h4>\u4fee\u6539docker-compose.yml\u6587\u4ef6<\/h4>\n<pre class=\"post-pre\"><code>\r\nversion: \"3.7\"\r\n\r\nnetworks:\r\n  frontend:\r\n  backend:\r\n\r\nvolumes:\r\n  pgdata:\r\n  opdata:\r\n\r\nx-op-restart-policy: &amp;restart_policy\r\n  restart: unless-stopped\r\nx-op-image: &amp;image\r\n  image: openproject\/community:11-arm64\r\nx-op-app: &amp;app\r\n  &lt;&lt;: *image\r\n  &lt;&lt;: *restart_policy\r\n  container_name: app\r\n  environment:\r\n    RAILS_CACHE_STORE: \"memcache\"\r\n    OPENPROJECT_CACHE__MEMCACHE__SERVER: \"cache:11211\"\r\n    OPENPROJECT_RAILS__RELATIVE__URL__ROOT: \"${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}\"\r\n    DATABASE_URL: \"postgres:\/\/postgres:p4ssw0rd@db\/openproject\"\r\n    USE_PUMA: \"true\"\r\n    # set to true to enable the email receiving feature. See .\/docker\/cron for more options\r\n    IMAP_ENABLED: \"${IMAP_ENABLED:-false}\"\r\n  volumes:\r\n    - \".\/opdata:\/var\/openproject\/assets\"\r\n\r\nservices:\r\n  db:\r\n    container_name: db\r\n    image: postgres:10\r\n    &lt;&lt;: *restart_policy\r\n    stop_grace_period: \"3s\"\r\n    volumes:\r\n      - \".\/pgdata:\/var\/lib\/postgresql\/data\"\r\n    environment:\r\n      POSTGRES_PASSWORD: p4ssw0rd\r\n      POSTGRES_DB: openproject\r\n    networks:\r\n      - backend\r\n\r\n  cache:\r\n    container_name: cache\r\n    image: memcached\r\n    &lt;&lt;: *restart_policy\r\n    networks:\r\n      - backend\r\n\r\n<span class=\"c\">#  proxy:<\/span>\r\n<span class=\"c\">#    &lt;&lt;: *image<\/span>\r\n<span class=\"c\">#    &lt;&lt;: *restart_policy<\/span>\r\n<span class=\"c\">#    command: \".\/docker\/prod\/proxy\"<\/span>\r\n<span class=\"c\">#    ports:<\/span>\r\n<span class=\"c\">#      - \"${PORT:-8080}:80\"<\/span>\r\n<span class=\"c\">#    environment:<\/span>\r\n<span class=\"c\">#      APP_HOST: web<\/span>\r\n<span class=\"c\">#      OPENPROJECT_RAILS__RELATIVE__URL__ROOT: \"${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}\"<\/span>\r\n\r\n  proxy:\r\n    &lt;&lt;: *restart_policy\r\n    container_name: proxy\r\n    build:\r\n      context: .\/proxy\r\n      network: host\r\n      args:\r\n        - CERTBOT_EMAIL=your-email@mail.com <span class=\"c\">#replace with your own email<\/span>\r\n        - DOMAIN_LIST=your.hostname.com            <span class=\"c\">#replace with your own domains<\/span>\r\n    ports:\r\n      - \"80:80\"\r\n      - \"443:443\"\r\n    volumes:\r\n      - .\/proxy\/default.conf.template:\/etc\/nginx\/templates\/default.conf.template\r\n    environment:\r\n      MY_DOMAIN_NAME: your.hostname.com <span class=\"c\">#replace with your own domains<\/span>\r\n    depends_on:\r\n      - web\r\n    networks:\r\n      - frontend\r\n  web:\r\n    &lt;&lt;: *app\r\n    container_name: web\r\n    command: \".\/docker\/prod\/web\"\r\n    networks:\r\n      - frontend\r\n      - backend\r\n    depends_on:\r\n      - db\r\n      - cache\r\n      - seeder\r\n\r\n  worker:\r\n    &lt;&lt;: *app\r\n    container_name: worker\r\n    command: \".\/docker\/prod\/worker\"\r\n    networks:\r\n      - backend\r\n    depends_on:\r\n      - db\r\n      - cache\r\n      - seeder\r\n\r\n  cron:\r\n    &lt;&lt;: *app\r\n    container_name: cron\r\n    command: \".\/docker\/prod\/cron\"\r\n    networks:\r\n      - backend\r\n    depends_on:\r\n      - db\r\n      - cache\r\n      - seeder\r\n\r\n  seeder:\r\n    &lt;&lt;: *app\r\n    container_name: seeder\r\n    command: \".\/docker\/prod\/seeder\"\r\n    restart: on-failure\r\n    networks:\r\n      - backend\r\n<\/code><\/pre>\n<h4>\u4fee\u6539proxy\/default.conf.template\u3002<\/h4>\n<pre class=\"post-pre\"><code><span class=\"n\">server<\/span> {\r\n    <span class=\"n\">listen<\/span>       <span class=\"m\">80<\/span>;\r\n    <span class=\"n\">server_name<\/span>  <span class=\"n\">localhost<\/span>;\r\n\r\n    <span class=\"c\">#charset koi8-r;\r\n<\/span>    <span class=\"c\">#access_log  \/var\/log\/nginx\/host.access.log  main;\r\n<\/span>    <span class=\"n\">return<\/span> <span class=\"m\">301<\/span> <span class=\"n\">https<\/span>:\/\/$<span class=\"n\">host<\/span>$<span class=\"n\">request_uri<\/span>;\r\n}\r\n\r\n<span class=\"n\">server<\/span> {\r\n    <span class=\"n\">listen<\/span> <span class=\"m\">443<\/span> <span class=\"n\">ssl<\/span>;\r\n    <span class=\"n\">server_name<\/span>  <span class=\"n\">localhost<\/span>;\r\n\r\n    <span class=\"n\">ssl_certificate<\/span> \/<span class=\"n\">etc<\/span>\/<span class=\"n\">letsencrypt<\/span>\/<span class=\"n\">live<\/span>\/${<span class=\"n\">MY_DOMAIN_NAME<\/span>}\/<span class=\"n\">fullchain<\/span>.<span class=\"n\">pem<\/span>;\r\n    <span class=\"n\">ssl_certificate_key<\/span> \/<span class=\"n\">etc<\/span>\/<span class=\"n\">letsencrypt<\/span>\/<span class=\"n\">live<\/span>\/${<span class=\"n\">MY_DOMAIN_NAME<\/span>}\/<span class=\"n\">privkey<\/span>.<span class=\"n\">pem<\/span>;\r\n\r\n    <span class=\"n\">location<\/span> \/ {\r\n        <span class=\"n\">proxy_pass<\/span> <span class=\"n\">http<\/span>:\/\/<span class=\"n\">web<\/span>:<span class=\"m\">8080<\/span>\/;\r\n        <span class=\"n\">proxy_set_header<\/span> <span class=\"n\">Host<\/span> $<span class=\"n\">http_host<\/span>;\r\n        <span class=\"n\">proxy_set_header<\/span> <span class=\"n\">X<\/span>-<span class=\"n\">Forwarded<\/span>-<span class=\"n\">For<\/span> $<span class=\"n\">proxy_add_x_forwarded_for<\/span>;\r\n        <span class=\"n\">proxy_redirect<\/span> <span class=\"n\">http<\/span>:\/\/ <span class=\"n\">https<\/span>:\/\/;\r\n    }\r\n    <span class=\"c\"># --- For CertBot ---\r\n<\/span>    <span class=\"n\">location<\/span> ^~ \/.<span class=\"n\">well<\/span>-<span class=\"n\">known<\/span>\/<span class=\"n\">acme<\/span>-<span class=\"n\">challenge<\/span>\/ {\r\n        <span class=\"n\">root<\/span> \/<span class=\"n\">usr<\/span>\/<span class=\"n\">share<\/span>\/<span class=\"n\">nginx<\/span>\/<span class=\"n\">html<\/span>\/;\r\n    }\r\n\r\n    <span class=\"n\">location<\/span> = \/.<span class=\"n\">well<\/span>-<span class=\"n\">known<\/span>\/<span class=\"n\">acme<\/span>-<span class=\"n\">challenge<\/span>\/ {\r\n        <span class=\"n\">return<\/span> <span class=\"m\">404<\/span>;\r\n    }\r\n}\r\n<\/code><\/pre>\n<h4>\u758f\u901a\uff08\u7159\u718f\uff09\u6e2c\u8a66<\/h4>\n<pre class=\"post-pre\"><code>docker-compose up\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u4f3c\u4e4e\u9700\u8981\u66f4\u52a0\u52aa\u529b\u624d\u80fd\u652f\u6301\u5efa\u7b51\u4e1a\u754c\u7684\u529f\u80fd\u3002 \u203b\u5982COLLADA2GLTF\u6216IFCconvert\u4e4b\u7c7b\u7684\u5de5\u5177\u3002\u60f3\u8981\u4f7f [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-34509","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u7528Raspberry Pi 4\u7684Docker\u5c06OpenProject\u8fd0\u884c\u8d77\u6765 - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u7528raspberry-pi-4\u7684docker\u5c06openproject\u8fd0\u884c\u8d77\u6765\u3002\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u7528Raspberry Pi 4\u7684Docker\u5c06OpenProject\u8fd0\u884c\u8d77\u6765\" \/>\n<meta property=\"og:description\" content=\"\u4f3c\u4e4e\u9700\u8981\u66f4\u52a0\u52aa\u529b\u624d\u80fd\u652f\u6301\u5efa\u7b51\u4e1a\u754c\u7684\u529f\u80fd\u3002 \u203b\u5982COLLADA2GLTF\u6216IFCconvert\u4e4b\u7c7b\u7684\u5de5\u5177\u3002\u60f3\u8981\u4f7f [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u7528raspberry-pi-4\u7684docker\u5c06openproject\u8fd0\u884c\u8d77\u6765\u3002\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-05-25T10:32:24+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-29T01:10:21+00:00\" \/>\n<meta name=\"author\" content=\"\u5b87, \u534e\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u5b87, \u534e\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/\",\"name\":\"\u7528Raspberry Pi 4\u7684Docker\u5c06OpenProject\u8fd0\u884c\u8d77\u6765 - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-05-25T10:32:24+00:00\",\"dateModified\":\"2024-04-29T01:10:21+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/513018e4e121d3add1b7c5de8be21458\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u7528Raspberry Pi 4\u7684Docker\u5c06OpenProject\u8fd0\u884c\u8d77\u6765\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/513018e4e121d3add1b7c5de8be21458\",\"name\":\"\u5b87, \u534e\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/63cd45cbc05a35fc4ff7637a163c83c4962ef58d27472726c3a3e0c9c5194f0f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/63cd45cbc05a35fc4ff7637a163c83c4962ef58d27472726c3a3e0c9c5194f0f?s=96&d=mm&r=g\",\"caption\":\"\u5b87, \u534e\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/yuhua\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u7528Raspberry Pi 4\u7684Docker\u5c06OpenProject\u8fd0\u884c\u8d77\u6765 - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u7528raspberry-pi-4\u7684docker\u5c06openproject\u8fd0\u884c\u8d77\u6765\u3002\/","og_locale":"zh_CN","og_type":"article","og_title":"\u7528Raspberry Pi 4\u7684Docker\u5c06OpenProject\u8fd0\u884c\u8d77\u6765","og_description":"\u4f3c\u4e4e\u9700\u8981\u66f4\u52a0\u52aa\u529b\u624d\u80fd\u652f\u6301\u5efa\u7b51\u4e1a\u754c\u7684\u529f\u80fd\u3002 \u203b\u5982COLLADA2GLTF\u6216IFCconvert\u4e4b\u7c7b\u7684\u5de5\u5177\u3002\u60f3\u8981\u4f7f [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u7528raspberry-pi-4\u7684docker\u5c06openproject\u8fd0\u884c\u8d77\u6765\u3002\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-05-25T10:32:24+00:00","article_modified_time":"2024-04-29T01:10:21+00:00","author":"\u5b87, \u534e","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u5b87, \u534e","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"7 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/","name":"\u7528Raspberry Pi 4\u7684Docker\u5c06OpenProject\u8fd0\u884c\u8d77\u6765 - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-05-25T10:32:24+00:00","dateModified":"2024-04-29T01:10:21+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/513018e4e121d3add1b7c5de8be21458"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u7528Raspberry Pi 4\u7684Docker\u5c06OpenProject\u8fd0\u884c\u8d77\u6765"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/513018e4e121d3add1b7c5de8be21458","name":"\u5b87, \u534e","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/63cd45cbc05a35fc4ff7637a163c83c4962ef58d27472726c3a3e0c9c5194f0f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/63cd45cbc05a35fc4ff7637a163c83c4962ef58d27472726c3a3e0c9c5194f0f?s=96&d=mm&r=g","caption":"\u5b87, \u534e"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/yuhua\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e7%94%a8raspberry-pi-4%e7%9a%84docker%e5%b0%86openproject%e8%bf%90%e8%a1%8c%e8%b5%b7%e6%9d%a5%e3%80%82\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/34509","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=34509"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/34509\/revisions"}],"predecessor-version":[{"id":84356,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/34509\/revisions\/84356"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=34509"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=34509"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=34509"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}