msztolcman / sendria

Sendria (formerly MailTrap) is a SMTP server designed to run in your dev/test environment, that is designed to catch any email you or your application is sending, and display it in a web interface instead of sending to real world.
MIT License
149 stars 14 forks source link

Dockerfile from local code #6

Closed Arzaroth closed 2 years ago

Arzaroth commented 3 years ago

I'm mostly using Docker and I think it would make more sense to build the image using the local version of the code.

Binding the image with the release on pypi hinders possibilities of "test builds". I've found myself having to change the Dockerfile to something similar to this PR while hacking the code.

The downside would be that you would have to checkout a specific tag before building the image in order to upload the correct version to docker hub.

msztolcman commented 3 years ago

Hi @Arzaroth,

I've tried to find a solution to be perfect for both worlds ;) Based on your solution, I've migrated to something else. Please look at branch dockerfile-playgames and say, what do you think about.

I've not tested it very deeply, just verified build, that Sendria is running and communication is working etc. Thanks to multistage of docker, you can run build with argument:

docker build --build-arg SENDRIA_BUILD_VERSION=dev -t msztolcman/sendria docker.build

To build container in developer friendly version. You can also change SENDRIA_BUILD_VERSION from dev to prod and build production container.

There is not working one thing in there (passing Sendria version using build params), but it doesn't matter now.

In above command you may want to adjust docker context (mine is docker.build, you may use . instead).

Please look at this and verify is this working for you or not? Maybe you have some opinion? I will be glad to hear yours :)

Arzaroth commented 3 years ago

Hi,

Rather than using a build-arg, I believe in this case using --target would fit better. It will be doing the same thing, it's just (in my understanding) a standardized way of doing what you're trying to achieve.

Thus, you could forego the final two FROM and just run this :

docker build --target install-dev -t msztolcman/sendria docker.build

In my opinion, if you want to have a "real" dev mode, you probably would use a volume to access the code rather than copying it, and implement some kind of "hot-reload" mechanism, but it might be a tad overkill.

Another solution, rather than using --target would be to use an environment variable (well, a build-arg rather), and defer the build process to a shell script, something along the lines of :

COPY install.sh install.sh
RUN chmod u+x install.sh && ./install.sh

install.sh :

if [ ${SENDRIA_BUILD_VERSION} = "dev" ]; then 
    ...
else
    ...
fi

The advantage of this method would be to skip the unwanted part of the build, at the cost of deporting the build code into another file.

I have a last remark. As I stated in an earlier message, I had the idea of adding sendria to the PATH, so there is the need to change the arguments, you wouldn't have to remember tedious commands. Using different commands between prod and dev adds an extra layer of complexity to the plan. But you wish to keep it that way, it could be solved by allowing the arguments to be specified in environment variables. It could be done in the python code directly, or by adding an ENTRYPOINT that would "convert" the environment variables to command line arguments.

chytreg commented 2 years ago

@Arzaroth As docker for development here is a good article https://evilmartians.com/chronicles/reusable-development-containers-with-docker-compose-and-dip it's for ruby, but could be applied here as well. The step with the multi-stage build is the good one, shortly you need a bit different image for dev and another one for release. docker-compose could orchestrate things to play nicely having development in the docker.

msztolcman commented 2 years ago

Hi @Arzaroth, I was thinking a while about your solution, about my in dockerfile-playgames branch etc, but non of them I like. However, you are right it's good to have a solution for working with local code, and will try to prepare separate Dockerfile for this. Thank you for idea and PR, forced me to think about this (yeah, took a little bit too long to finalize ;) but life and work...) and to find some solution, I like this :)

@chytreg Thanks for great link, didn't know this solution. I will study this a little bit later :)