Skip to content
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

allow containers to be skipped during startup #207

Closed
jgangemi opened this issue Jun 27, 2015 · 9 comments
Closed

allow containers to be skipped during startup #207

jgangemi opened this issue Jun 27, 2015 · 9 comments
Assignees
Labels
Milestone

Comments

@jgangemi
Copy link
Collaborator

during the verify phase, i start a postgres container to run all my integration tests against but i don't want the application container to start at the same time b/c it's not involved w/ any of the tests, etc.

i thought about doing this via profiles (i already use one so the tests don't run as part of the 'normal' build process) but i don't believe that is going to work w/o having to duplicate parts of the container configuration across various profile. instead, i'd like to see an additional element added to the run configuration called startup (open to other suggestions) that defaults to true but if it's false, that container will get skipped.

then i can define all my container configurations as part of the 'main' build definition and just define the property to disable startup in the appropriate profile(s).

@jgangemi jgangemi self-assigned this Jun 27, 2015
@rhuss
Copy link
Collaborator

rhuss commented Jun 27, 2015

I think this is already possible by using the top level image configuration parameter (or property docker.image) which can contain a comma separated list of images to build/start. So you can easily add a profile and set this filter-like configuration value on your own.

What I think could be quite helpful is to support Docker labels. So we can attach labels to images (when building) and then provide a similar top-level config docker.label for selecting the images to process.

But first: Does docker.image solves your use case ?

@rhuss
Copy link
Collaborator

rhuss commented Jun 27, 2015

I think, this could work (not tried):

<profile>
  <id>db-only</id>
  <plugin ....>
     ...
     <configuration>
         <image>postgres</image>
     </configuration>
 </plugin>
</profile>

@jgangemi
Copy link
Collaborator Author

lol - you're right and it clearly states that in the docs (although it can only be done by using the property to list the images). guess i should have rtfm a little more carefully when i was looking to see if there were any options to do this last night.

    <profile>
      <id>integration-tests</id>
      <properties>
        <docker.image>postgres:9.3</docker.image>
      </properties>
      <build>
        <plugins>
          <plugin>
            <groupId>org.jolokia</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <executions>
              <execution>
                <id>start</id>
                <phase>pre-integration-test</phase>
                <goals>
                  <goal>start</goal>
                </goals>
              </execution>
              <execution>
                <id>stop</id>
                <phase>post-integration-test</phase>
                <goals>
                  <goal>stop</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
          </plugin>
        </plugins>
      </build>
    </profile>

(i define the container configuration in the parent pom but not every sub-project needs the database container, so i have to define the executions in the child pom, otherwise a container starts/stops for every sub project).

this means i should be able to move the configuration block back to the main build section now instead of defining it in the profile.

this can be closed unless you happen to know of a way i can define executions in the main build section but still only have them run on applicable projects. i don't think it's possible to ignore executions sometimes and not others if they are defined at the top level.

for completeness, here's the definition in the parent pom

    <profile>
      <id>integration-tests</id>
      <build>
        <pluginManagement>
          <plugins>
            <plugin>
              <groupId>org.jolokia</groupId>
              <artifactId>docker-maven-plugin</artifactId>
              <configuration>
                <images combine.children="append">
                  <image>
                    <name>postgres:9.3</name>
                    <alias>${postgres.docker.alias}</alias>
                    <run>
                      <env>
                        <POSTGRES_USER>${database.username}</POSTGRES_USER>
                        <POSTGRES_PASSWORD>${database.password}</POSTGRES_PASSWORD>
                      </env>
                      <ports>
                        <port>${postgres.docker.port}:5432</port>
                      </ports>
                      <wait>
                        <log>database system is ready to accept connections</log>
                      </wait>
                      <namingStrategy>${postgres.docker.naming}</namingStrategy>
                    </run>
                  </image>
                </images>
              </configuration>           
              <!-- individial poms must define the execution configuraiton :( -->
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </profile>
  </profiles>

if i define the executions here, then any sub project that a configuration in their 'main` build section will cause them to activate.

@jgangemi
Copy link
Collaborator Author

actually - scratch that, the above is not going to resolve my use case. i still want the application's container to be built and pushed as part of the build when the integration tests run, just not started during the verification phase.

@rhuss
Copy link
Collaborator

rhuss commented Jul 1, 2015

If I understand you right, you want to have all image configurations in one place, but want different scenarios for building and running. Currently, every image which has a <build> will be build during docker:build and every image will be started during docker:start.

In order to overwrite this one would have to duplicate the configuration, removing the parts one doesn't need.

I see two solutions to this:

  • The first is what you have suggested: Define something like <mode> which can be run, build, both, none (default: both), so that you can set it like in <mode>${app.docker.mode}</mode> and then tweak this variable in various situations.
  • Define something like a "profile", which can be overridden by sub-projects in their configuration. This would be on the same levels as <images> and hence can be easily overridden. It would also avoid the usage of artificial properties only for this scenario.
<profile>
    <image>
         <name>....</name>
          <build>true</build>
          <run>false</run>
     </image>
      .....
</profile>

Is this approximately that what you mean ;-) ?

@jgangemi
Copy link
Collaborator Author

jgangemi commented Jul 1, 2015

having all image configurations in a central location doesn't really matter. it would be nice, but not a hard requirement. the rest is correct.

do you have an opinion on which option to use?

given they seem equivalent, i like the first one better b/c it's less xml and b/c i already toggle property values based upon which profile is in use rather then duplicating parts of the configuration, eg:

<build>
  <plugins>
    <plugin>docker-maven-plugin</plugin>
    ...
      <build>${enable.docker.build}</build>
      <run>${enable.docker.run}</run>
    ...
  </plugins>
</build>

<profile>
   <id>build-only</id>
   <properties>
     <enable.docker.build>true</enable.docker.build>
     <enable.docker.run>false</enable.docker.run>
  </properties>
</profile>

@tszpinda
Copy link

We have similar case I believe, having projects:

  • parent:
    • db,
    • app 1
    • app 2

both apps are sharing the same db, but during integration tests we want them to have a "clean start" so db should be empty and fresh for each of the app.
Db project prepares postgres database and runs all the upgrade scripts (100s of them) which only needs to happen once.

Ideally when running mvn install in the parent dir it would build db container once and save it at the end, then just start and stop the container it in both app 1 and app 2 projects. Is this already possible?

@rhuss
Copy link
Collaborator

rhuss commented Jul 15, 2015

This should be possible in 0.13.2 (coming out this week) if you do then the following:

  • The db project builds an own image based on the database image you want to use and running the updates scripts during the build (if you use a Dockerfile for that with the dockerFileDir mode this already works today. If you want to configure everything from the pom.xml you need to wait for 0.13.2). This image is stored in the docker host under the name 'myuser/testdb:latest'.
  • app1 references mysuser/testdb:latest as a link and has the full access to the pre-populated DB during itst tests run.
  • For app2 its the same, it gets a fresh container from the prepared db image.

The only problem I see with large DBs is, that the data shouldn't be stored in the container but mounted as volume for performance reasons. This can be also possible if you share the db directory on the host, but I haven't thought much yet about this scenario.

@tszpinda
Copy link

Great news, thanks!

rhuss added a commit that referenced this issue Jul 23, 2015
@jgangemi jgangemi added this to the 0.13.3 milestone Jul 23, 2015
@jgangemi jgangemi added the fixed label Jul 23, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants