Open ii-ii-ii opened 3 years ago
/cc @TriplEight
docker
to run rootles, it should be possible since ~November 2020 or consider using podman
, API is similar but the latter is more advanced. Alternatively, you could just chown
the output for your user.podman
for docker
and it will work.
Essentially, it does the following:podman run --rm -it
-w /shellhere/"$dirname" # runs the container in your current dir, i.e. in the cloned repo
-v "$(pwd)":/shellhere/"$dirname" # shares the current dir with a container
-v /home/"$user"/cache/"$dirname"/:/cache/ # outputs cargo cache to your machine so it can be reused
-e CARGO_HOME=/cache/cargo/ # env variable to redirect the dependencies cache
-e SCCACHE_DIR=/cache/sccache/ # env variable for sccache
-e CARGO_TARGET_DIR=/cache/target/ # cach redirection for the compilation cache
"$@" # your cargo command goes here
@TriplEight Thank you, cache is working well. But the issue of permissions remains unresolved. I am developing redspot and would like to integrate docker compilation. So I can't use podman and I can't use chown to change file permissions. I read the documentation for rust's docker. I found that they do this
$ docker run --rm --user "$(id -u)":"$(id -g)" -v "$PWD":/usr/src/myapp -w /usr/src/myapp rust:1.23.0 cargo build --release
They add --user "$(id -u)":"$(id -g)" to give the generated file the correct permissions. But for cargo contract docker
, when I add --user "$(id -u)":"$(id -g)"
, I get an error:
I'm not sure if the cargo contract dockerfile needs some modification to avoid this problem.
I think I'll need a more full repro here. I.e. from scratch on the clean repo.
@TriplEight You mean how to reproduce the error?
docker run --rm \
--user $(id -u):$(id -g) \
-v "$PWD":/usr/src/myapp \
-w /usr/src/myapp \
paritytech/contracts-ci-linux:production \
cargo contract new myapp
myapp
) and try adding the user parameter to compile the contract.
docker run --rm \
--user $(id -u):$(id -g) \
-v "$PWD":/usr/src/myapp \
-w /usr/src/myapp \
paritytech/contracts-ci-linux:production \
cargo contract build
get error:
ERROR: Error invoking `cargo metadata`
Caused by:
cargo metadata
exited with an error: error: failed to run rustc
to learn about target-specific information
Caused by:
process didn't exit successfully: `sccache rustc - --crate-name ___ --print=file-names --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=cfg` (exit code: 2)
--- stderr
sccache: error: Timed out waiting for server startup
Stack backtrace: 0: cargo_contract::crate_metadata::CrateMetadata::collect 1: cargo_contract::cmd::build::execute 2: cargo_contract::cmd::build::BuildCommand::exec 3: cargo_contract::main 4: std::sys_common::backtrace::__rust_begin_short_backtrace 5: std::rt::lang_start::{{closure}} 6: core::ops::function::impls::<impl core::ops::function::FnOnce for &F>::call_once at /rustc/07e0e2ec268c140e607e1ac7f49f145612d0f597/library/core/src/ops/function.rs:259:13 std::panicking::try::do_call at /rustc/07e0e2ec268c140e607e1ac7f49f145612d0f597/library/std/src/panicking.rs:379:40 std::panicking::try at /rustc/07e0e2ec268c140e607e1ac7f49f145612d0f597/library/std/src/panicking.rs:343:19 std::panic::catch_unwind at /rustc/07e0e2ec268c140e607e1ac7f49f145612d0f597/library/std/src/panic.rs:431:14 std::rt::lang_start_internal at /rustc/07e0e2ec268c140e607e1ac7f49f145612d0f597/library/std/src/rt.rs:51:25 7: main 8: __libc_start_main 9: _start
3. Remove the user parameter, then it compiles successfully. But the permission of the target directory is root.
docker run --rm \ -v "$PWD":/usr/src/myapp \ -w /usr/src/myapp \ paritytech/contracts-ci-linux:production \ cargo contract build
I'm experimenting and so far achieved the following:
--user $(id -u ${USER}):$(id -g ${USER})
next step would be turning off sccache
docker run --rm \
--user $(id -u):$(id -g) \
-v "$PWD":/usr/src/myapp \
-w /usr/src/myapp \
paritytech/contracts-ci-linux:production \
-e RUSTC_WRAPPER="" \
cargo contract build
and here we'll get to a problem cause, which is
ERROR: Error invoking `cargo metadata`
Caused by:
`cargo metadata` exited with an error: error: failed to get `anyhow` as a dependency of package `cargo-contract v0.11.1 (/shellhere/cargo-contract)`
Caused by:
failed to create directory `/cache/cargo/registry/index/github.com-1ecc6299db9ec823`
Caused by:
Permission denied (os error 13)
It can't create files in your OS. Why? Because --user
creates there a non-root user, which you need. But you're running docker
from root
and passing it a volume from root
as well. And now, a non-root container user sees that the mounted volume has root
access and it can't write to it.
This can't be helped by adding a non-root user to the image (we are working on it, but for a different reason).
The issue is that volume is mounted as root
and it's 7y old.
I see the only legal option: remap the user using userns
@ii-ii-ii does Denis' last comment help you at all, or is this still a problem for you?
@ii-ii-ii does Denis' last comment help you at all, or is this still a problem for you?
There are still some problems. But I solved this problem temporarily by using some ugly way. It is to use chown -R ${id}:${group} ${WORK_DIR}
to change the owner.
Please ask me, happy to help.
https://github.com/paritytech/scripts/tree/master/dockerfiles/contracts-ci-linux Docker is a great feature. This ensures that the files compiled on each platform are the same. But I encountered some problems when I used it. I don't know if I'm not using it the right way.
My compiled command is:
After I run docker, my file permissions look like this:
I don't know why the target folder and the Cargo.lock file are owned by root. Does this require some changes to the docker image? Or am I using it in the wrong way?