[{"data":1,"prerenderedAt":852},["ShallowReactive",2],{"post-docker-musl-build":3},{"id":4,"title":5,"author":6,"body":7,"description":838,"draft":839,"extension":840,"image":841,"meta":842,"navigation":88,"path":843,"pinned":839,"published":844,"seo":845,"stem":846,"tags":847,"__hash__":851},"posts\u002Fposts\u002Fdocker-musl-build\u002Findex.md","Docker 编译 musl 可执行文件",null,{"type":8,"value":9,"toc":827},"minimark",[10,14,18,21,279,283,327,330,348,351,502,505,641,644,647,705,708,823],[11,12,13],"h2",{"id":13},"解决问题",[15,16,17],"p",{},"用 Go 进行跨平台编译时往往步骤复杂，用 Docker 可以轻松解决。但 Docker 的当前最小镜像 Alpine 其动态链接库采用 musl，与主流的 glibc 不同，往往不能方便执行。",[11,19,20],{"id":20},"查阅资料",[22,23,28],"pre",{"className":24,"code":25,"language":26,"meta":27,"style":27},"language-bash shiki shiki-themes github-light github-dark","# 启动容器并挂载当前目录到 `\u002Fapp`\ndocker run -it --rm -v \"$PWD\":\u002Fapp -w \u002Fapp ubuntu:20.04 bash\n\n# 在容器内执行以下操作：\napt-get update && apt-get install -y musl-tools golang-go  # 安装 musl 和 Go\nexport CC=musl-gcc  # 指定 musl 编译器\nexport CGO_ENABLED=1  # 启用 CGO\n# 设置代理\ngo env -w GOPROXY=https:\u002F\u002Fgoproxy.cn,direct\ngo build -ldflags '-linkmode external -extldflags \"-static\"' -o myapp  # 静态编译\nexit  # 退出容器\n\n# 验证结果（在宿主机执行）\nfile myapp  # 应显示 \"statically linked\"\nldd myapp   # 应显示 \"not a dynamic executable\"\n\nwget https:\u002F\u002Fgo.dev\u002Fdl\u002Fgo1.21.linux-amd64.tar.gz\n\nENV PATH=\"\u002Fdata\u002Fgo\u002Fbin:$PATH\"\n","bash","",[29,30,31,40,83,90,96,125,144,160,166,180,203,212,217,223,234,245,250,259,264],"code",{"__ignoreMap":27},[32,33,36],"span",{"class":34,"line":35},"line",1,[32,37,39],{"class":38},"sHbNN","# 启动容器并挂载当前目录到 `\u002Fapp`\n",[32,41,43,47,51,55,58,61,64,68,71,74,77,80],{"class":34,"line":42},2,[32,44,46],{"class":45},"sw2iP","docker",[32,48,50],{"class":49},"scXbn"," run",[32,52,54],{"class":53},"suQ91"," -it",[32,56,57],{"class":53}," --rm",[32,59,60],{"class":53}," -v",[32,62,63],{"class":49}," \"",[32,65,67],{"class":66},"sIX_F","$PWD",[32,69,70],{"class":49},"\":\u002Fapp",[32,72,73],{"class":53}," -w",[32,75,76],{"class":49}," \u002Fapp",[32,78,79],{"class":49}," ubuntu:20.04",[32,81,82],{"class":49}," bash\n",[32,84,86],{"class":34,"line":85},3,[32,87,89],{"emptyLinePlaceholder":88},true,"\n",[32,91,93],{"class":34,"line":92},4,[32,94,95],{"class":38},"# 在容器内执行以下操作：\n",[32,97,99,102,105,108,110,113,116,119,122],{"class":34,"line":98},5,[32,100,101],{"class":45},"apt-get",[32,103,104],{"class":49}," update",[32,106,107],{"class":66}," && ",[32,109,101],{"class":45},[32,111,112],{"class":49}," install",[32,114,115],{"class":53}," -y",[32,117,118],{"class":49}," musl-tools",[32,120,121],{"class":49}," golang-go",[32,123,124],{"class":38},"  # 安装 musl 和 Go\n",[32,126,128,132,135,138,141],{"class":34,"line":127},6,[32,129,131],{"class":130},"siTax","export",[32,133,134],{"class":66}," CC",[32,136,137],{"class":130},"=",[32,139,140],{"class":66},"musl-gcc  ",[32,142,143],{"class":38},"# 指定 musl 编译器\n",[32,145,147,149,152,154,157],{"class":34,"line":146},7,[32,148,131],{"class":130},[32,150,151],{"class":66}," CGO_ENABLED",[32,153,137],{"class":130},[32,155,156],{"class":53},"1",[32,158,159],{"class":38},"  # 启用 CGO\n",[32,161,163],{"class":34,"line":162},8,[32,164,165],{"class":38},"# 设置代理\n",[32,167,169,172,175,177],{"class":34,"line":168},9,[32,170,171],{"class":45},"go",[32,173,174],{"class":49}," env",[32,176,73],{"class":53},[32,178,179],{"class":49}," GOPROXY=https:\u002F\u002Fgoproxy.cn,direct\n",[32,181,183,185,188,191,194,197,200],{"class":34,"line":182},10,[32,184,171],{"class":45},[32,186,187],{"class":49}," build",[32,189,190],{"class":53}," -ldflags",[32,192,193],{"class":49}," '-linkmode external -extldflags \"-static\"'",[32,195,196],{"class":53}," -o",[32,198,199],{"class":49}," myapp",[32,201,202],{"class":38},"  # 静态编译\n",[32,204,206,209],{"class":34,"line":205},11,[32,207,208],{"class":53},"exit",[32,210,211],{"class":38},"  # 退出容器\n",[32,213,215],{"class":34,"line":214},12,[32,216,89],{"emptyLinePlaceholder":88},[32,218,220],{"class":34,"line":219},13,[32,221,222],{"class":38},"# 验证结果（在宿主机执行）\n",[32,224,226,229,231],{"class":34,"line":225},14,[32,227,228],{"class":45},"file",[32,230,199],{"class":49},[32,232,233],{"class":38},"  # 应显示 \"statically linked\"\n",[32,235,237,240,242],{"class":34,"line":236},15,[32,238,239],{"class":45},"ldd",[32,241,199],{"class":49},[32,243,244],{"class":38},"   # 应显示 \"not a dynamic executable\"\n",[32,246,248],{"class":34,"line":247},16,[32,249,89],{"emptyLinePlaceholder":88},[32,251,253,256],{"class":34,"line":252},17,[32,254,255],{"class":45},"wget",[32,257,258],{"class":49}," https:\u002F\u002Fgo.dev\u002Fdl\u002Fgo1.21.linux-amd64.tar.gz\n",[32,260,262],{"class":34,"line":261},18,[32,263,89],{"emptyLinePlaceholder":88},[32,265,267,270,273,276],{"class":34,"line":266},19,[32,268,269],{"class":45},"ENV",[32,271,272],{"class":49}," PATH=\"\u002Fdata\u002Fgo\u002Fbin:",[32,274,275],{"class":66},"$PATH",[32,277,278],{"class":49},"\"\n",[280,281,282],"h3",{"id":282},"遇到问题",[284,285,286,313],"ol",{},[287,288,289,292,293,296,299,300,303,305,306,308],"li",{},[29,290,291],{},"go mod tidy"," 时报错 ",[29,294,295],{},"tls: failed to verify certificate: x509: certificate",[297,298],"br",{},"解决：",[29,301,302],{},"RUN apt-get update && apt-get install -y ca-certificates && rm -rf \u002Fvar\u002Flib\u002Fapt\u002Flists\u002F*",[297,304],{},"基础镜像的证书未更新，导致 https 的请求出现类似错误。",[297,307],{},[309,310],"img",{"alt":311,"src":312},"image-20250327100813512","\u002Fposts\u002Fdocker-musl-build\u002Fimg\u002Fimage-20250327100813512.png",[287,314,315,316,319,320,322,323,326],{},"直接安装 ",[29,317,318],{},"golang-go"," 其版本过低",[297,321],{},"解决: ",[29,324,325],{},"PATH=\"\u002Fdata\u002Fgo\u002Fbin:$PATH\""," 手动指定环境",[11,328,329],{"id":329},"最终方案",[284,331,332,339,342],{},[287,333,334,335,338],{},"下载 ",[29,336,337],{},"go1.24.1.linux-amd64.tar.gz"," 解压",[287,340,341],{},"编写 Dockerfile",[287,343,344,345],{},"执行 ",[29,346,347],{},"docker build -t go-build:v1 .",[15,349,350],{},"Dockerfile 内容：",[22,352,356],{"className":353,"code":354,"language":355,"meta":27,"style":27},"language-dockerfile shiki shiki-themes github-light github-dark","FROM ubuntu:20.04\n\nLABEL org.opencontainers.image.authors=\"sutong\"\n\nCOPY go\u002F \u002Fgo\u002F\n\nENV PATH=\"\u002Fgo\u002Fbin:$PATH\"\n\nRUN apt-get update && apt-get install -y musl-tools\n\n## go mod tidy 时报错 tls: failed to verify certificate: x509: certificate\nRUN apt-get update && apt-get install -y ca-certificates && rm -rf \u002Fvar\u002Flib\u002Fapt\u002Flists\u002F*\n# 指定 musl 编译器\nENV CC=musl-gcc\n# 启用 CGO\nENV CGO_ENABLED=1\n\nVOLUME \u002Fdata\n\nWORKDIR \u002Fdata\n\nCMD [\"\u002Fbin\u002Fbash\"]\n","dockerfile",[29,357,358,366,370,381,385,393,397,407,411,419,423,428,435,439,446,451,458,462,470,474,482,487],{"__ignoreMap":27},[32,359,360,363],{"class":34,"line":35},[32,361,362],{"class":130},"FROM",[32,364,365],{"class":66}," ubuntu:20.04\n",[32,367,368],{"class":34,"line":42},[32,369,89],{"emptyLinePlaceholder":88},[32,371,372,375,378],{"class":34,"line":85},[32,373,374],{"class":130},"LABEL",[32,376,377],{"class":66}," org.opencontainers.image.authors=",[32,379,380],{"class":49},"\"sutong\"\n",[32,382,383],{"class":34,"line":92},[32,384,89],{"emptyLinePlaceholder":88},[32,386,387,390],{"class":34,"line":98},[32,388,389],{"class":130},"COPY",[32,391,392],{"class":66}," go\u002F \u002Fgo\u002F\n",[32,394,395],{"class":34,"line":127},[32,396,89],{"emptyLinePlaceholder":88},[32,398,399,401,404],{"class":34,"line":146},[32,400,269],{"class":130},[32,402,403],{"class":66}," PATH=",[32,405,406],{"class":49},"\"\u002Fgo\u002Fbin:$PATH\"\n",[32,408,409],{"class":34,"line":162},[32,410,89],{"emptyLinePlaceholder":88},[32,412,413,416],{"class":34,"line":168},[32,414,415],{"class":130},"RUN",[32,417,418],{"class":66}," apt-get update && apt-get install -y musl-tools\n",[32,420,421],{"class":34,"line":182},[32,422,89],{"emptyLinePlaceholder":88},[32,424,425],{"class":34,"line":205},[32,426,427],{"class":38},"## go mod tidy 时报错 tls: failed to verify certificate: x509: certificate\n",[32,429,430,432],{"class":34,"line":214},[32,431,415],{"class":130},[32,433,434],{"class":66}," apt-get update && apt-get install -y ca-certificates && rm -rf \u002Fvar\u002Flib\u002Fapt\u002Flists\u002F*\n",[32,436,437],{"class":34,"line":219},[32,438,143],{"class":38},[32,440,441,443],{"class":34,"line":225},[32,442,269],{"class":130},[32,444,445],{"class":66}," CC=musl-gcc\n",[32,447,448],{"class":34,"line":236},[32,449,450],{"class":38},"# 启用 CGO\n",[32,452,453,455],{"class":34,"line":247},[32,454,269],{"class":130},[32,456,457],{"class":66}," CGO_ENABLED=1\n",[32,459,460],{"class":34,"line":252},[32,461,89],{"emptyLinePlaceholder":88},[32,463,464,467],{"class":34,"line":261},[32,465,466],{"class":130},"VOLUME",[32,468,469],{"class":66}," \u002Fdata\n",[32,471,472],{"class":34,"line":266},[32,473,89],{"emptyLinePlaceholder":88},[32,475,477,480],{"class":34,"line":476},20,[32,478,479],{"class":130},"WORKDIR",[32,481,469],{"class":66},[32,483,485],{"class":34,"line":484},21,[32,486,89],{"emptyLinePlaceholder":88},[32,488,490,493,496,499],{"class":34,"line":489},22,[32,491,492],{"class":130},"CMD",[32,494,495],{"class":66}," [",[32,497,498],{"class":49},"\"\u002Fbin\u002Fbash\"",[32,500,501],{"class":66},"]\n",[280,503,504],{"id":504},"构建",[22,506,508],{"className":24,"code":507,"language":26,"meta":27,"style":27},"# docker build -t go-build:v1 .\n\n# 直接执行编译 编译后删除\ndocker run --rm -v .:\u002Fdata go-build:v1 go build -o app_musl\n\n# 构建编译环境\ndocker run -it -d -v .:\u002Fdata --name \u003C容器名称> go-build:v1 \u002Fbin\u002Fbash\n# eg：docker run -it -d -v .:\u002Fdata --name logbus-build go-build:v1 \u002Fbin\u002Fbash\n\ndocker exec -it \u003C容器名称> go build -o \u003Cmyapp>\n# eg：docker exec -it logbus-build go build -o logbus_musl_1\n",[29,509,510,515,519,524,550,554,559,594,599,603,636],{"__ignoreMap":27},[32,511,512],{"class":34,"line":35},[32,513,514],{"class":38},"# docker build -t go-build:v1 .\n",[32,516,517],{"class":34,"line":42},[32,518,89],{"emptyLinePlaceholder":88},[32,520,521],{"class":34,"line":85},[32,522,523],{"class":38},"# 直接执行编译 编译后删除\n",[32,525,526,528,530,532,534,537,540,543,545,547],{"class":34,"line":92},[32,527,46],{"class":45},[32,529,50],{"class":49},[32,531,57],{"class":53},[32,533,60],{"class":53},[32,535,536],{"class":49}," .:\u002Fdata",[32,538,539],{"class":49}," go-build:v1",[32,541,542],{"class":49}," go",[32,544,187],{"class":49},[32,546,196],{"class":53},[32,548,549],{"class":49}," app_musl\n",[32,551,552],{"class":34,"line":98},[32,553,89],{"emptyLinePlaceholder":88},[32,555,556],{"class":34,"line":127},[32,557,558],{"class":38},"# 构建编译环境\n",[32,560,561,563,565,567,570,572,574,577,580,583,586,589,591],{"class":34,"line":146},[32,562,46],{"class":45},[32,564,50],{"class":49},[32,566,54],{"class":53},[32,568,569],{"class":53}," -d",[32,571,60],{"class":53},[32,573,536],{"class":49},[32,575,576],{"class":53}," --name",[32,578,579],{"class":130}," \u003C",[32,581,582],{"class":49},"容器名",[32,584,585],{"class":66},"称",[32,587,588],{"class":130},">",[32,590,539],{"class":49},[32,592,593],{"class":49}," \u002Fbin\u002Fbash\n",[32,595,596],{"class":34,"line":162},[32,597,598],{"class":38},"# eg：docker run -it -d -v .:\u002Fdata --name logbus-build go-build:v1 \u002Fbin\u002Fbash\n",[32,600,601],{"class":34,"line":168},[32,602,89],{"emptyLinePlaceholder":88},[32,604,605,607,610,612,614,616,618,620,622,624,626,628,631,633],{"class":34,"line":182},[32,606,46],{"class":45},[32,608,609],{"class":49}," exec",[32,611,54],{"class":53},[32,613,579],{"class":130},[32,615,582],{"class":49},[32,617,585],{"class":66},[32,619,588],{"class":130},[32,621,542],{"class":49},[32,623,187],{"class":49},[32,625,196],{"class":53},[32,627,579],{"class":130},[32,629,630],{"class":49},"myap",[32,632,15],{"class":66},[32,634,635],{"class":130},">\n",[32,637,638],{"class":34,"line":205},[32,639,640],{"class":38},"# eg：docker exec -it logbus-build go build -o logbus_musl_1\n",[280,642,643],{"id":643},"额外注意",[15,645,646],{},"若没科学上网需要设置代理：",[22,648,650],{"className":24,"code":649,"language":26,"meta":27,"style":27},"docker exec -it \u003C容器名称> \u002Fbin\u002Fbash\ngo env -w GOPROXY=https:\u002F\u002Fgoproxy.cn,direct\ngo build -ldflags '-linkmode external -extldflags \"-static\"' -o myapp  # 静态编译\ngo build # musl 库编译\n",[29,651,652,670,680,696],{"__ignoreMap":27},[32,653,654,656,658,660,662,664,666,668],{"class":34,"line":35},[32,655,46],{"class":45},[32,657,609],{"class":49},[32,659,54],{"class":53},[32,661,579],{"class":130},[32,663,582],{"class":49},[32,665,585],{"class":66},[32,667,588],{"class":130},[32,669,593],{"class":49},[32,671,672,674,676,678],{"class":34,"line":42},[32,673,171],{"class":45},[32,675,174],{"class":49},[32,677,73],{"class":53},[32,679,179],{"class":49},[32,681,682,684,686,688,690,692,694],{"class":34,"line":85},[32,683,171],{"class":45},[32,685,187],{"class":49},[32,687,190],{"class":53},[32,689,193],{"class":49},[32,691,196],{"class":53},[32,693,199],{"class":49},[32,695,202],{"class":38},[32,697,698,700,702],{"class":34,"line":92},[32,699,171],{"class":45},[32,701,187],{"class":49},[32,703,704],{"class":38}," # musl 库编译\n",[280,706,707],{"id":707},"运行环境示例",[22,709,711],{"className":353,"code":710,"language":355,"meta":27,"style":27},"FROM alpine:latest\n\nLABEL org.opencontainers.image.authors=\"sutong\"\n\nCOPY glog_musl \u002Fapp\u002F\n\nCOPY conf.ini \u002Fdata\u002F\nCOPY ipname.ini \u002Fdata\u002F\n\nWORKDIR \u002Fapp\n\nRUN chmod 777 \u002Fapp\u002Fglog_musl\n\nCMD [\".\u002Fglog_musl\", \"logsweb\", \"\u002Fdata\u002Fconf.ini\"]\n\n# docker build -t glog:v1 .\n# docker run -p 6801:6801 glog:v1\n",[29,712,713,720,724,732,736,743,747,754,761,765,772,776,783,787,809,813,818],{"__ignoreMap":27},[32,714,715,717],{"class":34,"line":35},[32,716,362],{"class":130},[32,718,719],{"class":66}," alpine:latest\n",[32,721,722],{"class":34,"line":42},[32,723,89],{"emptyLinePlaceholder":88},[32,725,726,728,730],{"class":34,"line":85},[32,727,374],{"class":130},[32,729,377],{"class":66},[32,731,380],{"class":49},[32,733,734],{"class":34,"line":92},[32,735,89],{"emptyLinePlaceholder":88},[32,737,738,740],{"class":34,"line":98},[32,739,389],{"class":130},[32,741,742],{"class":66}," glog_musl \u002Fapp\u002F\n",[32,744,745],{"class":34,"line":127},[32,746,89],{"emptyLinePlaceholder":88},[32,748,749,751],{"class":34,"line":146},[32,750,389],{"class":130},[32,752,753],{"class":66}," conf.ini \u002Fdata\u002F\n",[32,755,756,758],{"class":34,"line":162},[32,757,389],{"class":130},[32,759,760],{"class":66}," ipname.ini \u002Fdata\u002F\n",[32,762,763],{"class":34,"line":168},[32,764,89],{"emptyLinePlaceholder":88},[32,766,767,769],{"class":34,"line":182},[32,768,479],{"class":130},[32,770,771],{"class":66}," \u002Fapp\n",[32,773,774],{"class":34,"line":205},[32,775,89],{"emptyLinePlaceholder":88},[32,777,778,780],{"class":34,"line":214},[32,779,415],{"class":130},[32,781,782],{"class":66}," chmod 777 \u002Fapp\u002Fglog_musl\n",[32,784,785],{"class":34,"line":219},[32,786,89],{"emptyLinePlaceholder":88},[32,788,789,791,793,796,799,802,804,807],{"class":34,"line":225},[32,790,492],{"class":130},[32,792,495],{"class":66},[32,794,795],{"class":49},"\".\u002Fglog_musl\"",[32,797,798],{"class":66},", ",[32,800,801],{"class":49},"\"logsweb\"",[32,803,798],{"class":66},[32,805,806],{"class":49},"\"\u002Fdata\u002Fconf.ini\"",[32,808,501],{"class":66},[32,810,811],{"class":34,"line":236},[32,812,89],{"emptyLinePlaceholder":88},[32,814,815],{"class":34,"line":247},[32,816,817],{"class":38},"# docker build -t glog:v1 .\n",[32,819,820],{"class":34,"line":252},[32,821,822],{"class":38},"# docker run -p 6801:6801 glog:v1\n",[824,825,826],"style",{},"html pre.shiki code .sHbNN, html code.shiki .sHbNN{--shiki-light:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sw2iP, html code.shiki .sw2iP{--shiki-light:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .scXbn, html code.shiki .scXbn{--shiki-light:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .suQ91, html code.shiki .suQ91{--shiki-light:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sIX_F, html code.shiki .sIX_F{--shiki-light:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .siTax, html code.shiki .siTax{--shiki-light:#D73A49;--shiki-dark:#F97583}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":27,"searchDepth":42,"depth":85,"links":828},[829,830,833],{"id":13,"depth":42,"text":13},{"id":20,"depth":42,"text":20,"children":831},[832],{"id":282,"depth":85,"text":282},{"id":329,"depth":42,"text":329,"children":834},[835,836,837],{"id":504,"depth":85,"text":504},{"id":643,"depth":85,"text":643},{"id":707,"depth":85,"text":707},"解决 Go 语言跨平台编译问题，使用 Docker + musl 编译静态链接的可执行文件。",false,"md","\u002Fposts\u002Fdocker-musl-build\u002Fimg\u002Fcover.svg",{},"\u002Fposts\u002Fdocker-musl-build","2025-03-27",{"title":5,"description":838},"posts\u002Fdocker-musl-build\u002Findex",[848,849,850],"Docker","Go","运维","dkLU2pJYx10M_f4jWmgiVUow7XSYd6S5JavgEqrFrvI",1780733791991]