Skip to content

Commit

Permalink
Many improvements:
Browse files Browse the repository at this point in the history
Handle common errors with better messages
Add docker-compose example
Flesh out docs
Make multi-arch dockerfile work
  • Loading branch information
itaylor committed Mar 15, 2022
1 parent 39b39f9 commit 66adcbf
Show file tree
Hide file tree
Showing 9 changed files with 312 additions and 62 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
128 changes: 118 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
name = "docker-vhoster"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "docker-vhoster"
path = "src/main.rs"

# [package.release]
# opt-level = 's' # Optimize for size.
Expand All @@ -10,11 +13,13 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1.0"
bollard = "0.11"
envy = "0.4"
# envy = "0.4"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
chrono = "0.4"
futures-util = "0.3"
futures-retry = "0.6.0"
ctrlc = { version = "3.0", features = ["termination"] }
ctrlc = { version = "3.0", features = ["termination"] }
clap = { version = "3.1", features = ["derive", "env", "color"] }
27 changes: 17 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
FROM rust:1.59 as BUILD

ARG RUSTFLAGS='-C link-arg=-s'
ARG TARGET='x86_64-unknown-linux-musl'
ARG TARGETPLATFORM
RUN case "$TARGETPLATFORM" in \
"linux/amd64") echo x86_64-unknown-linux-musl > /rust_target.txt ;; \
"linux/arm64") echo aarch64-unknown-linux-musl > /rust_target.txt ;; \
*) exit 1 ;; \
esac

RUN USER=root cargo new --bin docker-vhoster
WORKDIR /docker-vhoster
RUN mkdir /build && cd /build &&\
USER=root cargo new --bin docker-vhoster &&\
cargo install cargo-build-deps &&\
rustup target add $(cat /rust_target.txt)
WORKDIR /build/docker-vhoster

# copy over your manifests
COPY ./Cargo.toml ./Cargo.toml
COPY ./Cargo.toml ./Cargo.lock ./

ENV RUSTFLAGS=${RUSTFLAGS}
# cache deps
RUN rustup target add ${TARGET} && cargo build --release --target ${TARGET} && rm src/*.rs
COPY ./src /docker-vhoster/src
RUN cargo build-deps --release --target=$(cat /rust_target.txt)
COPY ./src /build/docker-vhoster/src
# build as a statically linked library
RUN cargo build --release --target ${TARGET} --bin docker-vhoster
#RUN ls -alh /docker-vhoster/target/${TARGET} && exit 1
RUN cargo build --release --target $(cat /rust_target.txt) --bin docker-vhoster &&\
mv /build/docker-vhoster/target/$(cat /rust_target.txt)/release/docker-vhoster /

FROM scratch
ARG TARGET='x86_64-unknown-linux-musl'
COPY --from=BUILD /docker-vhoster/target/${TARGET}/release/docker-vhoster /
COPY --from=BUILD /docker-vhoster /
CMD ["/docker-vhoster"]
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

build:
docker buildx build --platform linux/arm64,linux/amd64 -t itaylor/docker-vhoster --push ./
55 changes: 47 additions & 8 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,57 @@

Listens on the docker socket for containers to start/end and adds entries for them to your `/etc/hosts` file.

This is designed to be used alongside a tool like `jwilder/nginx-proxy` which creates vhost entries for running services. It allows you to map them to the hosts file.
This is designed to be used alongside a tool like `jwilder/nginx-proxy` which creates vhost entries for running services.
If you follow it's pattern for setting `VIRTUAL_HOST` environment variables that program nginx, this will allow those same variables to also control your `/etc/hosts` file.

## Configuration
## One time setup:

Three options:
* `HOST_FILE_LOCATION`: default: `/etc/hosts` the path to the etc hosts file to modify.
* `ENV_VAR_NAME`: default: `VIRTUAL_HOST` the name of the environment variable to look at to determine what vhosts to add.
* `VHOST_IP_ADDR` default `127.0.0.1` Use this to provide/override the IP address used to map the vhost entries.
We need to give your user permission to modify the /etc/hosts file. This is done differently on different OS.

When run as a container, pass these as env vars. When run as a cli program, they are arguments.
On MacOS, run in terminal:
```sh
chmod +a user:$(whoami) allow read,write,append,readattr,writeattr,readextattr,writeextattr,readsecurity /etc/hosts
```

On Windows... Powershell is too complex for me to understand how to do it as a script, so in the UI:
* Navigate in Explorer to `C:\Windows\System32\drivers\etc`
* Right click the `hosts` file -> Properties
* Security -> Edit
* Add...
* Enter your user name
* Check Names
* Ok
* Check "Full Control" box
* Ok, Ok

On Linux:
Do nothing, this just works

## Options

Options:
All options can be set as cli arguments or as env vars

| argument | env var | default | description |
| ---------------------------------- | -------------------- | ------------- | ----------- |
| `-h, --host-file-location <path>` | `HOST_FILE_LOCATION` | `/etc/hosts` | The path to the hosts file to modify |
| `-e, --env-var-name <string>` | `ENV_VAR_NAME` | `VIRTUAL_HOST`| The env var used to look up the host name on a per-container basis |
| `-v, --vhost-ip-addr <ip address>` | `VHOST_IP_ADDR` | `127.0.0.1` | The IP address to set in the /etc/hosts file |

## Required file/volume mount!
You must use this on a machine/container where `/var/run/docker.sock` is available

## Running it
The most common way this is meant to be used is to run inside of docker alongside containers.
Typically, if you're running `docker-vhoster` inside of docker, this is done as:
`docker run -v /var/run/docker.sock:/var/run/docker.sock:ro itaylor/docker-vhoster`
`docker run -v /var/run/docker.sock:/var/run/docker.sock:ro -v /etc/hosts:/tmp/hosts itaylor/docker-vhoster -h /tmp/hosts`

## Example using docker-compose
See the `example/` folder.
```sh
cd example/
docker-compose up
```
Once the containers start you'll be able to open a browser to `http://web-example.fake.com` and have it display a hello world message.

*Note* if using Docker for windows, you'll have to change the `example/docker-compose.yml` to have the correct path to Windows' `etc/hosts` file.
32 changes: 32 additions & 0 deletions example/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# An example docker-compose config that uses jwilder/nginx-proxy and itaylor/docker-vhoster to automatically add /etc/hosts entries
services:

nginx-proxy:
image: jwilder/nginx-proxy
ports:
- 80:80
- 443:443
volumes:
- "/var/run/docker.sock:/tmp/docker.sock:ro"

docker-vhoster:
build: ../
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "/etc/hosts:/tmp/hosts"
# For windows, use below instead:
# - C:\Windows\System32\drivers\etc\hosts:/tmp/hosts
environment:
- HOST_FILE_LOCATION=/tmp/hosts

web-example:
image: node:16
volumes:
- "./helloworld.js:/app/helloworld.js"
command: node /app/helloworld.js
expose:
- 3000
environment:
# The values set here will be used by both nginx-proxy to setup nginx
# And by docker-vhoster to edit the /etc/hosts entries
- VIRTUAL_HOST=web-example.fake.com,web-example.local
12 changes: 12 additions & 0 deletions example/helloworld.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const http = require("http");
const { chdir } = require("process");
const host = '0.0.0.0';
const port = 3000;
const server = http.createServer(onRequest);
server.listen(port, host, () => {
console.log(`Running on http://${host}:${port}`);
});
function onRequest(req,res) {
res.writeHead(200);
res.end("Hello World!");
}
Loading

0 comments on commit 66adcbf

Please sign in to comment.