Comment déployer Heroku avec Webpack

Webpack est un outil utilisé dans les applications JavaScript pour la gestion des dépendances. En parcourant toutes les importations de votre application, webpack crée un graphique de dépendance composé de tous les actifs nécessaires à votre application. Ce graphe de dépendance est ensuite utilisé pour générer un ou plusieurs fichiers appelés bundles.

Concepts de base du WebPack

Entrée

Le point d'entrée identifie le module avec lequel webpack doit démarrer lors de la création de son graphe de dépendance interne. Par défaut, webpack utilise ./src/index.js.

Sortir

La sortie spécifie l'emplacement que webpack doit utiliser pour émettre des bundles et comment les nommer. Par défaut, webpack utilise ./dist/main.jsle fichier de sortie principal et le ./distdossier pour les autres fichiers générés.

Loaders

Les chargeurs sont le moyen utilisé par Webpack pour permettre aux développeurs de regrouper des fichiers autres que JavaScript et JSON que Webpack ne comprend pas immédiatement.

Configuration de l'application

Pour continuer, assurez-vous que les derniers nodeJS et npm sont installés sur votre ordinateur.

Créez un nouveau dossier nommé deploy-react-webpacket accédez au dossier.

mkdir deploy-react-webpack
cd deploy-react-webpack

Initialisez le projet avec les options par défaut.

npm init -y

Cela crée un fichier package.json.

Installez les packages ReactJs requis.

npm i react react-dom

Babel

Babel convertit la syntaxe ES5 et ES6 utilisée dans ReactJs en une version rétrocompatible de JavaScript qui est prise en charge par les navigateurs plus anciens et plus récents.

Installer Babel :

npm i -D @babel/core babel-loader @babel/preset-env @babel/preset-react

Installez webpack et webpack-cli :

npm i -D  webpack webpack-cli webpack-dev-server

Configuration de Babel

Créez un nouveau fichier à la racine du projet nommé .babelrc.

touch .babelrc

Ajoutez le code suivant au fichier et enregistrez.

{
  "presets": [
      "@babel/preset-env","@babel/preset-react"
   ]
}

Configurer Webpack

Créez un nouveau fichier à la racine du projet nommé webpack.config.js.

Ajouter des composants pour le traitement HTML

npm i html-webpack-plugin html-loader --save-dev
touch webpack.config.js

Ajoutez le code suivant.

const HtmlWebPackPlugin = require("html-webpack-plugin");

module.exports = {
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader"
                }
            },
            {
                test: /\.html$/,
                use: [
                    {
                        loader: "html-loader"
                    }
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebPackPlugin({
            template: "./src/index.html",
            filename: "./index.html"
        })
    ]
};

entryindique à webpack par où commencer lors du regroupement de votre application. La testrègle spécifie les extensions de fichier où le babel-loaderpeut être utilisé tout en excluant les fichiers dans le node_modules.

Création de l'application React

À cette étape, vous allez créer l'application React réelle avec laquelle les utilisateurs peuvent interagir.

Créer à l' index.htmlintérieur src.

mkdir src
cd src
touch index.html

Ajoutez le code suivant à index.html.

<html lang="en">
<head>
    <meta charset="utf-8">
     <meta name="viewport" content="width=device-width,initial-scale=1, shrink-to-fit=no">
    <title>How To Deploy React Js With Babel On Heroku</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

A l'intérieur src, créez un fichier nommé index.js.

touch index.js

Ajoutez le code suivant.

import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component{
    render(){
        return(
            <div>
                Hello World !
            </div>
        )
    }
}
ReactDOM.render(<App/>, document.getElementById("root"));

Cela crée un simple composant React hello world.

Remplacez le code suivant dans votre package.json.

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
},

avec

"scripts": {
    "dev": "webpack serve",
    "start": "node server.js",
    "build": "webpack --mode production"
  },

La devcommande est utilisée pour exécuter l'application en mode développement. La startcommande est utilisée par Heroku pour servir des fichiers en production.

Votre package.json devrait ressembler à ceci.

{
  "name": "deploy-react-webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack serve",
    "start": "node server.js",
    "build": "webpack --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.3",
    "@babel/preset-env": "^7.12.1",
    "@babel/preset-react": "^7.12.5",
    "@webpack-cli/serve": "^1.0.1",
    "babel-loader": "^8.1.0",
    "html-loader": "^1.3.2",
    "html-webpack-plugin": "^4.5.0",
    "webpack": "^5.4.0",
    "webpack-cli": "^4.1.0",
    "webpack-dev-server": "^3.11.0"
  }
}

Ajout d'Express pour servir des fichiers dans Heroku

Installez Express à l'aide de la commande suivante :

npm install express

Créez un fichier à la racine du projet nommé server.jset ajoutez le code suivant :

var path = require('path');
var express = require('express');

var app = express();

app.use(express.static(path.join(__dirname, 'dist')));
app.set('port', process.env.PORT || 8080);

var server = app.listen(app.get('port'), function() {
  console.log('listening on port ', server.address().port);
});

Aperçu du projet localement

Exécutez la commande suivante pour lancer le projet localement.

npm run dev

Ouvrez le lien suivant dans la fenêtre de votre navigateur :

http://127.0.0.1:8080/

Vous devriez voir une page comme celle-ci :

Construire un projet pour la production

npm run build

Déployer sur Heroku

Créez un compte sur Heroku et confirmez votre adresse e-mail.

Installez Heroku CLI :

npm install -g heroku

Confirmez que Heroku CLI est installé en exécutant :

heroku --version

Vous devriez voir votre version Heroku CLI.

Connectez-vous à Heroku en exécutant la commande ci-dessous.

heroku login

L'exécution de cette commande ouvrira le site Heroku sur votre navigateur, où vous pourrez vous connecter.

Configurez un référentiel Git à la racine du projet.

git init

Ignorez les modules Node dans Git.

touch .gitignore

Ajoutez la ligne suivante au fichier :

node_modules
git add .
git commit -m "initial commit"

Créez une application Heroku.

heroku create

Publier sur Heroku.

git push heroku master

Une fois la construction réussie, vous pouvez accéder au tableau de bord de vos applications Heroku et ouvrir votre application ou ouvrir le lien dans votre console.

Une fois le lien ouvert, votre application devrait ressembler à ceci :

Aperçu de la construction

 

La maîtrise de cette compétence est vitale dans des rôles tels que le développement front-end et devOps se penchant vers les projets front-end.

What is GEEK

Buddha Community

Dexter  Goodwin

Dexter Goodwin

1650394920

Webpack: A Bundler for Javascript and Friends

webpack

Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

Install

Install with npm:

npm install --save-dev webpack

Install with yarn:

yarn add webpack --dev

Introduction

Webpack is a bundler for modules. The main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

TL;DR

  • Bundles ES Modules, CommonJS, and AMD modules (even combined).
  • Can create a single bundle or multiple chunks that are asynchronously loaded at runtime (to reduce initial loading time).
  • Dependencies are resolved during compilation, reducing the runtime size.
  • Loaders can preprocess files while compiling, e.g. TypeScript to JavaScript, Handlebars strings to compiled functions, images to Base64, etc.
  • Highly modular plugin system to do whatever else your application requires.

Get Started

Check out webpack's quick Get Started guide and the other guides.

Browser Compatibility

Webpack supports all browsers that are ES5-compliant (IE8 and below are not supported). Webpack also needs Promise for import() and require.ensure(). If you want to support older browsers, you will need to load a polyfill before using these expressions.

Concepts

Plugins

Webpack has a rich plugin interface. Most of the features within webpack itself use this plugin interface. This makes webpack very flexible.

NameStatusInstall SizeDescription
[mini-css-extract-plugin][mini-css]![mini-css-npm]![mini-css-size]Extracts CSS into separate files. It creates a CSS file per JS file which contains CSS.
[compression-webpack-plugin][compression]![compression-npm]![compression-size]Prepares compressed versions of assets to serve them with Content-Encoding
[html-webpack-plugin][html-plugin]![html-plugin-npm]![html-plugin-size]Simplifies creation of HTML files (index.html) to serve your bundles

Loaders

Webpack enables the use of loaders to preprocess files. This allows you to bundle any static resource way beyond JavaScript. You can easily write your own loaders using Node.js.

Loaders are activated by using loadername! prefixes in require() statements, or are automatically applied via regex from your webpack configuration.

Files

NameStatusInstall SizeDescription
[val-loader][val]![val-npm]![val-size]Executes code as module and considers exports as JS code

JSON

NameStatusInstall SizeDescription
![cson-npm]![cson-size]Loads and transpiles a CSON file

Transpiling

NameStatusInstall SizeDescription
![babel-npm]![babel-size]Loads ES2015+ code and transpiles to ES5 using Babel
![type-npm]![type-size]Loads TypeScript like JavaScript
![coffee-npm]![coffee-size]Loads CoffeeScript like JavaScript

Templating

NameStatusInstall SizeDescription
![html-npm]![html-size]Exports HTML as string, requires references to static resources
![pug-npm]![pug-size]Loads Pug templates and returns a function
![md-npm]![md-size]Compiles Markdown to HTML
![posthtml-npm]![posthtml-size]Loads and transforms a HTML file using PostHTML
![hbs-npm]![hbs-size]Compiles Handlebars to HTML

Styling

NameStatusInstall SizeDescription
<style>![style-npm]![style-size]Add exports of a module as style to DOM
![css-npm]![css-size]Loads CSS file with resolved imports and returns CSS code
![less-npm]![less-size]Loads and compiles a LESS file
![sass-npm]![sass-size]Loads and compiles a Sass/SCSS file
![stylus-npm]![stylus-size]Loads and compiles a Stylus file
![postcss-npm]![postcss-size]Loads and transforms a CSS/SSS file using PostCSS

Frameworks

NameStatusInstall SizeDescription
![vue-npm]![vue-size]Loads and compiles Vue Components
![polymer-npm]![polymer-size]Process HTML & CSS with preprocessor of choice and require() Web Components like first-class modules
![angular-npm]![angular-size]Loads and compiles Angular 2 Components
![riot-npm]![riot-size]Riot official webpack loader

Performance

Webpack uses async I/O and has multiple caching levels. This makes webpack fast and incredibly fast on incremental compilations.

Module Formats

Webpack supports ES2015+, CommonJS and AMD modules out of the box. It performs clever static analysis on the AST of your code. It even has an evaluation engine to evaluate simple expressions. This allows you to support most existing libraries out of the box.

Code Splitting

Webpack allows you to split your codebase into multiple chunks. Chunks are loaded asynchronously at runtime. This reduces the initial loading time.

Optimizations

Webpack can do many optimizations to reduce the output size of your JavaScript by deduplicating frequently used modules, minifying, and giving you full control of what is loaded initially and what is loaded at runtime through code splitting. It can also make your code chunks cache friendly by using hashes.

Contributing

We want contributing to webpack to be fun, enjoyable, and educational for anyone, and everyone. We have a vibrant ecosystem that spans beyond this single repo. We welcome you to check out any of the repositories in our organization or webpack-contrib organization which houses all of our loaders and plugins.

Contributions go far beyond pull requests and commits. Although we love giving you the opportunity to put your stamp on webpack, we also are thrilled to receive a variety of other contributions including:

  • Documentation updates, enhancements, designs, or bugfixes
  • Spelling or grammar fixes
  • README.md corrections or redesigns
  • Adding unit, or functional tests
  • Triaging GitHub issues -- especially determining whether an issue still persists or is reproducible.
  • Searching #webpack on twitter and helping someone else who needs help
  • Teaching others how to contribute to one of the many webpack's repos!
  • Blogging, speaking about, or creating tutorials about one of webpack's many features.
  • Helping others in our webpack gitter channel.

To get started have a look at our documentation on contributing.

If you are worried or don't know where to start, you can always reach out to Sean Larkin (@TheLarkInn) on Twitter or simply submit an issue and a maintainer can help give you guidance!

We have also started a series on our Medium Publication called The Contributor's Guide to webpack. We welcome you to read it and post any questions or responses if you still need help.

Looking to speak about webpack? We'd love to review your talk abstract/CFP! You can email it to webpack [at] opencollective [dot] com and we can give pointers or tips!!!

Creating your own plugins and loaders

If you create a loader or plugin, we would <3 for you to open source it, and put it on npm. We follow the x-loader, x-webpack-plugin naming convention.

Support

We consider webpack to be a low-level tool used not only individually but also layered beneath other awesome tools. Because of its flexibility, webpack isn't always the easiest entry-level solution, however we do believe it is the most powerful. That said, we're always looking for ways to improve and simplify the tool without compromising functionality. If you have any ideas on ways to accomplish this, we're all ears!

If you're just getting started, take a look at our new docs and concepts page. This has a high level overview that is great for beginners!!

Looking for webpack 1 docs? Please check out the old wiki, but note that this deprecated version is no longer supported.

If you want to discuss something or just need help, here is our Gitter room where there are always individuals looking to help out!

If you are still having difficulty, we would love for you to post a question to StackOverflow with the webpack tag. It is much easier to answer questions that include your webpack.config.js and relevant files! So if you can provide them, we'd be extremely grateful (and more likely to help you find the answer!)

If you are twitter savvy you can tweet #webpack with your question and someone should be able to reach out and help also.

If you have discovered a 🐜 or have a feature suggestion, feel free to create an issue on Github.

Sponsoring

Most of the core team members, webpack contributors and contributors in the ecosystem do this open source work in their free time. If you use webpack for a serious task, and you'd like us to invest more time on it, please donate. This project increases your income/productivity too. It makes development and applications faster and it reduces the required bandwidth.

This is how we use the donations:

  • Allow the core team to work on webpack
  • Thank contributors if they invested a large amount of time in contributing
  • Support projects in the ecosystem that are of great value for users
  • Support projects that are voted most (work in progress)
  • Infrastructure cost
  • Fees for money handling

Author: Webpack
Source Code: https://github.com/webpack/webpack 
License: MIT License

#webpack #javascript 

Lawrence  Lesch

Lawrence Lesch

1642275180

Webpack: Packs Commonjs/AMD Modules for The Browser

webpack

Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

Table of Contents

  1. Install
  2. Introduction
  3. Concepts
  4. Contributing
  5. Support
  6. Core Team
  7. Sponsoring
  8. Premium Partners
  9. Other Backers and Sponsors
  10. Gold Sponsors
  11. Silver Sponsors
  12. Bronze Sponsors
  13. Backers
  14. Special Thanks

Install

Install with npm:

npm install --save-dev webpack

Install with yarn:

yarn add webpack --dev

Introduction

Webpack is a bundler for modules. The main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

TL;DR

  • Bundles ES Modules, CommonJS, and AMD modules (even combined).
  • Can create a single bundle or multiple chunks that are asynchronously loaded at runtime (to reduce initial loading time).
  • Dependencies are resolved during compilation, reducing the runtime size.
  • Loaders can preprocess files while compiling, e.g. TypeScript to JavaScript, Handlebars strings to compiled functions, images to Base64, etc.
  • Highly modular plugin system to do whatever else your application requires.

Get Started

Check out webpack's quick Get Started guide and the other guides.

Browser Compatibility

Webpack supports all browsers that are ES5-compliant (IE8 and below are not supported). Webpack also needs Promise for import() and require.ensure(). If you want to support older browsers, you will need to load a polyfill before using these expressions.

Concepts

Plugins

Webpack has a rich plugin interface. Most of the features within webpack itself use this plugin interface. This makes webpack very flexible.

NameStatusInstall SizeDescription
mini-css-extract-pluginmini-css-npmmini-css-sizeExtracts CSS into separate files. It creates a CSS file per JS file which contains CSS.
compression-webpack-plugincompression-npmcompression-sizePrepares compressed versions of assets to serve them with Content-Encoding
html-webpack-pluginhtml-plugin-npmhtml-plugin-sizeSimplifies creation of HTML files (index.html) to serve your bundles

Loaders

Webpack enables the use of loaders to preprocess files. This allows you to bundle any static resource way beyond JavaScript. You can easily write your own loaders using Node.js.

Loaders are activated by using loadername! prefixes in require() statements, or are automatically applied via regex from your webpack configuration.

Files

NameStatusInstall SizeDescription
val-loaderval-npmval-sizeExecutes code as module and considers exports as JS code

JSON

NameStatusInstall SizeDescription
cson-npmcson-sizeLoads and transpiles a CSON file

Transpiling

NameStatusInstall SizeDescription
babel-npmbabel-sizeLoads ES2015+ code and transpiles to ES5 using Babel
type-npmtype-sizeLoads TypeScript like JavaScript
coffee-npmcoffee-sizeLoads CoffeeScript like JavaScript

Templating

NameStatusInstall SizeDescription
html-npmhtml-sizeExports HTML as string, requires references to static resources
pug-npmpug-sizeLoads Pug templates and returns a function
md-npmmd-sizeCompiles Markdown to HTML
posthtml-npmposthtml-sizeLoads and transforms a HTML file using PostHTML
hbs-npmhbs-sizeCompiles Handlebars to HTML

Styling

NameStatusInstall SizeDescription
<style>style-npmstyle-sizeAdd exports of a module as style to DOM
css-npmcss-sizeLoads CSS file with resolved imports and returns CSS code
less-npmless-sizeLoads and compiles a LESS file
sass-npmsass-sizeLoads and compiles a Sass/SCSS file
stylus-npmstylus-sizeLoads and compiles a Stylus file
postcss-npmpostcss-sizeLoads and transforms a CSS/SSS file using PostCSS

Frameworks

NameStatusInstall SizeDescription
vue-npmvue-sizeLoads and compiles Vue Components
polymer-npmpolymer-sizeProcess HTML & CSS with preprocessor of choice and require() Web Components like first-class modules
angular-npmangular-sizeLoads and compiles Angular 2 Components
riot-npmriot-sizeRiot official webpack loader

Performance

Webpack uses async I/O and has multiple caching levels. This makes webpack fast and incredibly fast on incremental compilations.

Module Formats

Webpack supports ES2015+, CommonJS and AMD modules out of the box. It performs clever static analysis on the AST of your code. It even has an evaluation engine to evaluate simple expressions. This allows you to support most existing libraries out of the box.

Code Splitting

Webpack allows you to split your codebase into multiple chunks. Chunks are loaded asynchronously at runtime. This reduces the initial loading time.

Optimizations

Webpack can do many optimizations to reduce the output size of your JavaScript by deduplicating frequently used modules, minifying, and giving you full control of what is loaded initially and what is loaded at runtime through code splitting. It can also make your code chunks cache friendly by using hashes.

Contributing

We want contributing to webpack to be fun, enjoyable, and educational for anyone, and everyone. We have a vibrant ecosystem that spans beyond this single repo. We welcome you to check out any of the repositories in our organization or webpack-contrib organization which houses all of our loaders and plugins.

Contributions go far beyond pull requests and commits. Although we love giving you the opportunity to put your stamp on webpack, we also are thrilled to receive a variety of other contributions including:

  • Documentation updates, enhancements, designs, or bugfixes
  • Spelling or grammar fixes
  • README.md corrections or redesigns
  • Adding unit, or functional tests
  • Triaging GitHub issues -- especially determining whether an issue still persists or is reproducible.
  • Searching #webpack on twitter and helping someone else who needs help
  • Teaching others how to contribute to one of the many webpack's repos!
  • Blogging, speaking about, or creating tutorials about one of webpack's many features.
  • Helping others in our webpack gitter channel.

To get started have a look at our documentation on contributing.

If you are worried or don't know where to start, you can always reach out to Sean Larkin (@TheLarkInn) on Twitter or simply submit an issue and a maintainer can help give you guidance!

We have also started a series on our Medium Publication called The Contributor's Guide to webpack. We welcome you to read it and post any questions or responses if you still need help.

Looking to speak about webpack? We'd love to review your talk abstract/CFP! You can email it to webpack [at] opencollective [dot] com and we can give pointers or tips!!!

Creating your own plugins and loaders

If you create a loader or plugin, we would <3 for you to open source it, and put it on npm. We follow the x-loader, x-webpack-plugin naming convention.

Support

We consider webpack to be a low-level tool used not only individually but also layered beneath other awesome tools. Because of its flexibility, webpack isn't always the easiest entry-level solution, however we do believe it is the most powerful. That said, we're always looking for ways to improve and simplify the tool without compromising functionality. If you have any ideas on ways to accomplish this, we're all ears!

If you're just getting started, take a look at our new docs and concepts page. This has a high level overview that is great for beginners!!

Looking for webpack 1 docs? Please check out the old wiki, but note that this deprecated version is no longer supported.

If you want to discuss something or just need help, here is our Gitter room where there are always individuals looking to help out!

If you are still having difficulty, we would love for you to post a question to StackOverflow with the webpack tag. It is much easier to answer questions that include your webpack.config.js and relevant files! So if you can provide them, we'd be extremely grateful (and more likely to help you find the answer!)

If you are twitter savvy you can tweet #webpack with your question and someone should be able to reach out and help also.

If you have discovered a 🐜 or have a feature suggestion, feel free to create an issue on Github.

Author: Webpack
Source Code: https://github.com/webpack/webpack 
License: MIT License

#webpack #javascript 

Deploying to Heroku with Webpack

Webpack is a tool used in JavaScript applications for dependency management. By traversing all the imports in your app, webpack creates a dependency graph consisting of all the assets needed by your app. This dependency graph is then used to generate one or more files called bundles.

WebPack Core Concepts

Entry

The entry point pinpoints the module that webpack should start with when creating its internal dependency graph. By default, webpack uses ./src/index.js.

Output

The output specifies the location that webpack should use to emit bundles and how to name them. By default, webpack uses ./dist/main.js for the main output file and ./dist folder for other generated files.

Loaders

Loaders are webpack’s way of allowing developers to bundle files other than JavaScript and JSON that Webpack does not understand out of the box.

#webpack #heroku

Eladio  Rau

Eladio Rau

1660389180

Comment Déployer Une Application Django Sur Heroku Avec Docker

Cet article explique comment déployer une application Django sur Heroku avec Docker via Heroku Container Runtime.

Objectifs

À la fin de ce didacticiel, vous serez en mesure de :

  1. Expliquez pourquoi vous pouvez utiliser le Container Runtime de Heroku pour exécuter une application
  2. Dockeriser une application Django
  3. Déployer et exécuter une application Django dans un conteneur Docker sur Heroku
  4. Configurer GitLab CI pour déployer des images Docker sur Heroku
  5. Gérez les ressources statiques avec WhiteNoise
  6. Configurer Postgres pour qu'il s'exécute sur Heroku
  7. Créer un Dockerfile de production qui utilise des builds Docker en plusieurs étapes
  8. Utiliser le registre de conteneurs Heroku et le manifeste de construction pour déployer Docker sur Heroku

Exécution du conteneur Heroku

Outre les déploiements traditionnels du compilateur Git plus slug ( git push heroku master), Heroku prend également en charge les déploiements basés sur Docker, avec Heroku Container Runtime.

Déploiements basés sur Docker

Les déploiements basés sur Docker présentent de nombreux avantages par rapport à l'approche traditionnelle :

  1. Aucune limite de slug : Heroku autorise une taille de slug maximale de 500 Mo pour les déploiements traditionnels basés sur Git. Les déploiements basés sur Docker, en revanche, n'ont pas cette limite.
  2. Contrôle total sur le système d'exploitation : Plutôt que d'être limité par les packages installés par les buildpacks Heroku , vous avez un contrôle total sur le système d'exploitation et pouvez installer n'importe quel package que vous souhaitez avec Docker.
  3. Parité dev/prod plus forte : les builds basés sur Docker ont une parité plus forte entre le développement et la production puisque les environnements sous-jacents sont les mêmes.
  4. Moins de dépendance vis-à-vis d'un fournisseur : Enfin, Docker facilite grandement le passage à un autre fournisseur d'hébergement cloud tel qu'AWS ou GCP.

En général, les déploiements basés sur Docker vous offrent une plus grande flexibilité et un meilleur contrôle sur l'environnement de déploiement. Vous pouvez déployer les applications que vous souhaitez dans l'environnement de votre choix. Cela dit, vous êtes désormais responsable des mises à jour de sécurité. Avec les déploiements traditionnels basés sur Git, Heroku en est responsable. Ils appliquent les mises à jour de sécurité pertinentes à leurs Stacks et migrent votre application vers les nouvelles Stacks si nécessaire. Garde ça en tête.

Il existe actuellement deux façons de déployer des applications avec Docker sur Heroku :

  1. Container Registry : déployez des images Docker pré-construites sur Heroku
  2. Build Manifest : étant donné un Dockerfile, Heroku construit et déploie l'image Docker

La principale différence entre ces deux est qu'avec la dernière approche - par exemple, via le Build Manifest - vous avez accès aux fonctionnalités Pipelines , Review et Release . Ainsi, si vous convertissez une application d'un déploiement basé sur Git vers Docker et que vous utilisez l'une de ces fonctionnalités, vous devez utiliser l'approche Build Manifest.

Rassurez-vous, nous examinerons les deux approches dans cet article.

Dans les deux cas, vous aurez toujours accès à la CLI Heroku , à tous les puissants addons et au tableau de bord . En d'autres termes, toutes ces fonctionnalités fonctionnent avec le Container Runtime.

Type de déploiementMécanisme de déploiementMises à jour de sécurité (qui gère)Accès aux pipelines, examen, publicationAccès à la CLI, aux modules complémentaires et au tableau de bordLimites de taille des lingots
Compilateur Git + SlugPoussée GitHérokuOuiOuiOui
Docker + Exécution du conteneurPoussée DockerTuNonOuiNon
Docker + Build ManifestPoussée GitTuOuiOuiNon

Gardez à l'esprit que les déploiements basés sur Docker sont limités aux mêmes contraintes que les déploiements basés sur Git. Par exemple, les volumes persistants ne sont pas pris en charge car le système de fichiers est éphémère et les processus Web ne prennent en charge que les requêtes HTTP(S). Pour plus d'informations à ce sujet, consultez les commandes Dockerfile et le runtime .

Concepts Docker contre Heroku

DockerHéroku
Fichier DockerBuildPack
ImageLimace
RécipientDynamo

Configuration du projet

Créez un répertoire de projet, créez et activez un nouvel environnement virtuel et installez Django :

$ mkdir django-heroku-docker
$ cd django-heroku-docker

$ python3.10 -m venv env
$ source env/bin/activate

(env)$ pip install django==3.2.9

N'hésitez pas à échanger virtualenv et Pip contre Poetry ou Pipenv . Pour en savoir plus, consultez Environnements Python modernes .

Ensuite, créez un nouveau projet Django, appliquez les migrations et lancez le serveur :

(env)$ django-admin startproject hello_django .
(env)$ python manage.py migrate
(env)$ python manage.py runserver

Accédez à http://localhost:8000/ pour afficher l'écran de bienvenue de Django. Tuez le serveur et quittez l'environnement virtuel une fois terminé.

Docker

Ajoutez un Dockerfile à la racine du projet :

# pull official base image
FROM python:3.10-alpine

# set work directory
WORKDIR /app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0

# install psycopg2
RUN apk update \
    && apk add --virtual build-essential gcc python3-dev musl-dev \
    && apk add postgresql-dev \
    && pip install psycopg2

# install dependencies
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# copy project
COPY . .

# add and run as non-root user
RUN adduser -D myuser
USER myuser

# run gunicorn
CMD gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT

Ici, nous avons commencé avec une image Docker basée sur Alpine pour Python 3.10. Nous définissons ensuite un répertoire de travail avec deux variables d'environnement :

  1. PYTHONDONTWRITEBYTECODE: Empêche Python d'écrire des fichiers pyc sur le disque
  2. PYTHONUNBUFFERED: Empêche Python de mettre en mémoire tampon stdout et stderr

Ensuite, nous avons installé des dépendances au niveau du système et des packages Python, copié les fichiers du projet, créé et basculé vers un utilisateur non root (ce qui est recommandé par Heroku ) et utilisé CMD pour exécuter Gunicorn lorsqu'un conteneur tourne au moment de l'exécution. Prenez note de la $PORTvariable. Essentiellement, tout serveur Web qui s'exécute sur le Container Runtime doit écouter le trafic HTTP au niveau de $PORTla variable d'environnement, qui est définie par Heroku au moment de l'exécution .

Créez un fichier requirements.txt :

Django==3.2.9
gunicorn==20.1.0

Ajoutez ensuite un fichier .dockerignore :

__pycache__
*.pyc
env/
db.sqlite3

Mettez à jour les variables SECRET_KEY, DEBUGet dans settings.py :ALLOWED_HOSTS

SECRET_KEY = os.environ.get('SECRET_KEY', default='foo')

DEBUG = int(os.environ.get('DEBUG', default=0))

ALLOWED_HOSTS = ['localhost', '127.0.0.1']

N'oubliez pas l'importation :

import os

Pour tester localement, créez l'image et exécutez le conteneur, en veillant à transmettre les variables d'environnement appropriées :

$ docker build -t web:latest .
$ docker run -d --name django-heroku -e "PORT=8765" -e "DEBUG=1" -p 8007:8765 web:latest

Assurez-vous que l'application est en cours d'exécution sur http://localhost:8007/ dans votre navigateur. Arrêtez puis supprimez le conteneur en cours d'exécution une fois terminé :

$ docker stop django-heroku
$ docker rm django-heroku

Ajoutez un .gitignore :

__pycache__
*.pyc
env/
db.sqlite3

Ensuite, créons une vue Django rapide pour tester facilement l'application lorsque le mode débogage est désactivé.

Ajoutez un fichier views.py au répertoire "hello_django":

from django.http import JsonResponse


def ping(request):
    data = {'ping': 'pong!'}
    return JsonResponse(data)

Ensuite, mettez à jour urls.py :

from django.contrib import admin
from django.urls import path

from .views import ping


urlpatterns = [
    path('admin/', admin.site.urls),
    path('ping/', ping, name="ping"),
]

Testez ceci à nouveau avec le mode débogage désactivé :

$ docker build -t web:latest .
$ docker run -d --name django-heroku -e "PORT=8765" -e "DEBUG=0" -p 8007:8765 web:latest

Vérifiez que http://localhost:8007/ping/ fonctionne comme prévu :

{
  "ping": "pong!"
}

Arrêtez puis supprimez le conteneur en cours d'exécution une fois terminé :

$ docker stop django-heroku
$ docker rm django-heroku

Bruit blanc

Si vous souhaitez utiliser WhiteNoise pour gérer vos actifs statiques, ajoutez d'abord le package au fichier requirements.txt :

Django==3.2.9
gunicorn==20.1.0
whitenoise==5.3.0

Mettez à jour le middleware dans settings.py comme ceci :

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # new
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Configurez ensuite la gestion de vos fichiers statiques avec STATIC_ROOT:

STATIC_ROOT = BASE_DIR / 'staticfiles'

Enfin, ajoutez la prise en charge de la compression et de la mise en cache :

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Ajoutez la collectstaticcommande au Dockerfile :

# pull official base image
FROM python:3.10-alpine

# set work directory
WORKDIR /app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0

# install psycopg2
RUN apk update \
    && apk add --virtual build-essential gcc python3-dev musl-dev \
    && apk add postgresql-dev \
    && pip install psycopg2

# install dependencies
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# copy project
COPY . .

# collect static files
RUN python manage.py collectstatic --noinput

# add and run as non-root user
RUN adduser -D myuser
USER myuser

# run gunicorn
CMD gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT

Pour tester, créez la nouvelle image et lancez un nouveau conteneur :

$ docker build -t web:latest .
$ docker run -d --name django-heroku -e "PORT=8765" -e "DEBUG=1" -p 8007:8765 web:latest

Vous devriez pouvoir afficher les fichiers statiques lorsque vous exécutez :

$ docker exec django-heroku ls /app/staticfiles
$ docker exec django-heroku ls /app/staticfiles/admin

Arrêtez puis supprimez à nouveau le conteneur en cours d'exécution :

$ docker stop django-heroku
$ docker rm django-heroku

postgres

Pour que Postgres soit opérationnel, nous utiliserons le package dj_database_url pour générer le dictionnaire de configuration de base de données approprié pour les paramètres de Django en fonction d'une DATABASE_URLvariable d'environnement.

Ajoutez la dépendance au fichier requirements :

Django==3.2.9
dj-database-url==0.5.0
gunicorn==20.1.0
whitenoise==5.3.0

Ensuite, apportez les modifications suivantes aux paramètres pour mettre à jour la configuration de la base de données si le DATABASE_URLest présent :

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

DATABASE_URL = os.environ.get('DATABASE_URL')
db_from_env = dj_database_url.config(default=DATABASE_URL, conn_max_age=500, ssl_require=True)
DATABASES['default'].update(db_from_env)

Ainsi, si le DATABASE_URLn'est pas présent, SQLite sera toujours utilisé.

Ajoutez également l'importation en haut :

import dj_database_url

Nous testerons cela un peu après avoir créé une base de données Postgres sur Heroku.

Configuration Heroku

Créez un compte Heroku (si vous n'en avez pas déjà un), puis installez la CLI Heroku (si vous ne l'avez pas déjà fait).

Créez une nouvelle application :

$ heroku create
Creating app... done, ⬢ limitless-atoll-51647
https://limitless-atoll-51647.herokuapp.com/ | https://git.heroku.com/limitless-atoll-51647.git

Ajoutez la SECRET_KEYvariable d'environnement :

$ heroku config:set SECRET_KEY=SOME_SECRET_VALUE -a limitless-atoll-51647

Remplacez SOME_SECRET_VALUE-la par une chaîne générée aléatoirement d'au moins 50 caractères.

Ajoutez l'URL Heroku ci-dessus à la liste de ALLOWED_HOSTShello_django /settings.py comme suit :

ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'limitless-atoll-51647.herokuapp.com']

Assurez-vous de remplacer limitless-atoll-51647chacune des commandes ci-dessus par le nom de votre application.

Déploiement Heroku Docker

À ce stade, nous sommes prêts à commencer à déployer des images Docker sur Heroku. Avez-vous décidé de l'approche que vous souhaitez adopter ?

  1. Container Registry : déployez des images Docker pré-construites sur Heroku
  2. Build Manifest : étant donné un Dockerfile, Heroku construit et déploie l'image Docker

Incertain? Essayez-les tous les deux !

Approche #1 : Registre des conteneurs

Ignorez cette section si vous utilisez l'approche Build Manifest.

Encore une fois, avec cette approche, vous pouvez déployer des images Docker prédéfinies sur Heroku.

Connectez-vous au Heroku Container Registry , pour indiquer à Heroku que nous souhaitons utiliser le Container Runtime :

$ heroku container:login

Recréez l'image Docker et étiquetez-la au format suivant :

registry.heroku.com/<app>/<process-type>

Assurez-vous de remplacer <app>par le nom de l'application Heroku que vous venez de créer et <process-type>avec webpuisqu'il s'agira d'un processus Web .

Par exemple:

$ docker build -t registry.heroku.com/limitless-atoll-51647/web .

Poussez l'image vers le registre :

$ docker push registry.heroku.com/limitless-atoll-51647/web

Libérez l'image :

$ heroku container:release -a limitless-atoll-51647 web

Cela exécutera le conteneur. Vous devriez pouvoir voir l'application sur https://APP_NAME.herokuapp.com . Il devrait renvoyer un 404.

Essayez d'exécuter heroku open -a limitless-atoll-51647pour ouvrir l'application dans votre navigateur par défaut.

Vérifiez que https://APP_NAME.herokuapp.com/ping fonctionne également :

{
  "ping": "pong!"
}

Vous devriez également pouvoir afficher les fichiers statiques :

$ heroku run ls /app/staticfiles -a limitless-atoll-51647
$ heroku run ls /app/staticfiles/admin -a limitless-atoll-51647

Assurez-vous de remplacer limitless-atoll-51647chacune des commandes ci-dessus par le nom de votre application.

Accédez à la section "Test Postgres" une fois terminé.

Approche #2 : Construire un manifeste

Ignorez cette section si vous utilisez l'approche Container Registry.

Encore une fois, avec l' approche Build Manifest , vous pouvez demander à Heroku de créer et de déployer des images Docker basées sur un fichier manifeste heroku.yml .

Définissez la pile de votre application sur conteneur :

$ heroku stack:set container -a limitless-atoll-51647

Ajoutez un fichier heroku.yml à la racine du projet :

build:
  docker:
    web: Dockerfile

Ici, nous disons simplement à Heroku quel Dockerfile utiliser pour créer l'image.

Parallèlement à build, vous pouvez également définir les étapes suivantes :

  • setupest utilisé pour définir les modules complémentaires Heroku et les variables de configuration à créer lors du provisionnement de l'application.
  • releaseest utilisé pour définir les tâches que vous souhaitez exécuter lors d'une release.
  • runest utilisé pour définir les commandes à exécuter pour les processus Web et de travail.

Assurez-vous de consulter la documentation Heroku pour en savoir plus sur ces quatre étapes.

Il convient de noter que la gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORTcommande peut être supprimée du Dockerfile et ajoutée au fichier heroku.yml sous la runscène :

build:
  docker:
    web: Dockerfile
run:
  web: gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT

Assurez-vous également de placer la commande 'collectstatic' dans votre Dockerfile. Ne le déplacez pas sur releasescène. Pour en savoir plus, consultez cette question Stack Overflow .

Ensuite, installez le heroku-manifestplug-in à partir du canal CLI bêta :

$ heroku update beta
$ heroku plugins:install @heroku-cli/plugin-manifest

Avec cela, initialisez un référentiel Git et créez un commit.

Ensuite, ajoutez la télécommande Heroku :

$ heroku git:remote -a limitless-atoll-51647

Poussez le code jusqu'à Heroku pour créer l'image et exécuter le conteneur :

$ git push heroku master

Vous devriez pouvoir voir l'application sur https://APP_NAME.herokuapp.com . Il devrait renvoyer un 404.

Essayez d'exécuter heroku open -a limitless-atoll-51647pour ouvrir l'application dans votre navigateur par défaut.

Vérifiez que https://APP_NAME.herokuapp.com/ping fonctionne également :

{
  "ping": "pong!"
}

Vous devriez également pouvoir afficher les fichiers statiques :

$ heroku run ls /app/staticfiles -a limitless-atoll-51647
$ heroku run ls /app/staticfiles/admin -a limitless-atoll-51647

Assurez-vous de remplacer limitless-atoll-51647chacune des commandes ci-dessus par le nom de votre application.

Test Postgres

Créez la base de données :

$ heroku addons:create heroku-postgresql:hobby-dev -a limitless-atoll-51647

Cette commande définit automatiquement la DATABASE_URLvariable d'environnement pour le conteneur.

Une fois la base de données opérationnelle, exécutez les migrations :

$ heroku run python manage.py makemigrations -a limitless-atoll-51647
$ heroku run python manage.py migrate -a limitless-atoll-51647

Ensuite, sautez dans psql pour afficher les tables nouvellement créées :

$ heroku pg:psql -a limitless-atoll-51647

# \dt
                      List of relations
 Schema |            Name            | Type  |     Owner
--------+----------------------------+-------+----------------
 public | auth_group                 | table | siodzhzzcvnwwp
 public | auth_group_permissions     | table | siodzhzzcvnwwp
 public | auth_permission            | table | siodzhzzcvnwwp
 public | auth_user                  | table | siodzhzzcvnwwp
 public | auth_user_groups           | table | siodzhzzcvnwwp
 public | auth_user_user_permissions | table | siodzhzzcvnwwp
 public | django_admin_log           | table | siodzhzzcvnwwp
 public | django_content_type        | table | siodzhzzcvnwwp
 public | django_migrations          | table | siodzhzzcvnwwp
 public | django_session             | table | siodzhzzcvnwwp
(10 rows)

# \q

Encore une fois, assurez-vous de remplacer limitless-atoll-51647chacune des commandes ci-dessus par le nom de votre application Heroku.

CI GitLab

Créez un compte GitLab (si nécessaire), puis créez un nouveau projet (à nouveau, si nécessaire).

Récupérez votre jeton d'authentification Heroku :

$ heroku auth:token

Ensuite, enregistrez le jeton en tant que nouvelle variable appelée HEROKU_AUTH_TOKENdans les paramètres CI/CD de votre projet : Paramètres > CI/CD > Variables.

configuration gitlab

Ensuite, nous devons ajouter un fichier de configuration GitLab CI/CD appelé .gitlab-ci.yml à la racine du projet. Le contenu de ce fichier variera en fonction de l'approche utilisée.

Approche #1 : Registre des conteneurs

Ignorez cette section si vous utilisez l'approche Build Manifest.

.gitlab-ci.yml :

image: docker:stable
services:
  - docker:dind

variables:
  DOCKER_DRIVER: overlay2
  HEROKU_APP_NAME: <APP_NAME>
  HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web

stages:
  - build_and_deploy

build_and_deploy:
  stage: build_and_deploy
  script:
    - apk add --no-cache curl
    - docker login -u _ -p $HEROKU_AUTH_TOKEN registry.heroku.com
    - docker pull $HEROKU_REGISTRY_IMAGE || true
    - docker build
      --cache-from $HEROKU_REGISTRY_IMAGE
      --tag $HEROKU_REGISTRY_IMAGE
      --file ./Dockerfile
      "."
    - docker push $HEROKU_REGISTRY_IMAGE
    - chmod +x ./release.sh
    - ./release.sh

release.sh :

#!/bin/sh


IMAGE_ID=$(docker inspect ${HEROKU_REGISTRY_IMAGE} --format={{.Id}})
PAYLOAD='{"updates": [{"type": "web", "docker_image": "'"$IMAGE_ID"'"}]}'

curl -n -X PATCH https://api.heroku.com/apps/$HEROKU_APP_NAME/formation \
  -d "${PAYLOAD}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/vnd.heroku+json; version=3.docker-releases" \
  -H "Authorization: Bearer ${HEROKU_AUTH_TOKEN}"

Ici, nous avons défini une seule build_and_deploy étape où nous :

  1. Installer cURL
  2. Connectez-vous au registre de conteneurs Heroku
  3. Tirez l'image précédemment poussée (si elle existe)
  4. Construire et étiqueter la nouvelle image
  5. Poussez l'image jusqu'au registre
  6. Créez une nouvelle version via l' API Heroku en utilisant l'ID d'image dans le script release.sh

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Avec cela, initialisez un dépôt Git, validez, ajoutez la télécommande GitLab et poussez votre code jusqu'à GitLab pour déclencher un nouveau pipeline . Cela exécutera la build_and_deployscène comme un travail unique. Une fois terminée, une nouvelle version devrait être automatiquement créée sur Heroku.

Approche #2 : Construire un manifeste

Ignorez cette section si vous utilisez l'approche Container Registry.

.gitlab-ci.yml :

variables:
  HEROKU_APP_NAME: <APP_NAME>

stages:
  - deploy

deploy:
  stage: deploy
  script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN

Ici, nous avons défini une seule deploy étape où nous :

  1. Installez Ruby avec une gemme appelée dpl
  2. Déployer le code sur Heroku avec dpl

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Validez, ajoutez la télécommande GitLab et poussez votre code jusqu'à GitLab pour déclencher un nouveau pipeline . Cela exécutera l' deployétape comme un travail unique. Une fois terminé, le code doit être déployé sur Heroku.

IC avancée

Plutôt que de simplement créer l'image Docker et de créer une version sur GitLab CI, exécutons également les tests Django, Flake8 , Black et isort .

Encore une fois, cela variera en fonction de l'approche que vous avez utilisée.

Approche #1 : Registre des conteneurs

Ignorez cette section si vous utilisez l'approche Build Manifest.

Mettez à jour .gitlab-ci.yml comme suit :

stages:
  - build
  - test
  - deploy

variables:
  IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:latest || true
    - docker build
      --cache-from $IMAGE:latest
      --tag $IMAGE:latest
      --file ./Dockerfile
      "."
    - docker push $IMAGE:latest

test:
  stage: test
  image: $IMAGE:latest
  services:
    - postgres:latest
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: runner
    POSTGRES_PASSWORD: ""
    DATABASE_URL: postgresql://runner@postgres:5432/test
  script:
    - python manage.py test
    - flake8 hello_django --max-line-length=100
    - black hello_django --check
    - isort hello_django --check --profile black

deploy:
  stage: deploy
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
    HEROKU_APP_NAME: <APP_NAME>
    HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web
  script:
    - apk add --no-cache curl
    - docker login -u _ -p $HEROKU_AUTH_TOKEN registry.heroku.com
    - docker pull $HEROKU_REGISTRY_IMAGE || true
    - docker build
      --cache-from $HEROKU_REGISTRY_IMAGE
      --tag $HEROKU_REGISTRY_IMAGE
      --file ./Dockerfile
      "."
    - docker push $HEROKU_REGISTRY_IMAGE
    - chmod +x ./release.sh
    - ./release.sh

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Donc, nous avons maintenant trois étapes : build, test, et deploy.

Dans l' buildétape, nous :

  1. Connectez-vous au registre de conteneurs GitLab
  2. Tirez l'image précédemment poussée (si elle existe)
  3. Construire et étiqueter la nouvelle image
  4. Poussez l'image vers le registre de conteneurs GitLab

Ensuite, dans l' testétape, nous configurons Postgres , définissons la DATABASE_URLvariable d'environnement, puis exécutons les tests Django, Flake8, Black et isort en utilisant l'image qui a été construite à l'étape précédente.

Dans l' deployétape, nous :

  1. Installer cURL
  2. Connectez-vous au registre de conteneurs Heroku
  3. Tirez l'image précédemment poussée (si elle existe)
  4. Construire et étiqueter la nouvelle image
  5. Poussez l'image jusqu'au registre
  6. Créez une nouvelle version via l' API Heroku en utilisant l'ID d'image dans le script release.sh

Ajoutez les nouvelles dépendances au fichier requirements :

# prod
Django==3.2.9
dj-database-url==0.5.0
gunicorn==20.1.0
whitenoise==5.3.0

# dev and test
black==21.11b1
flake8==4.0.1
isort==5.10.1

Avant de passer à GitLab, exécutez les tests Django localement :

$ source env/bin/activate
(env)$ pip install -r requirements.txt
(env)$ python manage.py test

System check identified no issues (0 silenced).

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

Assurez-vous que Flake8 réussit, puis mettez à jour le code source en fonction des recommandations Black et isort :

(env)$ flake8 hello_django --max-line-length=100
(env)$ black hello_django
(env)$ isort hello_django --profile black

Validez et poussez votre code encore une fois. Assurez-vous que toutes les étapes passent.

Approche #2 : Construire un manifeste

Ignorez cette section si vous utilisez l'approche Container Registry.

Mettez à jour .gitlab-ci.yml comme suit :

stages:
  - build
  - test
  - deploy

variables:
  IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:latest || true
    - docker build
      --cache-from $IMAGE:latest
      --tag $IMAGE:latest
      --file ./Dockerfile
      "."
    - docker push $IMAGE:latest

test:
  stage: test
  image: $IMAGE:latest
  services:
    - postgres:latest
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: runner
    POSTGRES_PASSWORD: ""
    DATABASE_URL: postgresql://runner@postgres:5432/test
  script:
    - python manage.py test
    - flake8 hello_django --max-line-length=100
    - black hello_django --check
    - isort hello_django --check --profile black

deploy:
  stage: deploy
  variables:
    HEROKU_APP_NAME: <APP_NAME>
  script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Donc, nous avons maintenant trois étapes : build, test, et deploy.

Dans l' buildétape, nous :

  1. Connectez-vous au registre de conteneurs GitLab
  2. Tirez l'image précédemment poussée (si elle existe)
  3. Construire et étiqueter la nouvelle image
  4. Poussez l'image vers le registre de conteneurs GitLab

Ensuite, dans l' testétape, nous configurons Postgres , définissons la DATABASE_URLvariable d'environnement, puis exécutons les tests Django, Flake8, Black et isort en utilisant l'image qui a été construite à l'étape précédente.

Dans l' deployétape, nous :

  1. Installez Ruby avec une gemme appelée dpl
  2. Déployer le code sur Heroku avec dpl

Ajoutez les nouvelles dépendances au fichier requirements :

# prod
Django==3.2.9
dj-database-url==0.5.0
gunicorn==20.1.0
whitenoise==5.3.0

# dev and test
black==21.11b1
flake8==4.0.1
isort==5.10.1

Avant de passer à GitLab, exécutez les tests Django localement :

$ source env/bin/activate
(env)$ pip install -r requirements.txt
(env)$ python manage.py test

System check identified no issues (0 silenced).

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

Assurez-vous que Flake8 réussit, puis mettez à jour le code source en fonction des recommandations Black et isort :

(env)$ flake8 hello_django --max-line-length=100
(env)$ black hello_django
(env)$ isort hello_django --profile black

Validez et poussez votre code encore une fois. Assurez-vous que toutes les étapes passent.

Construction Docker en plusieurs étapes

Enfin, mettez à jour le Dockerfile comme ceci pour utiliser une construction en plusieurs étapes afin de réduire la taille finale de l'image :

FROM python:3.10-alpine AS build-python
RUN apk update && apk add --virtual build-essential gcc python3-dev musl-dev postgresql-dev
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY ./requirements.txt .
RUN pip install -r requirements.txt

FROM python:3.10-alpine
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0
ENV PATH="/opt/venv/bin:$PATH"
COPY --from=build-python /opt/venv /opt/venv
RUN apk update && apk add --virtual build-deps gcc python3-dev musl-dev postgresql-dev
RUN pip install psycopg2-binary
WORKDIR /app
COPY . .
RUN python manage.py collectstatic --noinput
RUN adduser -D myuser
USER myuser
CMD gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT

Ensuite, nous devons mettre à jour la configuration GitLab pour tirer parti de la mise en cache de la couche Docker.

Approche #1 : Registre des conteneurs

Ignorez cette section si vous utilisez l'approche Build Manifest.

.gitlab-ci.yml :

stages:
  - build
  - test
  - deploy

variables:
  IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
  HEROKU_APP_NAME: <APP_NAME>
  HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:build-python || true
    - docker pull $IMAGE:production || true
    - docker build
      --target build-python
      --cache-from $IMAGE:build-python
      --tag $IMAGE:build-python
      --file ./Dockerfile
      "."
    - docker build
      --cache-from $IMAGE:production
      --tag $IMAGE:production
      --tag $HEROKU_REGISTRY_IMAGE
      --file ./Dockerfile
      "."
    - docker push $IMAGE:build-python
    - docker push $IMAGE:production

test:
  stage: test
  image: $IMAGE:production
  services:
    - postgres:latest
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: runner
    POSTGRES_PASSWORD: ""
    DATABASE_URL: postgresql://runner@postgres:5432/test
  script:
    - python manage.py test
    - flake8 hello_django --max-line-length=100
    - black hello_django --check
    - isort hello_django --check --profile black

deploy:
  stage: deploy
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - apk add --no-cache curl
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:build-python || true
    - docker pull $IMAGE:production || true
    - docker build
      --target build-python
      --cache-from $IMAGE:build-python
      --tag $IMAGE:build-python
      --file ./Dockerfile
      "."
    - docker build
      --cache-from $IMAGE:production
      --tag $IMAGE:production
      --tag $HEROKU_REGISTRY_IMAGE
      --file ./Dockerfile
      "."
    - docker push $IMAGE:build-python
    - docker push $IMAGE:production
    - docker login -u _ -p $HEROKU_AUTH_TOKEN registry.heroku.com
    - docker push $HEROKU_REGISTRY_IMAGE
    - chmod +x ./release.sh
    - ./release.sh

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Examinez les modifications par vous-même. Ensuite, testez-le une dernière fois.

Pour en savoir plus sur ce modèle de mise en cache, consultez la section "Multi-stage" de l'article Faster CI Builds with Docker Cache .

Approche #2 : Construire un manifeste

Ignorez cette section si vous utilisez l'approche Container Registry.

.gitlab-ci.yml :

stages:
  - build
  - test
  - deploy

variables:
  IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
  HEROKU_APP_NAME: <APP_NAME>

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:build-python || true
    - docker pull $IMAGE:production || true
    - docker build
      --target build-python
      --cache-from $IMAGE:build-python
      --tag $IMAGE:build-python
      --file ./Dockerfile
      "."
    - docker build
      --cache-from $IMAGE:production
      --tag $IMAGE:production
      --file ./Dockerfile
      "."
    - docker push $IMAGE:build-python
    - docker push $IMAGE:production

test:
  stage: test
  image: $IMAGE:production
  services:
    - postgres:latest
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: runner
    POSTGRES_PASSWORD: ""
    DATABASE_URL: postgresql://runner@postgres:5432/test
  script:
    - python manage.py test
    - flake8 hello_django --max-line-length=100
    - black hello_django --check
    - isort hello_django --check --profile black

deploy:
  stage: deploy
  script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Examinez les modifications par vous-même. Ensuite, testez-le une dernière fois.

Pour en savoir plus sur ce modèle de mise en cache, consultez la section "Multi-stage" de l'article Faster CI Builds with Docker Cache .

Conclusion

Dans cet article, nous avons parcouru deux approches pour déployer une application Django sur Heroku avec Docker : le registre de conteneurs et le manifeste de construction.

Alors, quand devriez-vous penser à utiliser Heroku Container Runtime plutôt que le compilateur Git et slug traditionnel pour les déploiements ?

Lorsque vous avez besoin de plus de contrôle sur l'environnement de déploiement de production.

Exemples:

  1. Votre application et vos dépendances dépassent la limite maximale de 500 Mo de slug.
  2. Votre application nécessite des packages non installés par les packs de construction Heroku habituels.
  3. Vous voulez une plus grande assurance que votre application se comportera de la même manière en développement qu'en production.
  4. Vous aimez vraiment, vraiment travailler avec Docker.

Source :  https://testdrive.io

#django #heroku #docker 

JavaScript Dev

JavaScript Dev

1588754605

Webpacker gem provide "it-just-works" webpack integration with Rails?

How does the Webpacker gem provide “it-just-works” webpack integration with Rails? That simplicity did not come easily. The rich functionality, complexity, and rapid evolution of the webpack ecosystem necessitated extension points beyond a simple Ruby config file.

Yet you need to know almost nothing about webpack to leverage the modern JavaScript ecosystem. But what if you want to extend the standard configuration? What information might help you upgrade webpack and webpacker in the future?

This talk will explain the magical plumbing of Webpacker so you can leverage the webpack ecosystem on your terms.

For the talk slides, email Justin at justin@shakacode.com


Justin has been a passionate user of webpack since early 2014 when he just could not stand copy-pasting one more jQuery file into his Rails project. In 2015, he created the gem “React on Rails,” which integrated server-side rendered React and Webpack with Rails long before the Webpacker gem. These days, as CEO of ShakaCode.com, he helps companies optimize their Rails websites. He and his ShakaCode team also build Rails apps with modern front-ends, including their startup app, HiChee.com.

#webpack #javascript #ruby #webpacker #rails