├── .github └── workflows │ ├── post-diffs-in-pr.yml │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── compiled_starters ├── c │ ├── .gitattributes │ ├── Dockerfile │ ├── README.md │ ├── app │ │ └── main.c │ ├── codecrafters.yml │ └── your_docker.sh ├── go │ ├── .gitattributes │ ├── Dockerfile │ ├── README.md │ ├── app │ │ └── main.go │ ├── codecrafters.yml │ ├── go.mod │ ├── go.sum │ └── your_docker.sh ├── nim │ ├── .gitattributes │ ├── Dockerfile │ ├── README.md │ ├── app │ │ └── main.nim │ ├── codecrafters.yml │ └── your_docker.sh ├── php │ ├── .gitattributes │ ├── Dockerfile │ ├── README.md │ ├── app │ │ └── main.php │ ├── codecrafters.yml │ └── your_docker.sh ├── python │ ├── .gitattributes │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── app │ │ └── main.py │ ├── codecrafters.yml │ └── your_docker.sh ├── ruby │ ├── .gitattributes │ ├── Dockerfile │ ├── README.md │ ├── app │ │ └── main.rb │ ├── codecrafters.yml │ └── your_docker.sh ├── rust │ ├── .gitattributes │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── Dockerfile │ ├── README.md │ ├── codecrafters.yml │ ├── src │ │ └── main.rs │ └── your_docker.sh └── swift │ ├── .gitattributes │ ├── .gitignore │ ├── Dockerfile │ ├── Package.swift │ ├── README.md │ ├── Sources │ └── swift-docker-challenge │ │ └── Main.swift │ ├── codecrafters.yml │ └── your_docker.sh ├── course-definition.yml ├── dockerfiles ├── c-9.2.Dockerfile ├── go-1.13.Dockerfile ├── go-1.16.Dockerfile ├── go-1.19.Dockerfile ├── go-1.21.Dockerfile ├── go-1.22.Dockerfile ├── nim-1.0.Dockerfile ├── php-7.4.Dockerfile ├── python-3.11.Dockerfile ├── python-3.12.Dockerfile ├── ruby-2.7.Dockerfile ├── ruby-3.2.Dockerfile ├── rust-1.43.Dockerfile ├── rust-1.54.Dockerfile ├── rust-1.62.Dockerfile ├── rust-1.68.Dockerfile ├── rust-1.70.Dockerfile ├── rust-1.76.Dockerfile ├── rust-1.77.Dockerfile └── swift-5.6.Dockerfile ├── solutions ├── c │ └── 01-je9 │ │ ├── code │ │ ├── .gitattributes │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── app │ │ │ └── main.c │ │ ├── codecrafters.yml │ │ └── your_docker.sh │ │ ├── diff │ │ └── app │ │ │ └── main.c.diff │ │ └── explanation.md ├── go │ └── 01-je9 │ │ ├── code │ │ ├── .gitattributes │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── app │ │ │ └── main.go │ │ ├── codecrafters.yml │ │ ├── go.mod │ │ ├── go.sum │ │ └── your_docker.sh │ │ ├── diff │ │ └── app │ │ │ └── main.go.diff │ │ └── explanation.md ├── nim │ └── 01-je9 │ │ ├── code │ │ ├── .gitattributes │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── app │ │ │ └── main.nim │ │ ├── codecrafters.yml │ │ └── your_docker.sh │ │ ├── diff │ │ └── app │ │ │ └── main.nim.diff │ │ └── explanation.md ├── php │ └── 01-je9 │ │ ├── code │ │ ├── .gitattributes │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── app │ │ │ └── main.php │ │ ├── codecrafters.yml │ │ └── your_docker.sh │ │ ├── diff │ │ └── app │ │ │ └── main.php.diff │ │ └── explanation.md ├── python │ └── 01-je9 │ │ ├── code │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── app │ │ │ └── main.py │ │ ├── codecrafters.yml │ │ └── your_docker.sh │ │ ├── diff │ │ └── app │ │ │ └── main.py.diff │ │ └── explanation.md ├── ruby │ └── 01-je9 │ │ ├── code │ │ ├── .gitattributes │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── app │ │ │ └── main.rb │ │ ├── codecrafters.yml │ │ └── your_docker.sh │ │ ├── diff │ │ └── app │ │ │ └── main.rb.diff │ │ └── explanation.md ├── rust │ └── 01-je9 │ │ ├── code │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── codecrafters.yml │ │ ├── src │ │ │ └── main.rs │ │ └── your_docker.sh │ │ ├── diff │ │ └── src │ │ │ └── main.rs.diff │ │ └── explanation.md └── swift │ └── 01-je9 │ ├── code │ ├── .gitattributes │ ├── .gitignore │ ├── Dockerfile │ ├── Package.swift │ ├── README.md │ ├── Sources │ │ └── swift-docker-challenge │ │ │ └── Main.swift │ ├── codecrafters.yml │ └── your_docker.sh │ ├── diff │ └── Sources │ │ └── swift-docker-challenge │ │ └── Main.swift.diff │ └── explanation.md └── starter_templates ├── all └── code │ ├── .gitattributes │ ├── README.md │ └── codecrafters.yml ├── c ├── code │ ├── Dockerfile │ ├── app │ │ └── main.c │ └── your_docker.sh └── config.yml ├── go ├── code │ ├── Dockerfile │ ├── app │ │ └── main.go │ ├── go.mod │ ├── go.sum │ └── your_docker.sh └── config.yml ├── nim ├── code │ ├── Dockerfile │ ├── app │ │ └── main.nim │ └── your_docker.sh └── config.yml ├── php ├── code │ ├── Dockerfile │ ├── app │ │ └── main.php │ └── your_docker.sh └── config.yml ├── python ├── code │ ├── .gitignore │ ├── Dockerfile │ ├── app │ │ └── main.py │ └── your_docker.sh └── config.yml ├── ruby ├── code │ ├── Dockerfile │ ├── app │ │ └── main.rb │ └── your_docker.sh └── config.yml ├── rust ├── code │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── Dockerfile │ ├── src │ │ └── main.rs │ └── your_docker.sh └── config.yml └── swift ├── code ├── .gitignore ├── Dockerfile ├── Package.swift ├── Sources │ └── swift-docker-challenge │ │ └── Main.swift └── your_docker.sh └── config.yml /.github/workflows/post-diffs-in-pr.yml: -------------------------------------------------------------------------------- 1 | name: Post diffs 2 | 3 | on: 4 | pull_request: 5 | 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.ref }} 8 | cancel-in-progress: true 9 | 10 | jobs: 11 | post_diffs: 12 | uses: codecrafters-io/course-sdk/.github/workflows/post-diffs-in-pr.yml@main 13 | with: 14 | sdkRef: main 15 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: [main] 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | test_course_definition: 14 | uses: codecrafters-io/course-sdk/.github/workflows/test-course-definition.yml@main 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | course_definition_tester 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 CodeCrafters 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # build-your-own-docker 2 | 3 | Content for the "Build your own Docker" challenge 4 | 5 | ### Setup 6 | 7 | This challenge is developed using https://github.com/codecrafters-io/course-sdk. Read the README there for information 8 | on how to contribute language support & submit solutions. -------------------------------------------------------------------------------- /compiled_starters/c/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /compiled_starters/c/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM n0madic/alpine-gcc:9.2.0 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | # Download docker-explorer 7 | ARG docker_explorer_version=v18 8 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 9 | RUN chmod +x /usr/local/bin/docker-explorer 10 | 11 | COPY . /app 12 | WORKDIR /app 13 | 14 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 15 | 16 | ENTRYPOINT ["/app/your_docker.sh"] 17 | -------------------------------------------------------------------------------- /compiled_starters/c/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for C solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.c`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /compiled_starters/c/app/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Usage: your_docker.sh run ... 6 | int main(int argc, char *argv[]) { 7 | // Disable output buffering 8 | setbuf(stdout, NULL); 9 | setbuf(stderr, NULL); 10 | 11 | // You can use print statements as follows for debugging, they'll be visible when running tests. 12 | printf("Logs from your program will appear here!\n"); 13 | 14 | // Uncomment this block to pass the first stage 15 | // 16 | // char *command = argv[3]; 17 | // int child_pid = fork(); 18 | // if (child_pid == -1) { 19 | // printf("Error forking!"); 20 | // return 1; 21 | // } 22 | // 23 | // if (child_pid == 0) { 24 | // // Replace current program with calling program 25 | // execv(command, &argv[3]); 26 | // } else { 27 | // // We're in parent 28 | // wait(NULL); 29 | // printf("Child terminated"); 30 | // } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /compiled_starters/c/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the C version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: c-9.2 11 | language_pack: c-9.2 12 | -------------------------------------------------------------------------------- /compiled_starters/c/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | tmpFile=$(mktemp) 4 | gcc -lcurl app/*.c -o $tmpFile 5 | exec "$tmpFile" "$@" 6 | -------------------------------------------------------------------------------- /compiled_starters/go/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /compiled_starters/go/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.22-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 14 | 15 | ENTRYPOINT ["/app/your_docker.sh"] 16 | -------------------------------------------------------------------------------- /compiled_starters/go/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Go solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.go`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /compiled_starters/go/app/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | ) 8 | 9 | // Ensures gofmt doesn't remove the imports above (feel free to remove this!) 10 | var _ = os.Args 11 | var _ = exec.Command 12 | 13 | // Usage: your_docker.sh run ... 14 | func main() { 15 | // You can use print statements as follows for debugging, they'll be visible when running tests. 16 | fmt.Println("Logs from your program will appear here!") 17 | 18 | // Uncomment this block to pass the first stage! 19 | // 20 | // command := os.Args[3] 21 | // args := os.Args[4:len(os.Args)] 22 | // 23 | // cmd := exec.Command(command, args...) 24 | // output, err := cmd.Output() 25 | // if err != nil { 26 | // fmt.Printf("Err: %v", err) 27 | // os.Exit(1) 28 | // } 29 | // 30 | // fmt.Println(string(output)) 31 | } 32 | -------------------------------------------------------------------------------- /compiled_starters/go/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Go version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: go-1.22 11 | language_pack: go-1.22 12 | -------------------------------------------------------------------------------- /compiled_starters/go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/codecrafters-io/docker-starter-go 2 | 3 | go 1.22 4 | -------------------------------------------------------------------------------- /compiled_starters/go/go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codecrafters-io/build-your-own-docker/f96e97152c526fdb7b474e62be28454791552c26/compiled_starters/go/go.sum -------------------------------------------------------------------------------- /compiled_starters/go/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | tmpFile=$(mktemp) 4 | go build -o "$tmpFile" app/*.go 5 | exec "$tmpFile" "$@" 6 | -------------------------------------------------------------------------------- /compiled_starters/nim/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /compiled_starters/nim/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nimlang/nim:1.0.6-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | 5 | # Download docker-explorer. 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 14 | 15 | ENTRYPOINT ["/app/your_docker.sh"] 16 | -------------------------------------------------------------------------------- /compiled_starters/nim/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Nim solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.nim`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /compiled_starters/nim/app/main.nim: -------------------------------------------------------------------------------- 1 | # Usage: your_docker.sh run ... 2 | 3 | from os import commandLineParams 4 | from osproc import execProcess 5 | 6 | 7 | # You can use print statements as follows for debugging, they'll be visible when running tests. 8 | echo "Logs from your program will appear here" 9 | 10 | # Uncomment this block to pass the first stage 11 | # 12 | # let command = commandLineParams()[2] 13 | # let args = commandLineParams()[3..^1] 14 | # 15 | # let output = execProcess(command, "", args, options={}) 16 | # echo output 17 | -------------------------------------------------------------------------------- /compiled_starters/nim/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Nim version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: nim-1.0 11 | language_pack: nim-1.0 12 | -------------------------------------------------------------------------------- /compiled_starters/nim/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | tmpFile=$(mktemp) 4 | nim compile --verbosity:0 --hints:off --out:"$tmpFile" app/main.nim 5 | exec "$tmpFile" "$@" 6 | -------------------------------------------------------------------------------- /compiled_starters/php/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /compiled_starters/php/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.4-cli-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | RUN docker-php-ext-install pcntl 7 | 8 | # Download docker-explorer. 9 | ARG docker_explorer_version=v18 10 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 11 | RUN chmod +x /usr/local/bin/docker-explorer 12 | 13 | COPY . /app 14 | WORKDIR /app 15 | 16 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 17 | 18 | ENTRYPOINT ["/app/your_docker.sh"] 19 | -------------------------------------------------------------------------------- /compiled_starters/php/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for PHP solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.php`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /compiled_starters/php/app/main.php: -------------------------------------------------------------------------------- 1 | ... 3 | 4 | // Disable output buffering. 5 | while (ob_get_level() !== 0) { 6 | ob_end_clean(); 7 | } 8 | 9 | // You can use print statements as follows for debugging, they'll be visible when running tests. 10 | echo "Logs from your program will appear here!\n"; 11 | 12 | // Uncomment this to pass the first stage. 13 | // $child_pid = pcntl_fork(); 14 | // if ($child_pid == -1) { 15 | // echo "Error forking!"; 16 | // } 17 | // elseif ($child_pid) { 18 | // // We're in parent. 19 | // pcntl_wait($status); 20 | // echo "Child terminates!"; 21 | // } 22 | // else { 23 | // // Replace current program with calling program. 24 | // echo exec(implode(' ', array_slice($argv, 3))); 25 | // } 26 | -------------------------------------------------------------------------------- /compiled_starters/php/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the PHP version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: php-7.4 11 | language_pack: php-7.4 12 | -------------------------------------------------------------------------------- /compiled_starters/php/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec php app/main.php "$@" 3 | -------------------------------------------------------------------------------- /compiled_starters/python/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /compiled_starters/python/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | -------------------------------------------------------------------------------- /compiled_starters/python/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.12-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 14 | 15 | ENTRYPOINT ["/app/your_docker.sh"] 16 | -------------------------------------------------------------------------------- /compiled_starters/python/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Python solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.py`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /compiled_starters/python/app/main.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | 5 | def main(): 6 | # You can use print statements as follows for debugging, they'll be visible when running tests. 7 | print("Logs from your program will appear here!") 8 | 9 | # Uncomment this block to pass the first stage 10 | # 11 | # command = sys.argv[3] 12 | # args = sys.argv[4:] 13 | # 14 | # completed_process = subprocess.run([command, *args], capture_output=True) 15 | # print(completed_process.stdout.decode("utf-8")) 16 | 17 | 18 | if __name__ == "__main__": 19 | main() 20 | -------------------------------------------------------------------------------- /compiled_starters/python/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Python version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: python-3.12 11 | language_pack: python-3.12 12 | -------------------------------------------------------------------------------- /compiled_starters/python/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PYTHONPATH=$(dirname $0) exec python3 -m app.main "$@" 3 | -------------------------------------------------------------------------------- /compiled_starters/ruby/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /compiled_starters/ruby/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.2-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | # Download docker-explorer 7 | ARG docker_explorer_version=v18 8 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 9 | RUN chmod +x /usr/local/bin/docker-explorer 10 | 11 | COPY . /app 12 | WORKDIR /app 13 | 14 | ENTRYPOINT ["/app/your_docker.sh"] 15 | -------------------------------------------------------------------------------- /compiled_starters/ruby/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Ruby solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.rb`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /compiled_starters/ruby/app/main.rb: -------------------------------------------------------------------------------- 1 | require "open3" 2 | 3 | # You can use print statements as follows for debugging, they'll be visible when running tests. 4 | puts "Logs from your program will appear here!" 5 | 6 | # Uncomment this block to pass the first stage 7 | # 8 | # command = ARGV[2] 9 | # args = ARGV[3..] 10 | # 11 | # stdout, stderr, status = Open3.capture3(command, *args) 12 | # 13 | # puts stdout 14 | -------------------------------------------------------------------------------- /compiled_starters/ruby/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Ruby version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: ruby-3.2 11 | language_pack: ruby-3.2 12 | -------------------------------------------------------------------------------- /compiled_starters/ruby/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec ruby app/main.rb "$@" 3 | -------------------------------------------------------------------------------- /compiled_starters/rust/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /compiled_starters/rust/.gitignore: -------------------------------------------------------------------------------- 1 | target/ -------------------------------------------------------------------------------- /compiled_starters/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "adler" 7 | version = "1.0.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 10 | 11 | [[package]] 12 | name = "aho-corasick" 13 | version = "0.7.20" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" 16 | dependencies = [ 17 | "memchr", 18 | ] 19 | 20 | [[package]] 21 | name = "anyhow" 22 | version = "1.0.59" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "c91f1f46651137be86f3a2b9a8359f9ab421d04d941c62b5982e1ca21113adf9" 25 | 26 | [[package]] 27 | name = "autocfg" 28 | version = "1.1.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 31 | 32 | [[package]] 33 | name = "base64" 34 | version = "0.13.0" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 37 | 38 | [[package]] 39 | name = "bitflags" 40 | version = "1.3.2" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 43 | 44 | [[package]] 45 | name = "bumpalo" 46 | version = "3.10.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" 49 | 50 | [[package]] 51 | name = "bytes" 52 | version = "1.3.0" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" 55 | 56 | [[package]] 57 | name = "cc" 58 | version = "1.0.73" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 61 | 62 | [[package]] 63 | name = "cfg-if" 64 | version = "1.0.0" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 67 | 68 | [[package]] 69 | name = "core-foundation" 70 | version = "0.9.3" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 73 | dependencies = [ 74 | "core-foundation-sys", 75 | "libc", 76 | ] 77 | 78 | [[package]] 79 | name = "core-foundation-sys" 80 | version = "0.8.3" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 83 | 84 | [[package]] 85 | name = "crc32fast" 86 | version = "1.3.2" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 89 | dependencies = [ 90 | "cfg-if", 91 | ] 92 | 93 | [[package]] 94 | name = "docker-starter-rust" 95 | version = "0.1.0" 96 | dependencies = [ 97 | "anyhow", 98 | "bytes", 99 | "flate2", 100 | "libc", 101 | "regex", 102 | "reqwest", 103 | "serde", 104 | "serde_json", 105 | "tar", 106 | "tempfile", 107 | "thiserror", 108 | "tokio", 109 | ] 110 | 111 | [[package]] 112 | name = "encoding_rs" 113 | version = "0.8.31" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" 116 | dependencies = [ 117 | "cfg-if", 118 | ] 119 | 120 | [[package]] 121 | name = "fastrand" 122 | version = "1.8.0" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" 125 | dependencies = [ 126 | "instant", 127 | ] 128 | 129 | [[package]] 130 | name = "filetime" 131 | version = "0.2.19" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" 134 | dependencies = [ 135 | "cfg-if", 136 | "libc", 137 | "redox_syscall", 138 | "windows-sys 0.42.0", 139 | ] 140 | 141 | [[package]] 142 | name = "flate2" 143 | version = "1.0.25" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" 146 | dependencies = [ 147 | "crc32fast", 148 | "miniz_oxide", 149 | ] 150 | 151 | [[package]] 152 | name = "fnv" 153 | version = "1.0.7" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 156 | 157 | [[package]] 158 | name = "foreign-types" 159 | version = "0.3.2" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 162 | dependencies = [ 163 | "foreign-types-shared", 164 | ] 165 | 166 | [[package]] 167 | name = "foreign-types-shared" 168 | version = "0.1.1" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 171 | 172 | [[package]] 173 | name = "form_urlencoded" 174 | version = "1.0.1" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" 177 | dependencies = [ 178 | "matches", 179 | "percent-encoding", 180 | ] 181 | 182 | [[package]] 183 | name = "futures-channel" 184 | version = "0.3.21" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" 187 | dependencies = [ 188 | "futures-core", 189 | ] 190 | 191 | [[package]] 192 | name = "futures-core" 193 | version = "0.3.21" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" 196 | 197 | [[package]] 198 | name = "futures-io" 199 | version = "0.3.21" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" 202 | 203 | [[package]] 204 | name = "futures-sink" 205 | version = "0.3.21" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" 208 | 209 | [[package]] 210 | name = "futures-task" 211 | version = "0.3.21" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" 214 | 215 | [[package]] 216 | name = "futures-util" 217 | version = "0.3.21" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" 220 | dependencies = [ 221 | "futures-core", 222 | "futures-io", 223 | "futures-task", 224 | "memchr", 225 | "pin-project-lite", 226 | "pin-utils", 227 | "slab", 228 | ] 229 | 230 | [[package]] 231 | name = "h2" 232 | version = "0.3.15" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" 235 | dependencies = [ 236 | "bytes", 237 | "fnv", 238 | "futures-core", 239 | "futures-sink", 240 | "futures-util", 241 | "http", 242 | "indexmap", 243 | "slab", 244 | "tokio", 245 | "tokio-util", 246 | "tracing", 247 | ] 248 | 249 | [[package]] 250 | name = "hashbrown" 251 | version = "0.12.3" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 254 | 255 | [[package]] 256 | name = "hermit-abi" 257 | version = "0.1.19" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 260 | dependencies = [ 261 | "libc", 262 | ] 263 | 264 | [[package]] 265 | name = "http" 266 | version = "0.2.8" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" 269 | dependencies = [ 270 | "bytes", 271 | "fnv", 272 | "itoa", 273 | ] 274 | 275 | [[package]] 276 | name = "http-body" 277 | version = "0.4.5" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 280 | dependencies = [ 281 | "bytes", 282 | "http", 283 | "pin-project-lite", 284 | ] 285 | 286 | [[package]] 287 | name = "httparse" 288 | version = "1.8.0" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 291 | 292 | [[package]] 293 | name = "httpdate" 294 | version = "1.0.2" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 297 | 298 | [[package]] 299 | name = "hyper" 300 | version = "0.14.23" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" 303 | dependencies = [ 304 | "bytes", 305 | "futures-channel", 306 | "futures-core", 307 | "futures-util", 308 | "h2", 309 | "http", 310 | "http-body", 311 | "httparse", 312 | "httpdate", 313 | "itoa", 314 | "pin-project-lite", 315 | "socket2", 316 | "tokio", 317 | "tower-service", 318 | "tracing", 319 | "want", 320 | ] 321 | 322 | [[package]] 323 | name = "hyper-tls" 324 | version = "0.5.0" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 327 | dependencies = [ 328 | "bytes", 329 | "hyper", 330 | "native-tls", 331 | "tokio", 332 | "tokio-native-tls", 333 | ] 334 | 335 | [[package]] 336 | name = "idna" 337 | version = "0.2.3" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" 340 | dependencies = [ 341 | "matches", 342 | "unicode-bidi", 343 | "unicode-normalization", 344 | ] 345 | 346 | [[package]] 347 | name = "indexmap" 348 | version = "1.9.1" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" 351 | dependencies = [ 352 | "autocfg", 353 | "hashbrown", 354 | ] 355 | 356 | [[package]] 357 | name = "instant" 358 | version = "0.1.12" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 361 | dependencies = [ 362 | "cfg-if", 363 | ] 364 | 365 | [[package]] 366 | name = "ipnet" 367 | version = "2.5.0" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" 370 | 371 | [[package]] 372 | name = "itoa" 373 | version = "1.0.3" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" 376 | 377 | [[package]] 378 | name = "js-sys" 379 | version = "0.3.59" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" 382 | dependencies = [ 383 | "wasm-bindgen", 384 | ] 385 | 386 | [[package]] 387 | name = "lazy_static" 388 | version = "1.4.0" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 391 | 392 | [[package]] 393 | name = "libc" 394 | version = "0.2.127" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b" 397 | 398 | [[package]] 399 | name = "lock_api" 400 | version = "0.4.9" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 403 | dependencies = [ 404 | "autocfg", 405 | "scopeguard", 406 | ] 407 | 408 | [[package]] 409 | name = "log" 410 | version = "0.4.17" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 413 | dependencies = [ 414 | "cfg-if", 415 | ] 416 | 417 | [[package]] 418 | name = "matches" 419 | version = "0.1.9" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" 422 | 423 | [[package]] 424 | name = "memchr" 425 | version = "2.5.0" 426 | source = "registry+https://github.com/rust-lang/crates.io-index" 427 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 428 | 429 | [[package]] 430 | name = "mime" 431 | version = "0.3.16" 432 | source = "registry+https://github.com/rust-lang/crates.io-index" 433 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 434 | 435 | [[package]] 436 | name = "miniz_oxide" 437 | version = "0.6.2" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" 440 | dependencies = [ 441 | "adler", 442 | ] 443 | 444 | [[package]] 445 | name = "mio" 446 | version = "0.8.5" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" 449 | dependencies = [ 450 | "libc", 451 | "log", 452 | "wasi", 453 | "windows-sys 0.42.0", 454 | ] 455 | 456 | [[package]] 457 | name = "native-tls" 458 | version = "0.2.10" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" 461 | dependencies = [ 462 | "lazy_static", 463 | "libc", 464 | "log", 465 | "openssl", 466 | "openssl-probe", 467 | "openssl-sys", 468 | "schannel", 469 | "security-framework", 470 | "security-framework-sys", 471 | "tempfile", 472 | ] 473 | 474 | [[package]] 475 | name = "num_cpus" 476 | version = "1.13.1" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 479 | dependencies = [ 480 | "hermit-abi", 481 | "libc", 482 | ] 483 | 484 | [[package]] 485 | name = "once_cell" 486 | version = "1.13.0" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" 489 | 490 | [[package]] 491 | name = "openssl" 492 | version = "0.10.41" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" 495 | dependencies = [ 496 | "bitflags", 497 | "cfg-if", 498 | "foreign-types", 499 | "libc", 500 | "once_cell", 501 | "openssl-macros", 502 | "openssl-sys", 503 | ] 504 | 505 | [[package]] 506 | name = "openssl-macros" 507 | version = "0.1.0" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" 510 | dependencies = [ 511 | "proc-macro2", 512 | "quote", 513 | "syn", 514 | ] 515 | 516 | [[package]] 517 | name = "openssl-probe" 518 | version = "0.1.5" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 521 | 522 | [[package]] 523 | name = "openssl-sys" 524 | version = "0.9.75" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" 527 | dependencies = [ 528 | "autocfg", 529 | "cc", 530 | "libc", 531 | "pkg-config", 532 | "vcpkg", 533 | ] 534 | 535 | [[package]] 536 | name = "parking_lot" 537 | version = "0.12.1" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 540 | dependencies = [ 541 | "lock_api", 542 | "parking_lot_core", 543 | ] 544 | 545 | [[package]] 546 | name = "parking_lot_core" 547 | version = "0.9.5" 548 | source = "registry+https://github.com/rust-lang/crates.io-index" 549 | checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" 550 | dependencies = [ 551 | "cfg-if", 552 | "libc", 553 | "redox_syscall", 554 | "smallvec", 555 | "windows-sys 0.42.0", 556 | ] 557 | 558 | [[package]] 559 | name = "percent-encoding" 560 | version = "2.1.0" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 563 | 564 | [[package]] 565 | name = "pin-project-lite" 566 | version = "0.2.9" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 569 | 570 | [[package]] 571 | name = "pin-utils" 572 | version = "0.1.0" 573 | source = "registry+https://github.com/rust-lang/crates.io-index" 574 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 575 | 576 | [[package]] 577 | name = "pkg-config" 578 | version = "0.3.25" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" 581 | 582 | [[package]] 583 | name = "proc-macro2" 584 | version = "1.0.43" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" 587 | dependencies = [ 588 | "unicode-ident", 589 | ] 590 | 591 | [[package]] 592 | name = "quote" 593 | version = "1.0.21" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 596 | dependencies = [ 597 | "proc-macro2", 598 | ] 599 | 600 | [[package]] 601 | name = "redox_syscall" 602 | version = "0.2.16" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 605 | dependencies = [ 606 | "bitflags", 607 | ] 608 | 609 | [[package]] 610 | name = "regex" 611 | version = "1.7.0" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" 614 | dependencies = [ 615 | "aho-corasick", 616 | "memchr", 617 | "regex-syntax", 618 | ] 619 | 620 | [[package]] 621 | name = "regex-syntax" 622 | version = "0.6.28" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" 625 | 626 | [[package]] 627 | name = "remove_dir_all" 628 | version = "0.5.3" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 631 | dependencies = [ 632 | "winapi", 633 | ] 634 | 635 | [[package]] 636 | name = "reqwest" 637 | version = "0.11.13" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" 640 | dependencies = [ 641 | "base64", 642 | "bytes", 643 | "encoding_rs", 644 | "futures-core", 645 | "futures-util", 646 | "h2", 647 | "http", 648 | "http-body", 649 | "hyper", 650 | "hyper-tls", 651 | "ipnet", 652 | "js-sys", 653 | "log", 654 | "mime", 655 | "native-tls", 656 | "once_cell", 657 | "percent-encoding", 658 | "pin-project-lite", 659 | "serde", 660 | "serde_json", 661 | "serde_urlencoded", 662 | "tokio", 663 | "tokio-native-tls", 664 | "tower-service", 665 | "url", 666 | "wasm-bindgen", 667 | "wasm-bindgen-futures", 668 | "web-sys", 669 | "winreg", 670 | ] 671 | 672 | [[package]] 673 | name = "ryu" 674 | version = "1.0.11" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" 677 | 678 | [[package]] 679 | name = "schannel" 680 | version = "0.1.20" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" 683 | dependencies = [ 684 | "lazy_static", 685 | "windows-sys 0.36.1", 686 | ] 687 | 688 | [[package]] 689 | name = "scopeguard" 690 | version = "1.1.0" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 693 | 694 | [[package]] 695 | name = "security-framework" 696 | version = "2.6.1" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" 699 | dependencies = [ 700 | "bitflags", 701 | "core-foundation", 702 | "core-foundation-sys", 703 | "libc", 704 | "security-framework-sys", 705 | ] 706 | 707 | [[package]] 708 | name = "security-framework-sys" 709 | version = "2.6.1" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" 712 | dependencies = [ 713 | "core-foundation-sys", 714 | "libc", 715 | ] 716 | 717 | [[package]] 718 | name = "serde" 719 | version = "1.0.142" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2" 722 | dependencies = [ 723 | "serde_derive", 724 | ] 725 | 726 | [[package]] 727 | name = "serde_derive" 728 | version = "1.0.142" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "34b5b8d809babe02f538c2cfec6f2c1ed10804c0e5a6a041a049a4f5588ccc2e" 731 | dependencies = [ 732 | "proc-macro2", 733 | "quote", 734 | "syn", 735 | ] 736 | 737 | [[package]] 738 | name = "serde_json" 739 | version = "1.0.83" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" 742 | dependencies = [ 743 | "itoa", 744 | "ryu", 745 | "serde", 746 | ] 747 | 748 | [[package]] 749 | name = "serde_urlencoded" 750 | version = "0.7.1" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 753 | dependencies = [ 754 | "form_urlencoded", 755 | "itoa", 756 | "ryu", 757 | "serde", 758 | ] 759 | 760 | [[package]] 761 | name = "signal-hook-registry" 762 | version = "1.4.0" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 765 | dependencies = [ 766 | "libc", 767 | ] 768 | 769 | [[package]] 770 | name = "slab" 771 | version = "0.4.7" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 774 | dependencies = [ 775 | "autocfg", 776 | ] 777 | 778 | [[package]] 779 | name = "smallvec" 780 | version = "1.10.0" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 783 | 784 | [[package]] 785 | name = "socket2" 786 | version = "0.4.7" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" 789 | dependencies = [ 790 | "libc", 791 | "winapi", 792 | ] 793 | 794 | [[package]] 795 | name = "syn" 796 | version = "1.0.99" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" 799 | dependencies = [ 800 | "proc-macro2", 801 | "quote", 802 | "unicode-ident", 803 | ] 804 | 805 | [[package]] 806 | name = "tar" 807 | version = "0.4.38" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" 810 | dependencies = [ 811 | "filetime", 812 | "libc", 813 | "xattr", 814 | ] 815 | 816 | [[package]] 817 | name = "tempfile" 818 | version = "3.3.0" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 821 | dependencies = [ 822 | "cfg-if", 823 | "fastrand", 824 | "libc", 825 | "redox_syscall", 826 | "remove_dir_all", 827 | "winapi", 828 | ] 829 | 830 | [[package]] 831 | name = "thiserror" 832 | version = "1.0.32" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" 835 | dependencies = [ 836 | "thiserror-impl", 837 | ] 838 | 839 | [[package]] 840 | name = "thiserror-impl" 841 | version = "1.0.32" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" 844 | dependencies = [ 845 | "proc-macro2", 846 | "quote", 847 | "syn", 848 | ] 849 | 850 | [[package]] 851 | name = "tinyvec" 852 | version = "1.6.0" 853 | source = "registry+https://github.com/rust-lang/crates.io-index" 854 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 855 | dependencies = [ 856 | "tinyvec_macros", 857 | ] 858 | 859 | [[package]] 860 | name = "tinyvec_macros" 861 | version = "0.1.0" 862 | source = "registry+https://github.com/rust-lang/crates.io-index" 863 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 864 | 865 | [[package]] 866 | name = "tokio" 867 | version = "1.23.0" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" 870 | dependencies = [ 871 | "autocfg", 872 | "bytes", 873 | "libc", 874 | "memchr", 875 | "mio", 876 | "num_cpus", 877 | "parking_lot", 878 | "pin-project-lite", 879 | "signal-hook-registry", 880 | "socket2", 881 | "tokio-macros", 882 | "windows-sys 0.42.0", 883 | ] 884 | 885 | [[package]] 886 | name = "tokio-macros" 887 | version = "1.8.2" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" 890 | dependencies = [ 891 | "proc-macro2", 892 | "quote", 893 | "syn", 894 | ] 895 | 896 | [[package]] 897 | name = "tokio-native-tls" 898 | version = "0.3.0" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" 901 | dependencies = [ 902 | "native-tls", 903 | "tokio", 904 | ] 905 | 906 | [[package]] 907 | name = "tokio-util" 908 | version = "0.7.4" 909 | source = "registry+https://github.com/rust-lang/crates.io-index" 910 | checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" 911 | dependencies = [ 912 | "bytes", 913 | "futures-core", 914 | "futures-sink", 915 | "pin-project-lite", 916 | "tokio", 917 | "tracing", 918 | ] 919 | 920 | [[package]] 921 | name = "tower-service" 922 | version = "0.3.2" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 925 | 926 | [[package]] 927 | name = "tracing" 928 | version = "0.1.36" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" 931 | dependencies = [ 932 | "cfg-if", 933 | "pin-project-lite", 934 | "tracing-core", 935 | ] 936 | 937 | [[package]] 938 | name = "tracing-core" 939 | version = "0.1.29" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" 942 | dependencies = [ 943 | "once_cell", 944 | ] 945 | 946 | [[package]] 947 | name = "try-lock" 948 | version = "0.2.3" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 951 | 952 | [[package]] 953 | name = "unicode-bidi" 954 | version = "0.3.8" 955 | source = "registry+https://github.com/rust-lang/crates.io-index" 956 | checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" 957 | 958 | [[package]] 959 | name = "unicode-ident" 960 | version = "1.0.3" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" 963 | 964 | [[package]] 965 | name = "unicode-normalization" 966 | version = "0.1.21" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" 969 | dependencies = [ 970 | "tinyvec", 971 | ] 972 | 973 | [[package]] 974 | name = "url" 975 | version = "2.2.2" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" 978 | dependencies = [ 979 | "form_urlencoded", 980 | "idna", 981 | "matches", 982 | "percent-encoding", 983 | ] 984 | 985 | [[package]] 986 | name = "vcpkg" 987 | version = "0.2.15" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 990 | 991 | [[package]] 992 | name = "want" 993 | version = "0.3.0" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 996 | dependencies = [ 997 | "log", 998 | "try-lock", 999 | ] 1000 | 1001 | [[package]] 1002 | name = "wasi" 1003 | version = "0.11.0+wasi-snapshot-preview1" 1004 | source = "registry+https://github.com/rust-lang/crates.io-index" 1005 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1006 | 1007 | [[package]] 1008 | name = "wasm-bindgen" 1009 | version = "0.2.82" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" 1012 | dependencies = [ 1013 | "cfg-if", 1014 | "wasm-bindgen-macro", 1015 | ] 1016 | 1017 | [[package]] 1018 | name = "wasm-bindgen-backend" 1019 | version = "0.2.82" 1020 | source = "registry+https://github.com/rust-lang/crates.io-index" 1021 | checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" 1022 | dependencies = [ 1023 | "bumpalo", 1024 | "log", 1025 | "once_cell", 1026 | "proc-macro2", 1027 | "quote", 1028 | "syn", 1029 | "wasm-bindgen-shared", 1030 | ] 1031 | 1032 | [[package]] 1033 | name = "wasm-bindgen-futures" 1034 | version = "0.4.32" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" 1037 | dependencies = [ 1038 | "cfg-if", 1039 | "js-sys", 1040 | "wasm-bindgen", 1041 | "web-sys", 1042 | ] 1043 | 1044 | [[package]] 1045 | name = "wasm-bindgen-macro" 1046 | version = "0.2.82" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" 1049 | dependencies = [ 1050 | "quote", 1051 | "wasm-bindgen-macro-support", 1052 | ] 1053 | 1054 | [[package]] 1055 | name = "wasm-bindgen-macro-support" 1056 | version = "0.2.82" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" 1059 | dependencies = [ 1060 | "proc-macro2", 1061 | "quote", 1062 | "syn", 1063 | "wasm-bindgen-backend", 1064 | "wasm-bindgen-shared", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "wasm-bindgen-shared" 1069 | version = "0.2.82" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" 1072 | 1073 | [[package]] 1074 | name = "web-sys" 1075 | version = "0.3.59" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" 1078 | dependencies = [ 1079 | "js-sys", 1080 | "wasm-bindgen", 1081 | ] 1082 | 1083 | [[package]] 1084 | name = "winapi" 1085 | version = "0.3.9" 1086 | source = "registry+https://github.com/rust-lang/crates.io-index" 1087 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1088 | dependencies = [ 1089 | "winapi-i686-pc-windows-gnu", 1090 | "winapi-x86_64-pc-windows-gnu", 1091 | ] 1092 | 1093 | [[package]] 1094 | name = "winapi-i686-pc-windows-gnu" 1095 | version = "0.4.0" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1098 | 1099 | [[package]] 1100 | name = "winapi-x86_64-pc-windows-gnu" 1101 | version = "0.4.0" 1102 | source = "registry+https://github.com/rust-lang/crates.io-index" 1103 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1104 | 1105 | [[package]] 1106 | name = "windows-sys" 1107 | version = "0.36.1" 1108 | source = "registry+https://github.com/rust-lang/crates.io-index" 1109 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 1110 | dependencies = [ 1111 | "windows_aarch64_msvc 0.36.1", 1112 | "windows_i686_gnu 0.36.1", 1113 | "windows_i686_msvc 0.36.1", 1114 | "windows_x86_64_gnu 0.36.1", 1115 | "windows_x86_64_msvc 0.36.1", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "windows-sys" 1120 | version = "0.42.0" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 1123 | dependencies = [ 1124 | "windows_aarch64_gnullvm", 1125 | "windows_aarch64_msvc 0.42.0", 1126 | "windows_i686_gnu 0.42.0", 1127 | "windows_i686_msvc 0.42.0", 1128 | "windows_x86_64_gnu 0.42.0", 1129 | "windows_x86_64_gnullvm", 1130 | "windows_x86_64_msvc 0.42.0", 1131 | ] 1132 | 1133 | [[package]] 1134 | name = "windows_aarch64_gnullvm" 1135 | version = "0.42.0" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" 1138 | 1139 | [[package]] 1140 | name = "windows_aarch64_msvc" 1141 | version = "0.36.1" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 1144 | 1145 | [[package]] 1146 | name = "windows_aarch64_msvc" 1147 | version = "0.42.0" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" 1150 | 1151 | [[package]] 1152 | name = "windows_i686_gnu" 1153 | version = "0.36.1" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 1156 | 1157 | [[package]] 1158 | name = "windows_i686_gnu" 1159 | version = "0.42.0" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" 1162 | 1163 | [[package]] 1164 | name = "windows_i686_msvc" 1165 | version = "0.36.1" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 1168 | 1169 | [[package]] 1170 | name = "windows_i686_msvc" 1171 | version = "0.42.0" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" 1174 | 1175 | [[package]] 1176 | name = "windows_x86_64_gnu" 1177 | version = "0.36.1" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 1180 | 1181 | [[package]] 1182 | name = "windows_x86_64_gnu" 1183 | version = "0.42.0" 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" 1185 | checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" 1186 | 1187 | [[package]] 1188 | name = "windows_x86_64_gnullvm" 1189 | version = "0.42.0" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" 1192 | 1193 | [[package]] 1194 | name = "windows_x86_64_msvc" 1195 | version = "0.36.1" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 1198 | 1199 | [[package]] 1200 | name = "windows_x86_64_msvc" 1201 | version = "0.42.0" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" 1204 | 1205 | [[package]] 1206 | name = "winreg" 1207 | version = "0.10.1" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" 1210 | dependencies = [ 1211 | "winapi", 1212 | ] 1213 | 1214 | [[package]] 1215 | name = "xattr" 1216 | version = "0.2.3" 1217 | source = "registry+https://github.com/rust-lang/crates.io-index" 1218 | checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" 1219 | dependencies = [ 1220 | "libc", 1221 | ] 1222 | -------------------------------------------------------------------------------- /compiled_starters/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docker-starter-rust" 3 | version = "0.1.0" 4 | authors = ["Codecrafters "] 5 | edition = "2021" 6 | 7 | [dependencies] 8 | reqwest = { version = "0.11.13", features = ["json", "blocking"] } # http requests 9 | bytes = "1.3.0" # helps wrap responses from reqwest 10 | tokio = { version = "1.23.0", features = ["full"] } # async http requests 11 | libc = "0.2.103" # for syscalls like chroot 12 | serde = { version = "1.0.136", features = ["derive"] } # for json mangling 13 | serde_json = "1.0.79" # for json mangling 14 | anyhow = "1.0.59" # error handling 15 | thiserror = "1.0.32" # error handling 16 | tempfile = "3" # creating temporary directories 17 | regex = "1" # for regular expressions 18 | flate2 = "1.0.25" # for handling compressed data 19 | tar = "0.4.38" 20 | -------------------------------------------------------------------------------- /compiled_starters/rust/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.77-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | # Grab the dependencies and compile them as they dont change much 9 | COPY Cargo.toml /app/Cargo.toml 10 | COPY Cargo.lock /app/Cargo.lock 11 | 12 | RUN mkdir /app/src 13 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 14 | 15 | WORKDIR /app 16 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | # Grab the real code 20 | COPY . /app 21 | 22 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 23 | 24 | ENTRYPOINT ["/app/your_docker.sh"] 25 | -------------------------------------------------------------------------------- /compiled_starters/rust/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Rust solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `src/main.rs`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | 52 | This command compiles your Rust project, so it might be slow the first time you 53 | run it. Subsequent runs will be fast. 54 | -------------------------------------------------------------------------------- /compiled_starters/rust/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Rust version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: rust-1.77 11 | language_pack: rust-1.77 12 | -------------------------------------------------------------------------------- /compiled_starters/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{Context, Result}; 2 | 3 | // Usage: your_docker.sh run ... 4 | fn main() -> Result<()> { 5 | // You can use print statements as follows for debugging, they'll be visible when running tests. 6 | println!("Logs from your program will appear here!"); 7 | 8 | // Uncomment this block to pass the first stage! 9 | // let args: Vec<_> = std::env::args().collect(); 10 | // let command = &args[3]; 11 | // let command_args = &args[4..]; 12 | // let output = std::process::Command::new(command) 13 | // .args(command_args) 14 | // .output() 15 | // .with_context(|| { 16 | // format!( 17 | // "Tried to run '{}' with arguments {:?}", 18 | // command, command_args 19 | // ) 20 | // })?; 21 | // 22 | // if output.status.success() { 23 | // let std_out = std::str::from_utf8(&output.stdout)?; 24 | // println!("{}", std_out); 25 | // } else { 26 | // std::process::exit(1); 27 | // } 28 | 29 | Ok(()) 30 | } 31 | -------------------------------------------------------------------------------- /compiled_starters/rust/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec cargo run \ 3 | --quiet \ 4 | --release \ 5 | --target-dir=/tmp/codecrafters-docker-target \ 6 | --manifest-path "$(dirname "$0")/Cargo.toml" "$@" 7 | -------------------------------------------------------------------------------- /compiled_starters/swift/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /compiled_starters/swift/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | -------------------------------------------------------------------------------- /compiled_starters/swift/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM swift:5.6.1-focal 2 | 3 | RUN apt-get update && \ 4 | apt-get install --no-install-recommends -y curl=7.68.* && \ 5 | apt-get clean && \ 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | # Download docker-explorer 9 | ARG docker_explorer_version=v18 10 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 11 | RUN chmod +x /usr/local/bin/docker-explorer 12 | 13 | -------------------------------------------------------------------------------- /compiled_starters/swift/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.6 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "swift-docker-challenge", 8 | dependencies: [ 9 | // Dependencies declare other packages that this package depends on. 10 | // .package(url: /* package url */, from: "1.0.0"), 11 | ], 12 | targets: [ 13 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 14 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 15 | .executableTarget( 16 | name: "swift-docker-challenge", 17 | dependencies: []), 18 | ] 19 | ) 20 | -------------------------------------------------------------------------------- /compiled_starters/swift/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Swift solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is 18 | `Sources/swift-docker-challenge/Main.swift`. Study and uncomment the relevant 19 | code, and push your changes to pass the first stage: 20 | 21 | ```sh 22 | git commit -am "pass 1st stage" # any msg 23 | git push origin master 24 | ``` 25 | 26 | That's all! 27 | 28 | # Stage 2 & beyond 29 | 30 | Note: This section is for stages 2 and beyond. 31 | 32 | You'll use linux-specific syscalls in this challenge. so we'll run your code 33 | _inside_ a Docker container. 34 | 35 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 36 | locally. 37 | 38 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 39 | 40 | ```sh 41 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 42 | ``` 43 | 44 | (The `--cap-add="SYS_ADMIN"` flag is required to create 45 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 46 | 47 | You can now execute your program like this: 48 | 49 | ```sh 50 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 51 | ``` 52 | -------------------------------------------------------------------------------- /compiled_starters/swift/Sources/swift-docker-challenge/Main.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | @main 4 | struct Main { 5 | 6 | // Usage: your_docker.sh run ... 7 | static func main() async throws { 8 | // You can use print statements as follows for debugging, they'll be visible when running tests. 9 | print("Logs from your program will appear here!") 10 | 11 | // Uncomment this block to pass the first stage! 12 | // let command = CommandLine.arguments[3] 13 | // let arguments = CommandLine.arguments.dropFirst(4).map { String($0) } 14 | // let process = Process() 15 | // process.executableURL = URL(fileURLWithPath: command) 16 | // process.arguments = arguments 17 | // try process.run() 18 | // process.waitUntilExit() 19 | // guard process.terminationStatus == .zero, let output = process.standardOutput as? String else { 20 | // exit(1) 21 | // } 22 | // print(output) 23 | 24 | exit(0) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /compiled_starters/swift/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Swift version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: swift-5.6 11 | language_pack: swift-5.6 12 | -------------------------------------------------------------------------------- /compiled_starters/swift/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # Swift build writes errors to stdout instead of stderr. Let's collect all output in a file and only print if the exit code is zero. 6 | buildOutputFile=$(mktemp) 7 | swift build -c release > "$buildOutputFile" || (cat "$buildOutputFile" && exit 1) 8 | exec swift run -c release --skip-build swift-docker-challenge "$@" 9 | -------------------------------------------------------------------------------- /course-definition.yml: -------------------------------------------------------------------------------- 1 | slug: "docker" 2 | name: "Build your own Docker" 3 | short_name: "Docker" 4 | release_status: "deprecated" 5 | 6 | # This is shown on the course overview page. Markdown supported, recommended length ~40 words. 7 | # 8 | # Recommended format: 9 | # 10 | # > ABC is . In this challenge, you'll build your own ABC that's capable of D, E, F and G. 11 | # > 12 | # > Along the way, we'll learn about X, Y, Z and more. 13 | # 14 | # Example: 15 | # 16 | # > Redis is an in-memory data structure store often used as a database, cache, message broken and streaming engine. In this challenge 17 | # > you'll build your own Redis server that is capable of serving basic commands, reading RDB files and more. 18 | # > 19 | # > Along the way, you'll learn about TCP servers, the Redis Protocol and more. 20 | description_md: |- 21 | Docker is a tool used to build & run applications in containers. In this challenge, you'll build 22 | your own Docker implementation that can pull an image from Docker Hub and execute commands in it. 23 | 24 | Along the way, you'll learn about chroot, kernel namespaces, the Docker registry API and much more. 25 | 26 | # Keep this under 70 characters 27 | short_description_md: |- 28 | Learn about kernel namespaces, chroot, the registry API and more 29 | 30 | completion_percentage: 30 31 | 32 | languages: 33 | - slug: "c" 34 | 35 | - slug: "go" 36 | 37 | - slug: "nim" 38 | 39 | - slug: "php" 40 | 41 | - slug: "python" 42 | release_status: "beta" 43 | 44 | - slug: "ruby" 45 | release_status: "beta" 46 | 47 | - slug: "rust" 48 | 49 | - slug: "swift" 50 | release_status: "alpha" 51 | alpha_tester_usernames: ["Terky"] 52 | 53 | marketing: 54 | difficulty: medium 55 | sample_extension_idea_title: "Build from Dockerfile" 56 | sample_extension_idea_description: "A Docker implementation that can build images from a Dockerfile" 57 | testimonials: 58 | - author_name: "Raghav Dua" 59 | author_description: "SRE, Coinbase" 60 | author_avatar: "https://codecrafters.io/images/external/testimonials/raghav-dua.jpeg" 61 | link: "https://github.com/duaraghav8" 62 | text: |- 63 | I spent a full day on your Docker building course and ended up building the whole thing myself. As a SRE (and 64 | mostly a user of docker), digging into the internals blew me away. 65 | 66 | - author_name: "Beyang Liu" 67 | author_description: "CTO at SourceGraph" 68 | author_avatar: "https://codecrafters.io/images/external/testimonials/beyang-liu.jpeg" 69 | link: "https://twitter.com/beyang" 70 | text: |- 71 | CodeCrafters has you build your own version of things like Git and Docker from scratch. A cool way to build a stronger mental model of how those tools work. 72 | 73 | stages: 74 | - slug: "je9" 75 | name: "Execute a program" 76 | difficulty: very_easy 77 | description_md: |- 78 | Your task is to implement a very basic version 79 | of [`docker run`](https://docs.docker.com/engine/reference/run/). It will 80 | be executed similar to `docker run`: 81 | 82 | ``` 83 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 84 | ``` 85 | 86 | [docker-explorer](https://github.com/codecrafters-io/docker-explorer) is a custom test program that exposes 87 | commands like `echo` and `ls`. 88 | 89 | For now, don't worry about pulling the `alpine:latest` image. We will just 90 | execute a local program for this stage and print its output. You'll work on 91 | pulling images from Docker Hub in stage 6. 92 | marketing_md: |- 93 | In this stage, you'll execute a program using `fork` + `exec`. 94 | tester_source_code_url: "https://github.com/codecrafters-io/docker-tester/blob/18245703a5beed8ee0a7e1cbb7204a7ee3b3b5d1/internal/stage_basic_exec.go#L9" 95 | 96 | - slug: "kf3" 97 | name: "Wireup stdout & stderr" 98 | difficulty: easy 99 | description_md: |- 100 | You'll now pipe the program's stdout and stderr to the 101 | parent process. 102 | 103 | Like the last stage, the tester will run your program like this: 104 | 105 | ``` 106 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 107 | ``` 108 | 109 | To test this behaviour locally, you could use the `echo` + `echo_stderr` 110 | commands that `docker-explorer` exposes. Run `docker-explorer --help` to 111 | view usage. 112 | 113 | If you've got any logs or print statements in your code, make sure to remove 114 | them. The tester can't differentiate between debug logs and the actual 115 | output! 116 | 117 | Note: The **README** in your repository contains setup 118 | information for this stage and beyond (takes < 5 min). 119 | marketing_md: |- 120 | In this stage, you'll relay the child program's stdout & stderr to the 121 | parent process. 122 | tester_source_code_url: "https://github.com/codecrafters-io/docker-tester/blob/18245703a5beed8ee0a7e1cbb7204a7ee3b3b5d1/internal/stage_stdio.go#L9" 123 | 124 | - slug: "cn8" 125 | name: "Handle exit codes" 126 | difficulty: easy 127 | description_md: |- 128 | In this stage, you'll need to relay the program's exit code to the parent 129 | process. 130 | 131 | If the program you're executing exits with exit code 1, your program 132 | should exit with exit code 1 too. 133 | 134 | To test this behaviour locally, you could use the `exit` command that 135 | `docker-explorer` exposes. Run `docker-explorer --help` to view usage. 136 | 137 | Just like the previous stage, the tester will run your program like this: 138 | 139 | ``` 140 | mydocker run alpine:latest /usr/local/bin/docker-explorer exit 1 141 | ``` 142 | marketing_md: |- 143 | In this stage, you'll wait for the child program's exit code and exit with 144 | it. 145 | tester_source_code_url: "https://github.com/codecrafters-io/docker-tester/blob/18245703a5beed8ee0a7e1cbb7204a7ee3b3b5d1/internal/stage_exit_code.go#L9" 146 | 147 | - slug: "if6" 148 | name: "Filesystem isolation" 149 | difficulty: medium 150 | description_md: |- 151 | In the previous stage, we executed a program that existed locally on our 152 | machine. This program had write access to the whole filesystem, which 153 | means that it could do **dangerous** things! 154 | 155 | In this stage, you'll use [chroot](https://en.wikipedia.org/wiki/Chroot) 156 | to ensure that the program you execute doesn't have access to any files on 157 | the host machine. Create an empty temporary directory and `chroot` into it 158 | when executing the command. You'll need to copy the binary being executed 159 | too. 160 | 161 | {{#lang_is_rust}} 162 | At the time of writing this, the implementation of chroot in Rust's standard library 163 | ([std::os::unix::fs::chroot](https://doc.rust-lang.org/std/os/unix/fs/fn.chroot.html)) is still a 164 | nightly-only experimental API. We've included [libc](https://crates.io/crates/libc) as a dependency 165 | instead. 166 | {{/lang_is_rust}} 167 | 168 | {{#lang_is_nim}} 169 | Since Nim's [posix module](https://nim-lang.org/docs/posix.html) doesn't 170 | have `chroot` defined, you'll need to implement this yourself! For 171 | examples on how to do this, view the source for other syscalls like 172 | [chdir](https://nim-lang.org/docs/posix.html#chdir%2Ccstring). 173 | {{/lang_is_nim}} 174 | 175 | {{#lang_is_go}} 176 | When executing your program within the chroot directory, you might run into an error that says 177 | `open /dev/null: no such file or directory`. This is because [Cmd.Run()](https://golang.org/pkg/os/exec/#Cmd.Run) 178 | and its siblings expect `/dev/null` to be present. You can work around this by either creating an empty 179 | `/dev/null` file inside the chroot directory, or by ensuring that `Cmd.Stdout`, `Cmd.Stderr` and `Cmd.Stdin` are not `nil`. 180 | More details about this [here](https://rohitpaulk.com/articles/cmd-run-dev-null). 181 | {{/lang_is_go}} 182 | 183 | {{#lang_is_rust}} 184 | When executing your program within the chroot directory, you might run into an error that says 185 | `no such file or directory` even if the binary exists within the chroot. This is because 186 | [Command::output()](https://doc.rust-lang.org/std/process/struct.Command.html#method.output) 187 | expects `/dev/null` to be present. You can work around this by creating an empty 188 | `/dev/null` file inside the chroot directory. This cryptic error effects Go programs too, more details 189 | [here](https://rohitpaulk.com/articles/cmd-run-dev-null). 190 | {{/lang_is_rust}} 191 | 192 | Just like the previous stage, the tester will run your program like this: 193 | 194 | ``` 195 | mydocker run alpine:latest /usr/local/bin/docker-explorer ls /some_dir 196 | ``` 197 | marketing_md: |- 198 | In this stage, you'll restrict a program's access to the host filesystem 199 | by using [chroot](https://en.wikipedia.org/wiki/Chroot). 200 | tester_source_code_url: "https://github.com/codecrafters-io/docker-tester/blob/18245703a5beed8ee0a7e1cbb7204a7ee3b3b5d1/internal/stage_fs_isolation.go#L8" 201 | 202 | - slug: "lu7" 203 | name: "Process isolation" 204 | difficulty: medium 205 | description_md: |- 206 | In the previous stage, we guarded against malicious activity by 207 | restricting an executable's access to the filesystem. 208 | 209 | There's another resource that needs to be guarded: the process tree. The 210 | process you're executing is currently capable of viewing all other 211 | processes running on the host system, and sending signals to them. 212 | 213 | In this stage, you'll use [PID 214 | namespaces](http://man7.org/linux/man-pages/man7/pid_namespaces.7.html) to 215 | ensure that the program you execute has its own isolated process tree. 216 | The process being executed must see itself as PID 1. 217 | 218 | {{#lang_is_php}} 219 | You'll need to use the `pcntl_unshare` function for this, which was 220 | [added in PHP 7.4](https://www.php.net/manual/en/migration74.new-functions.php), and isn't properly documented 221 | yet (as of 22 Jan 2021). Here's the [pull request](https://github.com/php/php-src/pull/3760) where it was added. 222 | {{/lang_is_php}} 223 | 224 | Just like the previous stage, the tester will run your program like this: 225 | 226 | ``` 227 | mydocker run alpine:latest /usr/local/bin/docker-explorer mypid 228 | ``` 229 | marketing_md: |- 230 | In this stage, you'll restrict a program's access to the host's process 231 | tree by using [PID 232 | namespaces](http://man7.org/linux/man-pages/man7/pid_namespaces.7.html). 233 | tester_source_code_url: "https://github.com/codecrafters-io/docker-tester/blob/18245703a5beed8ee0a7e1cbb7204a7ee3b3b5d1/internal/stage_process_isolation.go#L5" 234 | 235 | - slug: "hs1" 236 | name: "Fetch an image from the Docker Registry" 237 | should_skip_previous_stages_for_test_run: true 238 | difficulty: hard 239 | description_md: |- 240 | Your docker implementation can now execute a program with a fair degree of 241 | isolation - it can't modify files or interact with processes running on 242 | the host. 243 | 244 | In this stage, you'll use [the Docker registry 245 | API](https://docs.docker.com/registry/spec/api/) to fetch the contents of 246 | a public image on [Docker Hub](https://hub.docker.com/) and then execute a 247 | command within it. 248 | 249 | You'll need to: 250 | 251 | - Do a small [authentication dance](https://docs.docker.com/registry/spec/auth/token/) 252 | - Fetch the [image manifest](https://docs.docker.com/registry/spec/api/#pulling-an-image-manifest) 253 | - [Pull layers](https://docs.docker.com/registry/spec/api/#pulling-a-layer) of an image and extract them to the chroot directory 254 | 255 | The base URL for Docker Hub's public registry is `registry.hub.docker.com`. 256 | 257 | The tester will run your program like this: 258 | 259 | ``` 260 | mydocker run alpine:latest /bin/echo hey 261 | ``` 262 | 263 | The image used will be an [official 264 | image](https://docs.docker.com/docker-hub/official_images/) from Docker 265 | Hub. For example: [`alpine:latest`](https://hub.docker.com/_/alpine), 266 | [`alpine:latest`](https://hub.docker.com/_/alpine), 267 | [`busybox:latest`](https://hub.docker.com/_/busybox). When interacting with the 268 | Registry API, you'll need to prepend `library/` to the image names. 269 | 270 | {{#lang_is_rust}} 271 | Since Rust doesn't have an archive extraction utility in its stdlib, you 272 | might want to shell out and use `tar`. 273 | 274 | You can use the [reqwest](https://crates.io/crates/reqwest) crate to make 275 | HTTP requests, we've included it in the `Cargo.toml` file. We've also included 276 | [serde_json](https://crates.io/crates/serde_json) to help with parsing JSON. 277 | {{/lang_is_rust}} 278 | 279 | {{#lang_is_go}} 280 | Since Go doesn't have an archive extraction utility in its stdlib, you 281 | might want to shell out and use `tar`. 282 | {{/lang_is_go}} 283 | 284 | {{#lang_is_nim}} 285 | Since Nim doesn't have an archive extraction utility in its stdlib, you 286 | might want to shell out and use `tar`. 287 | {{/lang_is_nim}} 288 | 289 | {{#lang_is_c}} 290 | Since C doesn't have an archive extraction utility in its stdlib, you 291 | might want to shell out and use `tar`. 292 | 293 | You can assume that `libcurl` is available in the build environment. 294 | {{/lang_is_c}} 295 | marketing_md: |- 296 | In this stage, you'll fetch an image from Docker Hub and execute a command 297 | in it. You'll need to use [the Docker Registry 298 | API](https://docs.docker.com/registry/spec/api/) for this. 299 | tester_source_code_url: "https://github.com/codecrafters-io/docker-tester/blob/18245703a5beed8ee0a7e1cbb7204a7ee3b3b5d1/internal/stage_fetch_from_registry.go#L8" 300 | -------------------------------------------------------------------------------- /dockerfiles/c-9.2.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM n0madic/alpine-gcc:9.2.0 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # For making HTTP requests using libcurl 6 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 7 | 8 | # Download docker-explorer 9 | ARG docker_explorer_version=v18 10 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 11 | RUN chmod +x /usr/local/bin/docker-explorer 12 | -------------------------------------------------------------------------------- /dockerfiles/go-1.13.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.13-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | -------------------------------------------------------------------------------- /dockerfiles/go-1.16.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.16-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | -------------------------------------------------------------------------------- /dockerfiles/go-1.19.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.19-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="go.mod,go.sum" 11 | 12 | WORKDIR /app 13 | 14 | COPY go.mod go.sum ./ 15 | 16 | RUN go mod download 17 | -------------------------------------------------------------------------------- /dockerfiles/go-1.21.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.21-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="go.mod,go.sum" 11 | 12 | WORKDIR /app 13 | 14 | COPY go.mod go.sum ./ 15 | 16 | # Starting from Go 1.20, the go standard library is no loger compiled 17 | # setting the GODEBUG environment to "installgoroot=all" restores the old behavior 18 | RUN GODEBUG="installgoroot=all" go install std 19 | 20 | RUN go mod download 21 | -------------------------------------------------------------------------------- /dockerfiles/go-1.22.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.22-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="go.mod,go.sum" 11 | 12 | WORKDIR /app 13 | 14 | COPY go.mod go.sum ./ 15 | 16 | # Starting from Go 1.20, the go standard library is no loger compiled 17 | # setting the GODEBUG environment to "installgoroot=all" restores the old behavior 18 | RUN GODEBUG="installgoroot=all" go install std 19 | 20 | RUN go mod download 21 | -------------------------------------------------------------------------------- /dockerfiles/nim-1.0.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nimlang/nim:1.0.6-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | -------------------------------------------------------------------------------- /dockerfiles/php-7.4.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.4-cli-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | RUN docker-php-ext-install pcntl 7 | 8 | # Download docker-explorer. 9 | ARG docker_explorer_version=v18 10 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 11 | RUN chmod +x /usr/local/bin/docker-explorer 12 | -------------------------------------------------------------------------------- /dockerfiles/python-3.11.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer. 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | -------------------------------------------------------------------------------- /dockerfiles/python-3.12.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.12-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer. 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | -------------------------------------------------------------------------------- /dockerfiles/ruby-2.7.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:2.7-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | # Download docker-explorer 7 | ARG docker_explorer_version=v18 8 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 9 | RUN chmod +x /usr/local/bin/docker-explorer 10 | -------------------------------------------------------------------------------- /dockerfiles/ruby-3.2.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.2-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | # Download docker-explorer 7 | ARG docker_explorer_version=v18 8 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 9 | RUN chmod +x /usr/local/bin/docker-explorer 10 | -------------------------------------------------------------------------------- /dockerfiles/rust-1.43.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.43-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | COPY Cargo.toml /app/Cargo.toml 9 | COPY Cargo.lock /app/Cargo.lock 10 | 11 | RUN mkdir /app/src 12 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 13 | 14 | WORKDIR /app 15 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 16 | 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | RUN rm -rf /app/src 20 | 21 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="Cargo.toml,Cargo.lock" -------------------------------------------------------------------------------- /dockerfiles/rust-1.54.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.54-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | COPY Cargo.toml /app/Cargo.toml 9 | COPY Cargo.lock /app/Cargo.lock 10 | 11 | RUN mkdir /app/src 12 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 13 | 14 | WORKDIR /app 15 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 16 | 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | RUN rm -rf /app/src 20 | 21 | RUN echo "cd \${CODECRAFTERS_REPOSITORY_DIR} && cargo build --release --target-dir=/tmp/codecrafters-docker-target --manifest-path Cargo.toml" > /codecrafters-precompile.sh 22 | RUN chmod +x /codecrafters-precompile.sh 23 | 24 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="Cargo.toml,Cargo.lock" -------------------------------------------------------------------------------- /dockerfiles/rust-1.62.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.62-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | COPY Cargo.toml /app/Cargo.toml 9 | COPY Cargo.lock /app/Cargo.lock 10 | 11 | RUN mkdir /app/src 12 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 13 | 14 | WORKDIR /app 15 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 16 | 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | RUN rm -rf /app/src 20 | 21 | RUN echo "cd \${CODECRAFTERS_REPOSITORY_DIR} && cargo build --release --target-dir=/tmp/codecrafters-docker-target --manifest-path Cargo.toml" > /codecrafters-precompile.sh 22 | RUN chmod +x /codecrafters-precompile.sh 23 | 24 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="Cargo.toml,Cargo.lock" 25 | -------------------------------------------------------------------------------- /dockerfiles/rust-1.68.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.68-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | COPY Cargo.toml /app/Cargo.toml 9 | COPY Cargo.lock /app/Cargo.lock 10 | 11 | RUN mkdir /app/src 12 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 13 | 14 | WORKDIR /app 15 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 16 | 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | RUN rm -rf /app/src 20 | 21 | RUN echo "cd \${CODECRAFTERS_REPOSITORY_DIR} && cargo build --release --target-dir=/tmp/codecrafters-docker-target --manifest-path Cargo.toml" > /codecrafters-precompile.sh 22 | RUN chmod +x /codecrafters-precompile.sh 23 | 24 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="Cargo.toml,Cargo.lock" 25 | -------------------------------------------------------------------------------- /dockerfiles/rust-1.70.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.70-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | COPY Cargo.toml /app/Cargo.toml 9 | COPY Cargo.lock /app/Cargo.lock 10 | 11 | RUN mkdir /app/src 12 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 13 | 14 | WORKDIR /app 15 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 16 | 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | RUN rm -rf /app/src 20 | 21 | RUN echo "cd \${CODECRAFTERS_REPOSITORY_DIR} && cargo build --release --target-dir=/tmp/codecrafters-docker-target --manifest-path Cargo.toml" > /codecrafters-precompile.sh 22 | RUN chmod +x /codecrafters-precompile.sh 23 | 24 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="Cargo.toml,Cargo.lock" 25 | -------------------------------------------------------------------------------- /dockerfiles/rust-1.76.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.76-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | COPY Cargo.toml /app/Cargo.toml 9 | COPY Cargo.lock /app/Cargo.lock 10 | 11 | RUN mkdir /app/src 12 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 13 | 14 | WORKDIR /app 15 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 16 | 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | RUN rm -rf /app/src 20 | 21 | RUN echo "cd \${CODECRAFTERS_REPOSITORY_DIR} && cargo build --release --target-dir=/tmp/codecrafters-docker-target --manifest-path Cargo.toml" > /codecrafters-precompile.sh 22 | RUN chmod +x /codecrafters-precompile.sh 23 | 24 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="Cargo.toml,Cargo.lock" 25 | -------------------------------------------------------------------------------- /dockerfiles/rust-1.77.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.77-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | COPY Cargo.toml /app/Cargo.toml 9 | COPY Cargo.lock /app/Cargo.lock 10 | 11 | RUN mkdir /app/src 12 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 13 | 14 | WORKDIR /app 15 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 16 | 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | RUN rm -rf /app/src 20 | 21 | RUN echo "cd \${CODECRAFTERS_REPOSITORY_DIR} && cargo build --release --target-dir=/tmp/codecrafters-docker-target --manifest-path Cargo.toml" > /codecrafters-precompile.sh 22 | RUN chmod +x /codecrafters-precompile.sh 23 | 24 | ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="Cargo.toml,Cargo.lock" 25 | -------------------------------------------------------------------------------- /dockerfiles/swift-5.6.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM swift:5.6.1-focal 2 | 3 | RUN apt-get update && \ 4 | apt-get install --no-install-recommends -y curl=7.68.* && \ 5 | apt-get clean && \ 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | # Download docker-explorer 9 | ARG docker_explorer_version=v18 10 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 11 | RUN chmod +x /usr/local/bin/docker-explorer 12 | -------------------------------------------------------------------------------- /solutions/c/01-je9/code/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /solutions/c/01-je9/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM n0madic/alpine-gcc:9.2.0 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | # Download docker-explorer 7 | ARG docker_explorer_version=v18 8 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 9 | RUN chmod +x /usr/local/bin/docker-explorer 10 | 11 | COPY . /app 12 | WORKDIR /app 13 | 14 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 15 | 16 | ENTRYPOINT ["/app/your_docker.sh"] 17 | -------------------------------------------------------------------------------- /solutions/c/01-je9/code/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for C solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.c`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /solutions/c/01-je9/code/app/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Usage: your_docker.sh run ... 6 | int main(int argc, char *argv[]) { 7 | // Disable output buffering 8 | setbuf(stdout, NULL); 9 | setbuf(stderr, NULL); 10 | 11 | char *command = argv[3]; 12 | int child_pid = fork(); 13 | if (child_pid == -1) { 14 | printf("Error forking!"); 15 | return 1; 16 | } 17 | 18 | if (child_pid == 0) { 19 | // Replace current program with calling program 20 | execv(command, &argv[3]); 21 | } else { 22 | // We're in parent 23 | wait(NULL); 24 | printf("Child terminated"); 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /solutions/c/01-je9/code/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the C version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: c-9.2 11 | language_pack: c-9.2 12 | -------------------------------------------------------------------------------- /solutions/c/01-je9/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | tmpFile=$(mktemp) 4 | gcc -lcurl app/*.c -o $tmpFile 5 | exec "$tmpFile" "$@" 6 | -------------------------------------------------------------------------------- /solutions/c/01-je9/diff/app/main.c.diff: -------------------------------------------------------------------------------- 1 | @@ -1,33 +1,28 @@ 2 | #include 3 | #include 4 | #include 5 | 6 | // Usage: your_docker.sh run ... 7 | int main(int argc, char *argv[]) { 8 | // Disable output buffering 9 | setbuf(stdout, NULL); 10 | setbuf(stderr, NULL); 11 | 12 | - // You can use print statements as follows for debugging, they'll be visible when running tests. 13 | - printf("Logs from your program will appear here!\n"); 14 | + char *command = argv[3]; 15 | + int child_pid = fork(); 16 | + if (child_pid == -1) { 17 | + printf("Error forking!"); 18 | + return 1; 19 | + } 20 | 21 | - // Uncomment this block to pass the first stage 22 | - // 23 | - // char *command = argv[3]; 24 | - // int child_pid = fork(); 25 | - // if (child_pid == -1) { 26 | - // printf("Error forking!"); 27 | - // return 1; 28 | - // } 29 | - // 30 | - // if (child_pid == 0) { 31 | - // // Replace current program with calling program 32 | - // execv(command, &argv[3]); 33 | - // } else { 34 | - // // We're in parent 35 | - // wait(NULL); 36 | - // printf("Child terminated"); 37 | - // } 38 | + if (child_pid == 0) { 39 | + // Replace current program with calling program 40 | + execv(command, &argv[3]); 41 | + } else { 42 | + // We're in parent 43 | + wait(NULL); 44 | + printf("Child terminated"); 45 | + } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /solutions/c/01-je9/explanation.md: -------------------------------------------------------------------------------- 1 | The entry point for your Docker implementation is in `app/main.c`. 2 | 3 | Study and uncomment the relevant code: 4 | 5 | ```c 6 | // Uncomment this block to pass the first stage 7 | 8 | char *command = argv[3]; 9 | int child_pid = fork(); 10 | if (child_pid == -1) { 11 | printf("Error forking!"); 12 | return 1; 13 | } 14 | 15 | if (child_pid == 0) { 16 | // Replace current program with calling program 17 | execv(command, &argv[3]); 18 | } else { 19 | // We're in parent 20 | wait(NULL); 21 | printf("Child terminated"); 22 | } 23 | ``` 24 | 25 | Push your changes to pass the first stage: 26 | 27 | ``` 28 | git add . 29 | git commit -m "pass 1st stage" # any msg 30 | git push origin master 31 | ``` 32 | -------------------------------------------------------------------------------- /solutions/go/01-je9/code/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /solutions/go/01-je9/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.22-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 14 | 15 | ENTRYPOINT ["/app/your_docker.sh"] 16 | -------------------------------------------------------------------------------- /solutions/go/01-je9/code/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Go solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.go`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /solutions/go/01-je9/code/app/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | ) 8 | 9 | // Ensures gofmt doesn't remove the imports above (feel free to remove this!) 10 | var _ = os.Args 11 | var _ = exec.Command 12 | 13 | // Usage: your_docker.sh run ... 14 | func main() { 15 | command := os.Args[3] 16 | args := os.Args[4:len(os.Args)] 17 | 18 | cmd := exec.Command(command, args...) 19 | output, err := cmd.Output() 20 | if err != nil { 21 | fmt.Printf("Err: %v", err) 22 | os.Exit(1) 23 | } 24 | 25 | fmt.Println(string(output)) 26 | } 27 | -------------------------------------------------------------------------------- /solutions/go/01-je9/code/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Go version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: go-1.22 11 | language_pack: go-1.22 12 | -------------------------------------------------------------------------------- /solutions/go/01-je9/code/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/codecrafters-io/docker-starter-go 2 | 3 | go 1.22 4 | -------------------------------------------------------------------------------- /solutions/go/01-je9/code/go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codecrafters-io/build-your-own-docker/f96e97152c526fdb7b474e62be28454791552c26/solutions/go/01-je9/code/go.sum -------------------------------------------------------------------------------- /solutions/go/01-je9/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | tmpFile=$(mktemp) 4 | go build -o "$tmpFile" app/*.go 5 | exec "$tmpFile" "$@" 6 | -------------------------------------------------------------------------------- /solutions/go/01-je9/diff/app/main.go.diff: -------------------------------------------------------------------------------- 1 | @@ -1,31 +1,26 @@ 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | "os" 7 | "os/exec" 8 | ) 9 | 10 | // Ensures gofmt doesn't remove the imports above (feel free to remove this!) 11 | var _ = os.Args 12 | var _ = exec.Command 13 | 14 | // Usage: your_docker.sh run ... 15 | func main() { 16 | - // You can use print statements as follows for debugging, they'll be visible when running tests. 17 | - fmt.Println("Logs from your program will appear here!") 18 | + command := os.Args[3] 19 | + args := os.Args[4:len(os.Args)] 20 | 21 | - // Uncomment this block to pass the first stage! 22 | - // 23 | - // command := os.Args[3] 24 | - // args := os.Args[4:len(os.Args)] 25 | - // 26 | - // cmd := exec.Command(command, args...) 27 | - // output, err := cmd.Output() 28 | - // if err != nil { 29 | - // fmt.Printf("Err: %v", err) 30 | - // os.Exit(1) 31 | - // } 32 | - // 33 | - // fmt.Println(string(output)) 34 | + cmd := exec.Command(command, args...) 35 | + output, err := cmd.Output() 36 | + if err != nil { 37 | + fmt.Printf("Err: %v", err) 38 | + os.Exit(1) 39 | + } 40 | + 41 | + fmt.Println(string(output)) 42 | } 43 | -------------------------------------------------------------------------------- /solutions/go/01-je9/explanation.md: -------------------------------------------------------------------------------- 1 | The entry point for your Docker implementation is in `app/main.go`. 2 | 3 | Study and uncomment the relevant code: 4 | 5 | ```go 6 | // Uncomment this block to pass the first stage! 7 | 8 | command := os.Args[3] 9 | args := os.Args[4:len(os.Args)] 10 | 11 | cmd := exec.Command(command, args...) 12 | output, err := cmd.Output() 13 | if err != nil { 14 | fmt.Printf("Err: %v", err) 15 | os.Exit(1) 16 | } 17 | 18 | fmt.Println(string(output)) 19 | ``` 20 | 21 | Push your changes to pass the first stage: 22 | 23 | ``` 24 | git add . 25 | git commit -m "pass 1st stage" # any msg 26 | git push origin master 27 | ``` 28 | -------------------------------------------------------------------------------- /solutions/nim/01-je9/code/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /solutions/nim/01-je9/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nimlang/nim:1.0.6-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | 5 | # Download docker-explorer. 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 14 | 15 | ENTRYPOINT ["/app/your_docker.sh"] 16 | -------------------------------------------------------------------------------- /solutions/nim/01-je9/code/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Nim solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.nim`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /solutions/nim/01-je9/code/app/main.nim: -------------------------------------------------------------------------------- 1 | # Usage: your_docker.sh run ... 2 | 3 | from os import commandLineParams 4 | from osproc import execProcess 5 | 6 | 7 | let command = commandLineParams()[2] 8 | let args = commandLineParams()[3..^1] 9 | 10 | let output = execProcess(command, "", args, options={}) 11 | echo output 12 | -------------------------------------------------------------------------------- /solutions/nim/01-je9/code/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Nim version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: nim-1.0 11 | language_pack: nim-1.0 12 | -------------------------------------------------------------------------------- /solutions/nim/01-je9/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | tmpFile=$(mktemp) 4 | nim compile --verbosity:0 --hints:off --out:"$tmpFile" app/main.nim 5 | exec "$tmpFile" "$@" 6 | -------------------------------------------------------------------------------- /solutions/nim/01-je9/diff/app/main.nim.diff: -------------------------------------------------------------------------------- 1 | @@ -1,16 +1,11 @@ 2 | # Usage: your_docker.sh run ... 3 | 4 | from os import commandLineParams 5 | from osproc import execProcess 6 | 7 | 8 | -# You can use print statements as follows for debugging, they'll be visible when running tests. 9 | -echo "Logs from your program will appear here" 10 | +let command = commandLineParams()[2] 11 | +let args = commandLineParams()[3..^1] 12 | 13 | -# Uncomment this block to pass the first stage 14 | -# 15 | -# let command = commandLineParams()[2] 16 | -# let args = commandLineParams()[3..^1] 17 | -# 18 | -# let output = execProcess(command, "", args, options={}) 19 | -# echo output 20 | +let output = execProcess(command, "", args, options={}) 21 | +echo output 22 | -------------------------------------------------------------------------------- /solutions/nim/01-je9/explanation.md: -------------------------------------------------------------------------------- 1 | The entry point for your Docker implementation is in `app/main.nim`. 2 | 3 | Study and uncomment the relevant code: 4 | 5 | ```nim 6 | # Uncomment this block to pass the first stage 7 | 8 | let command = commandLineParams()[2] 9 | let args = commandLineParams()[3..^1] 10 | 11 | let output = execProcess(command, "", args, options={}) 12 | echo output 13 | ``` 14 | 15 | Push your changes to pass the first stage: 16 | 17 | ``` 18 | git add . 19 | git commit -m "pass 1st stage" # any msg 20 | git push origin master 21 | ``` 22 | -------------------------------------------------------------------------------- /solutions/php/01-je9/code/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /solutions/php/01-je9/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.4-cli-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | RUN docker-php-ext-install pcntl 7 | 8 | # Download docker-explorer. 9 | ARG docker_explorer_version=v18 10 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 11 | RUN chmod +x /usr/local/bin/docker-explorer 12 | 13 | COPY . /app 14 | WORKDIR /app 15 | 16 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 17 | 18 | ENTRYPOINT ["/app/your_docker.sh"] 19 | -------------------------------------------------------------------------------- /solutions/php/01-je9/code/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for PHP solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.php`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /solutions/php/01-je9/code/app/main.php: -------------------------------------------------------------------------------- 1 | ... 3 | 4 | // Disable output buffering. 5 | while (ob_get_level() !== 0) { 6 | ob_end_clean(); 7 | } 8 | 9 | $child_pid = pcntl_fork(); 10 | if ($child_pid == -1) { 11 | echo "Error forking!"; 12 | } 13 | elseif ($child_pid) { 14 | // We're in parent. 15 | pcntl_wait($status); 16 | echo "Child terminates!"; 17 | } 18 | else { 19 | // Replace current program with calling program. 20 | echo exec(implode(' ', array_slice($argv, 3))); 21 | } 22 | -------------------------------------------------------------------------------- /solutions/php/01-je9/code/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the PHP version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: php-7.4 11 | language_pack: php-7.4 12 | -------------------------------------------------------------------------------- /solutions/php/01-je9/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec php app/main.php "$@" 3 | -------------------------------------------------------------------------------- /solutions/php/01-je9/diff/app/main.php.diff: -------------------------------------------------------------------------------- 1 | @@ -1,25 +1,21 @@ 2 | ... 4 | 5 | // Disable output buffering. 6 | while (ob_get_level() !== 0) { 7 | ob_end_clean(); 8 | } 9 | 10 | -// You can use print statements as follows for debugging, they'll be visible when running tests. 11 | -echo "Logs from your program will appear here!\n"; 12 | - 13 | -// Uncomment this to pass the first stage. 14 | -// $child_pid = pcntl_fork(); 15 | -// if ($child_pid == -1) { 16 | -// echo "Error forking!"; 17 | -// } 18 | -// elseif ($child_pid) { 19 | -// // We're in parent. 20 | -// pcntl_wait($status); 21 | -// echo "Child terminates!"; 22 | -// } 23 | -// else { 24 | -// // Replace current program with calling program. 25 | -// echo exec(implode(' ', array_slice($argv, 3))); 26 | -// } 27 | +$child_pid = pcntl_fork(); 28 | +if ($child_pid == -1) { 29 | + echo "Error forking!"; 30 | +} 31 | +elseif ($child_pid) { 32 | + // We're in parent. 33 | + pcntl_wait($status); 34 | + echo "Child terminates!"; 35 | +} 36 | +else { 37 | + // Replace current program with calling program. 38 | + echo exec(implode(' ', array_slice($argv, 3))); 39 | +} 40 | -------------------------------------------------------------------------------- /solutions/php/01-je9/explanation.md: -------------------------------------------------------------------------------- 1 | The entry point for your Docker implementation is in `app/main.php`. 2 | 3 | Study and uncomment the relevant code: 4 | 5 | ```php 6 | // Uncomment this to pass the first stage. 7 | $child_pid = pcntl_fork(); 8 | if ($child_pid == -1) { 9 | echo "Error forking!"; 10 | } 11 | elseif ($child_pid) { 12 | // We're in parent. 13 | pcntl_wait($status); 14 | echo "Child terminates!"; 15 | } 16 | else { 17 | // Replace current program with calling program. 18 | echo exec(implode(' ', array_slice($argv, 3))); 19 | } 20 | ``` 21 | 22 | Push your changes to pass the first stage: 23 | 24 | ``` 25 | git add . 26 | git commit -m "pass 1st stage" # any msg 27 | git push origin master 28 | ``` 29 | -------------------------------------------------------------------------------- /solutions/python/01-je9/code/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /solutions/python/01-je9/code/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | -------------------------------------------------------------------------------- /solutions/python/01-je9/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.12-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 14 | 15 | ENTRYPOINT ["/app/your_docker.sh"] 16 | -------------------------------------------------------------------------------- /solutions/python/01-je9/code/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Python solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.py`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /solutions/python/01-je9/code/app/main.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | 5 | def main(): 6 | command = sys.argv[3] 7 | args = sys.argv[4:] 8 | 9 | completed_process = subprocess.run([command, *args], capture_output=True) 10 | print(completed_process.stdout.decode("utf-8")) 11 | 12 | 13 | if __name__ == "__main__": 14 | main() 15 | -------------------------------------------------------------------------------- /solutions/python/01-je9/code/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Python version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: python-3.12 11 | language_pack: python-3.12 12 | -------------------------------------------------------------------------------- /solutions/python/01-je9/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PYTHONPATH=$(dirname $0) exec python3 -m app.main "$@" 3 | -------------------------------------------------------------------------------- /solutions/python/01-je9/diff/app/main.py.diff: -------------------------------------------------------------------------------- 1 | @@ -1,19 +1,14 @@ 2 | import subprocess 3 | import sys 4 | 5 | 6 | def main(): 7 | - # You can use print statements as follows for debugging, they'll be visible when running tests. 8 | - print("Logs from your program will appear here!") 9 | + command = sys.argv[3] 10 | + args = sys.argv[4:] 11 | 12 | - # Uncomment this block to pass the first stage 13 | - # 14 | - # command = sys.argv[3] 15 | - # args = sys.argv[4:] 16 | - # 17 | - # completed_process = subprocess.run([command, *args], capture_output=True) 18 | - # print(completed_process.stdout.decode("utf-8")) 19 | + completed_process = subprocess.run([command, *args], capture_output=True) 20 | + print(completed_process.stdout.decode("utf-8")) 21 | 22 | 23 | if __name__ == "__main__": 24 | main() 25 | -------------------------------------------------------------------------------- /solutions/python/01-je9/explanation.md: -------------------------------------------------------------------------------- 1 | The entry point for your Docker implementation is in `app/main.py`. 2 | 3 | Study and uncomment the relevant code: 4 | 5 | ```python 6 | # Uncomment this block to pass the first stage 7 | 8 | command = sys.argv[3] 9 | args = sys.argv[4:] 10 | 11 | completed_process = subprocess.run([command, *args], capture_output=True) 12 | print(completed_process.stdout.decode("utf-8")) 13 | ``` 14 | 15 | Push your changes to pass the first stage: 16 | 17 | ``` 18 | git add . 19 | git commit -m "pass 1st stage" # any msg 20 | git push origin master 21 | ``` 22 | -------------------------------------------------------------------------------- /solutions/ruby/01-je9/code/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /solutions/ruby/01-je9/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.2-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | # Download docker-explorer 7 | ARG docker_explorer_version=v18 8 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 9 | RUN chmod +x /usr/local/bin/docker-explorer 10 | 11 | COPY . /app 12 | WORKDIR /app 13 | 14 | ENTRYPOINT ["/app/your_docker.sh"] 15 | -------------------------------------------------------------------------------- /solutions/ruby/01-je9/code/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Ruby solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `app/main.rb`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | -------------------------------------------------------------------------------- /solutions/ruby/01-je9/code/app/main.rb: -------------------------------------------------------------------------------- 1 | require "open3" 2 | 3 | command = ARGV[2] 4 | args = ARGV[3..] 5 | 6 | stdout, stderr, status = Open3.capture3(command, *args) 7 | 8 | puts stdout 9 | -------------------------------------------------------------------------------- /solutions/ruby/01-je9/code/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Ruby version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: ruby-3.2 11 | language_pack: ruby-3.2 12 | -------------------------------------------------------------------------------- /solutions/ruby/01-je9/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec ruby app/main.rb "$@" 3 | -------------------------------------------------------------------------------- /solutions/ruby/01-je9/diff/app/main.rb.diff: -------------------------------------------------------------------------------- 1 | @@ -1,13 +1,8 @@ 2 | require "open3" 3 | 4 | -# You can use print statements as follows for debugging, they'll be visible when running tests. 5 | -puts "Logs from your program will appear here!" 6 | +command = ARGV[2] 7 | +args = ARGV[3..] 8 | 9 | -# Uncomment this block to pass the first stage 10 | -# 11 | -# command = ARGV[2] 12 | -# args = ARGV[3..] 13 | -# 14 | -# stdout, stderr, status = Open3.capture3(command, *args) 15 | -# 16 | -# puts stdout 17 | +stdout, stderr, status = Open3.capture3(command, *args) 18 | + 19 | +puts stdout 20 | -------------------------------------------------------------------------------- /solutions/ruby/01-je9/explanation.md: -------------------------------------------------------------------------------- 1 | The entry point for your Docker implementation is in `app/main.rb`. 2 | 3 | Study and uncomment the relevant code: 4 | 5 | ```ruby 6 | # Uncomment this block to pass the first stage 7 | 8 | command = ARGV[2] 9 | args = ARGV[3..] 10 | 11 | stdout, stderr, status = Open3.capture3(command, *args) 12 | 13 | puts stdout 14 | ``` 15 | 16 | Push your changes to pass the first stage: 17 | 18 | ``` 19 | git add . 20 | git commit -m "pass 1st stage" # any msg 21 | git push origin master 22 | ``` 23 | -------------------------------------------------------------------------------- /solutions/rust/01-je9/code/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /solutions/rust/01-je9/code/.gitignore: -------------------------------------------------------------------------------- 1 | target/ -------------------------------------------------------------------------------- /solutions/rust/01-je9/code/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docker-starter-rust" 3 | version = "0.1.0" 4 | authors = ["Codecrafters "] 5 | edition = "2021" 6 | 7 | [dependencies] 8 | reqwest = { version = "0.11.13", features = ["json", "blocking"] } # http requests 9 | bytes = "1.3.0" # helps wrap responses from reqwest 10 | tokio = { version = "1.23.0", features = ["full"] } # async http requests 11 | libc = "0.2.103" # for syscalls like chroot 12 | serde = { version = "1.0.136", features = ["derive"] } # for json mangling 13 | serde_json = "1.0.79" # for json mangling 14 | anyhow = "1.0.59" # error handling 15 | thiserror = "1.0.32" # error handling 16 | tempfile = "3" # creating temporary directories 17 | regex = "1" # for regular expressions 18 | flate2 = "1.0.25" # for handling compressed data 19 | tar = "0.4.38" 20 | -------------------------------------------------------------------------------- /solutions/rust/01-je9/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.77-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | # Grab the dependencies and compile them as they dont change much 9 | COPY Cargo.toml /app/Cargo.toml 10 | COPY Cargo.lock /app/Cargo.lock 11 | 12 | RUN mkdir /app/src 13 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 14 | 15 | WORKDIR /app 16 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | # Grab the real code 20 | COPY . /app 21 | 22 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 23 | 24 | ENTRYPOINT ["/app/your_docker.sh"] 25 | -------------------------------------------------------------------------------- /solutions/rust/01-je9/code/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Rust solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `src/main.rs`. Study and 18 | uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run your code 32 | _inside_ a Docker container. 33 | 34 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 35 | locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create 44 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 45 | 46 | You can now execute your program like this: 47 | 48 | ```sh 49 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 50 | ``` 51 | 52 | This command compiles your Rust project, so it might be slow the first time you 53 | run it. Subsequent runs will be fast. 54 | -------------------------------------------------------------------------------- /solutions/rust/01-je9/code/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Rust version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: rust-1.77 11 | language_pack: rust-1.77 12 | -------------------------------------------------------------------------------- /solutions/rust/01-je9/code/src/main.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{Context, Result}; 2 | 3 | // Usage: your_docker.sh run ... 4 | fn main() -> Result<()> { 5 | let args: Vec<_> = std::env::args().collect(); 6 | let command = &args[3]; 7 | let command_args = &args[4..]; 8 | let output = std::process::Command::new(command) 9 | .args(command_args) 10 | .output() 11 | .with_context(|| { 12 | format!( 13 | "Tried to run '{}' with arguments {:?}", 14 | command, command_args 15 | ) 16 | })?; 17 | 18 | if output.status.success() { 19 | let std_out = std::str::from_utf8(&output.stdout)?; 20 | println!("{}", std_out); 21 | } else { 22 | std::process::exit(1); 23 | } 24 | 25 | Ok(()) 26 | } 27 | -------------------------------------------------------------------------------- /solutions/rust/01-je9/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec cargo run \ 3 | --quiet \ 4 | --release \ 5 | --target-dir=/tmp/codecrafters-docker-target \ 6 | --manifest-path "$(dirname "$0")/Cargo.toml" "$@" 7 | -------------------------------------------------------------------------------- /solutions/rust/01-je9/diff/src/main.rs.diff: -------------------------------------------------------------------------------- 1 | @@ -1,30 +1,26 @@ 2 | use anyhow::{Context, Result}; 3 | 4 | // Usage: your_docker.sh run ... 5 | fn main() -> Result<()> { 6 | - // You can use print statements as follows for debugging, they'll be visible when running tests. 7 | - println!("Logs from your program will appear here!"); 8 | + let args: Vec<_> = std::env::args().collect(); 9 | + let command = &args[3]; 10 | + let command_args = &args[4..]; 11 | + let output = std::process::Command::new(command) 12 | + .args(command_args) 13 | + .output() 14 | + .with_context(|| { 15 | + format!( 16 | + "Tried to run '{}' with arguments {:?}", 17 | + command, command_args 18 | + ) 19 | + })?; 20 | 21 | - // Uncomment this block to pass the first stage! 22 | - // let args: Vec<_> = std::env::args().collect(); 23 | - // let command = &args[3]; 24 | - // let command_args = &args[4..]; 25 | - // let output = std::process::Command::new(command) 26 | - // .args(command_args) 27 | - // .output() 28 | - // .with_context(|| { 29 | - // format!( 30 | - // "Tried to run '{}' with arguments {:?}", 31 | - // command, command_args 32 | - // ) 33 | - // })?; 34 | - // 35 | - // if output.status.success() { 36 | - // let std_out = std::str::from_utf8(&output.stdout)?; 37 | - // println!("{}", std_out); 38 | - // } else { 39 | - // std::process::exit(1); 40 | - // } 41 | + if output.status.success() { 42 | + let std_out = std::str::from_utf8(&output.stdout)?; 43 | + println!("{}", std_out); 44 | + } else { 45 | + std::process::exit(1); 46 | + } 47 | 48 | Ok(()) 49 | } 50 | -------------------------------------------------------------------------------- /solutions/rust/01-je9/explanation.md: -------------------------------------------------------------------------------- 1 | The entry point for your Docker implementation is in `src/main.rs`. 2 | 3 | Study and uncomment the relevant code: 4 | 5 | ```rust 6 | // Uncomment this block to pass the first stage! 7 | let args: Vec<_> = std::env::args().collect(); 8 | let command = &args[3]; 9 | let command_args = &args[4..]; 10 | let output = std::process::Command::new(command) 11 | .args(command_args) 12 | .output() 13 | .with_context(|| { 14 | format!( 15 | "Tried to run '{}' with arguments {:?}", 16 | command, command_args 17 | ) 18 | })?; 19 | 20 | if output.status.success() { 21 | let std_out = std::str::from_utf8(&output.stdout)?; 22 | println!("{}", std_out); 23 | } else { 24 | std::process::exit(1); 25 | } 26 | ``` 27 | 28 | Push your changes to pass the first stage: 29 | 30 | ``` 31 | git add . 32 | git commit -m "pass 1st stage" # any msg 33 | git push origin master 34 | ``` 35 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/code/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/code/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM swift:5.6.1-focal 2 | 3 | RUN apt-get update && \ 4 | apt-get install --no-install-recommends -y curl=7.68.* && \ 5 | apt-get clean && \ 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | # Download docker-explorer 9 | ARG docker_explorer_version=v18 10 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 11 | RUN chmod +x /usr/local/bin/docker-explorer 12 | 13 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/code/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.6 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "swift-docker-challenge", 8 | dependencies: [ 9 | // Dependencies declare other packages that this package depends on. 10 | // .package(url: /* package url */, from: "1.0.0"), 11 | ], 12 | targets: [ 13 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 14 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 15 | .executableTarget( 16 | name: "swift-docker-challenge", 17 | dependencies: []), 18 | ] 19 | ) 20 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/code/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for Swift solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from 7 | [Docker Hub](https://hub.docker.com/) and execute commands in it. Along the way, 8 | we'll learn about [chroot](https://en.wikipedia.org/wiki/Chroot), 9 | [kernel namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the 10 | [docker registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is 18 | `Sources/swift-docker-challenge/Main.swift`. Study and uncomment the relevant 19 | code, and push your changes to pass the first stage: 20 | 21 | ```sh 22 | git commit -am "pass 1st stage" # any msg 23 | git push origin master 24 | ``` 25 | 26 | That's all! 27 | 28 | # Stage 2 & beyond 29 | 30 | Note: This section is for stages 2 and beyond. 31 | 32 | You'll use linux-specific syscalls in this challenge. so we'll run your code 33 | _inside_ a Docker container. 34 | 35 | Please ensure you have [Docker installed](https://docs.docker.com/get-docker/) 36 | locally. 37 | 38 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 39 | 40 | ```sh 41 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 42 | ``` 43 | 44 | (The `--cap-add="SYS_ADMIN"` flag is required to create 45 | [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 46 | 47 | You can now execute your program like this: 48 | 49 | ```sh 50 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 51 | ``` 52 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/code/Sources/swift-docker-challenge/Main.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | @main 4 | struct Main { 5 | 6 | // Usage: your_docker.sh run ... 7 | static func main() async throws { 8 | let command = CommandLine.arguments[3] 9 | let arguments = CommandLine.arguments.dropFirst(4).map { String($0) } 10 | let process = Process() 11 | process.executableURL = URL(fileURLWithPath: command) 12 | process.arguments = arguments 13 | try process.run() 14 | process.waitUntilExit() 15 | guard process.terminationStatus == .zero, let output = process.standardOutput as? String else { 16 | exit(1) 17 | } 18 | print(output) 19 | 20 | exit(0) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/code/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Swift version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: swift-5.6 11 | language_pack: swift-5.6 12 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # Swift build writes errors to stdout instead of stderr. Let's collect all output in a file and only print if the exit code is zero. 6 | buildOutputFile=$(mktemp) 7 | swift build -c release > "$buildOutputFile" || (cat "$buildOutputFile" && exit 1) 8 | exec swift run -c release --skip-build swift-docker-challenge "$@" 9 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/diff/Sources/swift-docker-challenge/Main.swift.diff: -------------------------------------------------------------------------------- 1 | @@ -1,26 +1,22 @@ 2 | import Foundation 3 | 4 | @main 5 | struct Main { 6 | 7 | // Usage: your_docker.sh run ... 8 | static func main() async throws { 9 | - // You can use print statements as follows for debugging, they'll be visible when running tests. 10 | - print("Logs from your program will appear here!") 11 | - 12 | - // Uncomment this block to pass the first stage! 13 | - // let command = CommandLine.arguments[3] 14 | - // let arguments = CommandLine.arguments.dropFirst(4).map { String($0) } 15 | - // let process = Process() 16 | - // process.executableURL = URL(fileURLWithPath: command) 17 | - // process.arguments = arguments 18 | - // try process.run() 19 | - // process.waitUntilExit() 20 | - // guard process.terminationStatus == .zero, let output = process.standardOutput as? String else { 21 | - // exit(1) 22 | - // } 23 | - // print(output) 24 | + let command = CommandLine.arguments[3] 25 | + let arguments = CommandLine.arguments.dropFirst(4).map { String($0) } 26 | + let process = Process() 27 | + process.executableURL = URL(fileURLWithPath: command) 28 | + process.arguments = arguments 29 | + try process.run() 30 | + process.waitUntilExit() 31 | + guard process.terminationStatus == .zero, let output = process.standardOutput as? String else { 32 | + exit(1) 33 | + } 34 | + print(output) 35 | 36 | exit(0) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /solutions/swift/01-je9/explanation.md: -------------------------------------------------------------------------------- 1 | The entry point for your Docker implementation is in `Sources/swift-docker-challenge/Main.swift`. 2 | 3 | Study and uncomment the relevant code: 4 | 5 | ```swift 6 | // Uncomment this block to pass the first stage! 7 | let command = CommandLine.arguments[3] 8 | let arguments = CommandLine.arguments.dropFirst(4).map { String($0) } 9 | let process = Process() 10 | process.executableURL = URL(fileURLWithPath: command) 11 | process.arguments = arguments 12 | try process.run() 13 | process.waitUntilExit() 14 | guard process.terminationStatus == .zero, let output = process.standardOutput as? String else { 15 | exit(1) 16 | } 17 | print(output) 18 | ``` 19 | 20 | Push your changes to pass the first stage: 21 | 22 | ``` 23 | git add . 24 | git commit -m "pass 1st stage" # any msg 25 | git push origin master 26 | ``` 27 | -------------------------------------------------------------------------------- /starter_templates/all/code/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /starter_templates/all/code/README.md: -------------------------------------------------------------------------------- 1 | ![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/docker.png) 2 | 3 | This is a starting point for {{language_name}} solutions to the 4 | ["Build Your Own Docker" Challenge](https://codecrafters.io/challenges/docker). 5 | 6 | In this challenge, you'll build a program that can pull an image from [Docker 7 | Hub](https://hub.docker.com/) and execute commands in it. Along the way, we'll 8 | learn about [chroot](https://en.wikipedia.org/wiki/Chroot), [kernel 9 | namespaces](https://en.wikipedia.org/wiki/Linux_namespaces), the [docker 10 | registry API](https://docs.docker.com/registry/spec/api/) and much more. 11 | 12 | **Note**: If you're viewing this repo on GitHub, head over to 13 | [codecrafters.io](https://codecrafters.io) to try the challenge. 14 | 15 | # Passing the first stage 16 | 17 | The entry point for your Docker implementation is `{{ user_editable_file }}`. 18 | Study and uncomment the relevant code, and push your changes to pass the first stage: 19 | 20 | ```sh 21 | git commit -am "pass 1st stage" # any msg 22 | git push origin master 23 | ``` 24 | 25 | That's all! 26 | 27 | # Stage 2 & beyond 28 | 29 | Note: This section is for stages 2 and beyond. 30 | 31 | You'll use linux-specific syscalls in this challenge. so we'll run 32 | your code _inside_ a Docker container. 33 | 34 | Please ensure you have 35 | [Docker installed](https://docs.docker.com/get-docker/) locally. 36 | 37 | Next, add a [shell alias](https://shapeshed.com/unix-alias/): 38 | 39 | ```sh 40 | alias mydocker='docker build -t mydocker . && docker run --cap-add="SYS_ADMIN" mydocker' 41 | ``` 42 | 43 | (The `--cap-add="SYS_ADMIN"` flag is required to create [PID Namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html)) 44 | 45 | You can now execute your program like this: 46 | 47 | ```sh 48 | mydocker run alpine:latest /usr/local/bin/docker-explorer echo hey 49 | ``` 50 | 51 | {{# language_is_rust }}This command compiles your 52 | Rust project, so it might be slow the first time you run it. Subsequent runs 53 | will be fast.{{/ language_is_rust}} 54 | -------------------------------------------------------------------------------- /starter_templates/all/code/codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the {{language_name}} version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: {{language_pack_with_version}} 11 | language_pack: {{language_pack_with_version}} 12 | -------------------------------------------------------------------------------- /starter_templates/c/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM n0madic/alpine-gcc:9.2.0 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | # Download docker-explorer 7 | ARG docker_explorer_version=v18 8 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 9 | RUN chmod +x /usr/local/bin/docker-explorer 10 | 11 | COPY . /app 12 | WORKDIR /app 13 | 14 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 15 | 16 | ENTRYPOINT ["/app/your_docker.sh"] 17 | -------------------------------------------------------------------------------- /starter_templates/c/code/app/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Usage: your_docker.sh run ... 6 | int main(int argc, char *argv[]) { 7 | // Disable output buffering 8 | setbuf(stdout, NULL); 9 | setbuf(stderr, NULL); 10 | 11 | // You can use print statements as follows for debugging, they'll be visible when running tests. 12 | printf("Logs from your program will appear here!\n"); 13 | 14 | // Uncomment this block to pass the first stage 15 | // 16 | // char *command = argv[3]; 17 | // int child_pid = fork(); 18 | // if (child_pid == -1) { 19 | // printf("Error forking!"); 20 | // return 1; 21 | // } 22 | // 23 | // if (child_pid == 0) { 24 | // // Replace current program with calling program 25 | // execv(command, &argv[3]); 26 | // } else { 27 | // // We're in parent 28 | // wait(NULL); 29 | // printf("Child terminated"); 30 | // } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /starter_templates/c/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | tmpFile=$(mktemp) 4 | gcc -lcurl app/*.c -o $tmpFile 5 | exec "$tmpFile" "$@" 6 | -------------------------------------------------------------------------------- /starter_templates/c/config.yml: -------------------------------------------------------------------------------- 1 | attributes: 2 | required_executable: gcc 3 | user_editable_file: app/main.c 4 | -------------------------------------------------------------------------------- /starter_templates/go/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.22-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 14 | 15 | ENTRYPOINT ["/app/your_docker.sh"] 16 | -------------------------------------------------------------------------------- /starter_templates/go/code/app/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | ) 8 | 9 | // Ensures gofmt doesn't remove the imports above (feel free to remove this!) 10 | var _ = os.Args 11 | var _ = exec.Command 12 | 13 | // Usage: your_docker.sh run ... 14 | func main() { 15 | // You can use print statements as follows for debugging, they'll be visible when running tests. 16 | fmt.Println("Logs from your program will appear here!") 17 | 18 | // Uncomment this block to pass the first stage! 19 | // 20 | // command := os.Args[3] 21 | // args := os.Args[4:len(os.Args)] 22 | // 23 | // cmd := exec.Command(command, args...) 24 | // output, err := cmd.Output() 25 | // if err != nil { 26 | // fmt.Printf("Err: %v", err) 27 | // os.Exit(1) 28 | // } 29 | // 30 | // fmt.Println(string(output)) 31 | } 32 | -------------------------------------------------------------------------------- /starter_templates/go/code/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/codecrafters-io/docker-starter-go 2 | 3 | go 1.22 4 | -------------------------------------------------------------------------------- /starter_templates/go/code/go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codecrafters-io/build-your-own-docker/f96e97152c526fdb7b474e62be28454791552c26/starter_templates/go/code/go.sum -------------------------------------------------------------------------------- /starter_templates/go/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | tmpFile=$(mktemp) 4 | go build -o "$tmpFile" app/*.go 5 | exec "$tmpFile" "$@" 6 | -------------------------------------------------------------------------------- /starter_templates/go/config.yml: -------------------------------------------------------------------------------- 1 | attributes: 2 | required_executable: go 3 | user_editable_file: app/main.go 4 | -------------------------------------------------------------------------------- /starter_templates/nim/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nimlang/nim:1.0.6-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | 5 | # Download docker-explorer. 6 | ARG docker_explorer_version=v18 7 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 14 | 15 | ENTRYPOINT ["/app/your_docker.sh"] 16 | -------------------------------------------------------------------------------- /starter_templates/nim/code/app/main.nim: -------------------------------------------------------------------------------- 1 | # Usage: your_docker.sh run ... 2 | 3 | from os import commandLineParams 4 | from osproc import execProcess 5 | 6 | 7 | # You can use print statements as follows for debugging, they'll be visible when running tests. 8 | echo "Logs from your program will appear here" 9 | 10 | # Uncomment this block to pass the first stage 11 | # 12 | # let command = commandLineParams()[2] 13 | # let args = commandLineParams()[3..^1] 14 | # 15 | # let output = execProcess(command, "", args, options={}) 16 | # echo output 17 | -------------------------------------------------------------------------------- /starter_templates/nim/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | tmpFile=$(mktemp) 4 | nim compile --verbosity:0 --hints:off --out:"$tmpFile" app/main.nim 5 | exec "$tmpFile" "$@" 6 | -------------------------------------------------------------------------------- /starter_templates/nim/config.yml: -------------------------------------------------------------------------------- 1 | attributes: 2 | required_executable: nim (1.0) 3 | user_editable_file: app/main.nim 4 | -------------------------------------------------------------------------------- /starter_templates/php/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.4-cli-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | RUN docker-php-ext-install pcntl 7 | 8 | # Download docker-explorer. 9 | ARG docker_explorer_version=v18 10 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 11 | RUN chmod +x /usr/local/bin/docker-explorer 12 | 13 | COPY . /app 14 | WORKDIR /app 15 | 16 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 17 | 18 | ENTRYPOINT ["/app/your_docker.sh"] 19 | -------------------------------------------------------------------------------- /starter_templates/php/code/app/main.php: -------------------------------------------------------------------------------- 1 | ... 3 | 4 | // Disable output buffering. 5 | while (ob_get_level() !== 0) { 6 | ob_end_clean(); 7 | } 8 | 9 | // You can use print statements as follows for debugging, they'll be visible when running tests. 10 | echo "Logs from your program will appear here!\n"; 11 | 12 | // Uncomment this to pass the first stage. 13 | // $child_pid = pcntl_fork(); 14 | // if ($child_pid == -1) { 15 | // echo "Error forking!"; 16 | // } 17 | // elseif ($child_pid) { 18 | // // We're in parent. 19 | // pcntl_wait($status); 20 | // echo "Child terminates!"; 21 | // } 22 | // else { 23 | // // Replace current program with calling program. 24 | // echo exec(implode(' ', array_slice($argv, 3))); 25 | // } 26 | -------------------------------------------------------------------------------- /starter_templates/php/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec php app/main.php "$@" 3 | -------------------------------------------------------------------------------- /starter_templates/php/config.yml: -------------------------------------------------------------------------------- 1 | attributes: 2 | required_executable: php (7.4) 3 | user_editable_file: app/main.php 4 | -------------------------------------------------------------------------------- /starter_templates/python/code/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | -------------------------------------------------------------------------------- /starter_templates/python/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.12-alpine 2 | 3 | RUN apk add --no-cache 'curl>=7.66' 4 | 5 | # Download docker-explorer 6 | ARG docker_explorer_version=v18 7 | RUN curl -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 8 | RUN chmod +x /usr/local/bin/docker-explorer 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 14 | 15 | ENTRYPOINT ["/app/your_docker.sh"] 16 | -------------------------------------------------------------------------------- /starter_templates/python/code/app/main.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | 5 | def main(): 6 | # You can use print statements as follows for debugging, they'll be visible when running tests. 7 | print("Logs from your program will appear here!") 8 | 9 | # Uncomment this block to pass the first stage 10 | # 11 | # command = sys.argv[3] 12 | # args = sys.argv[4:] 13 | # 14 | # completed_process = subprocess.run([command, *args], capture_output=True) 15 | # print(completed_process.stdout.decode("utf-8")) 16 | 17 | 18 | if __name__ == "__main__": 19 | main() 20 | -------------------------------------------------------------------------------- /starter_templates/python/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PYTHONPATH=$(dirname $0) exec python3 -m app.main "$@" 3 | -------------------------------------------------------------------------------- /starter_templates/python/config.yml: -------------------------------------------------------------------------------- 1 | attributes: 2 | required_executable: python (3.x) 3 | user_editable_file: app/main.py 4 | -------------------------------------------------------------------------------- /starter_templates/ruby/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.2-alpine 2 | 3 | RUN apk add --no-cache --upgrade 'curl>=7.66' 4 | RUN apk add --no-cache --upgrade 'curl-dev>=7.66' 5 | 6 | # Download docker-explorer 7 | ARG docker_explorer_version=v18 8 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 9 | RUN chmod +x /usr/local/bin/docker-explorer 10 | 11 | COPY . /app 12 | WORKDIR /app 13 | 14 | ENTRYPOINT ["/app/your_docker.sh"] 15 | -------------------------------------------------------------------------------- /starter_templates/ruby/code/app/main.rb: -------------------------------------------------------------------------------- 1 | require "open3" 2 | 3 | # You can use print statements as follows for debugging, they'll be visible when running tests. 4 | puts "Logs from your program will appear here!" 5 | 6 | # Uncomment this block to pass the first stage 7 | # 8 | # command = ARGV[2] 9 | # args = ARGV[3..] 10 | # 11 | # stdout, stderr, status = Open3.capture3(command, *args) 12 | # 13 | # puts stdout 14 | -------------------------------------------------------------------------------- /starter_templates/ruby/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec ruby app/main.rb "$@" 3 | -------------------------------------------------------------------------------- /starter_templates/ruby/config.yml: -------------------------------------------------------------------------------- 1 | attributes: 2 | required_executable: ruby (2.7) 3 | user_editable_file: app/main.rb 4 | -------------------------------------------------------------------------------- /starter_templates/rust/code/.gitignore: -------------------------------------------------------------------------------- 1 | target/ -------------------------------------------------------------------------------- /starter_templates/rust/code/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docker-starter-rust" 3 | version = "0.1.0" 4 | authors = ["Codecrafters "] 5 | edition = "2021" 6 | 7 | [dependencies] 8 | reqwest = { version = "0.11.13", features = ["json", "blocking"] } # http requests 9 | bytes = "1.3.0" # helps wrap responses from reqwest 10 | tokio = { version = "1.23.0", features = ["full"] } # async http requests 11 | libc = "0.2.103" # for syscalls like chroot 12 | serde = { version = "1.0.136", features = ["derive"] } # for json mangling 13 | serde_json = "1.0.79" # for json mangling 14 | anyhow = "1.0.59" # error handling 15 | thiserror = "1.0.32" # error handling 16 | tempfile = "3" # creating temporary directories 17 | regex = "1" # for regular expressions 18 | flate2 = "1.0.25" # for handling compressed data 19 | tar = "0.4.38" 20 | -------------------------------------------------------------------------------- /starter_templates/rust/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.77-buster 2 | 3 | # Download docker-explorer 4 | ARG docker_explorer_version=v18 5 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 6 | RUN chmod +x /usr/local/bin/docker-explorer 7 | 8 | # Grab the dependencies and compile them as they dont change much 9 | COPY Cargo.toml /app/Cargo.toml 10 | COPY Cargo.lock /app/Cargo.lock 11 | 12 | RUN mkdir /app/src 13 | RUN echo 'fn main() { println!("Hello World!"); }' > /app/src/main.rs 14 | 15 | WORKDIR /app 16 | RUN cargo build --release --target-dir=/tmp/codecrafters-docker-target 17 | RUN cargo clean -p docker-starter-rust --release --target-dir=/tmp/codecrafters-docker-target 18 | 19 | # Grab the real code 20 | COPY . /app 21 | 22 | RUN sed -i -e 's/\r$//' /app/your_docker.sh 23 | 24 | ENTRYPOINT ["/app/your_docker.sh"] 25 | -------------------------------------------------------------------------------- /starter_templates/rust/code/src/main.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{Context, Result}; 2 | 3 | // Usage: your_docker.sh run ... 4 | fn main() -> Result<()> { 5 | // You can use print statements as follows for debugging, they'll be visible when running tests. 6 | println!("Logs from your program will appear here!"); 7 | 8 | // Uncomment this block to pass the first stage! 9 | // let args: Vec<_> = std::env::args().collect(); 10 | // let command = &args[3]; 11 | // let command_args = &args[4..]; 12 | // let output = std::process::Command::new(command) 13 | // .args(command_args) 14 | // .output() 15 | // .with_context(|| { 16 | // format!( 17 | // "Tried to run '{}' with arguments {:?}", 18 | // command, command_args 19 | // ) 20 | // })?; 21 | // 22 | // if output.status.success() { 23 | // let std_out = std::str::from_utf8(&output.stdout)?; 24 | // println!("{}", std_out); 25 | // } else { 26 | // std::process::exit(1); 27 | // } 28 | 29 | Ok(()) 30 | } 31 | -------------------------------------------------------------------------------- /starter_templates/rust/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec cargo run \ 3 | --quiet \ 4 | --release \ 5 | --target-dir=/tmp/codecrafters-docker-target \ 6 | --manifest-path "$(dirname "$0")/Cargo.toml" "$@" 7 | -------------------------------------------------------------------------------- /starter_templates/rust/config.yml: -------------------------------------------------------------------------------- 1 | attributes: 2 | required_executable: cargo (1.54) 3 | user_editable_file: src/main.rs 4 | -------------------------------------------------------------------------------- /starter_templates/swift/code/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | -------------------------------------------------------------------------------- /starter_templates/swift/code/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM swift:5.6.1-focal 2 | 3 | RUN apt-get update && \ 4 | apt-get install --no-install-recommends -y curl=7.68.* && \ 5 | apt-get clean && \ 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | # Download docker-explorer 9 | ARG docker_explorer_version=v18 10 | RUN curl --fail -Lo /usr/local/bin/docker-explorer https://github.com/codecrafters-io/docker-explorer/releases/download/${docker_explorer_version}/${docker_explorer_version}_linux_amd64 11 | RUN chmod +x /usr/local/bin/docker-explorer 12 | 13 | -------------------------------------------------------------------------------- /starter_templates/swift/code/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.6 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "swift-docker-challenge", 8 | dependencies: [ 9 | // Dependencies declare other packages that this package depends on. 10 | // .package(url: /* package url */, from: "1.0.0"), 11 | ], 12 | targets: [ 13 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 14 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 15 | .executableTarget( 16 | name: "swift-docker-challenge", 17 | dependencies: []), 18 | ] 19 | ) 20 | -------------------------------------------------------------------------------- /starter_templates/swift/code/Sources/swift-docker-challenge/Main.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | @main 4 | struct Main { 5 | 6 | // Usage: your_docker.sh run ... 7 | static func main() async throws { 8 | // You can use print statements as follows for debugging, they'll be visible when running tests. 9 | print("Logs from your program will appear here!") 10 | 11 | // Uncomment this block to pass the first stage! 12 | // let command = CommandLine.arguments[3] 13 | // let arguments = CommandLine.arguments.dropFirst(4).map { String($0) } 14 | // let process = Process() 15 | // process.executableURL = URL(fileURLWithPath: command) 16 | // process.arguments = arguments 17 | // try process.run() 18 | // process.waitUntilExit() 19 | // guard process.terminationStatus == .zero, let output = process.standardOutput as? String else { 20 | // exit(1) 21 | // } 22 | // print(output) 23 | 24 | exit(0) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /starter_templates/swift/code/your_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # Swift build writes errors to stdout instead of stderr. Let's collect all output in a file and only print if the exit code is zero. 6 | buildOutputFile=$(mktemp) 7 | swift build -c release > "$buildOutputFile" || (cat "$buildOutputFile" && exit 1) 8 | exec swift run -c release --skip-build swift-docker-challenge "$@" 9 | -------------------------------------------------------------------------------- /starter_templates/swift/config.yml: -------------------------------------------------------------------------------- 1 | attributes: 2 | required_executable: swift 3 | user_editable_file: Sources/swift-docker-challenge/Main.swift 4 | --------------------------------------------------------------------------------