Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Golang Start Command #748

Closed
1 task done
Fish1 opened this issue Jan 2, 2023 · 8 comments · Fixed by #803
Closed
1 task done

Golang Start Command #748

Fish1 opened this issue Jan 2, 2023 · 8 comments · Fixed by #803
Labels
bug Something isn't working

Comments

@Fish1
Copy link
Contributor

Fish1 commented Jan 2, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Nix pack works fine for building a default container. But when I start adding custom start commands, something fails.

Here is a working build & deploy, without start commands

image
image

Builds fine but it's just using the default start command.

Here is a build with start commands, it fails

==============
Using Nixpacks
==============
context: ed2947ad0e8ecf616927e0060d4c0270
 
╔═══════════════ Nixpacks v1.0.2 ══════════════╗
║ setup      │ go                              ║
║──────────────────────────────────────────────║
║ install    │ go mod download                 ║
║──────────────────────────────────────────────║
║ build      │ go build -o out                 ║
║──────────────────────────────────────────────║
║ start      │ ./out serve --http=0.0.0.0:8080 ║
╚══════════════════════════════════════════════╝
 
 
#1 [internal] load build definition from Dockerfile
 
#1 sha256:e8bb16e8b634bd9bebc0c66b16d603251cefc3f0a6271aa60196a5fd4ae5bff9
#1 transferring dockerfile: 2.22kB done
#1 DONE 0.1s
 
#2 [internal] load .dockerignore
#2 sha256:83ba8f630c928851beada741a87c4013a3d1396fd70fcd285f0cf5b60ba967ae
#2 transferring context: 2B done
#2 DONE 0.1s
 
 
#4 [internal] load metadata for ghcr.io/railwayapp/nixpacks:ubuntu-1671044363
#4 sha256:d2df4677b7c4c8365aa628f14d4cbdd9867466b6b454c21060180de4b7936a2e
 
#4 DONE 0.2s
 
#3 [internal] load metadata for docker.io/library/ubuntu:jammy
#3 sha256:5e41972c0cdee05640f3ed85ad5e7dca92c5a589ced43badaf14d81466f891ae
 
#3 DONE 0.3s
 
#7 [stage-0 1/8] FROM ghcr.io/railwayapp/nixpacks:ubuntu-1671044363@sha256:4df36f942799b8b727c8648ca4fa05d9cd2526e41e7994665082c0f7ef03d95b
#7 sha256:a20b8f1ac783d9d00f7c673a9ef0cf3b8f0aaee89856a86f7aff78cda1934897
#7 DONE 0.0s
 
#5 [stage-1 1/5] FROM docker.io/library/ubuntu:jammy@sha256:27cb6e6ccef575a4698b66f5de06c7ecd61589132d5a91d098f7f3f9285415a9
#5 sha256:6f3b08c859f255cb37cf3502bfa9aed8c925823cc7863ca0013f3d26e621ba0a
#5 DONE 0.0s
 
#9 [internal] load build context
#9 sha256:5ba5de9ca6e5738400782728f92c78b5d56c3c0483e12cb60e36c0f1f9552217
 
#9 transferring context: 47.88MB 0.3s done
#9 DONE 0.4s
 
#8 [stage-0 2/8] WORKDIR /app/
#8 sha256:46f35bb14209f31cddb6d0e80d42b3ceb58d2f45672a3486e22a069140ac06a3
#8 CACHED
 
#10 [stage-0 3/8] COPY .nixpacks/nixpkgs-ffca9ffaaafb38c8979068cee98b2644bd3f14cb.nix .nixpacks/nixpkgs-ffca9ffaaafb38c8979068cee98b2644bd3f14cb.nix
#10 sha256:70ce6a4b3804a2f877ed74a578551f50633788dede0695d433b48111d338f981
#10 CACHED
 
#11 [stage-0 4/8] RUN nix-env -if .nixpacks/nixpkgs-ffca9ffaaafb38c8979068cee98b2644bd3f14cb.nix && nix-collect-garbage -d
#11 sha256:59b918cc061dba6437fa95b37561145b04058cd12ce1167115d3a26179aa4c47
#11 CACHED
 
#12 [stage-0 5/8] COPY . /app/.
#12 sha256:147cc57d0c70d995b1d9c5abc4d3807c3a8a843574fd4543384d357f8987a46a
 
#12 DONE 0.2s
 
#13 [stage-0 6/8] RUN --mount=type=cache,id=s/0098b1a9-7adb-49c6-8db1-ed7f1c65db8d-/root/cache/go-build,target=/root/.cache/go-build go mod download
#13 sha256:f7e5740124829bd271b77f19fd3cafa34cb163037e849ef9fdf721bfc4647361
 
#13 DONE 8.2s
 
#14 [stage-0 7/8] COPY . /app/.
#14 sha256:8eca9da03455fe36e13e2875747fa89fbbde0b733b9fda696447b4ea3c254394
 
#14 DONE 0.2s
 
 
#15 [stage-0 8/8] RUN --mount=type=cache,id=s/0098b1a9-7adb-49c6-8db1-ed7f1c65db8d-/root/cache/go-build,target=/root/.cache/go-build go build -o out
 
#15 sha256:788c2e178bb565b2ba5742e5f39bca0fea5b6166122b6e8771e53932e3bd5d56
 
#15 DONE 2.7s
 
 
#6 [stage-1 2/5] WORKDIR /app/
#6 sha256:b562f93b81a88474f0a0d1f49b4aedecd6daa1817f0bb2a067dec049c0a7db1c
#6 CACHED

#19 exporting layers done
#19 writing image sha256:b7b25b27a998eb25c2ab8f3d61263df773a08f71720434d031080d1cd237ea45
 
#19 writing image sha256:b7b25b27a998eb25c2ab8f3d61263df773a08f71720434d031080d1cd237ea45 0.0s done
#19 naming to us-west1-docker.pkg.dev/railway-infra/railway-docker-users/project/0c560053-13c4-41e8-b9be-287fe67a6dec/service/0098b1a9-7adb-49c6-8db1-ed7f1c65db8d:9e6482aa-20a2-4721-8060-6098db2fa736 0.0s done
#19 DONE 0.1s
 
#20 exporting cache
#20 sha256:2700d4ef94dee473593c5c614b55b2dedcca7893909811a8f2b48291a1f581e4
#20 preparing build cache for export 0.1s done
#20 DONE 0.1s
 
=== Successfully Built! ===
 
Run:
docker run -it us-west1-docker.pkg.dev/railway-infra/railway-docker-users/project/0c560053-13c4-41e8-b9be-287fe67a6dec/service/0098b1a9-7adb-49c6-8db1-ed7f1c65db8d:9e6482aa-20a2-4721-8060-6098db2fa736
 
Build time: 15.52 seconds
 
================
Publishing Image
================
The push refers to repository [us-west1-docker.pkg.dev/railway-infra/railway-docker-users/project/0c560053-13c4-41e8-b9be-287fe67a6dec/service/0098b1a9-7adb-49c6-8db1-ed7f1c65db8d]
Preparing  07458905b58b
Preparing  5f70bf18a086
Preparing  8112635cc30b
Preparing  1a22f5485129
Preparing  6515074984c6
Waiting  6515074984c6
Layer already exists  8112635cc30b
Layer already exists  5f70bf18a086
Layer already exists  1a22f5485129
Layer already exists  6515074984c6
Pushing [>                                                  ]  546.8kB/98.11MB 07458905b58b
Pushing [=>                                                 ]  2.218MB/98.11MB 07458905b58b
Pushing [=>                                                 ]  3.889MB/98.11MB 07458905b58b
Pushing [==>                                                ]   5.56MB/98.11MB 07458905b58b
Pushing [===>                                               ]  7.231MB/98.11MB 07458905b58b
Pushing [====>                                              ]  8.903MB/98.11MB 07458905b58b
Pushing [=====>                                             ]  11.13MB/98.11MB 07458905b58b
Pushing [======>                                            ]   12.8MB/98.11MB 07458905b58b
Pushing [=======>                                           ]  14.47MB/98.11MB 07458905b58b
Pushing [========>                                          ]   16.7MB/98.11MB 07458905b58b
Pushing [=========>                                         ]  18.93MB/98.11MB 07458905b58b
Pushing [==========>                                        ]  21.16MB/98.11MB 07458905b58b
Pushing [===========>                                       ]  23.39MB/98.11MB 07458905b58b
Pushing [============>                                      ]  25.06MB/98.11MB 07458905b58b
Pushing [==============>                                    ]  28.96MB/98.11MB 07458905b58b
Pushing [================>                                  ]  31.74MB/98.11MB 07458905b58b
Pushing [=================>                                 ]  33.97MB/98.11MB 07458905b58b
Pushing [==================>                                ]   36.2MB/98.11MB 07458905b58b
Pushing [===================>                               ]  37.87MB/98.11MB 07458905b58b
Pushing [=====================>                             ]  41.21MB/98.11MB 07458905b58b
Pushing [======================>                            ]     44MB/98.11MB 07458905b58b
Pushing [=======================>                           ]  46.23MB/98.11MB 07458905b58b
Pushing [========================>                          ]   48.4MB/98.11MB 07458905b58b
Pushing [=========================>                         ]  50.07MB/98.11MB 07458905b58b
Pushing [==========================>                        ]  51.74MB/98.11MB 07458905b58b
Pushing [===========================>                       ]  53.41MB/98.11MB 07458905b58b
Pushing [============================>                      ]  55.09MB/98.11MB 07458905b58b
Pushing [============================>                      ]  56.76MB/98.11MB 07458905b58b
Pushing [==============================>                    ]  58.98MB/98.11MB 07458905b58b
Pushing [==============================>                    ]  60.66MB/98.11MB 07458905b58b
Pushing [===============================>                   ]  62.33MB/98.11MB 07458905b58b
Pushing [================================>                  ]  64.56MB/98.11MB 07458905b58b
Pushing [==================================>                ]  66.78MB/98.11MB 07458905b58b
Pushing [===================================>               ]  69.01MB/98.11MB 07458905b58b
Pushing [====================================>              ]  71.24MB/98.11MB 07458905b58b
Pushing [=====================================>             ]  73.47MB/98.11MB 07458905b58b
Pushing [=======================================>           ]  76.81MB/98.11MB 07458905b58b
Pushing [========================================>          ]  80.15MB/98.11MB 07458905b58b
Pushing [=========================================>         ]  81.82MB/98.11MB 07458905b58b
Pushing [==========================================>        ]   83.5MB/98.11MB 07458905b58b
Pushing [===========================================>       ]  85.72MB/98.11MB 07458905b58b
Pushing [============================================>      ]  87.95MB/98.11MB 07458905b58b
Pushing [=============================================>     ]  90.18MB/98.11MB 07458905b58b
Pushing [===============================================>   ]  92.41MB/98.11MB 07458905b58b
Pushing [================================================>  ]  94.64MB/98.11MB 07458905b58b
Pushing [=================================================> ]  96.31MB/98.11MB 07458905b58b
Pushing [==================================================>]  98.12MB 07458905b58b
Pushed  07458905b58b
9e6482aa-20a2-4721-8060-6098db2fa736: digest: sha256:a3ce8dba1ef09d3c3e0928122f45b9334e174c3c3a60fda4eaf4954b5adda6d4 size: 1366
 
 
========================
Container Start Failure!
========================
rpc error: code = Unknown desc = Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "./out serve --http=0.0.0.0:8080": stat ./out serve --http=0.0.0.0:8080: no such file or directory: unknown
 

To reproduce

Build a standard golang application with commands. I am using pocketbase.

Add start commands to add to the run command.

Expected behavior

The build to go through like standard, but with start commands.

Environment

Nixpacks 18, on railway

@Fish1 Fish1 added the bug Something isn't working label Jan 2, 2023
@AhmedMozaly
Copy link
Contributor

AhmedMozaly commented Jan 3, 2023

Nixpacks currently renders start command as CMD ["./out serve --http=0.0.0.0:8080"]

But it should be one of:

  • CMD ["./out", "serve", "--http=0.0.0.0:8080"]

  • CMD ./out serve --http=0.0.0.0:8080

https://docs.docker.com/engine/reference/builder/#cmd

@Fish1
Copy link
Contributor Author

Fish1 commented Feb 12, 2023

Currently looking into this issue... this is the change that manages to fix the issue. Though it seemingly breaks how node projects are executed. CMD ["npm", "run", "start"] doesn't work with this change.

pub fn get_exec_command(command: &str) -> String {
    let params_quote_split = command.split('\"').collect::<Vec<&str>>();

    let mut params_space_split = Vec::new();

    for (index, arg) in params_quote_split.iter().enumerate() {
        let arg = arg.trim();
        if arg.is_empty() {
            continue;
        }

        if index % 2 == 0 {
            let mut split = arg.split_ascii_whitespace().collect::<Vec<&str>>();
            params_space_split.append(&mut split);
        } else {
            params_space_split.push(arg);
        }
    }
   
    format!("CMD {params_space_split:?}")
}

This will change the format to...
CMD ["arg1", "arg2", "my third arg"]

@Fish1
Copy link
Contributor Author

Fish1 commented Feb 12, 2023

This doesn't work...
--start-cmd "npm run start"
image


This works...
--start-cmd "\"npm run start\""
image

These screenshots were from inspecting the docker.

@Fish1
Copy link
Contributor Author

Fish1 commented Feb 12, 2023

Looking a bit deeper...
I think it has to do with how the Entrypoint is defined.

FROM node:18

WORKDIR /app

COPY ./package.json ./

RUN npm install

COPY . .

# this causes the CMD to not execute correctly
ENTRYPOINT [ "/bin/bash", "-c"]

CMD ["npm", "run", "start"]

Defining this entry point causes the CMD ["arg1", "arg2"] syntax to fail. As it tries to execute npm without its arguments.

This entrypoint is set if nixpacks detects a Node project, but it is not set when it detects something like golang. Resulting in the failure of node projects to start, but not other projects.

@Fish1
Copy link
Contributor Author

Fish1 commented Feb 12, 2023

Comparing the dockerfile that is generated for node and golang show why there is an entrypoint difference.

GOLANG: run inside ubuntu:jammy, which doesn't have an entrypoint.

FROM ghcr.io/railwayapp/nixpacks:ubuntu-1675123887

ENTRYPOINT ["/bin/bash", "-l", "-c"]
WORKDIR /app/


COPY .nixpacks/nixpkgs-293a28df6d7ff3dec1e61e37cc4ee6e6c0fb0847.nix .nixpacks/nixpkgs-293a28df6d7ff3dec1e61e37cc4ee6e6c0fb0847.nix
RUN nix-env -if .nixpacks/nixpkgs-293a28df6d7ff3dec1e61e37cc4ee6e6c0fb0847.nix && nix-collect-garbage -d


ARG CGO_ENABLED NIXPACKS_METADATA
ENV CGO_ENABLED=$CGO_ENABLED NIXPACKS_METADATA=$NIXPACKS_METADATA

# setup phase
# noop

# build phase
COPY . /app/.
RUN --mount=type=cache,id=xmGFbf20G0-/root/cache/go-build,target=/root/.cache/go-build go build -o out main.go


# start
FROM ubuntu:jammy
WORKDIR /app/
COPY --from=0 /etc/ssl/certs /etc/ssl/certs
RUN true
COPY --from=0 /app/ /app/
CMD ["./out", "hello", "world", "cool bro"]

NODE: runs inside the NIXPACKS custom docker, and sets the ENTRYPOINT without switching docker stages.

FROM ghcr.io/railwayapp/nixpacks:ubuntu-1675123887

ENTRYPOINT ["/bin/bash", "-l", "-c"]
WORKDIR /app/


COPY .nixpacks/nixpkgs-293a28df6d7ff3dec1e61e37cc4ee6e6c0fb0847.nix .nixpacks/nixpkgs-293a28df6d7ff3dec1e61e37cc4ee6e6c0fb0847.nix
RUN nix-env -if .nixpacks/nixpkgs-293a28df6d7ff3dec1e61e37cc4ee6e6c0fb0847.nix && nix-collect-garbage -d


ARG CI NIXPACKS_METADATA NODE_ENV NPM_CONFIG_PRODUCTION
ENV CI=$CI NIXPACKS_METADATA=$NIXPACKS_METADATA NODE_ENV=$NODE_ENV NPM_CONFIG_PRODUCTION=$NPM_CONFIG_PRODUCTION

# setup phase
# noop

# install phase
ENV PATH /app/node_modules/.bin:$PATH
RUN printf '\nPATH=/app/node_modules/.bin:$PATH' >> /root/.profile
COPY . /app/.
RUN --mount=type=cache,id=OexUejBTDmo-/root/npm,target=/root/.npm npm ci

# build phase
# noop


# start
COPY . /app
CMD ["npm", "run", "start"]

@Fish1
Copy link
Contributor Author

Fish1 commented Feb 12, 2023

One more level deeper...

I found where nixpack is changing the docker stage to use ubuntu:jammy.

image

run_in_slim_image changes the image to ubuntu:jammy.

So, I think there are two different solution that I can see here.

  1. Alter how run_in_slim_image works.
    Inside the impl DockerfileGenerator for StartPhase, I've added the entry point to mimic what is happening inside the nixpacks image. This allowed me to run a golang binary with arguments.

dockerfile_generation.rs
impl DockerfileGenerator for StartPhase
image

I personally have never use, or seen the CMD command used like this with an entrypoint... I am not sure why this is being done. But maybe there are a bunch of people who expect their start command to be executed this way. So this might be the best way to fix it?

  1. Remove the ENTRYPOINT from the base docker image, inside dockerfile_generation.rs. And implement the standard CMD dockerfile format inside

dockerfile_generation.rs
impl DockerfileGenerator for BuildPlan
image

utils.rs
image


I'm thinking the second change might be better because it is more in line to how docker recommends using the CMD command. But I might think there are people who have built customized processes that expect the start command to be executed inside the /bin/bash -c "my command here" call... and having it executed a different way would break their builds somehow.

@Milo123459
Copy link
Collaborator

can you try not splitting and just making it CMD ..... as opposed to CMD [..]

@Fish1
Copy link
Contributor Author

Fish1 commented Feb 17, 2023

@Milo123459 I've done the test you requested.

It allowed go to execute properly. But node would simply drop into a shell.
image

Adding the ENTRYPOINT to the golang run_in_slim_image also caused golang to drop into a shell environment.

From reading the docker docs, https://docs.docker.com/engine/reference/builder/#cmd , the CMD ..... format is telling docker to run it inside a shell. Where as CMD [...] doesn't running inside a shell. So having an ENTRYPOINT is redundant with the CMD ..... format.

So now I'm thinking using CMD ..... and removing the ENTRYPOINT, might be the best solution here. It allows both node and golang to execute with complex shell commands.

Here are two complex start CMDs, and their executions.
image

image

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants