-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(docker): Add option to run via Docker Compose #40
base: main
Are you sure you want to change the base?
Conversation
Adds a basic Dockerfile and docker-compose.yml. Still needs work since we seemingly can't pass in the results of git describe --tags at start, but it's something.
You should add volumes for persistent data:
Otherwise the image will just lose all state when it is restarted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really see the point of using Docker here, after all Deno is a single, self-contained binary which only depends on its cache directory and, in case of this project, the contents of this repository's checked out directory. But I also don't have a lot of experience with Docker, so I may be missing some other benefits.
That said, I think you can remove the version argument, it is optional and any usage scenario which wants to use all providers requires additional environment variables being specified.
To be honest, I don't know the ideal way to pass a dynamic env variable to the container, but hardcoding it into the compose file is not maintainable.
(All other env variables are rather static and can be passed in using the .env
file which atj already mentioned.)
Something like this would work cleanly for the environment variables: services:
web:
build:
context: .
container_name: harmony-container
image: harmony
ports:
- "8000:8000"
volumes:
- ./snaps/:/app/snaps/:rw
- ./snaps.db:/app/snap.db:rw
environment:
HARMONY_CODE_URL: ${HARMONY_CODE_URL}
HARMONY_SUPPORT_URL: ${HARMONY_SUPPORT_URL}
MUSICBRAINZ_URL: ${MUSICBRAINZ_URL}
DENO_DEPLOYMENT_ID: ${DENO_DEPLOYMENT_ID}
FORWARD_PROTO: ${FORWARD_PROTO}
HARMONY_SPOTIFY_CLIENT_ID: ${HARMONY_SPOTIFY_CLIENT_ID}
HARMONY_SPOTIFY_CLIENT_SECRET: ${HARMONY_SPOTIFY_CLIENT_SECRET}
HARMONY_TIDAL_CLIENT_ID: ${HARMONY_TIDAL_CLIENT_ID}
HARMONY_TIDAL_CLIENT_SECRET: ${HARMONY_TIDAL_CLIENT_SECRET} This would work as docker compose also reads the Side note: While the above is a little verbose I would very much advise this over e.g. using something like |
One advantage is that it can allow you to run a different (stable) version of Deno inside the container than your system has installed. (Or you don't need to install Deno at all if you don't want to.) It may only be a single binary, but I still install it through my system package manager (which may provide an older version than I want) and would rather not manage multiple binaries. |
|
||
WORKDIR /app | ||
|
||
ADD . /app |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A .dockerignore file should probably be added (with the same or similar entries as .gitignore) so that this doesn't copy unwanted stuff.
args: | ||
version: v2024.6.12 | ||
container_name: harmony-container | ||
image: harmony |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tagging the image with $DENO_DEPLOYMENT_ID
might make sense? (I don't have much Deno experience, so not sure if this variable is ideal for versioning.)
image: harmony | |
image: harmony:$DENO_DEPLOYMENT_ID |
Hi all, Thanks for the discussion and contributions so far! Unfortunately, I'm more than a bit busy today and this weekend, but will work on responding to all of this early next week. |
Apologies for not meeting my own timeline of "early next week"... here I am a full week later. 😅 Part of my initial motivation with putting this together was to enable deployment of Harmony in environments where one does not necessarily have access to an underlying operating system/dev environment. With a built container (e.g., published through GitHub Packages), it becomes substantially easier to run things like Harmony on platforms that simply offer Docker container hosting. In addition, as @mwiencek indicated, having a Docker container obviates the need to have Deno installed wherever Harmony is being run. (e.g., personally I didn't have Deno installed on my computer before beginning to work with Harmony) In any case, I'm going to go through the discussion in this PR and address things as appropriate. Thanks again for all of your input so far! |
Co-authored-by: Michael Wiencek <[email protected]>
Unfortunately, I'm having a little trouble with this portion. Regardless of whether I put it into my
Here are the only differences in my working directory besides adding a diff --git a/Dockerfile b/Dockerfile
index ee48b9e..00de358 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,7 +8,5 @@ ADD . /app
RUN deno cache server/main.ts
-ARG version
-ENV DENO_DEPLOYMENT_ID $version
USER deno:deno
CMD deno run -A server/main.ts
diff --git a/docker-compose.yml b/docker-compose.yml
index b800f65..91ddd3a 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,9 +2,12 @@ services:
web:
build:
context: .
- args:
- version: v2024.6.12
container_name: harmony
image: harmony
ports:
- "8000:8000"
+ volumes:
+ - ./snaps/:/app/snaps/:rw
+ - ./snaps.db:/app/snaps.db:rw
+ environment:
+ DENO_DEPLOYMENT_ID: ${DENO_DEPLOYMENT_ID} @phw @atj any suggestions for how to properly handle persisting that file and making it available to the container? I've done some looking around, and I also tried manually |
I think you need to specify a bind mount volume type, e.g. volumes:
- type: bind
source: ./snaps.db
target: /app/snaps.db See this Stack Overflow post: https://stackoverflow.com/questions/42248198/how-to-mount-a-single-file-in-a-volume |
Tried that too, and unfortunately no luck there:
And adding a new bind mount with similar syntax for
|
If mounting an SQLite DB into Docker is such a PITA, we could also create the DB in a dedicated data directory by passing it as an argument here: Line 114 in dfdffd4
Ideally that would be done using another environment variable, with the default still being the current working directory for backward compatibility. Another option (which I haven't tested to confirm it is working) would be to mount a |
Yes, having a separate directory would be preferable and easy management, because when bind mounting a single file it should exist beforehand. Also this allows specifying this directory as a volume directly in the Dockerfile. Then one can easily run the docker image and have the persistent data in a volume even without explicitly defining a local directory as a bind mount. |
I am sorry that it took me so long to get back to this, but I have finally made the data directory configurable in 6b02fe5. You can set it with a |
No problem! I'm still interested in setting up Docker for Harmony. I'm currently preoccupied working on MetaBrainz-internal stuff, but this is on my radar for sure. |
I know this isn't necessarily a needed option at this point, but I thought I'd try my hand at Dockerizing this project in the interest of making it able to run on more platforms. Open to any questions, suggestions, or concerns you might have!
The Dockerfile and Compose spec included in this draft are relatively basic at this point; for one thing, the choice of version to run currently has to be manually specified in the Dockerfile. However, if further development is desired, it may be possible to work around this while developing a more formal build workflow through GitHub Actions or the like.