skip to Main Content

I am setting up an Gitlab CI/CD pipeline to test several Laravel micro services and an front-end. To check if the front-end displays the results from the API endpoints correctly I thought to pass it the results form the endpoints as artifacts.

I thought this would be simple, like doing something like

after_script:
  ...
  - wget --no-check-certificate 'https://localhost/api/product/' -O ./artifacts/product_api.json

artifacts:
    when: always
    paths:
      - ./artifacts/product_api.json

But I was wrong. Localhost is the server that starts the containers. So somehow I need to find out what is the Hostname or the IP of the container.

I found various place (for example here) that claim the hostname is ‘docker’, yet I can’t even ping that name.

Anothers suggest I find is using:

  - CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAdress}}{{end}}' myapp) // Replace myapp with your container name.
  - sleep 15
  - curl $CONTAINER_IP:8000

but this would require me to install Docker, which I would much rather not.

Is there a way to reach your current container in Gitlab CI/CD? (I am NOT self-hosting the runners)

My .gitlab-ci.yml looks something like:

Product-API:
  image: serversideup/php:8.2-fpm-nginx
 
  services:
    - name: mysql:8.0.33-debian
      alias: mysql
      entrypoint: ['/bin/sh', '-c', 'sed -i -e "/^skip-name-resolve/d" /etc/mysql/conf.d/docker.cnf && /usr/local/bin/docker-entrypoint.sh mysqld']
  
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
    GIT_SUBMODULE_FORCE_HTTPS: "true"
    #FF_NETWORK_PER_BUILD: 1

    #mysql variables
    MYSQL_DATABASE: $MYSQL_DATABASE
    MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
    MYSQL_USER: $MYSQL_SHOP_ADMIN
    MYSQL_PASSWORD: $MYSQL_SHOP_ADMIN_PASSWORD
    
    #laravel variables
    APP_DEBUG: "true"
    DB_CONNECTION: mysql
    DB_HOST: $MYSQL_HOST
    DB_PORT: 3306
    DB_USERNAME: '$PRODUCTAPI_DB_USER'
    DB_PASSWORD: '$PRODUCTAPI_DB_PASSWORD'
    DB_DATABASE: $MYSQL_DATABASE


  before_script:
    #download and unpack the product database
    - mkdir artifacts
    - 'curl --location --output ./artifacts/db_dump.zip --header "PRIVATE-TOKEN: $ARTIFACTS_TOKEN" "https://gitlab.com/api/v4/projects/test1/jobs/artifacts/develop/download?job=Database-Tables"'
    - 'curl --location --output ./artifacts/mysqlusersandgrants.zip --header "PRIVATE-TOKEN: $ARTIFACTS_TOKEN" "https://gitlab.com/api/v4/projects/test2/jobs/artifacts/develop/download?job=Database-Users"'
    - unzip ./artifacts/db_dump.zip    
    - unzip ./artifacts/mysqlusersandgrants.zip
 
    #put the database in place
    - apt-get update
    - apt-get install -y mysql-client
    - mysql -uroot -p$MYSQL_ROOT_PASSWORD --host=$MYSQL_HOST "$MYSQL_DATABASE" < ./artifacts/db_dump.sql
    - mysql -uroot -p$MYSQL_ROOT_PASSWORD --host=$MYSQL_HOST mysql < ./artifacts/mysqlusersandgrants.sql

    #putting and .env file in place
    - mv .env.example .env
    #install Laravel
    - composer install
    - php artisan key:generate
    - php artisan config:cache
    - php artisan route:cache
    - php artisan view:cache
    #setting user and group rights
    - chown -R webuser:webgroup .

  script:
     - php artisan test --log-junit productapi_results.xml

  after_script:
    - 'curl -k --location --output ./artifacts/product_api.json "https://docker/api/product/"'
    - cat ./artifacts/product_api.json

  artifacts:
    when: always
    paths:
      - ./artifacts/product_api.json
      - productapi_results.xml
    reports:
      junit: productapi_results.xml

This gives the error:

Running after script...
$ curl -k --location --output ./artifacts/product_api.json "https://docker/api/product/"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: docker
[18-Jan-2024 20:19:43] NOTICE: Terminating ...
[18-Jan-2024 20:19:43] NOTICE: exiting, bye-bye!
WARNING: after_script failed, but job will continue unaffected: exit code 1

2

Answers


  1. I couldn’t find where you start the web server, thus added that too:

    • Should serve in background to keep continue. That’s why & is added.
    • Waiting a little is probably good idea, thus sleep 10.
      script:
        - php artisan test --log-junit productapi_results.xml
        - php artisan serve --port=8000 &
        - sleep 10
        - curl http://localhost:8000/api/product/ --output ./artifacts/product_api.json
    

    You can’t use after_script to make request to your web server that runs in script phase:

    • It runs after that script is completed, if you start a web server it won’t complete (fail or success).
    • It’s in separate shell, your changes won’t be here.

    From doc:

    Don’t have access to changes done by commands defined in the before_script or script, including:
    Command aliases and variables exported in script scripts.
    Changes outside of the working tree (depending on the runner executor), like software installed by a before_script or script script.


    To make things clear below is minimal reproducible example:

    dep:
      image: nginx:latest
      script:
        - nginx -g 'daemon off;' 2>&1 > /dev/null & 
        - curl http://localhost > product_api.json
      artifacts:
        when: always
        paths: 
          - product_api.json
    
    Login or Signup to reply.
  2. "Could not resolve host: docker"? I have only seen ‘docker‘ as a hostname when accessing the docker registry hostname, where the shorter service hostname docker is expected.

    In GitLab CI/CD, especially when not self-hosting runners, the hostname docker does not necessarily point to the current running container or any service within the CI job. That hostname might not be recognized in the GitLab-managed runners’ environment.

    In your case, the Laravel application is accessible to the curl command within the same container, using localhost as the hostname and 8000 as the port number.

    +-----------------------------------------------------------+
    | GitLab CI/CD Runner                                       |
    | +-------------------------------------------------------+ |
    | | CI Job Container                                      | |
    | |                                                       | |
    | | +---------------------------------------------------+ | |
    | | | Laravel Application (Product-API)                 | | |
    | | | - Served on localhost:8000                        | | |
    | | +---------------------------------------------------+ | |
    | |                                                       | |
    | | +---------------------------------------------------+ | |
    | | | Curl Command                                       | | |
    | | | - Accessing Laravel App via http://localhost:8000 | | |
    | | +---------------------------------------------------+ | |
    | +-------------------------------------------------------+ |
    +-----------------------------------------------------------+
    

    You have used https in your curl command. Make sure your Laravel application is set up to handle HTTPS requests. If it is not configured for HTTPS, you should use http instead (so no -k option needed).

    Since your Laravel application and the curl command are executed within the same CI job (and hence, within the same container), you should be able to use localhost to access your application. That means the URL in your curl command should be http://localhost:8000/api/product/ if you are using the default HTTP port 8000.

    Make sure the port you are using in the curl command matches the port on which your Laravel application is running. If you are using the default Laravel port (8000), then localhost:8000 is correct. If you have configured a different port, adjust the curl command accordingly.

    Make sure the Laravel server is running when you execute the curl command. As mentioned in the previous response, you can start the Laravel server in the background during the script phase of your CI/CD pipeline.

    Your .gitlab-ci.yml would be:

      script:
        - php artisan serve --port=8000 &
        - sleep 10 # Wait for the server to start
        - curl http://localhost:8000/api/product/ --output ./artifacts/product_api.json
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search