diff options
-rw-r--r-- | Dockerfile | 22 | ||||
-rw-r--r-- | Dockerfile.arm32v7 | 16 | ||||
-rw-r--r-- | Dockerfile.arm64v8 | 16 | ||||
-rw-r--r-- | README.md | 25 | ||||
-rw-r--r-- | docker-compose.yml | 7 | ||||
-rw-r--r-- | entrypoint.sh | 23 | ||||
-rw-r--r-- | lighttpd.conf | 10 | ||||
-rw-r--r-- | src/App.vue | 18 | ||||
-rw-r--r-- | src/assets/app.scss | 4 | ||||
-rw-r--r-- | src/components/GetStarted.vue | 2 | ||||
-rw-r--r-- | src/components/services/Emby.vue | 2 |
11 files changed, 93 insertions, 52 deletions
@@ -12,22 +12,28 @@ RUN yarn build | |||
12 | # production stage | 12 | # production stage |
13 | FROM alpine:3.15 | 13 | FROM alpine:3.15 |
14 | 14 | ||
15 | ENV USER darkhttpd | 15 | ENV GID 1000 |
16 | ENV GROUP darkhttpd | 16 | ENV UID 1000 |
17 | ENV GID 911 | ||
18 | ENV UID 911 | ||
19 | ENV PORT 8080 | 17 | ENV PORT 8080 |
18 | ENV SUBFOLDER "/_" | ||
19 | ENV INIT_ASSETS 1 | ||
20 | 20 | ||
21 | RUN addgroup -S ${GROUP} -g ${GID} && adduser -D -S -u ${UID} ${USER} ${GROUP} && \ | 21 | RUN addgroup -S lighttpd -g ${GID} && adduser -D -S -u ${UID} lighttpd lighttpd && \ |
22 | apk add -U --no-cache su-exec darkhttpd | 22 | apk add -U --no-cache lighttpd |
23 | 23 | ||
24 | COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist /www/ | 24 | WORKDIR /www |
25 | COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist/assets /www/default-assets | 25 | |
26 | COPY lighttpd.conf /lighttpd.conf | ||
26 | COPY entrypoint.sh /entrypoint.sh | 27 | COPY entrypoint.sh /entrypoint.sh |
28 | COPY --from=build-stage --chown=${UID}:${GID} /app/dist /www/ | ||
29 | COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist/assets /www/default-assets | ||
30 | |||
31 | USER ${UID}:${GID} | ||
27 | 32 | ||
28 | HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ | 33 | HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ |
29 | CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1 | 34 | CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1 |
30 | 35 | ||
31 | EXPOSE ${PORT} | 36 | EXPOSE ${PORT} |
32 | VOLUME /www/assets | 37 | VOLUME /www/assets |
38 | |||
33 | ENTRYPOINT ["/bin/sh", "/entrypoint.sh"] | 39 | ENTRYPOINT ["/bin/sh", "/entrypoint.sh"] |
diff --git a/Dockerfile.arm32v7 b/Dockerfile.arm32v7 index 95a2db1..7e1d92b 100644 --- a/Dockerfile.arm32v7 +++ b/Dockerfile.arm32v7 | |||
@@ -21,23 +21,27 @@ FROM arm32v7/alpine:3.11 | |||
21 | 21 | ||
22 | COPY --from=qemu qemu-arm-static /usr/bin/ | 22 | COPY --from=qemu qemu-arm-static /usr/bin/ |
23 | 23 | ||
24 | ENV USER darkhttpd | 24 | ENV USER lighttpd |
25 | ENV GROUP darkhttpd | 25 | ENV GROUP lighttpd |
26 | ENV GID 911 | 26 | ENV GID 911 |
27 | ENV UID 911 | 27 | ENV UID 911 |
28 | ENV PORT 8080 | 28 | ENV PORT 8080 |
29 | ENV SUBFOLDER "/_" | ||
29 | 30 | ||
30 | RUN addgroup -S ${GROUP} -g ${GID} && adduser -D -S -u ${UID} ${USER} ${GROUP} && \ | 31 | RUN addgroup -S ${GROUP} -g ${GID} && adduser -D -S -u ${UID} ${USER} ${GROUP} && \ |
31 | apk add -U --no-cache darkhttpd su-exec && \ | 32 | apk add -U --no-cache lighttpd && \ |
32 | rm /usr/bin/qemu-arm-static | 33 | rm /usr/bin/qemu-arm-static |
33 | 34 | ||
35 | WORKDIR /www | ||
36 | |||
37 | COPY lighttpd.conf /lighttpd.conf | ||
34 | COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist /www/ | 38 | COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist /www/ |
35 | COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist/assets /www/default-assets | ||
36 | COPY entrypoint.sh /entrypoint.sh | ||
37 | 39 | ||
40 | USER ${USER} | ||
38 | HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ | 41 | HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ |
39 | CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1 | 42 | CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1 |
40 | 43 | ||
41 | EXPOSE ${PORT} | 44 | EXPOSE ${PORT} |
42 | VOLUME /www/assets | 45 | VOLUME /www/assets |
43 | ENTRYPOINT ["/bin/sh", "/entrypoint.sh"] | 46 | |
47 | CMD ["lighttpd", "-D", "-f", "/lighttpd.conf"] | ||
diff --git a/Dockerfile.arm64v8 b/Dockerfile.arm64v8 index cd15e4a..573a2e4 100644 --- a/Dockerfile.arm64v8 +++ b/Dockerfile.arm64v8 | |||
@@ -21,23 +21,27 @@ FROM arm64v8/alpine:3.11 | |||
21 | 21 | ||
22 | COPY --from=qemu qemu-aarch64-static /usr/bin/ | 22 | COPY --from=qemu qemu-aarch64-static /usr/bin/ |
23 | 23 | ||
24 | ENV USER darkhttpd | 24 | ENV USER lighttpd |
25 | ENV GROUP darkhttpd | 25 | ENV GROUP lighttpd |
26 | ENV GID 911 | 26 | ENV GID 911 |
27 | ENV UID 911 | 27 | ENV UID 911 |
28 | ENV PORT 8080 | 28 | ENV PORT 8080 |
29 | ENV SUBFOLDER "/_" | ||
29 | 30 | ||
30 | RUN addgroup -S ${GROUP} -g ${GID} && adduser -D -S -u ${UID} ${USER} ${GROUP} && \ | 31 | RUN addgroup -S ${GROUP} -g ${GID} && adduser -D -S -u ${UID} ${USER} ${GROUP} && \ |
31 | apk add -U --no-cache darkhttpd su-exec && \ | 32 | apk add -U --no-cache lighttpd && \ |
32 | rm /usr/bin/qemu-aarch64-static | 33 | rm /usr/bin/qemu-aarch64-static |
33 | 34 | ||
35 | WORKDIR /www | ||
36 | |||
37 | COPY lighttpd.conf /lighttpd.conf | ||
34 | COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist /www/ | 38 | COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist /www/ |
35 | COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist/assets /www/default-assets | ||
36 | COPY entrypoint.sh /entrypoint.sh | ||
37 | 39 | ||
40 | USER ${USER} | ||
38 | HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ | 41 | HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ |
39 | CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1 | 42 | CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1 |
40 | 43 | ||
41 | EXPOSE ${PORT} | 44 | EXPOSE ${PORT} |
42 | VOLUME /www/assets | 45 | VOLUME /www/assets |
43 | ENTRYPOINT ["/bin/sh", "/entrypoint.sh"] | 46 | |
47 | CMD ["lighttpd", "-D", "-f", "/lighttpd.conf"] | ||
@@ -71,8 +71,6 @@ See [documentation](docs/configuration.md) for information about the configurati | |||
71 | 71 | ||
72 | ### Using docker | 72 | ### Using docker |
73 | 73 | ||
74 | To launch container: | ||
75 | |||
76 | ```sh | 74 | ```sh |
77 | docker run -d \ | 75 | docker run -d \ |
78 | -p 8080:8080 \ | 76 | -p 8080:8080 \ |
@@ -81,12 +79,19 @@ docker run -d \ | |||
81 | b4bz/homer:latest | 79 | b4bz/homer:latest |
82 | ``` | 80 | ``` |
83 | 81 | ||
84 | Default assets will be automatically installed in the `/www/assets` directory. Use `UID` and/or `GID` env var to change the assets owner (`docker run -e "UID=1000" -e "GID=1000" [...]`). | 82 | Environment variables: |
83 | |||
84 | * **`INIT_ASSETS`** (default: `1`) | ||
85 | Install exemple configuration file & assets (favicons, ...) to help you get started. | ||
86 | |||
87 | * **`SUBFOLDER`** (default: `null`) | ||
88 | If you would like to host Homer in a subfolder, (ex: *http://my-domain/**homer***), set this to the subfolder path (ex `/homer`). | ||
89 | |||
85 | 90 | ||
86 | ### Using docker-compose | 91 | ### Using docker-compose |
87 | 92 | ||
88 | The `docker-compose.yml` file must be edited to match your needs. | 93 | The `docker-compose.yml` file must be edited to match your needs. |
89 | Set the port and volume (equivalent to `-p` and `-v` arguments): | 94 | You probably want to set the port mapping and volume binding (equivalent to `-p` and `-v` arguments): |
90 | 95 | ||
91 | ```yaml | 96 | ```yaml |
92 | volumes: | 97 | volumes: |
@@ -95,21 +100,13 @@ ports: | |||
95 | - 8080:8080 | 100 | - 8080:8080 |
96 | ``` | 101 | ``` |
97 | 102 | ||
98 | To launch container: | 103 | Then launch the container: |
99 | 104 | ||
100 | ```sh | 105 | ```sh |
101 | cd /path/to/docker-compose.yml | 106 | cd /path/to/docker-compose.yml/ |
102 | docker-compose up -d | 107 | docker-compose up -d |
103 | ``` | 108 | ``` |
104 | 109 | ||
105 | Default assets will be automatically installed in the `/www/assets` directory. Use `UID` and/or `GID` env var to change the assets owner, also in `docker-compose.yml`: | ||
106 | |||
107 | ```yaml | ||
108 | environment: | ||
109 | - UID=1000 | ||
110 | - GID=1000 | ||
111 | ``` | ||
112 | |||
113 | ### Using the release tarball (prebuilt, ready to use) | 110 | ### Using the release tarball (prebuilt, ready to use) |
114 | 111 | ||
115 | Download and extract the latest release (`homer.zip`) from the [release page](https://github.com/bastienwirtz/homer/releases), rename the `assets/config.yml.dist` file to `assets/config.yml`, and put it behind a web server. | 112 | Download and extract the latest release (`homer.zip`) from the [release page](https://github.com/bastienwirtz/homer/releases), rename the `assets/config.yml.dist` file to `assets/config.yml`, and put it behind a web server. |
diff --git a/docker-compose.yml b/docker-compose.yml index 884703c..231e72a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml | |||
@@ -10,7 +10,6 @@ services: | |||
10 | - /your/local/assets/:/www/assets | 10 | - /your/local/assets/:/www/assets |
11 | ports: | 11 | ports: |
12 | - 8080:8080 | 12 | - 8080:8080 |
13 | #environment: | 13 | user: 1000:1000 # default |
14 | # - UID=1000 | 14 | environment: |
15 | # - GID=1000 | 15 | - INIT_ASSETS=1 # default |
16 | restart: unless-stopped | ||
diff --git a/entrypoint.sh b/entrypoint.sh index f1a8c22..eba1cb2 100644 --- a/entrypoint.sh +++ b/entrypoint.sh | |||
@@ -1,15 +1,18 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | # Ensure default assets are present. | 3 | PERMISSION_ERROR="Check assets directory permissions & docker user or skip default assets install by setting the INIT_ASSETS env var to 0" |
4 | while true; do echo n; done | cp -Ri /www/default-assets/* /www/assets/ &> /dev/null | ||
5 | 4 | ||
6 | # Ensure compatibility with previous version (config.yml was in the root directory) | 5 | # Default assets & exemple configuration installation if possible. |
7 | if [ -f "/www/config.yml" ]; then | 6 | if [[ "${INIT_ASSETS}" == "1" ]] && [[ ! -f "/www/config.yml" ]]; then |
8 | yes n | cp -i /www/config.yml /www/assets/ &> /dev/null | 7 | echo "No configuration found, installing default config & assets" |
9 | fi | 8 | if [[ ! -w "/www/assets/" ]]; then echo "Assets directory not writable. $PERMISSION_ERROR" && exit 1; fi |
9 | |||
10 | while true; do echo n; done | cp -Ri /www/default-assets/* /www/assets/ &> /dev/null | ||
11 | if [[ $? -ne 0 ]]; then echo "Fail to copy default assets. $PERMISSION_ERROR" && exit 1; fi | ||
10 | 12 | ||
11 | # Install default config if no one is available. | 13 | yes n | cp -i /www/default-assets/config.yml.dist /www/assets/config.yml &> /dev/null |
12 | yes n | cp -i /www/default-assets/config.yml.dist /www/assets/config.yml &> /dev/null | 14 | if [[ $? -ne 0 ]]; then echo "Fail to copy default config file. $PERMISSION_ERROR" && exit 1; fi |
15 | fi | ||
13 | 16 | ||
14 | chown -R $UID:$GID /www/assets | 17 | echo "Starting webserver" |
15 | exec su-exec $UID:$GID darkhttpd /www/ --no-listing --port "$PORT" | 18 | lighttpd -D -f /lighttpd.conf |
diff --git a/lighttpd.conf b/lighttpd.conf new file mode 100644 index 0000000..32e14da --- /dev/null +++ b/lighttpd.conf | |||
@@ -0,0 +1,10 @@ | |||
1 | include "/etc/lighttpd/mime-types.conf" | ||
2 | |||
3 | server.port = env.PORT | ||
4 | server.modules = ( "mod_alias" ) | ||
5 | server.username = "lighttpd" | ||
6 | server.groupname = "lighttpd" | ||
7 | server.document-root = "/www" | ||
8 | alias.url = ( env.SUBFOLDER => "/www" ) | ||
9 | server.indexfiles = ("index.html") | ||
10 | server.follow-symlink = "enable" | ||
diff --git a/src/App.vue b/src/App.vue index 81f92f7..515177e 100644 --- a/src/App.vue +++ b/src/App.vue | |||
@@ -18,7 +18,10 @@ | |||
18 | </a> | 18 | </a> |
19 | <i v-if="config.icon" :class="config.icon"></i> | 19 | <i v-if="config.icon" :class="config.icon"></i> |
20 | </div> | 20 | </div> |
21 | <div class="dashboard-title"> | 21 | <div |
22 | class="dashboard-title" | ||
23 | :class="{ 'no-logo': !config.icon || !config.logo }" | ||
24 | > | ||
22 | <span class="headline">{{ config.subtitle }}</span> | 25 | <span class="headline">{{ config.subtitle }}</span> |
23 | <h1>{{ config.title }}</h1> | 26 | <h1>{{ config.title }}</h1> |
24 | </div> | 27 | </div> |
@@ -61,7 +64,7 @@ | |||
61 | @network-status-update="offline = $event" | 64 | @network-status-update="offline = $event" |
62 | /> | 65 | /> |
63 | 66 | ||
64 | <GetStarted v-if="loaded && !services" /> | 67 | <GetStarted v-if="configurationNeeded" /> |
65 | 68 | ||
66 | <div v-if="!offline"> | 69 | <div v-if="!offline"> |
67 | <!-- Optional messages --> | 70 | <!-- Optional messages --> |
@@ -168,6 +171,7 @@ export default { | |||
168 | data: function () { | 171 | data: function () { |
169 | return { | 172 | return { |
170 | loaded: false, | 173 | loaded: false, |
174 | configNotFound: false, | ||
171 | config: null, | 175 | config: null, |
172 | services: null, | 176 | services: null, |
173 | offline: false, | 177 | offline: false, |
@@ -177,6 +181,11 @@ export default { | |||
177 | showMenu: false, | 181 | showMenu: false, |
178 | }; | 182 | }; |
179 | }, | 183 | }, |
184 | computed: { | ||
185 | configurationNeeded: function () { | ||
186 | return (this.loaded && !this.services) || this.configNotFound; | ||
187 | }, | ||
188 | }, | ||
180 | created: async function () { | 189 | created: async function () { |
181 | this.buildDashboard(); | 190 | this.buildDashboard(); |
182 | window.onhashchange = this.buildDashboard; | 191 | window.onhashchange = this.buildDashboard; |
@@ -228,6 +237,11 @@ export default { | |||
228 | return; | 237 | return; |
229 | } | 238 | } |
230 | 239 | ||
240 | if (response.status == 404) { | ||
241 | this.configNotFound = true; | ||
242 | return {}; | ||
243 | } | ||
244 | |||
231 | if (!response.ok) { | 245 | if (!response.ok) { |
232 | throw Error(`${response.statusText}: ${response.body}`); | 246 | throw Error(`${response.statusText}: ${response.body}`); |
233 | } | 247 | } |
diff --git a/src/assets/app.scss b/src/assets/app.scss index aa8b077..ae2cb6b 100644 --- a/src/assets/app.scss +++ b/src/assets/app.scss | |||
@@ -104,6 +104,10 @@ body { | |||
104 | 104 | ||
105 | .dashboard-title { | 105 | .dashboard-title { |
106 | padding: 6px 0 0 80px; | 106 | padding: 6px 0 0 80px; |
107 | |||
108 | &.no-logo { | ||
109 | padding-left: 0; | ||
110 | } | ||
107 | } | 111 | } |
108 | 112 | ||
109 | .first-line { | 113 | .first-line { |
diff --git a/src/components/GetStarted.vue b/src/components/GetStarted.vue index dcabc02..c256a0f 100644 --- a/src/components/GetStarted.vue +++ b/src/components/GetStarted.vue | |||
@@ -6,7 +6,7 @@ | |||
6 | <p> | 6 | <p> |
7 | <a | 7 | <a |
8 | class="button is-primary mt-5 has-text-weight-bold" | 8 | class="button is-primary mt-5 has-text-weight-bold" |
9 | href="https://github.com/bastienwirtz/homer/blob/main/README.md#getting-started" | 9 | href="https://github.com/bastienwirtz/homer/blob/main/docs/configuration.md#configuration" |
10 | target="_blank" | 10 | target="_blank" |
11 | > | 11 | > |
12 | Get started | 12 | Get started |
diff --git a/src/components/services/Emby.vue b/src/components/services/Emby.vue index 25a2612..d2411f0 100644 --- a/src/components/services/Emby.vue +++ b/src/components/services/Emby.vue | |||
@@ -62,7 +62,7 @@ export default { | |||
62 | this.fetch("/System/info/public") | 62 | this.fetch("/System/info/public") |
63 | .then((response) => { | 63 | .then((response) => { |
64 | if (response.Id) this.status = "running"; | 64 | if (response.Id) this.status = "running"; |
65 | else throw new Error(); | 65 | else throw new Error(); |
66 | }) | 66 | }) |
67 | .catch((e) => { | 67 | .catch((e) => { |
68 | console.log(e); | 68 | console.log(e); |